WiP (in-tunnel data forwarding)
[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 HANDLER HELPERS
30  * - MESH NETWORK HANDLES
31  * - MESH LOCAL HANDLER HELPERS
32  * - MESH LOCAL HANDLES
33  * - PERIODIC FUNCTIONS
34  * - MAIN FUNCTIONS (main & run)
35  * 
36  * TODO:
37  * - error reporting (CREATE/CHANGE/ADD/DEL?) -- new message!
38  * - partial disconnect reporting -- same as error reporting?
39  * - add vs create? change vs. keep-alive? same msg or different ones? -- thinking...
40  * - speed requirement specification (change?) in mesh API -- API call
41  * - add ping message (connection confirmation, others?)
42  */
43
44 #include "platform.h"
45 #include "gnunet_common.h"
46 #include "gnunet_util_lib.h"
47 #include "gnunet_peer_lib.h"
48 #include "gnunet_core_service.h"
49 #include "gnunet_protocols.h"
50
51 #include "mesh.h"
52 #include "mesh_protocol.h"
53 #include "gnunet_dht_service.h"
54
55 #define REFRESH_PATH_TIME GNUNET_TIME_relative_multiply(\
56                                     GNUNET_TIME_UNIT_SECONDS,\
57                                     300)
58
59
60 /******************************************************************************/
61 /************************      DATA STRUCTURES     ****************************/
62 /******************************************************************************/
63
64 /**
65  * Information regarding a path
66  */
67 struct MeshPath
68 {
69
70     /**
71      * Linked list
72      */
73     struct MeshPath             *next;
74     struct MeshPath             *prev;
75
76     /**
77      * Whether the path is serving traffic in a tunnel or is a backup
78      */
79     int                         in_use;
80
81     /**
82      * List of all the peers that form the path from origin to target
83      */
84     GNUNET_PEER_Id              *peers;
85
86     /**
87      * Number of peers (hops) in the path
88      */
89     unsigned int                length;
90 };
91
92
93 /**
94  * All the states a peer participating in a tunnel can be in.
95  */
96 enum MeshPeerState
97 {
98     /**
99      * Path to the peer not known yet
100      */
101     MESH_PEER_SEARCHING,
102
103     /**
104      * Request sent, not yet answered.
105      */
106     MESH_PEER_WAITING,
107
108     /**
109      * Peer connected and ready to accept data
110      */
111     MESH_PEER_READY,
112
113     /**
114      * Peer connected previosly but not responding
115      */
116     MESH_PEER_RECONNECTING
117 };
118
119
120 /**
121  * Struct containing all information regarding a given peer
122  */
123 struct MeshPeerInfo
124 {
125     /**
126      * ID of the peer
127      */
128     GNUNET_PEER_Id              id;
129
130     /**
131      * Is the peer reachable? Is the peer even connected?
132      */
133     enum MeshPeerState          state;
134
135     /**
136      * Last time we heard from this peer
137      */
138     struct GNUNET_TIME_Absolute last_contact;
139
140     /**
141      * Number of attempts to reconnect so far
142      */
143     int                         n_reconnect_attempts;
144
145     /**
146      * Paths to reach the peer
147      */
148     struct MeshPath             *path;
149     struct MeshPath             *path_tail;
150
151     /**
152      * Handle to stop the DHT search for a path to this peer
153      */
154     struct GNUNET_DHT_GetHandle *dhtget;
155 };
156
157
158 /**
159  * Data scheduled to transmit (to local client or remote peer)
160  */
161 struct MeshQueue
162 {
163     /**
164      * Double linked list
165      */
166     struct MeshQueue            *next;
167     struct MeshQueue            *prev;
168
169     /**
170      * Target of the data (NULL if target is client)
171      */
172     struct MeshPeerInfo         *peer;
173
174     /**
175      * Client to send the data to (NULL if target is peer)
176      */
177     struct MeshClient           *client;
178
179     /**
180      * Size of the message to transmit
181      */
182     unsigned int                size;
183
184     /**
185      * How old is the data?
186      */
187     struct GNUNET_TIME_Absolute timestamp;
188
189     /**
190      * Data itself
191      */
192     struct GNUNET_MessageHeader *data;
193 };
194
195 /**
196  * Globally unique tunnel identification (owner + number)
197  * DO NOT USE OVER THE NETWORK
198  */
199 struct MESH_TunnelID {
200     /**
201      * Node that owns the tunnel
202      */
203     GNUNET_PEER_Id      oid;
204
205     /**
206      * Tunnel number to differentiate all the tunnels owned by the node oid
207      * ( tid < GNUNET_MESH_LOCAL_TUNNEL_ID_MARK )
208      */
209     MESH_TunnelNumber   tid;
210 };
211
212
213 struct MeshClient; /* FWD declaration */
214 /**
215  * Struct containing all information regarding a tunnel
216  * For an intermediate node the improtant info used will be:
217  * - id        Tunnel unique identification
218  * - paths[0]  To know where to send it next
219  * - metainfo: ready, speeds, accounting
220  */
221 struct MeshTunnel
222 {
223     /**
224      * Tunnel ID
225      */
226     struct MESH_TunnelID        id;
227
228     /**
229      * Local tunnel number ( >= GNUNET_MESH_LOCAL_TUNNEL_ID_MARK or 0 )
230      */
231     MESH_TunnelNumber           local_tid;
232
233     /**
234      * Last time the tunnel was used
235      */
236     struct GNUNET_TIME_Absolute timestamp;
237
238     /**
239      * Peers in the tunnelindexed by PeerIdentity (MeshPeerInfo)
240      */
241     struct GNUNET_CONTAINER_MultiHashMap* peers;
242
243     /**
244      * Number of peers that are connected and potentially ready to receive data
245      */
246     unsigned int                peers_ready;
247
248     /**
249      * Number of peers that have been added to the tunnel
250      */
251     unsigned int                peers_total;
252
253
254     /**
255      * Client owner of the tunnel, if any
256      */
257     struct MeshClient           *client;
258
259     /**
260      * Messages ready to transmit
261      */
262     struct MeshQueue            *queue_head;
263     struct MeshQueue            *queue_tail;
264
265 };
266
267 /**
268  * Struct containing information about a client of the service
269  */
270 struct MeshClient
271 {
272     /**
273      * Linked list
274      */
275     struct MeshClient           *next;
276     struct MeshClient           *prev;
277
278     /**
279      * Tunnels that belong to this client, indexed by local id
280      */
281     struct GNUNET_CONTAINER_MultiHashMap* tunnels;
282
283     /**
284      * Handle to communicate with the client
285      */
286     struct GNUNET_SERVER_Client *handle;
287
288     /**
289      * Applications that this client has claimed to provide
290      */
291     GNUNET_MESH_ApplicationType *apps;
292     unsigned int                app_counter;
293
294     /**
295      * Messages that this client has declared interest in
296      */
297     uint16_t                    *types;
298     unsigned int                type_counter;
299
300 };
301
302 /******************************************************************************/
303 /***********************      GLOBAL VARIABLES     ****************************/
304 /******************************************************************************/
305
306 /**
307  * All the clients
308  */
309 static struct MeshClient                *clients;
310 static struct MeshClient                *clients_tail;
311
312 /**
313  * Tunnels known, indexed by MESH_TunnelID (MeshTunnel)
314  */
315 struct GNUNET_CONTAINER_MultiHashMap    *tunnels;
316
317 /**
318  * Peers known, indexed by PeerIdentity (MeshPeerInfo)
319  */
320 struct GNUNET_CONTAINER_MultiHashMap    *peers;
321
322 /**
323  * Handle to communicate with core
324  */
325 static struct GNUNET_CORE_Handle        *core_handle;
326
327 /**
328  * Handle to use DHT
329  */
330 static struct GNUNET_DHT_Handle         *dht_handle;
331
332 /**
333  * Local peer own ID (memory efficient handle)
334  */
335 static GNUNET_PEER_Id                   myid;
336
337 /**
338  * Tunnel ID for the next created tunnel (global tunnel number)
339  */
340 static MESH_TunnelNumber                next_tid;
341
342 /******************************************************************************/
343 /******************      GENERAL HELPER FUNCTIONS      ************************/
344 /******************************************************************************/
345
346 /**
347  * Retrieve the MeshPeerInfo stucture associated with the peer, create one
348  * and inster it in the appropiate structures if the peer is not known yet.
349  * @param peer Identity of the peer
350  * @return Existing or newly created peer info
351  */
352 static struct MeshPeerInfo *
353 get_peer_info (const struct GNUNET_PeerIdentity *peer)
354 {
355     struct MeshPeerInfo *       peer_info;
356
357     peer_info = GNUNET_CONTAINER_multihashmap_get(peers,
358                                                   &peer->hashPubKey);
359     if (NULL == peer_info) {
360         peer_info = (struct MeshPeerInfo *)
361                     GNUNET_malloc(sizeof(struct MeshPeerInfo));
362         GNUNET_CONTAINER_multihashmap_put(peers,
363                             &peer->hashPubKey,
364                             peer_info,
365                             GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
366         peer_info->id = GNUNET_PEER_intern(peer);
367         peer_info->state = MESH_PEER_SEARCHING;
368     }
369
370     return peer_info;
371 }
372
373 /**
374  * Find the first peer whom to send a packet to go down this path
375  * @param path The path to use
376  * @return short id of the next peer, myid in case of local delivery,
377  * or 0 in case of error
378  */
379 static GNUNET_PEER_Id
380 get_first_hop (struct MeshPath *path)
381 {
382     unsigned int        i;
383
384     while (NULL != path) {
385         if (path->in_use) break;
386         path = path->next;
387     }
388     if (NULL == path) {
389         GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
390                    "tried to get the next hop from an invalid path\n");
391         return 0;
392     }
393
394     for (i = 0; i < path->length; i++) {
395         if (path->peers[i] == myid) {
396             if (i < path->length - 1) {
397                 return path->peers[i+1];
398             } else {
399                 return myid;
400             }
401         }
402     }
403     return 0;
404 }
405
406
407 /**
408  * Get the cost of the path.
409  * @param path The path to analyze
410  * @return Number of hops to reach destination, UINT_MAX in case the peer is not
411  * in the path
412  */
413 static unsigned int
414 get_path_cost(struct MeshPath *path)
415 {
416     unsigned int        i;
417
418     if (NULL == path) return UINT_MAX;
419     for (i = 0; i < path->length; i++) {
420         if (path->peers[i] == myid) {
421             return path->length - i;
422         }
423     }
424     return UINT_MAX;
425 }
426
427
428 /**
429  * Add the path to the peer and update the path used to reach it in case this
430  * is the shortest.
431  * @param peer_info Destination peer to add the path to.
432  * @param path New path to add. Last peer must be the peer in arg 1.
433  */
434 static void
435 add_path_to_peer(struct MeshPeerInfo *peer_info, struct MeshPath *path)
436 {
437     unsigned int        i;
438     unsigned int        new_cost;
439     unsigned int        best_cost;
440     struct MeshPath     *aux;
441     struct MeshPath     *best;
442
443     if (NULL == peer_info || NULL == path) return;
444
445     new_cost = get_path_cost(path);
446     best_cost = UINT_MAX;
447     best = NULL;
448     for (aux = peer_info->path; aux != NULL; aux = aux->next) {
449         if ((i = get_path_cost(aux)) < best_cost) {
450             best = aux;
451             best_cost = i;
452         }
453     }
454     if (best_cost < new_cost) {
455         path->in_use = 0;
456         GNUNET_CONTAINER_DLL_insert_tail(peer_info->path,
457                                          peer_info->path_tail,
458                                          path);
459     } else {
460         if (NULL != best) best->in_use = 0;
461         path->in_use = 1;
462         GNUNET_CONTAINER_DLL_insert(peer_info->path,
463                                     peer_info->path_tail,
464                                     path);
465     }
466     return;
467 }
468
469
470 /**
471  * Add the path to the peer and update the path used to reach it in case this
472  * is the shortest. The path is given in reverse, the destination peer is
473  * path[0]. The function modifies the path, inverting it to use the origin as
474  * destination.
475  * @param peer_info Destination peer to add the path to.
476  * @param path New path to add. First peer must be the peer in arg 1.
477  */
478 static void
479 add_path_to_origin(struct MeshPeerInfo *peer_info, struct MeshPath *path)
480 {
481     GNUNET_PEER_Id      aux;
482     unsigned int        i;
483
484     for (i = 0; i < path->length/2; i++) {
485         aux = path->peers[i];
486         path->peers[i] = path->peers[path->length - i - 1];
487         path->peers[path->length - i - 1] = aux;
488     }
489     add_path_to_peer(peer_info, path);
490 }
491
492
493 /**
494  * Check if client has registered with the service and has not disconnected
495  * @param client the client to check
496  * @return non-NULL if client exists in the global DLL
497  */
498 static struct MeshClient *
499 retrieve_client (struct GNUNET_SERVER_Client *client)
500 {
501     struct MeshClient       *c;
502
503     c = clients; 
504     while (NULL != c) {
505         if (c->handle == client) return c;
506         c = c->next;
507     }
508     return NULL;
509 }
510
511
512 /**
513  * Search for a tunnel among the tunnels for a client
514  * @param client the client whose tunnels to search in
515  * @param tid the local id of the tunnel
516  * @return tunnel handler, NULL if doesn't exist
517  */
518 static struct MeshTunnel *
519 retrieve_tunnel_by_local_id (struct MeshClient *c, MESH_TunnelNumber tid)
520 {
521     GNUNET_HashCode hash;
522
523     GNUNET_CRYPTO_hash(&tid, sizeof(MESH_TunnelNumber), &hash);
524     return GNUNET_CONTAINER_multihashmap_get(c->tunnels, &hash);
525 }
526
527 /**
528  * Search for a tunnel by global ID using PEER_ID
529  * @param pi owner of the tunnel
530  * @param tid global tunnel number
531  * @return tunnel handler, NULL if doesn't exist
532  */
533 static struct MeshTunnel *
534 retrieve_tunnel_by_pi (GNUNET_PEER_Id pi, MESH_TunnelNumber tid)
535 {
536     struct MESH_TunnelID        id;
537     GNUNET_HashCode             hash;
538
539     id.oid = pi;
540     id.tid = tid;
541
542     GNUNET_CRYPTO_hash(&id, sizeof(struct MESH_TunnelID), &hash);
543     return GNUNET_CONTAINER_multihashmap_get(tunnels, &hash);
544 }
545
546
547
548 /**
549  * Search for a tunnel by global ID using full PeerIdentities
550  * @param oid owner of the tunnel
551  * @param tid global tunnel number
552  * @return tunnel handler, NULL if doesn't exist
553  */
554 static struct MeshTunnel *
555 retrieve_tunnel (struct GNUNET_PeerIdentity *oid, MESH_TunnelNumber tid)
556 {
557     return retrieve_tunnel_by_pi(GNUNET_PEER_search(oid), tid);
558 }
559
560
561 /**
562  * Destroy the path and free any allocated resources linked to it
563  * @param t tunnel the path belongs to
564  * @param p the path to destroy
565  * @return GNUNET_OK on success
566  */
567 static int
568 destroy_path(struct MeshPath *p)
569 {
570     GNUNET_PEER_decrement_rcs(p->peers, p->length);
571     GNUNET_free(p->peers);
572     GNUNET_free(p);
573     return GNUNET_OK;
574 }
575
576 #if LATER
577 /**
578  * Destroy the peer_info and free any allocated resources linked to it
579  * @param t tunnel the path belongs to
580  * @param pi the peer_info to destroy
581  * @return GNUNET_OK on success
582  */
583 static int
584 destroy_peer_info(struct MeshPeerInfo *pi)
585 {
586     GNUNET_HashCode                     hash;
587     struct GNUNET_PeerIdentity          id;
588
589     GNUNET_PEER_resolve(pi->id, &id);
590     GNUNET_PEER_change_rc(pi->id, -1);
591     GNUNET_CRYPTO_hash(&id, sizeof(struct GNUNET_PeerIdentity), &hash);
592
593     GNUNET_CONTAINER_multihashmap_remove(peers, &hash, pi);
594     GNUNET_free(pi);
595     return GNUNET_OK;
596 }
597 #endif
598
599
600 /**
601  * Destroy the tunnel and free any allocated resources linked to it
602  * @param c client the tunnel belongs to
603  * @param t the tunnel to destroy
604  * @return GNUNET_OK on success
605  */
606 static int
607 destroy_tunnel(struct MeshTunnel  *t)
608 {
609     struct MeshClient           *c;
610     GNUNET_HashCode             hash;
611     int                         r;
612
613     if (NULL == t) return GNUNET_OK;
614
615     c = t->client;
616
617     GNUNET_CRYPTO_hash(&t->id, sizeof(struct MESH_TunnelID), &hash);
618     if(GNUNET_YES != GNUNET_CONTAINER_multihashmap_remove(tunnels, &hash, t)) {
619         r = GNUNET_SYSERR;
620     }
621
622     GNUNET_CRYPTO_hash(&t->local_tid, sizeof(MESH_TunnelNumber), &hash);
623     if(GNUNET_YES !=
624         GNUNET_CONTAINER_multihashmap_remove(c->tunnels, &hash, t))
625     {
626         r = GNUNET_SYSERR;
627     }
628     GNUNET_free(t);
629     return r;
630 }
631
632 /******************************************************************************/
633 /****************      MESH NETWORK HANDLER HELPERS     ***********************/
634 /******************************************************************************/
635
636 /**
637  * Function called to notify a client about the socket
638  * being ready to queue more data.  "buf" will be
639  * NULL and "size" zero if the socket was closed for
640  * writing in the meantime.
641  *
642  * @param cls closure
643  * @param size number of bytes available in buf
644  * @param buf where the callee should write the message
645  * @return number of bytes written to buf
646  */
647 static size_t
648 send_core_create_path_for_peer (void *cls, size_t size, void *buf)
649 {
650     struct MeshPeerInfo                 *peer_info = cls;
651     struct GNUNET_MESH_ManipulatePath   *msg;
652     struct MeshPath                     *p;
653     struct GNUNET_PeerIdentity          *peer_ptr;
654     struct GNUNET_PeerIdentity          id;
655     size_t                              size_needed;
656     int                                 i;
657
658     if (0 == size && NULL == buf) {
659         GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Retransmitting create path\n");
660         GNUNET_PEER_resolve(get_first_hop(peer_info->path), &id);
661         GNUNET_CORE_notify_transmit_ready(core_handle,
662                             0,
663                             0,
664                             GNUNET_TIME_UNIT_FOREVER_REL,
665                             &id,
666                             sizeof(struct GNUNET_MESH_ManipulatePath)
667                             + (peer_info->path->length
668                             * sizeof (struct GNUNET_PeerIdentity)),
669                             &send_core_create_path_for_peer,
670                             peer_info);
671         return 0;
672     }
673     p = peer_info->path;
674     while (NULL != p) {
675         if (p->in_use) {
676             break;
677         }
678         p = p->next;
679     }
680     if (p == NULL) return 0; // TODO Notify ERROR Path not found
681
682     size_needed = sizeof(struct GNUNET_MESH_ManipulatePath)
683                   + p->length * sizeof(struct GNUNET_PeerIdentity);
684     if (size < size_needed) {
685         // TODO retry? cancel?
686         return 0;
687     }
688
689     msg = (struct GNUNET_MESH_ManipulatePath *) buf;
690     msg->header.size = htons(size_needed);
691     msg->header.type = htons(GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE);
692
693     peer_ptr = (struct GNUNET_PeerIdentity *) &msg[1];
694     for (i = 0; i < p->length; i++) {
695         GNUNET_PEER_resolve(p->peers[i], peer_ptr++);
696     }
697
698     peer_info->state = MESH_PEER_WAITING;
699
700     return size_needed;
701 }
702
703 /**
704  * FIXME / COMMENT
705  * There are several options to send a "data to origin" or similar packet.
706  * The core callback function needs to know at least: ID of tunnel and the
707  * data itself, so one parameter (cls) is not enough.
708  * 1. Build the message inside the original funtction, call core_ntfy_trnsmt_rdy
709  *    passing the created message as cls
710  *    - # memcpy: 2 (function X: to message struct, callback: from cls to buf)
711  *    - Very messy, original function becomes huge and ugly
712  *      (see "handle_mesh_path_create" for example)
713  * 2. Create a helper function to build the packet, then call
714  *    core_ntfy_trnsmt_rdy with message as cls.
715  *    - # memcpy: 2 (in helper function data->msg and in callback cls->buf)
716  * 3- Define new container, pass container with pointers
717  *    - # memcpy = 1 (in callback, cls->buf)
718  *    - Noise: extra containers defined per type of message
719  */
720     struct info_for_data_to_origin
721 {
722     struct MESH_TunnelID        *origin;
723     void                        *data;
724     size_t                      size;
725 };
726
727 /**
728  * Function called to notify a client about the socket
729  * being ready to queue more data.  "buf" will be
730  * NULL and "size" zero if the socket was closed for
731  * writing in the meantime.
732  *
733  * @param cls closure (info_for_data_to_origin with all info to build packet)
734  * @param size number of bytes available in buf
735  * @param buf where the callee should write the message
736  * @return number of bytes written to buf
737  */
738 static size_t
739 send_core_data_to_origin (void *cls, size_t size, void *buf)
740 {
741     struct info_for_data_to_origin              *info = cls;
742     struct GNUNET_MESH_DataMessageToOrigin      *msg = buf;
743     size_t                                      total_size;
744
745     GNUNET_assert(NULL != info);
746     total_size = sizeof(struct GNUNET_MESH_DataMessageToOrigin) + info->size;
747     GNUNET_assert(total_size < (uint16_t) -1); /* FIXME */
748
749     if (total_size > size) {
750         GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
751                    "not enough buffer to send data to origin\n");
752         return 0;
753     }
754     msg->header.size = htons(total_size);
755     msg->header.type = htons(GNUNET_MESSAGE_TYPE_DATA_MESSAGE_TO_ORIGIN);
756     GNUNET_PEER_resolve(info->origin->oid, &msg->oid);
757     msg->tid = htonl(info->origin->tid);
758     if (0 != info->size && NULL != info->data) {
759         memcpy(&msg[1], info->data, info->size);
760     }
761     GNUNET_free(info);
762     return total_size;
763 }
764
765 /**
766  * Function called to notify a client about the socket
767  * being ready to queue more data.  "buf" will be
768  * NULL and "size" zero if the socket was closed for
769  * writing in the meantime.
770  *
771  * @param cls closure (data itself)
772  * @param size number of bytes available in buf
773  * @param buf where the callee should write the message
774  * @return number of bytes written to buf
775  */
776 static size_t
777 send_core_data_from_origin (void *cls, size_t size, void *buf)
778 {
779     struct GNUNET_MESH_DataMessageFromOrigin    *msg = cls;
780     size_t                                      total_size;
781
782     GNUNET_assert(NULL != msg);
783     total_size = ntohs(msg->header.size);
784
785     if (total_size > size) {
786         GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
787                    "not enough buffer to send data futher\n");
788         return 0;
789     }
790     memcpy(msg, buf, total_size);
791     return total_size;
792 }
793
794
795 #if LATER
796 /**
797  * Function called to notify a client about the socket
798  * being ready to queue more data.  "buf" will be
799  * NULL and "size" zero if the socket was closed for
800  * writing in the meantime.
801  *
802  * @param cls closure (data itself)
803  * @param size number of bytes available in buf
804  * @param buf where the callee should write the message
805  * @return number of bytes written to buf
806  */
807 static size_t
808 send_core_data_to_peer (void *cls, size_t size, void *buf)
809 {
810     struct info_for_data_to_origin              *info = cls;
811     struct GNUNET_MESH_DataMessageToOrigin      *msg = buf;
812     size_t                                      total_size;
813
814     GNUNET_assert(NULL != info);
815     total_size = sizeof(struct GNUNET_MESH_DataMessageToOrigin) + info->size;
816     /* FIXME better constant? short >= 16 bits, not == 16 bits... */
817     GNUNET_assert(total_size < USHRT_MAX);
818
819     if (total_size > size) {
820         GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
821                    "not enough buffer to send data to origin\n");
822         return 0;
823     }
824     msg->header.size = htons(total_size);
825     msg->header.type = htons(GNUNET_MESSAGE_TYPE_DATA_MESSAGE_TO_ORIGIN);
826     GNUNET_PEER_resolve(info->origin->oid, &msg->oid);
827     msg->tid = htonl(info->origin->tid);
828     if (0 != info->size && NULL != info->data) {
829         memcpy(&msg[1], info->data, info->size);
830     }
831     GNUNET_free(info);
832     return total_size;
833 }
834
835
836 /**
837  * Send another peer a notification to destroy a tunnel
838  * @param cls The tunnel to destroy
839  * @param size Size in the buffer
840  * @param buf Memory where to put the data to transmit
841  * @return Size of data put in buffer
842  */
843 static size_t
844 send_p2p_tunnel_destroy(void *cls, size_t size, void *buf)
845 {
846     struct MeshTunnel                   *t = cls;
847     struct MeshClient                   *c;
848     struct GNUNET_MESH_TunnelMessage    *msg;
849
850     c = t->client;
851     msg = buf;
852     msg->header.type = htons(GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_DESTROY); /*FIXME*/
853     msg->header.size = htons(sizeof(struct GNUNET_MESH_TunnelMessage));
854     msg->tunnel_id = htonl(t->id.tid);
855
856     destroy_tunnel(c, t);
857     return sizeof(struct GNUNET_MESH_TunnelMessage);
858 }
859 #endif
860
861
862 /******************************************************************************/
863 /********************      MESH NETWORK HANDLERS     **************************/
864 /******************************************************************************/
865
866
867 /**
868  * Core handler for path creation
869  * struct GNUNET_CORE_MessageHandler
870  *
871  * @param cls closure
872  * @param message message
873  * @param peer peer identity this notification is about
874  * @param atsi performance data
875  * @return GNUNET_OK to keep the connection open,
876  *         GNUNET_SYSERR to close it (signal serious error)
877  *
878  */
879 static int
880 handle_mesh_path_create (void *cls,
881                               const struct GNUNET_PeerIdentity *peer,
882                               const struct GNUNET_MessageHeader *message,
883                               const struct GNUNET_TRANSPORT_ATS_Information
884                               *atsi)
885 {
886     unsigned int                        own_pos;
887     uint16_t                            size;
888     uint16_t                            i;
889     MESH_TunnelNumber                   tid;
890     struct GNUNET_MESH_ManipulatePath   *msg;
891     struct GNUNET_PeerIdentity          *pi;
892     struct GNUNET_PeerIdentity          id;
893     GNUNET_HashCode                     hash;
894     struct MeshPath                     *path;
895     struct MeshPeerInfo                 *dest_peer_info;
896     struct MeshPeerInfo                 *orig_peer_info;
897     struct MeshTunnel                   *t;
898
899
900     size = ntohs(message->size);
901     if (size < sizeof(struct GNUNET_MESH_ManipulatePath)) {
902         GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
903                    "received create path message too short\n");
904         return GNUNET_OK;
905     }
906
907     size -= sizeof(struct GNUNET_MESH_ManipulatePath);
908     if (size < 2 * sizeof(struct GNUNET_PeerIdentity)) {
909         GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
910                    "create path message lacks enough peers\n");
911         return GNUNET_OK;
912     }
913     if (size % sizeof(struct GNUNET_PeerIdentity)) {
914         GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
915                    "create path message of wrong size\n");
916         return GNUNET_OK;
917     }
918     msg = (struct GNUNET_MESH_ManipulatePath *) message;
919     size /= sizeof(struct GNUNET_PeerIdentity);
920
921     tid = ntohl(msg->tid);
922     pi = (struct GNUNET_PeerIdentity *) &msg[1];
923     t = retrieve_tunnel(pi, tid);
924
925     if (NULL == t) {
926         t = GNUNET_malloc(sizeof(struct MeshTunnel));
927         t->id.oid = GNUNET_PEER_intern(pi);
928         t->id.tid = tid;
929         t->local_tid = 0;
930         t->client = NULL;
931         t->peers = GNUNET_CONTAINER_multihashmap_create(32);
932
933         GNUNET_CRYPTO_hash(&t->id, sizeof(struct MESH_TunnelID), &hash);
934         if (GNUNET_OK !=
935             GNUNET_CONTAINER_multihashmap_put(tunnels,
936                             &hash,
937                             t,
938                             GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
939         {
940             GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
941                    "create path: could not store tunnel in hashmap\n");
942             return GNUNET_OK;
943         }
944
945     }
946     dest_peer_info = GNUNET_CONTAINER_multihashmap_get(peers,
947                                                   &pi[size - 1].hashPubKey);
948     if (NULL == dest_peer_info) {
949         dest_peer_info = GNUNET_malloc(sizeof(struct MeshPeerInfo));
950         dest_peer_info->id = GNUNET_PEER_intern(&pi[size - 1]);
951         dest_peer_info->state = MESH_PEER_WAITING;
952         GNUNET_CONTAINER_multihashmap_put(peers,
953                             &pi[size - 1].hashPubKey,
954                             dest_peer_info,
955                             GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
956     }
957     orig_peer_info = GNUNET_CONTAINER_multihashmap_get(peers, &pi->hashPubKey);
958     if (NULL == orig_peer_info) {
959         orig_peer_info = GNUNET_malloc(sizeof(struct MeshPeerInfo));
960         orig_peer_info->id = GNUNET_PEER_intern(pi);
961         orig_peer_info->state = MESH_PEER_WAITING;
962         GNUNET_CONTAINER_multihashmap_put(peers,
963                             &pi->hashPubKey,
964                             orig_peer_info,
965                             GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
966     }
967
968
969     path = GNUNET_malloc(sizeof(struct MeshPath));
970     path->length = size;
971     path->peers = GNUNET_malloc(size * sizeof(GNUNET_PEER_Id));
972     own_pos = 0;
973     for (i = 0; i < size; i++) {
974         path->peers[i] = GNUNET_PEER_intern(&pi[i]);
975         if (path->peers[i] == myid) own_pos = i;
976     }
977     if (own_pos == 0) { /* cannot be self, must be 'not found' */
978         GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
979                    "create path: self not found in path through self\n");
980         destroy_path(path);
981         /* FIXME error. destroy tunnel? leave for timeout? */
982         return 0;
983     }
984     if (own_pos == size - 1) { /* it is for us! */
985         add_path_to_origin(orig_peer_info, path);           /* inverts path!  */
986         GNUNET_PEER_resolve(get_first_hop(path), &id); /* path is inverted :) */
987         /* FIXME / COMMENT 
988          * is it allowed/desired to declare variables this way?
989          * (style, best bractices, etc)
990          * This variable is short lived and completely irrelevant for the rest
991          * of the function
992          */
993         struct info_for_data_to_origin *info =
994             GNUNET_malloc(sizeof(struct info_for_data_to_origin));
995         info->origin = &t->id;
996         info->data = NULL;
997         info->size = 0;
998         GNUNET_CORE_notify_transmit_ready(core_handle,
999                                 0,
1000                                 0,
1001                                 GNUNET_TIME_UNIT_FOREVER_REL,
1002                                 &id,
1003                                 sizeof(struct GNUNET_MessageHeader),
1004                                 &send_core_data_to_origin,
1005                                 info);
1006     } else {
1007         add_path_to_peer(dest_peer_info, path);
1008         GNUNET_PEER_resolve(get_first_hop(path), &id);
1009         GNUNET_CORE_notify_transmit_ready(core_handle,
1010                                 0,
1011                                 0,
1012                                 GNUNET_TIME_UNIT_FOREVER_REL,
1013                                 &id,
1014                                 sizeof(struct GNUNET_MessageHeader),
1015                                 &send_core_create_path_for_peer,
1016                                 dest_peer_info);
1017     }
1018     return GNUNET_OK;
1019 }
1020
1021
1022 /**
1023  * Core handler for mesh network traffic going from the origin to a peer
1024  *
1025  * @param cls closure
1026  * @param message message
1027  * @param peer peer identity this notification is about
1028  * @param atsi performance data
1029  * @return GNUNET_OK to keep the connection open,
1030  *         GNUNET_SYSERR to close it (signal serious error)
1031  */
1032 static int
1033 handle_mesh_data_unicast (void *cls,
1034                           const struct GNUNET_PeerIdentity *peer,
1035                           const struct GNUNET_MessageHeader *message,
1036                           const struct GNUNET_TRANSPORT_ATS_Information
1037                           *atsi)
1038 {
1039     struct GNUNET_MESH_DataMessageFromOrigin    *msg;
1040     struct GNUNET_PeerIdentity                  id;
1041     struct MeshTunnel                           *t;
1042     struct MeshPeerInfo                         *pi;
1043     size_t                                      size;
1044
1045     size = ntohs(message->size); 
1046     if (size < sizeof(struct GNUNET_MESH_DataMessageFromOrigin)) {
1047         GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
1048                 "got data from origin packet: too short\n");
1049         return GNUNET_OK; // FIXME maybe SYSERR? peer misbehaving?
1050     }
1051     msg = (struct GNUNET_MESH_DataMessageFromOrigin *) message;
1052     t = retrieve_tunnel(&msg->oid, ntohl(msg->tid));
1053     pi = GNUNET_CONTAINER_multihashmap_get(t->peers,
1054                                         &msg->destination.hashPubKey);
1055     if (NULL == pi) {
1056         GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
1057                    "got invalid data from origin packet: wrong destination\n");
1058         /* TODO are we so nice to try to deliver it anyway? maybe we missed
1059          * a Create_path packed that added the peer but we have it in the global
1060          * peer pool anyway...
1061          */
1062         return GNUNET_OK; // FIXME maybe SYSERR? peer misbehaving?
1063     }
1064     GNUNET_PEER_resolve(get_first_hop(pi->path), &id);
1065     GNUNET_CORE_notify_transmit_ready(core_handle,
1066         0,
1067         0,
1068         GNUNET_TIME_UNIT_FOREVER_REL,
1069         &id,
1070         size,
1071         &send_core_data_from_origin,
1072         msg);
1073     return GNUNET_OK;
1074 }
1075
1076
1077 /**
1078  * Core handler for mesh network traffic going from the origin to all peers
1079  *
1080  * @param cls closure
1081  * @param message message
1082  * @param peer peer identity this notification is about
1083  * @param atsi performance data
1084  * @return GNUNET_OK to keep the connection open,
1085  *         GNUNET_SYSERR to close it (signal serious error)
1086  */
1087 static int
1088 handle_mesh_data_multicast (void *cls,
1089                           const struct GNUNET_PeerIdentity *peer,
1090                           const struct GNUNET_MessageHeader *message,
1091                           const struct GNUNET_TRANSPORT_ATS_Information
1092                           *atsi)
1093 {
1094 //     struct GNUNET_MESH_DataMessageMulticast    *msg = message;
1095     return GNUNET_OK;
1096 }
1097
1098
1099 /**
1100  * Core handler for mesh network traffic
1101  *
1102  * @param cls closure
1103  * @param message message
1104  * @param peer peer identity this notification is about
1105  * @param atsi performance data
1106  * @return GNUNET_OK to keep the connection open,
1107  *         GNUNET_SYSERR to close it (signal serious error)
1108  */
1109 static int
1110 handle_mesh_data_to_orig (void *cls,
1111                           const struct GNUNET_PeerIdentity *peer,
1112                           const struct GNUNET_MessageHeader *message,
1113                           const struct GNUNET_TRANSPORT_ATS_Information
1114                           *atsi)
1115 {
1116 //     struct GNUNET_MESH_DataMessageToOrigin    *msg = message;
1117     return GNUNET_OK;
1118 }
1119
1120
1121 /**
1122  * Functions to handle messages from core
1123  */
1124 static struct GNUNET_CORE_MessageHandler core_handlers[] = {
1125   {&handle_mesh_path_create, GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE, 0},
1126   {&handle_mesh_data_unicast, GNUNET_MESSAGE_TYPE_DATA_MESSAGE_FROM_ORIGIN, 0},
1127   {&handle_mesh_data_multicast, GNUNET_MESSAGE_TYPE_DATA_MULTICAST, 0},
1128   {&handle_mesh_data_to_orig, GNUNET_MESSAGE_TYPE_DATA_MESSAGE_TO_ORIGIN, 0},
1129   {NULL, 0, 0}
1130 };
1131
1132
1133
1134 /******************************************************************************/
1135 /****************       MESH LOCAL HANDLER HELPERS      ***********************/
1136 /******************************************************************************/
1137
1138 /**
1139  * delete_tunnel_entry: iterator for deleting each tunnel that belongs to a
1140  * client when the client disconnects.
1141  * @param cls closure (client that is disconnecting)
1142  * @param key the hash of the local tunnel id (used to access the hashmap)
1143  * @param value the value stored at the key (tunnel to destroy)
1144  * @return GNUNET_OK on success
1145  */
1146 static int
1147 delete_tunnel_entry (void *cls, const GNUNET_HashCode * key, void *value) {
1148     int r;
1149     r = destroy_tunnel((struct MeshTunnel *) value);
1150     return r;
1151 }
1152
1153 #if LATER
1154 /**
1155  * notify_client_connection_failure: notify a client that the connection to the
1156  * requested remote peer is not possible (for instance, no route found)
1157  * Function called when the socket is ready to queue more data. "buf" will be
1158  * NULL and "size" zero if the socket was closed for writing in the meantime.
1159  *
1160  * @param cls closure
1161  * @param size number of bytes available in buf
1162  * @param buf where the callee should write the message
1163  * @return number of bytes written to buf
1164  */
1165 static size_t
1166 notify_client_connection_failure (void *cls, size_t size, void *buf)
1167 {
1168     int                                 size_needed;
1169     struct MeshPeerInfo                 *peer_info;
1170     struct GNUNET_MESH_PeerControl      *msg;
1171     struct GNUNET_PeerIdentity          id;
1172
1173     if (0 == size && NULL == buf) {
1174         // TODO retry? cancel?
1175         return 0;
1176     }
1177
1178     size_needed = sizeof(struct GNUNET_MESH_PeerControl);
1179     peer_info = (struct MeshPeerInfo *) cls;
1180     msg = (struct GNUNET_MESH_PeerControl *) buf;
1181     msg->header.size = htons(sizeof(struct GNUNET_MESH_PeerControl));
1182     msg->header.type = htons(GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_DISCONNECTED);
1183 //     msg->tunnel_id = htonl(peer_info->t->tid);
1184     GNUNET_PEER_resolve(peer_info->id, &id);
1185     memcpy(&msg->peer, &id, sizeof(struct GNUNET_PeerIdentity));
1186
1187     return size_needed;
1188 }
1189 #endif
1190
1191
1192 /**
1193  * Send keepalive packets for a peer
1194  *
1195  * @param cls unused
1196  * @param tc unused
1197  */
1198 static void
1199 path_refresh (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1200 {
1201     struct MeshPeerInfo         *peer_info = cls;
1202     struct GNUNET_PeerIdentity  id;
1203
1204     if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN) return;
1205     GNUNET_PEER_resolve(get_first_hop(peer_info->path), &id);
1206     GNUNET_CORE_notify_transmit_ready(core_handle,
1207                                 0,
1208                                 0,
1209                                 GNUNET_TIME_UNIT_FOREVER_REL,
1210                                 &id,
1211                                 sizeof(struct GNUNET_MESH_ManipulatePath)
1212                                 + (peer_info->path->length
1213                                 * sizeof (struct GNUNET_PeerIdentity)),
1214                                 &send_core_create_path_for_peer,
1215                                 peer_info);
1216
1217     return;
1218 }
1219
1220
1221 /**
1222  * Function to process paths received for a new peer addition. The recorded
1223  * paths form the initial tunnel, which can be optimized later.
1224  * Called on each result obtained for the DHT search.
1225  *
1226  * @param cls closure
1227  * @param exp when will this value expire
1228  * @param key key of the result
1229  * @param get_path NULL-terminated array of pointers
1230  *                 to the peers on reverse GET path (or NULL if not recorded)
1231  * @param put_path NULL-terminated array of pointers
1232  *                 to the peers on the PUT path (or NULL if not recorded)
1233  * @param type type of the result
1234  * @param size number of bytes in data
1235  * @param data pointer to the result data
1236  */
1237 static void
1238 dht_get_response_handler(void *cls,
1239                         struct GNUNET_TIME_Absolute exp,
1240                         const GNUNET_HashCode * key,
1241                         const struct GNUNET_PeerIdentity * const *get_path,
1242                         const struct GNUNET_PeerIdentity * const *put_path,
1243                         enum GNUNET_BLOCK_Type type,
1244                         size_t size,
1245                         const void *data)
1246 {
1247     struct MeshPeerInfo         *peer_info = cls;
1248     struct MeshPath             *p;
1249     struct GNUNET_PeerIdentity  pi;
1250     int                         i;
1251
1252     if ((NULL == get_path || NULL == put_path) && NULL == peer_info->path) {
1253         // Find ourselves some alternate initial path to the destination: retry
1254         GNUNET_DHT_get_stop(peer_info->dhtget);
1255         GNUNET_PEER_resolve(peer_info->id, &pi);
1256         peer_info->dhtget = GNUNET_DHT_get_start(dht_handle,
1257                                     GNUNET_TIME_UNIT_FOREVER_REL,
1258                                     GNUNET_BLOCK_TYPE_ANY,
1259                                     &pi.hashPubKey,
1260                                     4,    /* replication level */
1261                                     GNUNET_DHT_RO_RECORD_ROUTE,
1262                                     NULL, /* bloom filter */
1263                                     0,    /* mutator */
1264                                     NULL, /* xquery */
1265                                     0,    /* xquery bits */
1266                                     dht_get_response_handler,
1267                                     (void *)peer_info);
1268     }
1269
1270     p = GNUNET_malloc(sizeof(struct MeshPath));
1271     for (i = 0; get_path[i] != NULL; i++);
1272     for (i--; i >= 0; i--) {
1273         p->peers = GNUNET_realloc(p->peers,
1274                                    sizeof(GNUNET_PEER_Id) * (p->length + 1));
1275         p->peers[p->length] = GNUNET_PEER_intern(get_path[i]);
1276         p->length++;
1277     }
1278     for (i = 0; put_path[i] != NULL; i++);
1279     for (i--; i >= 0; i--) {
1280         p->peers = GNUNET_realloc(p->peers,
1281                                   sizeof(GNUNET_PEER_Id) * (p->length + 1));
1282         p->peers[p->length] = GNUNET_PEER_intern(put_path[i]);
1283         p->length++;
1284     }
1285     add_path_to_peer(peer_info, p);
1286     GNUNET_CORE_notify_transmit_ready(core_handle,
1287                                       0,
1288                                       0,
1289                                       GNUNET_TIME_UNIT_FOREVER_REL,
1290                                       get_path[1],
1291                                       sizeof(struct GNUNET_MESH_ManipulatePath)
1292                                         + (p->length
1293                                         * sizeof (struct GNUNET_PeerIdentity)),
1294                                       &send_core_create_path_for_peer,
1295                                       peer_info);
1296     GNUNET_SCHEDULER_add_delayed(REFRESH_PATH_TIME, &path_refresh, peer_info);
1297     return;
1298 }
1299
1300
1301 /******************************************************************************/
1302 /*********************       MESH LOCAL HANDLES      **************************/
1303 /******************************************************************************/
1304
1305
1306 /**
1307  * Handler for client disconnection
1308  *
1309  * @param cls closure
1310  * @param client identification of the client; NULL
1311  *        for the last call when the server is destroyed
1312  */
1313 static void
1314 handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
1315 {
1316     struct MeshClient   *c;
1317     struct MeshClient   *next;
1318
1319     GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1320                "client disconnected\n");
1321     c = clients;
1322     while (NULL != c) {
1323         if (c->handle == client) {
1324             GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1325                " matching client found, cleaning\n");
1326             GNUNET_CONTAINER_multihashmap_iterate(c->tunnels,
1327                                                   &delete_tunnel_entry,
1328                                                   c);
1329             GNUNET_CONTAINER_multihashmap_destroy(c->tunnels);
1330             if(0 != c->app_counter) GNUNET_free (c->apps);
1331             if(0 != c->type_counter) GNUNET_free (c->types);
1332             GNUNET_CONTAINER_DLL_remove(clients, clients_tail, c);
1333             next = c->next;
1334             GNUNET_free (c);
1335             c = next;
1336         } else {
1337             GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1338                "   ... searching\n");
1339             c = c->next;
1340         }
1341     }
1342     GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1343                "   done!\n");
1344     return;
1345 }
1346
1347
1348 /**
1349  * Handler for new clients
1350  * 
1351  * @param cls closure
1352  * @param client identification of the client
1353  * @param message the actual message, which includes messages the client wants
1354  */
1355 static void
1356 handle_local_new_client (void *cls,
1357                          struct GNUNET_SERVER_Client *client,
1358                          const struct GNUNET_MessageHeader *message)
1359 {
1360     struct GNUNET_MESH_ClientConnect    *cc_msg;
1361     struct MeshClient                   *c;
1362     unsigned int                        size;
1363     uint16_t                            types;
1364     uint16_t                            apps;
1365
1366     GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "new client connected\n");
1367     /* Check data sanity */
1368     size = ntohs(message->size) - sizeof(struct GNUNET_MESH_ClientConnect);
1369     cc_msg = (struct GNUNET_MESH_ClientConnect *) message;
1370     types = ntohs(cc_msg->types);
1371     apps = ntohs(cc_msg->applications);
1372     if (size !=
1373         types * sizeof(uint16_t) + apps * sizeof(GNUNET_MESH_ApplicationType))
1374     {
1375         GNUNET_break(0);
1376         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1377         return;
1378     }
1379
1380     /* Create new client structure */
1381     c = GNUNET_malloc(sizeof(struct MeshClient));
1382     c->handle = client;
1383     if (types != 0) {
1384         c->type_counter = types;
1385         c->types = GNUNET_malloc(types * sizeof(uint16_t));
1386         memcpy(c->types, &message[1], types * sizeof(uint16_t));
1387     }
1388     if (apps != 0) {
1389         c->app_counter = apps;
1390         c->apps = GNUNET_malloc(apps * sizeof(GNUNET_MESH_ApplicationType));
1391         memcpy(c->apps,
1392                &message[1] + types * sizeof(uint16_t),
1393                apps * sizeof(GNUNET_MESH_ApplicationType));
1394     }
1395     GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1396                " client has %u+%u subscriptions\n",
1397                c->type_counter,
1398                c->app_counter);
1399
1400     GNUNET_CONTAINER_DLL_insert(clients, clients_tail, c);
1401     c->tunnels = GNUNET_CONTAINER_multihashmap_create(32);
1402
1403     GNUNET_SERVER_receive_done(client, GNUNET_OK);
1404
1405 }
1406
1407
1408 /**
1409  * Handler for requests of new tunnels
1410  * 
1411  * @param cls closure
1412  * @param client identification of the client
1413  * @param message the actual message
1414  */
1415 static void
1416 handle_local_tunnel_create (void *cls,
1417                             struct GNUNET_SERVER_Client *client,
1418                             const struct GNUNET_MessageHeader *message)
1419 {
1420     struct GNUNET_MESH_TunnelMessage    *t_msg;
1421     struct MeshTunnel                   *t;
1422     struct MeshClient                   *c;
1423     GNUNET_HashCode                     hash;
1424
1425     /* Sanity check for client registration */
1426     if (NULL == (c = retrieve_client(client))) {
1427         GNUNET_break(0);
1428         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1429         return;
1430     }
1431
1432     /* Message sanity check */
1433     if (sizeof(struct GNUNET_MESH_TunnelMessage) != ntohs(message->size)) {
1434         GNUNET_break(0);
1435         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1436         return;
1437     }
1438
1439     t_msg = (struct GNUNET_MESH_TunnelMessage *) message;
1440     /* Sanity check for tunnel numbering */
1441     if (0 == (ntohl(t_msg->tunnel_id) & GNUNET_MESH_LOCAL_TUNNEL_ID_MARK)) {
1442         GNUNET_break(0);
1443         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1444         return;
1445     }
1446     /* Sanity check for duplicate tunnel IDs */
1447     if(NULL != retrieve_tunnel_by_local_id(c, ntohl(t_msg->tunnel_id))) {
1448         GNUNET_break(0);
1449         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1450         return;
1451     }
1452
1453     t = GNUNET_malloc(sizeof(struct MeshTunnel));
1454     while (NULL != retrieve_tunnel_by_pi(myid, next_tid))
1455         next_tid = (next_tid + 1) % GNUNET_MESH_LOCAL_TUNNEL_ID_MARK;
1456     t->id.tid = next_tid++;
1457     t->id.oid = myid;
1458     t->local_tid = ntohl(t_msg->tunnel_id);
1459     t->client = c;
1460     t->peers = GNUNET_CONTAINER_multihashmap_create(32);
1461
1462     GNUNET_CRYPTO_hash(&t->local_tid, sizeof(MESH_TunnelNumber), &hash);
1463     if (GNUNET_OK !=
1464         GNUNET_CONTAINER_multihashmap_put(c->tunnels, &hash, t,
1465                             GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
1466     {
1467         GNUNET_break(0);
1468         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1469         return;
1470     }
1471
1472     GNUNET_CRYPTO_hash(&t->id, sizeof(struct MESH_TunnelID), &hash);
1473     if (GNUNET_OK !=
1474         GNUNET_CONTAINER_multihashmap_put(tunnels, &hash, t,
1475                             GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
1476     {
1477         GNUNET_break(0);
1478         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1479         return;
1480     }
1481
1482     GNUNET_SERVER_receive_done(client, GNUNET_OK);
1483     return;
1484 }
1485
1486
1487 /**
1488  * Handler for requests of deleting tunnels
1489  * 
1490  * @param cls closure
1491  * @param client identification of the client
1492  * @param message the actual message
1493  */
1494 static void
1495 handle_local_tunnel_destroy (void *cls,
1496                              struct GNUNET_SERVER_Client *client,
1497                              const struct GNUNET_MessageHeader *message)
1498 {
1499     struct GNUNET_MESH_TunnelMessage    *tunnel_msg;
1500     struct MeshClient                   *c;
1501     struct MeshTunnel                   *t;
1502     MESH_TunnelNumber                   tid;
1503     GNUNET_HashCode                     hash;
1504
1505
1506     /* Sanity check for client registration */
1507     if (NULL == (c = retrieve_client(client))) {
1508         GNUNET_break(0);
1509         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1510         return;
1511     }
1512     /* Message sanity check */
1513     if (sizeof(struct GNUNET_MESH_TunnelMessage) != ntohs(message->size)) {
1514         GNUNET_break(0);
1515         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1516         return;
1517     }
1518
1519     tunnel_msg = (struct GNUNET_MESH_TunnelMessage *) message;
1520
1521     /* Retrieve tunnel */
1522     tid = ntohl(tunnel_msg->tunnel_id);
1523
1524     /* Remove from local id hashmap */
1525     GNUNET_CRYPTO_hash(&tid, sizeof(MESH_TunnelNumber), &hash);
1526     t = GNUNET_CONTAINER_multihashmap_get(c->tunnels, &hash);
1527     GNUNET_CONTAINER_multihashmap_remove(c->tunnels, &hash, t);
1528
1529     /* Remove from global id hashmap */
1530     GNUNET_CRYPTO_hash(&t->id, sizeof(struct MESH_TunnelID), &hash);
1531     GNUNET_CONTAINER_multihashmap_remove(tunnels, &hash, t);
1532
1533 //     notify_tunnel_destroy(t);
1534     GNUNET_SERVER_receive_done(client, GNUNET_OK);
1535     return;
1536 }
1537
1538
1539 /**
1540  * Handler for connection requests to new peers
1541  * 
1542  * @param cls closure
1543  * @param client identification of the client
1544  * @param message the actual message (PeerControl)
1545  */
1546 static void
1547 handle_local_connect_add (void *cls,
1548                           struct GNUNET_SERVER_Client *client,
1549                           const struct GNUNET_MessageHeader *message)
1550 {
1551     struct GNUNET_MESH_PeerControl      *peer_msg;
1552     struct MeshClient                   *c;
1553     struct MeshTunnel                   *t;
1554     MESH_TunnelNumber                   tid;
1555     struct MeshPeerInfo                 *peer_info;
1556
1557
1558     /* Sanity check for client registration */
1559     if (NULL == (c = retrieve_client(client))) {
1560         GNUNET_break(0);
1561         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1562         return;
1563     }
1564
1565     peer_msg = (struct GNUNET_MESH_PeerControl *)message;
1566     /* Sanity check for message size */
1567     if (sizeof(struct GNUNET_MESH_PeerControl)
1568         != ntohs(peer_msg->header.size))
1569     {
1570         GNUNET_break(0);
1571         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1572         return;
1573     }
1574
1575     /* Tunnel exists? */
1576     tid = ntohl(peer_msg->tunnel_id);
1577     t = retrieve_tunnel_by_local_id(c, tid);
1578     if (NULL == t) {
1579         GNUNET_break(0);
1580         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1581         return;
1582     }
1583
1584     /* Does client own tunnel? */
1585     if (t->client->handle != client) {
1586         GNUNET_break(0);
1587         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1588         return;
1589     }
1590
1591     t->peers_total++;
1592     peer_info = get_peer_info(&peer_msg->peer);
1593
1594     /* Start DHT search if needed */
1595     if(MESH_PEER_READY != peer_info->state && NULL == peer_info->dhtget) {
1596         peer_info->dhtget = GNUNET_DHT_get_start(dht_handle,
1597                                             GNUNET_TIME_UNIT_FOREVER_REL,
1598                                             GNUNET_BLOCK_TYPE_ANY,
1599                                             &peer_msg->peer.hashPubKey,
1600                                             4,    /* replication level */
1601                                             GNUNET_DHT_RO_RECORD_ROUTE,
1602                                             NULL, /* bloom filter */
1603                                             0,    /* mutator */
1604                                             NULL, /* xquery */
1605                                             0,    /* xquery bits */
1606                                             dht_get_response_handler,
1607                                             (void *)peer_info);
1608     }
1609
1610     GNUNET_SERVER_receive_done(client, GNUNET_OK);
1611     return;
1612 }
1613
1614
1615 /**
1616  * Handler for disconnection requests of peers in a tunnel
1617  * 
1618  * @param cls closure
1619  * @param client identification of the client
1620  * @param message the actual message (PeerControl)
1621  */
1622 static void
1623 handle_local_connect_del (void *cls,
1624                           struct GNUNET_SERVER_Client *client,
1625                           const struct GNUNET_MessageHeader *message)
1626 {
1627     struct GNUNET_MESH_PeerControl      *peer_msg;
1628     struct MeshClient                   *c;
1629     struct MeshTunnel                   *t;
1630     MESH_TunnelNumber                   tid;
1631
1632     /* Sanity check for client registration */
1633     if (NULL == (c = retrieve_client(client))) {
1634         GNUNET_break(0);
1635         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1636         return;
1637     }
1638     peer_msg = (struct GNUNET_MESH_PeerControl *)message;
1639     /* Sanity check for message size */
1640     if (sizeof(struct GNUNET_MESH_PeerControl)
1641         != ntohs(peer_msg->header.size))
1642     {
1643         GNUNET_break(0);
1644         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1645         return;
1646     }
1647
1648     /* Tunnel exists? */
1649     tid = ntohl(peer_msg->tunnel_id);
1650     t = retrieve_tunnel_by_local_id(c, tid);
1651     if (NULL == t) {
1652             GNUNET_break(0);
1653             GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1654             return;
1655         }
1656
1657     /* Does client own tunnel? */
1658     if (t->client->handle != client) {
1659         GNUNET_break(0);
1660         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1661         return;
1662     }
1663
1664     /* Ok, delete peer from tunnel */
1665     GNUNET_CONTAINER_multihashmap_remove_all(t->peers,
1666                                              &peer_msg->peer.hashPubKey);
1667
1668     GNUNET_SERVER_receive_done(client, GNUNET_OK);
1669     return;
1670 }
1671
1672
1673 /**
1674  * Handler for connection requests to new peers by type
1675  * 
1676  * @param cls closure
1677  * @param client identification of the client
1678  * @param message the actual message (ConnectPeerByType)
1679  */
1680 static void
1681 handle_local_connect_by_type (void *cls,
1682                               struct GNUNET_SERVER_Client *client,
1683                               const struct GNUNET_MessageHeader *message)
1684 {
1685     struct GNUNET_MESH_ConnectPeerByType        *connect_msg;
1686     MESH_TunnelNumber                           tid;
1687     GNUNET_MESH_ApplicationType                 application;
1688     struct MeshClient                           *c;
1689     struct MeshTunnel                           *t;
1690
1691     /* Sanity check for client registration */
1692     if (NULL == (c = retrieve_client(client))) {
1693         GNUNET_break(0);
1694         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1695         return;
1696     }
1697
1698     connect_msg = (struct GNUNET_MESH_ConnectPeerByType *)message;
1699     /* Sanity check for message size */
1700     if (sizeof(struct GNUNET_MESH_PeerControl) !=
1701             ntohs(connect_msg->header.size))
1702     {
1703         GNUNET_break(0);
1704         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1705         return;
1706     }
1707
1708     /* Tunnel exists? */
1709     tid = ntohl(connect_msg->tunnel_id);
1710     t = retrieve_tunnel_by_local_id(c, tid);
1711     if (NULL == t) {
1712         GNUNET_break(0);
1713         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1714         return;
1715     }
1716
1717     /* Does client own tunnel? */
1718     if (t->client->handle != client) {
1719         GNUNET_break(0);
1720         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1721         return;
1722     }
1723
1724     /* Ok, lets find a peer offering the service */
1725     application = ntohl(connect_msg->type);
1726     application++; // FIXME silence warnings
1727
1728     GNUNET_SERVER_receive_done(client, GNUNET_OK);
1729     return;
1730 }
1731
1732
1733 /**
1734  * Handler for client traffic directed to one peer
1735  * 
1736  * @param cls closure
1737  * @param client identification of the client
1738  * @param message the actual message
1739  */
1740 static void
1741 handle_local_network_traffic (void *cls,
1742                          struct GNUNET_SERVER_Client *client,
1743                          const struct GNUNET_MessageHeader *message)
1744 {
1745     struct MeshClient                           *c;
1746     struct MeshTunnel                           *t;
1747     struct MeshPeerInfo                         *pi;
1748     struct GNUNET_MESH_Data                     *data_msg;
1749     struct GNUNET_PeerIdentity                  next_hop;
1750     MESH_TunnelNumber                           tid;
1751
1752     /* Sanity check for client registration */
1753     if (NULL == (c = retrieve_client(client))) {
1754         GNUNET_break(0);
1755         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1756         return;
1757     }
1758     data_msg = (struct GNUNET_MESH_Data *)message;
1759     /* Sanity check for message size */
1760     if (sizeof(struct GNUNET_MESH_PeerControl) !=
1761             ntohs(data_msg->header.size))
1762     {
1763         GNUNET_break(0);
1764         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1765         return;
1766     }
1767
1768     /* Tunnel exists? */
1769     tid = ntohl(data_msg->tunnel_id);
1770     t = retrieve_tunnel_by_local_id(c, tid);
1771     if (NULL == t) {
1772         GNUNET_break(0);
1773         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1774         return;
1775     }
1776
1777     /*  Is it a local tunnel? Then, does client own the tunnel? */
1778     if (t->client->handle != NULL && t->client->handle != client) {
1779         GNUNET_break(0);
1780         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1781         return;
1782     }
1783
1784     pi = GNUNET_CONTAINER_multihashmap_get(t->peers,
1785                                            &data_msg->peer_id.hashPubKey);
1786     /* Is the selected peer in the tunnel? */
1787     if (NULL == pi) {
1788         /* TODO
1789          * Are we SO nice that we automatically try to add him to the tunnel?
1790          */
1791         GNUNET_break(0);
1792         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1793         return;
1794     }
1795     GNUNET_PEER_resolve(get_first_hop(pi->path), &next_hop);
1796     GNUNET_CORE_notify_transmit_ready(core_handle,
1797                             0,
1798                             0,
1799                             GNUNET_TIME_UNIT_FOREVER_REL,
1800                             &next_hop,
1801                             /* FIXME re-check types */
1802                             message->size - sizeof(struct GNUNET_MESH_Data)
1803                             + sizeof(struct GNUNET_MESH_DataMessageFromOrigin),
1804                             &send_core_data_to_origin, /* FIXME re-check */
1805                             NULL);
1806
1807     GNUNET_SERVER_receive_done(client, GNUNET_OK); /* FIXME not yet */
1808     return;
1809 }
1810
1811 /**
1812  * Handler for client traffic directed to all peers in a tunnel
1813  * 
1814  * @param cls closure
1815  * @param client identification of the client
1816  * @param message the actual message
1817  */
1818 static void
1819 handle_local_network_traffic_bcast (void *cls,
1820                                     struct GNUNET_SERVER_Client *client,
1821                                     const struct GNUNET_MessageHeader *message)
1822 {
1823     struct MeshClient                           *c;
1824     struct MeshTunnel                           *t;
1825     struct GNUNET_MESH_DataBroadcast            *data_msg;
1826     MESH_TunnelNumber                           tid;
1827
1828     /* Sanity check for client registration */
1829     if (NULL == (c = retrieve_client(client))) {
1830         GNUNET_break(0);
1831         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1832         return;
1833     }
1834     data_msg = (struct GNUNET_MESH_DataBroadcast *)message;
1835     /* Sanity check for message size */
1836     if (sizeof(struct GNUNET_MESH_PeerControl)
1837         != ntohs(data_msg->header.size))
1838     {
1839         GNUNET_break(0);
1840         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1841         return;
1842     }
1843
1844     /* Tunnel exists? */
1845     tid = ntohl(data_msg->tunnel_id);
1846     t = retrieve_tunnel_by_local_id(c, tid);
1847     if (NULL == t) {
1848         GNUNET_break(0);
1849         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1850         return;
1851     }
1852
1853     /* Does client own tunnel? */
1854     if (t->client->handle != client) {
1855         GNUNET_break(0);
1856         GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
1857         return;
1858     }
1859
1860     /*  TODO */
1861
1862     GNUNET_SERVER_receive_done(client, GNUNET_OK);
1863     return;
1864 }
1865
1866 /**
1867  * Functions to handle messages from clients
1868  */
1869 static struct GNUNET_SERVER_MessageHandler plugin_handlers[] = {
1870   {&handle_local_new_client, NULL, GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT, 0},
1871   {&handle_local_tunnel_create, NULL,
1872    GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_CREATE,
1873    sizeof(struct GNUNET_MESH_TunnelMessage)},
1874   {&handle_local_tunnel_destroy, NULL,
1875    GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_DESTROY,
1876    sizeof(struct GNUNET_MESH_TunnelMessage)},
1877   {&handle_local_connect_add, NULL,
1878    GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT_PEER_ADD,
1879    sizeof(struct GNUNET_MESH_PeerControl)},
1880   {&handle_local_connect_del, NULL,
1881    GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT_PEER_DEL,
1882    sizeof(struct GNUNET_MESH_PeerControl)},
1883   {&handle_local_connect_by_type, NULL,
1884    GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT_PEER_BY_TYPE,
1885    sizeof(struct GNUNET_MESH_ConnectPeerByType)},
1886   {&handle_local_network_traffic, NULL,
1887    GNUNET_MESSAGE_TYPE_MESH_LOCAL_DATA, 0},
1888   {&handle_local_network_traffic_bcast, NULL,
1889    GNUNET_MESSAGE_TYPE_MESH_LOCAL_DATA_BROADCAST, 0},
1890   {NULL, NULL, 0, 0}
1891 };
1892
1893
1894 /**
1895  * To be called on core init/fail.
1896  *
1897  * @param cls service closure
1898  * @param server handle to the server for this service
1899  * @param identity the public identity of this peer
1900  * @param publicKey the public key of this peer
1901  */
1902 static void
1903 core_init (void *cls,
1904            struct GNUNET_CORE_Handle *server,
1905            const struct GNUNET_PeerIdentity *identity,
1906            const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *publicKey)
1907 {
1908     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1909                 "Core init\n");
1910     core_handle = server;
1911     myid = GNUNET_PEER_intern(identity);
1912     return;
1913 }
1914
1915 /**
1916  * Method called whenever a given peer connects.
1917  *
1918  * @param cls closure
1919  * @param peer peer identity this notification is about
1920  * @param atsi performance data for the connection
1921  */
1922 static void
1923 core_connect (void *cls,
1924               const struct GNUNET_PeerIdentity *peer,
1925               const struct GNUNET_TRANSPORT_ATS_Information *atsi)
1926 {
1927 //     GNUNET_PEER_Id              pid;
1928     struct MeshPeerInfo         *peer_info;
1929     struct MeshPath             *path;
1930
1931     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1932                 "Peer connected\n");
1933     peer_info = get_peer_info(peer);
1934     if (myid == peer_info->id) {
1935         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1936                 "     (self)\n");
1937     }
1938     path = GNUNET_malloc(sizeof(struct MeshPath));
1939     path->length = 2;
1940     path->peers = GNUNET_malloc(sizeof(GNUNET_PEER_Id) * 2);
1941     path->peers[0] = myid;
1942     path->peers[1] = peer_info->id;
1943     add_path_to_peer(peer_info, path);
1944     return;
1945 }
1946
1947 /**
1948  * Method called whenever a peer disconnects.
1949  *
1950  * @param cls closure
1951  * @param peer peer identity this notification is about
1952  */
1953 static void
1954 core_disconnect (void *cls,
1955                 const struct
1956                 GNUNET_PeerIdentity *peer)
1957 {
1958     GNUNET_PEER_Id      pid;
1959     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1960                 "Peer disconnected\n");
1961     pid = GNUNET_PEER_search(peer);
1962     if (myid == pid) {
1963         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1964                 "     (self)\n");
1965     }
1966     return;
1967 }
1968
1969
1970 /******************************************************************************/
1971 /************************      MAIN FUNCTIONS      ****************************/
1972 /******************************************************************************/
1973
1974 /**
1975  * Task run during shutdown.
1976  *
1977  * @param cls unused
1978  * @param tc unused
1979  */
1980 static void
1981 shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1982 {
1983     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1984                 "shutting down\n");
1985     if (core_handle != NULL) {
1986         GNUNET_CORE_disconnect (core_handle);
1987         core_handle = NULL;
1988     }
1989     if (dht_handle != NULL) {
1990         GNUNET_DHT_disconnect (dht_handle);
1991         dht_handle = NULL;
1992     }
1993     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1994                 "shut down\n");
1995 }
1996
1997 /**
1998  * Process mesh requests.
1999  *
2000  * @param cls closure
2001  * @param server the initialized server
2002  * @param c configuration to use
2003  */
2004 static void
2005 run (void *cls,
2006      struct GNUNET_SERVER_Handle *server,
2007      const struct GNUNET_CONFIGURATION_Handle *c)
2008 {
2009     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2010                 "starting to run\n");
2011     GNUNET_SERVER_add_handlers (server, plugin_handlers);
2012     GNUNET_SERVER_disconnect_notify (server, &handle_client_disconnect, NULL);
2013     core_handle = GNUNET_CORE_connect (c,               /* Main configuration */
2014                             1,                                  /* queue size */
2015                             NULL,         /* Closure passed to MESH functions */
2016                             &core_init,      /* Call core_init once connected */
2017                             &core_connect,                 /* Handle connects */
2018                             &core_disconnect,  /* remove peers on disconnects */
2019                             NULL,       /* Do we care about "status" updates? */
2020                             NULL, /* Don't notify about all incoming messages */
2021                             GNUNET_NO,     /* For header only in notification */
2022                             NULL, /* Don't notify about all outbound messages */
2023                             GNUNET_NO,    /* For header-only out notification */
2024                             core_handlers);        /* Register these handlers */
2025     if (core_handle == NULL) {
2026         GNUNET_break(0);
2027     }
2028     dht_handle = GNUNET_DHT_connect(c, 64);
2029     if (dht_handle == NULL) {
2030         GNUNET_break(0);
2031     }
2032     next_tid = 0;
2033
2034     tunnels = GNUNET_CONTAINER_multihashmap_create(32);
2035     peers = GNUNET_CONTAINER_multihashmap_create(32);
2036     clients = NULL;
2037     clients_tail = NULL;
2038
2039     /* Scheduled the task to clean up when shutdown is called */
2040     GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
2041                                   &shutdown_task, NULL);
2042
2043     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2044                 "end if run()\n");
2045 }
2046
2047 /**
2048  * The main function for the mesh service.
2049  *
2050  * @param argc number of arguments from the command line
2051  * @param argv command line arguments
2052  * @return 0 ok, 1 on error
2053  */
2054 int
2055 main (int argc, char *const *argv)
2056 {
2057     int ret;
2058
2059     ret = (GNUNET_OK ==
2060            GNUNET_SERVICE_run (argc,
2061                                argv,
2062                                "mesh",
2063                                GNUNET_SERVICE_OPTION_NONE,
2064                                &run, NULL)) ? 0 : 1;
2065     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2066                 "end of main()\n");
2067     return ret;
2068 }