Simplified own ID handling in mesh service
[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  * - GENERAL HELPERS
30  * - PERIODIC FUNCTIONS
31  * - MESH NETWORK HANDLER HELPERS
32  * - MESH NETWORK HANDLES
33  * - MESH LOCAL HANDLER HELPERS
34  * - MESH LOCAL HANDLES
35  * - MAIN FUNCTIONS (main & run)
36  *
37  * TODO:
38  * - error reporting (CREATE/CHANGE/ADD/DEL?) -- new message!
39  * - partial disconnect reporting -- same as error reporting?
40  * - add vs create? change vs. keep-alive? same msg or different ones? -- thinking...
41  * - speed requirement specification (change?) in mesh API -- API call
42  * - add ping message
43  * - add connection confirmation message
44  * - handle trnsmt_rdy return values
45  */
46
47 #include "platform.h"
48 #include "gnunet_common.h"
49 #include "gnunet_util_lib.h"
50 #include "gnunet_peer_lib.h"
51 #include "gnunet_core_service.h"
52 #include "gnunet_protocols.h"
53
54 #include "mesh.h"
55 #include "mesh_protocol.h"
56 #include "gnunet_dht_service.h"
57
58 #define MESH_DEBUG              GNUNET_YES
59
60 #if MESH_DEBUG
61 /**
62  * GNUNET_SCHEDULER_Task for printing a message after some operation is done
63  */
64 static void
65 mesh_debug (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
66 {
67   char *s = cls;
68
69   if (GNUNET_SCHEDULER_REASON_SHUTDOWN == tc->reason)
70   {
71     return;
72   }
73   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: %s", s);
74 }
75 #endif
76
77 /* TODO: move into configuration file */
78 #define CORE_QUEUE_SIZE         10
79 #define LOCAL_QUEUE_SIZE        100
80 #define REFRESH_PATH_TIME       GNUNET_TIME_relative_multiply(\
81                                     GNUNET_TIME_UNIT_SECONDS,\
82                                     300)
83 #define APP_ANNOUNCE_TIME       GNUNET_TIME_relative_multiply(\
84                                     GNUNET_TIME_UNIT_SECONDS,\
85                                     60)
86
87 #define ID_ANNOUNCE_TIME        GNUNET_TIME_relative_multiply(\
88                                     GNUNET_TIME_UNIT_SECONDS,\
89                                     300)
90
91
92
93 /******************************************************************************/
94 /************************      DATA STRUCTURES     ****************************/
95 /******************************************************************************/
96
97 /**
98  * Information regarding a path
99  */
100 struct MeshPath
101 {
102
103     /**
104      * Linked list
105      */
106   struct MeshPath *next;
107   struct MeshPath *prev;
108
109     /**
110      * Whether the path is serving traffic in a tunnel or is a backup
111      */
112   int in_use;
113
114     /**
115      * List of all the peers that form the path from origin to target
116      */
117   GNUNET_PEER_Id *peers;
118
119     /**
120      * Number of peers (hops) in the path
121      */
122   unsigned int length;
123 };
124
125
126 /**
127  * All the states a peer participating in a tunnel can be in.
128  */
129 enum MeshPeerState
130 {
131     /**
132      * Path to the peer not known yet
133      */
134   MESH_PEER_SEARCHING,
135
136     /**
137      * Request sent, not yet answered.
138      */
139   MESH_PEER_WAITING,
140
141     /**
142      * Peer connected and ready to accept data
143      */
144   MESH_PEER_READY,
145
146     /**
147      * Peer connected previosly but not responding
148      */
149   MESH_PEER_RECONNECTING
150 };
151
152
153 /** FWD declaration */
154 struct MeshPeerInfo;
155
156 /**
157  * Struct containing all info possibly needed to build a package when called
158  * back by core.
159  */
160 struct MeshDataDescriptor
161 {
162     /** ID of the tunnel this packet travels in */
163   struct MESH_TunnelID *origin;
164
165     /** Ultimate destination of the packet */
166   GNUNET_PEER_Id destination;
167
168     /** Number of identical messages sent to different hops (multicast) */
169   unsigned int copies;
170
171     /** Size of the data */
172   size_t size;
173
174     /** Client that asked for the transmission, if any */
175   struct GNUNET_SERVER_Client *client;
176
177     /** Who was is message being sent to */
178   struct MeshPeerInfo *peer;
179
180     /** Which handler was used to request the transmission */
181   unsigned int handler_n;
182
183   /* Data at the end */
184 };
185
186
187 /**
188  * Struct containing all information regarding a given peer
189  */
190 struct MeshPeerInfo
191 {
192     /**
193      * ID of the peer
194      */
195   GNUNET_PEER_Id id;
196
197     /**
198      * Is the peer reachable? Is the peer even connected?
199      */
200   enum MeshPeerState state;
201
202     /**
203      * Last time we heard from this peer
204      */
205   struct GNUNET_TIME_Absolute last_contact;
206
207     /**
208      * Number of attempts to reconnect so far
209      */
210   int n_reconnect_attempts;
211
212     /**
213      * Paths to reach the peer
214      */
215   struct MeshPath *path;
216   struct MeshPath *path_tail;
217
218     /**
219      * Handle to stop the DHT search for a path to this peer
220      */
221   struct GNUNET_DHT_GetHandle *dhtget;
222
223     /**
224      * Handles to stop queued transmissions for this peer
225      */
226   struct GNUNET_CORE_TransmitHandle *core_transmit[CORE_QUEUE_SIZE];
227
228     /**
229      * Pointer to info stuctures used as cls for queued transmissions
230      */
231   struct MeshDataDescriptor *infos[CORE_QUEUE_SIZE];
232
233     /**
234      * Task to send keepalive packets over the current active path
235      */
236   GNUNET_SCHEDULER_TaskIdentifier path_refresh_task;
237 };
238
239
240 /**
241  * Data scheduled to transmit (to local client or remote peer)
242  */
243 struct MeshQueue
244 {
245     /**
246      * Double linked list
247      */
248   struct MeshQueue *next;
249   struct MeshQueue *prev;
250
251     /**
252      * Target of the data (NULL if target is client)
253      */
254   struct MeshPeerInfo *peer;
255
256     /**
257      * Client to send the data to (NULL if target is peer)
258      */
259   struct MeshClient *client;
260
261     /**
262      * Size of the message to transmit
263      */
264   unsigned int size;
265
266     /**
267      * How old is the data?
268      */
269   struct GNUNET_TIME_Absolute timestamp;
270
271     /**
272      * Data itself
273      */
274   struct GNUNET_MessageHeader *data;
275 };
276
277 /**
278  * Globally unique tunnel identification (owner + number)
279  * DO NOT USE OVER THE NETWORK
280  */
281 struct MESH_TunnelID
282 {
283     /**
284      * Node that owns the tunnel
285      */
286   GNUNET_PEER_Id oid;
287
288     /**
289      * Tunnel number to differentiate all the tunnels owned by the node oid
290      * ( tid < GNUNET_MESH_LOCAL_TUNNEL_ID_CLI )
291      */
292   MESH_TunnelNumber tid;
293 };
294
295
296 struct MeshClient;              /* FWD declaration */
297
298 /**
299  * Struct containing all information regarding a tunnel
300  * For an intermediate node the improtant info used will be:
301  * - id        Tunnel unique identification
302  * - paths[0]  To know where to send it next
303  * - metainfo: ready, speeds, accounting
304  */
305 struct MeshTunnel
306 {
307     /**
308      * Tunnel ID
309      */
310   struct MESH_TunnelID id;
311
312     /**
313      * Local tunnel number ( >= GNUNET_MESH_LOCAL_TUNNEL_ID_CLI or 0 )
314      */
315   MESH_TunnelNumber local_tid;
316
317     /**
318      * Last time the tunnel was used
319      */
320   struct GNUNET_TIME_Absolute timestamp;
321
322     /**
323      * Peers in the tunnel, indexed by PeerIdentity -> (MeshPeerInfo)
324      */
325   struct GNUNET_CONTAINER_MultiHashMap *peers;
326
327     /**
328      * Number of peers that are connected and potentially ready to receive data
329      */
330   unsigned int peers_ready;
331
332     /**
333      * Number of peers that have been added to the tunnel
334      */
335   unsigned int peers_total;
336
337
338     /**
339      * Client owner of the tunnel, if any
340      */
341   struct MeshClient *client;
342
343     /**
344      * Messages ready to transmit
345      */
346   struct MeshQueue *queue_head;
347   struct MeshQueue *queue_tail;
348
349 };
350
351 /**
352  * Struct containing information about a client of the service
353  */
354 struct MeshClient
355 {
356     /**
357      * Linked list
358      */
359   struct MeshClient *next;
360   struct MeshClient *prev;
361
362     /**
363      * Tunnels that belong to this client, indexed by local id
364      */
365   struct GNUNET_CONTAINER_MultiHashMap *tunnels;
366
367     /**
368      * Handle to communicate with the client
369      */
370   struct GNUNET_SERVER_Client *handle;
371
372     /**
373      * Applications that this client has claimed to provide
374      */
375   GNUNET_MESH_ApplicationType *apps;
376   unsigned int app_counter;
377
378     /**
379      * Messages that this client has declared interest in
380      */
381   uint16_t *types;
382   unsigned int type_counter;
383
384     /**
385      * Used for seachching peers offering a service
386      */
387   struct GNUNET_DHT_GetHandle *dht_get_type;
388
389 };
390
391 /******************************************************************************/
392 /***********************      GLOBAL VARIABLES     ****************************/
393 /******************************************************************************/
394
395 /**
396  * All the clients
397  */
398 static struct MeshClient *clients;
399 static struct MeshClient *clients_tail;
400
401 /**
402  * Tunnels known, indexed by MESH_TunnelID (MeshTunnel)
403  */
404 static struct GNUNET_CONTAINER_MultiHashMap *tunnels;
405
406 /**
407  * Peers known, indexed by PeerIdentity (MeshPeerInfo)
408  */
409 static struct GNUNET_CONTAINER_MultiHashMap *peers;
410
411 /**
412  * Handle to communicate with core
413  */
414 static struct GNUNET_CORE_Handle *core_handle;
415
416 /**
417  * Handle to use DHT
418  */
419 static struct GNUNET_DHT_Handle *dht_handle;
420
421 /**
422  * Handle to server
423  */
424 static struct GNUNET_SERVER_Handle *server_handle;
425
426 /**
427  * Notification context, to send messages to local clients
428  */
429 static struct GNUNET_SERVER_NotificationContext *nc;
430
431 /**
432  * Local peer own ID (memory efficient handle)
433  */
434 static GNUNET_PEER_Id myid;
435
436 /**
437  * Local peer own ID (full value)
438  */
439 static struct GNUNET_PeerIdentity my_full_id;
440
441 /**
442  * Tunnel ID for the next created tunnel (global tunnel number)
443  */
444 static MESH_TunnelNumber next_tid;
445
446 /**
447  * All application types provided by this peer
448  */
449 static GNUNET_MESH_ApplicationType *applications;
450
451 /**
452  * All application types provided by this peer (reference counter)
453  */
454 static unsigned int *applications_rc;
455
456 /**
457  * Number of applications provided by this peer
458  */
459 static unsigned int n_apps;
460
461 /**
462  * Task to periodically announce provided applications
463  */
464 GNUNET_SCHEDULER_TaskIdentifier announce_applications_task;
465
466 /**
467  * Task to periodically announce itself in the network
468  */
469 GNUNET_SCHEDULER_TaskIdentifier announce_id_task;
470
471
472 /******************************************************************************/
473 /******************      GENERAL HELPER FUNCTIONS      ************************/
474 /******************************************************************************/
475
476 /**
477  * Retrieve the MeshPeerInfo stucture associated with the peer, create one
478  * and inster it in the appropiate structures if the peer is not known yet.
479  * @param peer Identity of the peer
480  * @return Existing or newly created peer info
481  */
482 static struct MeshPeerInfo *
483 get_peer_info (const struct GNUNET_PeerIdentity *peer)
484 {
485   struct MeshPeerInfo *peer_info;
486
487   peer_info = GNUNET_CONTAINER_multihashmap_get (peers, &peer->hashPubKey);
488   if (NULL == peer_info)
489   {
490     peer_info =
491         (struct MeshPeerInfo *) GNUNET_malloc (sizeof (struct MeshPeerInfo));
492     GNUNET_CONTAINER_multihashmap_put (peers, &peer->hashPubKey, peer_info,
493                                        GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
494     peer_info->id = GNUNET_PEER_intern (peer);
495     peer_info->state = MESH_PEER_SEARCHING;
496   }
497
498   return peer_info;
499 }
500
501 /**
502  * Find the first peer whom to send a packet to go down this path
503  * @param path The path to use
504  * @return short id of the next peer, myid in case of local delivery,
505  * or 0 in case of error
506  */
507 static GNUNET_PEER_Id
508 get_first_hop (struct MeshPath *path)
509 {
510   unsigned int i;
511
512   while (NULL != path)
513   {
514     if (path->in_use)
515       break;
516     path = path->next;
517   }
518   if (NULL == path)
519   {
520     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
521                 "tried to get the next hop from an invalid path\n");
522     return 0;
523   }
524
525   for (i = 0; i < path->length; i++)
526   {
527     if (path->peers[i] == myid)
528     {
529       if (i < path->length - 1)
530       {
531         return path->peers[i + 1];
532       }
533       else
534       {
535         return myid;
536       }
537     }
538   }
539   return 0;
540 }
541
542
543 /**
544  * Get the cost of the path.
545  * @param path The path to analyze
546  * @return Number of hops to reach destination, UINT_MAX in case the peer is not
547  * in the path
548  */
549 static unsigned int
550 get_path_cost (struct MeshPath *path)
551 {
552   unsigned int i;
553
554   if (NULL == path)
555     return UINT_MAX;
556   for (i = 0; i < path->length; i++)
557   {
558     if (path->peers[i] == myid)
559     {
560       return path->length - i;
561     }
562   }
563   return UINT_MAX;
564 }
565
566
567 /**
568  * Add the path to the peer and update the path used to reach it in case this
569  * is the shortest.
570  * @param peer_info Destination peer to add the path to.
571  * @param path New path to add. Last peer must be the peer in arg 1.
572  */
573 static void
574 add_path_to_peer (struct MeshPeerInfo *peer_info, struct MeshPath *path)
575 {
576   unsigned int i;
577   unsigned int new_cost;
578   unsigned int best_cost;
579   struct MeshPath *aux;
580   struct MeshPath *best;
581
582   if (NULL == peer_info || NULL == path)
583     return;
584
585   new_cost = get_path_cost (path);
586   best_cost = UINT_MAX;
587   best = NULL;
588   for (aux = peer_info->path; aux != NULL; aux = aux->next)
589   {
590     if ((i = get_path_cost (aux)) < best_cost)
591     {
592       best = aux;
593       best_cost = i;
594     }
595   }
596   if (best_cost < new_cost)
597   {
598     path->in_use = 0;
599     GNUNET_CONTAINER_DLL_insert_tail (peer_info->path, peer_info->path_tail,
600                                       path);
601   }
602   else
603   {
604     if (NULL != best)
605       best->in_use = 0;
606     path->in_use = 1;
607     GNUNET_CONTAINER_DLL_insert (peer_info->path, peer_info->path_tail, path);
608   }
609   return;
610 }
611
612
613 /**
614  * Add the path to the peer and update the path used to reach it in case this
615  * is the shortest. The path is given in reverse, the destination peer is
616  * path[0]. The function modifies the path, inverting it to use the origin as
617  * destination.
618  * @param peer_info Destination peer to add the path to.
619  * @param path New path to add. First peer must be the peer in arg 1.
620  */
621 static void
622 add_path_to_origin (struct MeshPeerInfo *peer_info, struct MeshPath *path)
623 {
624   GNUNET_PEER_Id aux;
625   unsigned int i;
626
627   for (i = 0; i < path->length / 2; i++)
628   {
629     aux = path->peers[i];
630     path->peers[i] = path->peers[path->length - i - 1];
631     path->peers[path->length - i - 1] = aux;
632   }
633   add_path_to_peer (peer_info, path);
634 }
635
636
637 /**
638  * Check if client has registered with the service and has not disconnected
639  * @param client the client to check
640  * @return non-NULL if client exists in the global DLL
641  */
642 static struct MeshClient *
643 retrieve_client (struct GNUNET_SERVER_Client *client)
644 {
645   struct MeshClient *c;
646
647   c = clients;
648   while (NULL != c)
649   {
650     if (c->handle == client)
651       return c;
652     c = c->next;
653   }
654   return NULL;
655 }
656
657
658 /**
659  * Checks if a given client has subscribed to certain message type
660  * @param message_type Type of message to check
661  * @param c Client to check
662  * @return GNUNET_YES or GNUNET_NO, depending on subscription status
663  */
664 static int                      /* FIXME inline? */
665 is_client_subscribed (uint16_t message_type, struct MeshClient *c)
666 {
667   unsigned int i;
668
669   for (i = 0; i < c->type_counter; i++)
670   {
671     if (c->types[i] == message_type)
672       return GNUNET_YES;
673   }
674   return GNUNET_NO;
675 }
676
677
678 /**
679  * Search for a tunnel among the tunnels for a client
680  * @param client the client whose tunnels to search in
681  * @param tid the local id of the tunnel
682  * @return tunnel handler, NULL if doesn't exist
683  */
684 static struct MeshTunnel *
685 retrieve_tunnel_by_local_id (struct MeshClient *c, MESH_TunnelNumber tid)
686 {
687   GNUNET_HashCode hash;
688
689   GNUNET_CRYPTO_hash (&tid, sizeof (MESH_TunnelNumber), &hash);
690   return GNUNET_CONTAINER_multihashmap_get (c->tunnels, &hash);
691 }
692
693 /**
694  * Search for a tunnel by global ID using PEER_ID
695  * @param pi owner of the tunnel
696  * @param tid global tunnel number
697  * @return tunnel handler, NULL if doesn't exist
698  */
699 static struct MeshTunnel *
700 retrieve_tunnel_by_pi (GNUNET_PEER_Id pi, MESH_TunnelNumber tid)
701 {
702   struct MESH_TunnelID id;
703   GNUNET_HashCode hash;
704
705   id.oid = pi;
706   id.tid = tid;
707
708   GNUNET_CRYPTO_hash (&id, sizeof (struct MESH_TunnelID), &hash);
709   return GNUNET_CONTAINER_multihashmap_get (tunnels, &hash);
710 }
711
712
713
714 /**
715  * Search for a tunnel by global ID using full PeerIdentities
716  * @param oid owner of the tunnel
717  * @param tid global tunnel number
718  * @return tunnel handler, NULL if doesn't exist
719  */
720 static struct MeshTunnel *
721 retrieve_tunnel (struct GNUNET_PeerIdentity *oid, MESH_TunnelNumber tid)
722 {
723   return retrieve_tunnel_by_pi (GNUNET_PEER_search (oid), tid);
724 }
725
726
727 /**
728  * Destroy the path and free any allocated resources linked to it
729  * @param t tunnel the path belongs to
730  * @param p the path to destroy
731  * @return GNUNET_OK on success
732  */
733 static int
734 destroy_path (struct MeshPath *p)
735 {
736   GNUNET_PEER_decrement_rcs (p->peers, p->length);
737   GNUNET_free (p->peers);
738   GNUNET_free (p);
739   return GNUNET_OK;
740 }
741
742 #if LATER
743 /**
744  * Destroy the peer_info and free any allocated resources linked to it
745  * @param t tunnel the path belongs to
746  * @param pi the peer_info to destroy
747  * @return GNUNET_OK on success
748  */
749 static int
750 destroy_peer_info (struct MeshPeerInfo *pi)
751 {
752   GNUNET_HashCode hash;
753   struct GNUNET_PeerIdentity id;
754
755   GNUNET_PEER_resolve (pi->id, &id);
756   GNUNET_PEER_change_rc (pi->id, -1);
757   GNUNET_CRYPTO_hash (&id, sizeof (struct GNUNET_PeerIdentity), &hash);
758
759   GNUNET_CONTAINER_multihashmap_remove (peers, &hash, pi);
760   GNUNET_SCHEDULER_cancel (pi->path_refresh_task);
761   GNUNET_free (pi);
762   return GNUNET_OK;
763 }
764 #endif
765
766
767 /**
768  * Destroy the tunnel and free any allocated resources linked to it
769  * @param c client the tunnel belongs to
770  * @param t the tunnel to destroy
771  * @return GNUNET_OK on success
772  */
773 static int
774 destroy_tunnel (struct MeshTunnel *t)
775 {
776   struct MeshClient *c;
777   struct MeshQueue *q;
778   struct MeshQueue *qn;
779   GNUNET_HashCode hash;
780   int r;
781
782   if (NULL == t)
783     return GNUNET_OK;
784
785   c = t->client;
786
787   GNUNET_CRYPTO_hash (&t->id, sizeof (struct MESH_TunnelID), &hash);
788   if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_remove (tunnels, &hash, t))
789   {
790     r = GNUNET_SYSERR;
791   }
792
793   GNUNET_CRYPTO_hash (&t->local_tid, sizeof (MESH_TunnelNumber), &hash);
794   if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_remove (c->tunnels, &hash, t))
795   {
796     r = GNUNET_SYSERR;
797   }
798   GNUNET_CONTAINER_multihashmap_destroy (t->peers);
799   q = t->queue_head;
800   while (NULL != q)
801   {
802     if (NULL != q->data)
803       GNUNET_free (q->data);
804     qn = q->next;
805     GNUNET_free (q);
806     q = qn;
807     /* TODO cancel core transmit ready in case it was active */
808   }
809   GNUNET_free (t);
810   return r;
811 }
812
813 /******************************************************************************/
814 /************************    PERIODIC FUNCTIONS    ****************************/
815 /******************************************************************************/
816
817 /**
818  * Periodically announce what applications are provided by local clients
819  *
820  * @param cls closure
821  * @param tc task context
822  */
823 static void
824 announce_applications (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
825 {
826   GNUNET_HashCode hash;
827   uint8_t buffer[12] = "MESH_APP";
828   uint32_t *p;
829   uint32_t i;
830
831   if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN)
832   {
833     announce_applications_task = GNUNET_SCHEDULER_NO_TASK;
834     return;
835   }
836   p = (unsigned int *) &buffer[8];
837   for (i = 0; i < n_apps; i++)
838   {
839     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: Starting PUT for app %d\n",
840                 applications[i]);
841     *p = htonl (applications[i]);
842     GNUNET_CRYPTO_hash (buffer, 12, &hash);
843     GNUNET_DHT_put (dht_handle, &hash, 10U, GNUNET_DHT_RO_RECORD_ROUTE,
844                     GNUNET_BLOCK_TYPE_ANY, sizeof (struct GNUNET_PeerIdentity),
845                     (const char *) &my_full_id,
846                     GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (),
847                                               APP_ANNOUNCE_TIME),
848                     APP_ANNOUNCE_TIME,
849 #if MESH_DEBUG
850                     &mesh_debug, "MESH: DHT_put for apps completed\n");
851 #else
852                     NULL, NULL);
853 #endif
854   }
855   announce_applications_task =
856       GNUNET_SCHEDULER_add_delayed (APP_ANNOUNCE_TIME, &announce_applications,
857                                     cls);
858   return;
859 }
860
861
862 /**
863  * Periodically announce self id in the DHT
864  *
865  * @param cls closure
866  * @param tc task context
867  */
868 static void
869 announce_id (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
870 {
871   if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN)
872   {
873     announce_id_task = GNUNET_SCHEDULER_NO_TASK;
874     return;
875   }
876   /* TODO
877    * - Set data expiration in function of X
878    * - Adapt X to churn
879    */
880   GNUNET_DHT_put (dht_handle,   /* DHT handle */
881                   &my_full_id.hashPubKey,       /* Key to use */
882                   10U,          /* Replication level */
883                   GNUNET_DHT_RO_RECORD_ROUTE,   /* DHT options */
884                   GNUNET_BLOCK_TYPE_ANY,        /* Block type */
885                   0,            /* Size of the data */
886                   NULL,         /* Data itself */
887                   GNUNET_TIME_absolute_get_forever (),  /* Data expiration */
888                   GNUNET_TIME_UNIT_FOREVER_REL, /* Retry time */
889 #if MESH_DEBUG
890                   &mesh_debug, "DHT_put for id completed\n");
891 #else
892                   NULL,         /* Continuation */
893                   NULL);        /* Continuation closure */
894 #endif
895   announce_id_task =
896       GNUNET_SCHEDULER_add_delayed (ID_ANNOUNCE_TIME, &announce_id, cls);
897 }
898
899 /******************************************************************************/
900 /****************      MESH NETWORK HANDLER HELPERS     ***********************/
901 /******************************************************************************/
902
903 /**
904  * Function called to notify a client about the socket
905  * being ready to queue more data.  "buf" will be
906  * NULL and "size" zero if the socket was closed for
907  * writing in the meantime.
908  *
909  * @param cls closure
910  * @param size number of bytes available in buf
911  * @param buf where the callee should write the message
912  * @return number of bytes written to buf
913  */
914 static size_t
915 send_core_create_path_for_peer (void *cls, size_t size, void *buf)
916 {
917   struct MeshPeerInfo *peer_info = cls;
918   struct GNUNET_MESH_ManipulatePath *msg;
919   struct MeshPath *p;
920   struct GNUNET_PeerIdentity *peer_ptr;
921   struct GNUNET_PeerIdentity id;
922   size_t size_needed;
923   int i;
924
925   if (0 == size && NULL == buf)
926   {
927     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: Retransmitting create path\n");
928     GNUNET_PEER_resolve (get_first_hop (peer_info->path), &id);
929     GNUNET_CORE_notify_transmit_ready (core_handle, 0, 0,
930                                        GNUNET_TIME_UNIT_FOREVER_REL, &id,
931                                        sizeof (struct
932                                                GNUNET_MESH_ManipulatePath) +
933                                        (peer_info->path->length *
934                                         sizeof (struct GNUNET_PeerIdentity)),
935                                        &send_core_create_path_for_peer,
936                                        peer_info);
937     return 0;
938   }
939   p = peer_info->path;
940   while (NULL != p)
941   {
942     if (p->in_use)
943     {
944       break;
945     }
946     p = p->next;
947   }
948   if (p == NULL)
949     return 0;                   // TODO Notify ERROR Path not found
950
951   size_needed =
952       sizeof (struct GNUNET_MESH_ManipulatePath) +
953       p->length * sizeof (struct GNUNET_PeerIdentity);
954   if (size < size_needed)
955   {
956     // TODO retry? cancel?
957     return 0;
958   }
959
960   msg = (struct GNUNET_MESH_ManipulatePath *) buf;
961   msg->header.size = htons (size_needed);
962   msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE);
963
964   peer_ptr = (struct GNUNET_PeerIdentity *) &msg[1];
965   for (i = 0; i < p->length; i++)
966   {
967     GNUNET_PEER_resolve (p->peers[i], peer_ptr++);
968   }
969
970   peer_info->state = MESH_PEER_WAITING;
971
972   return size_needed;
973 }
974
975
976 #if LATER
977 /**
978  * Function called to notify a client about the socket
979  * being ready to queue more data.  "buf" will be
980  * NULL and "size" zero if the socket was closed for
981  * writing in the meantime.
982  *
983  * @param cls closure (MeshDataDescriptor with all info to build packet)
984  * @param size number of bytes available in buf
985  * @param buf where the callee should write the message
986  * @return number of bytes written to buf
987  */
988 static size_t
989 send_core_data_to_origin (void *cls, size_t size, void *buf)
990 {
991   struct MeshDataDescriptor *info = cls;
992   struct GNUNET_MESH_ToOrigin *msg = buf;
993   size_t total_size;
994
995   GNUNET_assert (NULL != info);
996   total_size = sizeof (struct GNUNET_MESH_ToOrigin) + info->size;
997   GNUNET_assert (total_size < 65536);   /* UNIT16_MAX */
998
999   if (total_size > size)
1000   {
1001     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1002                 "not enough buffer to send data to origin\n");
1003     return 0;
1004   }
1005   msg->header.size = htons (total_size);
1006   msg->header.type = htons (GNUNET_MESSAGE_TYPE_DATA_MESSAGE_TO_ORIGIN);
1007   GNUNET_PEER_resolve (info->origin->oid, &msg->oid);
1008   msg->tid = htonl (info->origin->tid);
1009   if (0 != info->size)
1010   {
1011     memcpy (&msg[1], &info[1], info->size);
1012   }
1013   if (NULL != info->client)
1014   {
1015     GNUNET_SERVER_receive_done (info->client, GNUNET_OK);
1016   }
1017   GNUNET_free (info);
1018   return total_size;
1019 }
1020 #endif
1021
1022 /**
1023  * Function called to notify a client about the socket
1024  * being ready to queue more data.  "buf" will be
1025  * NULL and "size" zero if the socket was closed for
1026  * writing in the meantime.
1027  *
1028  * @param cls closure (data itself)
1029  * @param size number of bytes available in buf
1030  * @param buf where the callee should write the message
1031  * @return number of bytes written to buf
1032  */
1033 static size_t
1034 send_core_data_unicast (void *cls, size_t size, void *buf)
1035 {
1036   struct MeshDataDescriptor *info = cls;
1037   struct GNUNET_MESH_Unicast *msg = buf;
1038   size_t total_size;
1039
1040   GNUNET_assert (NULL != info);
1041   total_size = sizeof (struct GNUNET_MESH_Unicast) + info->size;
1042   GNUNET_assert (total_size < 65536);   /* UNIT16_MAX */
1043
1044   if (total_size > size)
1045   {
1046     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1047                 "not enough buffer to send data to peer\n");
1048     return 0;
1049   }
1050   msg->header.size = htons (total_size);
1051   msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_UNICAST);
1052   GNUNET_PEER_resolve (info->origin->oid, &msg->oid);
1053   GNUNET_PEER_resolve (info->destination, &msg->destination);
1054   msg->tid = htonl (info->origin->tid);
1055   if (0 != info->size)
1056   {
1057     memcpy (&msg[1], &info[1], info->size);
1058   }
1059   if (NULL != info->client)
1060   {
1061     GNUNET_SERVER_receive_done (info->client, GNUNET_OK);
1062   }
1063   GNUNET_free (info);
1064   return total_size;
1065 }
1066
1067
1068 /**
1069  * Function called to notify a client about the socket
1070  * being ready to queue more data.  "buf" will be
1071  * NULL and "size" zero if the socket was closed for
1072  * writing in the meantime.
1073  *
1074  * @param cls closure (data itself)
1075  * @param size number of bytes available in buf
1076  * @param buf where the callee should write the message
1077  * @return number of bytes written to buf
1078  */
1079 static size_t
1080 send_core_data_multicast (void *cls, size_t size, void *buf)
1081 {
1082   struct MeshDataDescriptor *info = cls;
1083   struct GNUNET_MESH_Multicast *msg = buf;
1084   size_t total_size;
1085
1086   GNUNET_assert (NULL != info);
1087   total_size = info->size + sizeof (struct GNUNET_MESH_Multicast);
1088   GNUNET_assert (total_size < GNUNET_SERVER_MAX_MESSAGE_SIZE);
1089
1090   if (info->peer)
1091   {
1092     info->peer->core_transmit[info->handler_n] = NULL;
1093   }
1094   if (total_size > size)
1095   {
1096     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1097                 "not enough buffer to send data futher\n");
1098     return 0;
1099   }
1100   msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_MULTICAST);
1101   msg->header.size = htons (total_size);
1102   GNUNET_PEER_resolve (info->origin->oid, &msg->oid);
1103   msg->tid = htonl (info->origin->tid);
1104   memcpy (&msg[1], &info[1], total_size);
1105   if (0 == --info->copies)
1106   {
1107     if (NULL != info->client)
1108     {
1109       GNUNET_SERVER_receive_done (info->client, GNUNET_OK);
1110     }
1111     GNUNET_free (info);
1112   }
1113   return total_size;
1114 }
1115
1116
1117 /**
1118  * Function called to notify a client about the socket
1119  * being ready to queue more data.  "buf" will be
1120  * NULL and "size" zero if the socket was closed for
1121  * writing in the meantime.
1122  *
1123  * @param cls closure (MeshDataDescriptor)
1124  * @param size number of bytes available in buf
1125  * @param buf where the callee should write the message
1126  * @return number of bytes written to buf
1127  */
1128 static size_t
1129 send_core_path_ack (void *cls, size_t size, void *buf)
1130 {
1131   struct MeshDataDescriptor *info = cls;
1132   struct GNUNET_MESH_PathACK *msg = buf;
1133
1134   GNUNET_assert (NULL != info);
1135   if (info->peer)
1136   {
1137     info->peer->core_transmit[info->handler_n] = NULL;
1138   }
1139   if (sizeof (struct GNUNET_MESH_PathACK) > size)
1140   {
1141     GNUNET_break (0);
1142     return 0;
1143   }
1144   msg->header.size = htons (sizeof (struct GNUNET_MESH_PathACK));
1145   msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_PATH_ACK);
1146   GNUNET_PEER_resolve (info->origin->oid, &msg->oid);
1147   msg->tid = htonl (info->origin->tid);
1148   msg->peer_id = my_full_id;
1149   /* TODO add signature */
1150
1151   return sizeof (struct GNUNET_MESH_PathACK);
1152 }
1153
1154
1155 /**
1156  * Function called to notify a client about the socket
1157  * being ready to queue more data.  "buf" will be
1158  * NULL and "size" zero if the socket was closed for
1159  * writing in the meantime.
1160  *
1161  * @param cls closure (data itself)
1162  * @param size number of bytes available in buf
1163  * @param buf where the callee should write the message
1164  * @return number of bytes written to buf
1165  */
1166 static size_t
1167 send_core_data_raw (void *cls, size_t size, void *buf)
1168 {
1169   struct GNUNET_MessageHeader *msg = cls;
1170   size_t total_size;
1171
1172   GNUNET_assert (NULL != msg);
1173   total_size = ntohs (msg->size);
1174
1175   if (total_size > size)
1176   {
1177     GNUNET_break (0);
1178     return 0;
1179   }
1180   memcpy (buf, msg, total_size);
1181   GNUNET_free (cls);
1182   return total_size;
1183 }
1184
1185
1186 #if LATER
1187 /**
1188  * Send another peer a notification to destroy a tunnel
1189  * @param cls The tunnel to destroy
1190  * @param size Size in the buffer
1191  * @param buf Memory where to put the data to transmit
1192  * @return Size of data put in buffer
1193  */
1194 static size_t
1195 send_p2p_tunnel_destroy (void *cls, size_t size, void *buf)
1196 {
1197   struct MeshTunnel *t = cls;
1198   struct MeshClient *c;
1199   struct GNUNET_MESH_TunnelMessage *msg;
1200
1201   c = t->client;
1202   msg = buf;
1203   msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_DESTROY);
1204    /*FIXME*/ msg->header.size =
1205       htons (sizeof (struct GNUNET_MESH_TunnelMessage));
1206   msg->tunnel_id = htonl (t->id.tid);
1207
1208   destroy_tunnel (c, t);
1209   return sizeof (struct GNUNET_MESH_TunnelMessage);
1210 }
1211 #endif
1212
1213
1214 /**
1215  * Send the message to all clients that have subscribed to its type
1216  *
1217  * @param msg Pointer to the message itself
1218  * @return number of clients this message was sent to
1219  */
1220 static unsigned int
1221 send_subscribed_clients (struct GNUNET_MessageHeader *msg)
1222 {
1223   struct MeshClient *c;
1224   unsigned int count;
1225   uint16_t type;
1226
1227   type = ntohs (msg->type);
1228   for (count = 0, c = clients; c != NULL; c = c->next)
1229   {
1230     if (is_client_subscribed (type, c))
1231     {
1232       count++;
1233       GNUNET_SERVER_notification_context_unicast (nc, c->handle, msg,
1234                                                   GNUNET_YES);
1235     }
1236   }
1237   return count;
1238 }
1239
1240
1241 /**
1242  * Iterator over hash map peer entries collect all neighbors who to resend the
1243  * data to.
1244  *
1245  * @param cls closure (**GNUNET_PEER_Id to store hops to send packet)
1246  * @param key current key code (peer id hash)
1247  * @param value value in the hash map (peer_info)
1248  * @return GNUNET_YES if we should continue to iterate, GNUNET_NO if not.
1249  */
1250 static int
1251 iterate_collect_neighbors (void *cls, const GNUNET_HashCode * key, void *value)
1252 {
1253   struct MeshPeerInfo *peer_info = value;
1254   GNUNET_PEER_Id **neighbors = cls;
1255   GNUNET_PEER_Id id;
1256   unsigned int i;
1257
1258   if (peer_info->id == myid)
1259   {
1260     return GNUNET_YES;
1261   }
1262   id = get_first_hop (peer_info->path);
1263   for (i = 0; *neighbors[i] != 0; i++)
1264   {
1265     if (*neighbors[i] == id)
1266       return GNUNET_YES;
1267   }
1268   *neighbors = GNUNET_realloc (*neighbors, (i + 2) * sizeof (GNUNET_PEER_Id));
1269   *neighbors[i] = id;
1270   *neighbors[i + 1] = 0;
1271
1272   return GNUNET_YES;
1273 }
1274
1275
1276 /******************************************************************************/
1277 /********************      MESH NETWORK HANDLERS     **************************/
1278 /******************************************************************************/
1279
1280
1281 /**
1282  * Core handler for path creation
1283  * struct GNUNET_CORE_MessageHandler
1284  *
1285  * @param cls closure
1286  * @param message message
1287  * @param peer peer identity this notification is about
1288  * @param atsi performance data
1289  * @return GNUNET_OK to keep the connection open,
1290  *         GNUNET_SYSERR to close it (signal serious error)
1291  *
1292  */
1293 static int
1294 handle_mesh_path_create (void *cls, const struct GNUNET_PeerIdentity *peer,
1295                          const struct GNUNET_MessageHeader *message,
1296                          const struct GNUNET_TRANSPORT_ATS_Information *atsi)
1297 {
1298   unsigned int own_pos;
1299   uint16_t size;
1300   uint16_t i;
1301   MESH_TunnelNumber tid;
1302   struct GNUNET_MESH_ManipulatePath *msg;
1303   struct GNUNET_PeerIdentity *pi;
1304   struct GNUNET_PeerIdentity id;
1305   GNUNET_HashCode hash;
1306   struct MeshPath *path;
1307   struct MeshPeerInfo *dest_peer_info;
1308   struct MeshPeerInfo *orig_peer_info;
1309   struct MeshTunnel *t;
1310
1311   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1312               "MESH: Received a MESH path create msg\n");
1313   size = ntohs (message->size);
1314   if (size < sizeof (struct GNUNET_MESH_ManipulatePath))
1315   {
1316     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1317                 "received create path message too short\n");
1318     return GNUNET_OK;
1319   }
1320
1321   size -= sizeof (struct GNUNET_MESH_ManipulatePath);
1322   if (size < 2 * sizeof (struct GNUNET_PeerIdentity))
1323   {
1324     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1325                 "create path message lacks enough peers\n");
1326     return GNUNET_OK;
1327   }
1328   if (size % sizeof (struct GNUNET_PeerIdentity))
1329   {
1330     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1331                 "create path message of wrong size\n");
1332     return GNUNET_OK;
1333   }
1334   msg = (struct GNUNET_MESH_ManipulatePath *) message;
1335   size /= sizeof (struct GNUNET_PeerIdentity);
1336
1337   tid = ntohl (msg->tid);
1338   pi = (struct GNUNET_PeerIdentity *) &msg[1];
1339   t = retrieve_tunnel (pi, tid);
1340
1341   if (NULL == t)
1342   {
1343     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: Creating tunnel\n");
1344     t = GNUNET_malloc (sizeof (struct MeshTunnel));
1345     t->id.oid = GNUNET_PEER_intern (pi);
1346     t->id.tid = tid;
1347     t->peers = GNUNET_CONTAINER_multihashmap_create (32);
1348
1349     GNUNET_CRYPTO_hash (&t->id, sizeof (struct MESH_TunnelID), &hash);
1350     if (GNUNET_OK !=
1351         GNUNET_CONTAINER_multihashmap_put (tunnels, &hash, t,
1352                                            GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
1353     {
1354       GNUNET_break (0);
1355       return GNUNET_OK;
1356     }
1357
1358   }
1359   dest_peer_info =
1360       GNUNET_CONTAINER_multihashmap_get (peers, &pi[size - 1].hashPubKey);
1361   if (NULL == dest_peer_info)
1362   {
1363     dest_peer_info = GNUNET_malloc (sizeof (struct MeshPeerInfo));
1364     dest_peer_info->id = GNUNET_PEER_intern (&pi[size - 1]);
1365     dest_peer_info->state = MESH_PEER_WAITING;
1366     GNUNET_CONTAINER_multihashmap_put (peers, &pi[size - 1].hashPubKey,
1367                                        dest_peer_info,
1368                                        GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
1369   }
1370   orig_peer_info = GNUNET_CONTAINER_multihashmap_get (peers, &pi->hashPubKey);
1371   if (NULL == orig_peer_info)
1372   {
1373     orig_peer_info = GNUNET_malloc (sizeof (struct MeshPeerInfo));
1374     orig_peer_info->id = GNUNET_PEER_intern (pi);
1375     orig_peer_info->state = MESH_PEER_WAITING;
1376     GNUNET_CONTAINER_multihashmap_put (peers, &pi->hashPubKey, orig_peer_info,
1377                                        GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
1378   }
1379
1380
1381   path = GNUNET_malloc (sizeof (struct MeshPath));
1382   path->length = size;
1383   path->peers = GNUNET_malloc (size * sizeof (GNUNET_PEER_Id));
1384   own_pos = 0;
1385   for (i = 0; i < size; i++)
1386   {
1387     path->peers[i] = GNUNET_PEER_intern (&pi[i]);
1388     if (path->peers[i] == myid)
1389       own_pos = i;
1390   }
1391   if (own_pos == 0)
1392   {                             /* cannot be self, must be 'not found' */
1393     /* create path: self not found in path through self */
1394     GNUNET_break_op (0);
1395     destroy_path (path);
1396     /* FIXME error. destroy tunnel? leave for timeout? */
1397     return 0;
1398   }
1399   if (own_pos == size - 1)
1400   {                             /* it is for us! */
1401     struct MeshDataDescriptor *info;
1402     unsigned int j;
1403
1404     add_path_to_origin (orig_peer_info, path);  /* inverts path!  */
1405     GNUNET_PEER_resolve (get_first_hop (path), &id);    /* path is inverted :) */
1406     info = GNUNET_malloc (sizeof (struct MeshDataDescriptor));
1407     info->origin = &t->id;
1408     info->peer = GNUNET_CONTAINER_multihashmap_get (peers, &id.hashPubKey);
1409     GNUNET_assert (info->peer);
1410     for (j = 0; info->peer->core_transmit[j]; j++)
1411     {
1412       if (j == 9)
1413       {
1414         GNUNET_break (0);
1415         return GNUNET_OK;
1416       }
1417     }
1418     info->handler_n = j;
1419     info->peer->core_transmit[j] =
1420         GNUNET_CORE_notify_transmit_ready (core_handle, 0, 100,
1421                                            GNUNET_TIME_UNIT_FOREVER_REL, &id,
1422                                            sizeof (struct GNUNET_MessageHeader),
1423                                            &send_core_path_ack, info);
1424   }
1425   else
1426   {
1427     add_path_to_peer (dest_peer_info, path);
1428     GNUNET_PEER_resolve (get_first_hop (path), &id);
1429     GNUNET_CORE_notify_transmit_ready (core_handle, 0, 0,
1430                                        GNUNET_TIME_UNIT_FOREVER_REL, &id,
1431                                        sizeof (struct GNUNET_MessageHeader),
1432                                        &send_core_create_path_for_peer,
1433                                        dest_peer_info);
1434   }
1435   return GNUNET_OK;
1436 }
1437
1438
1439 /**
1440  * Core handler for mesh network traffic going from the origin to a peer
1441  *
1442  * @param cls closure
1443  * @param peer peer identity this notification is about
1444  * @param message message
1445  * @param atsi performance data
1446  * @return GNUNET_OK to keep the connection open,
1447  *         GNUNET_SYSERR to close it (signal serious error)
1448  */
1449 static int
1450 handle_mesh_data_unicast (void *cls, const struct GNUNET_PeerIdentity *peer,
1451                           const struct GNUNET_MessageHeader *message,
1452                           const struct GNUNET_TRANSPORT_ATS_Information *atsi)
1453 {
1454   struct GNUNET_MESH_Unicast *msg;
1455   struct GNUNET_PeerIdentity id;
1456   struct MeshTunnel *t;
1457   struct MeshPeerInfo *pi;
1458   size_t size;
1459
1460   size = ntohs (message->size);
1461   if (size <
1462       sizeof (struct GNUNET_MESH_Unicast) +
1463       sizeof (struct GNUNET_MessageHeader))
1464   {
1465     GNUNET_break (0);
1466     return GNUNET_OK;
1467   }
1468   msg = (struct GNUNET_MESH_Unicast *) message;
1469   t = retrieve_tunnel (&msg->oid, ntohl (msg->tid));
1470   if (NULL == t)
1471   {
1472     /* TODO notify back: we don't know this tunnel */
1473     return GNUNET_OK;
1474   }
1475   pi = GNUNET_CONTAINER_multihashmap_get (t->peers,
1476                                           &msg->destination.hashPubKey);
1477   if (NULL == pi)
1478   {
1479     /* TODO maybe feedback, log to statistics */
1480     return GNUNET_OK;
1481   }
1482   if (pi->id == myid)
1483   {
1484     send_subscribed_clients ((struct GNUNET_MessageHeader *) &msg[1]);
1485     return GNUNET_OK;
1486   }
1487   GNUNET_PEER_resolve (get_first_hop (pi->path), &id);
1488   msg = GNUNET_malloc (size);
1489   memcpy (msg, message, size);
1490   GNUNET_CORE_notify_transmit_ready (core_handle, 0, 0,
1491                                      GNUNET_TIME_UNIT_FOREVER_REL, &id, size,
1492                                      &send_core_data_raw, msg);
1493   return GNUNET_OK;
1494 }
1495
1496
1497 /**
1498  * Core handler for mesh network traffic going from the origin to all peers
1499  *
1500  * @param cls closure
1501  * @param message message
1502  * @param peer peer identity this notification is about
1503  * @param atsi performance data
1504  * @return GNUNET_OK to keep the connection open,
1505  *         GNUNET_SYSERR to close it (signal serious error)
1506  */
1507 static int
1508 handle_mesh_data_multicast (void *cls, const struct GNUNET_PeerIdentity *peer,
1509                             const struct GNUNET_MessageHeader *message,
1510                             const struct GNUNET_TRANSPORT_ATS_Information *atsi)
1511 {
1512   struct GNUNET_MESH_Multicast *msg;
1513   struct GNUNET_PeerIdentity id;
1514   struct MeshTunnel *t;
1515   struct MeshDataDescriptor *info;
1516   GNUNET_PEER_Id *neighbors;
1517   size_t size;
1518   uint16_t i;
1519   uint16_t j;
1520
1521
1522   size = ntohs (message->size);
1523   if (size <
1524       sizeof (struct GNUNET_MESH_Multicast) +
1525       sizeof (struct GNUNET_MessageHeader))
1526   {
1527     GNUNET_break_op (0);
1528     return GNUNET_OK;
1529   }
1530   msg = (struct GNUNET_MESH_Multicast *) message;
1531   t = retrieve_tunnel (&msg->oid, ntohl (msg->tid));
1532
1533   if (NULL == t)
1534   {
1535     /* TODO notify that we dont know that tunnel */
1536     return GNUNET_OK;
1537   }
1538
1539   /* Transmit to locally interested clients */
1540   if (GNUNET_CONTAINER_multihashmap_contains (t->peers, &my_full_id.hashPubKey))
1541   {
1542     send_subscribed_clients ((struct GNUNET_MessageHeader *) &msg[1]);
1543   }
1544
1545   /* Retransmit to other peers */
1546   neighbors = GNUNET_malloc (sizeof (GNUNET_PEER_Id));
1547   neighbors[0] = 0;
1548   GNUNET_CONTAINER_multihashmap_iterate (t->peers, &iterate_collect_neighbors,
1549                                          &neighbors);
1550   if (!neighbors[0])
1551   {
1552     return GNUNET_OK;
1553   }
1554   size -= sizeof (struct GNUNET_MESH_Multicast);
1555   info = GNUNET_malloc (sizeof (struct MeshDataDescriptor) + size);
1556   info->origin = &t->id;
1557   info->copies = 0;
1558   for (i = 0; 0 != neighbors[i]; i++)
1559   {
1560     GNUNET_PEER_resolve (neighbors[i], &id);
1561     info->copies++;
1562     info->destination = neighbors[i];
1563     info->peer = GNUNET_CONTAINER_multihashmap_get (peers, &id.hashPubKey);
1564     GNUNET_assert (info->peer);
1565     for (j = 0; info->peer->core_transmit[j]; j++)
1566     {
1567       if (j == 9)
1568       {
1569         GNUNET_break (0);
1570         return GNUNET_OK;
1571       }
1572     }
1573     info->handler_n = j;
1574     info->peer->infos[j] = info;
1575     info->peer->core_transmit[j] =
1576         GNUNET_CORE_notify_transmit_ready (core_handle, 0, 0,
1577                                            GNUNET_TIME_UNIT_FOREVER_REL, &id,
1578                                            ntohs (msg->header.size),
1579                                            &send_core_data_multicast, info);
1580   }
1581   return GNUNET_OK;
1582 }
1583
1584
1585 /**
1586  * Core handler for mesh network traffic
1587  *
1588  * @param cls closure
1589  * @param message message
1590  * @param peer peer identity this notification is about
1591  * @param atsi performance data
1592  * @return GNUNET_OK to keep the connection open,
1593  *         GNUNET_SYSERR to close it (signal serious error)
1594  */
1595 static int
1596 handle_mesh_data_to_orig (void *cls, const struct GNUNET_PeerIdentity *peer,
1597                           const struct GNUNET_MessageHeader *message,
1598                           const struct GNUNET_TRANSPORT_ATS_Information *atsi)
1599 {
1600   struct GNUNET_MESH_ToOrigin *msg;
1601   struct GNUNET_PeerIdentity id;
1602   struct MeshTunnel *t;
1603   struct MeshPeerInfo *peer_info;
1604   size_t size;
1605
1606   size = ntohs (message->size);
1607   if (size <
1608       sizeof (struct GNUNET_MESH_ToOrigin) +
1609       sizeof (struct GNUNET_MessageHeader))
1610   {
1611     GNUNET_break_op (0);
1612     return GNUNET_OK;
1613   }
1614   msg = (struct GNUNET_MESH_ToOrigin *) message;
1615   t = retrieve_tunnel (&msg->oid, ntohl (msg->tid));
1616
1617   if (NULL == t)
1618   {
1619     /* TODO notify that we dont know this tunnel (whom)? */
1620     return GNUNET_OK;
1621   }
1622
1623   if (t->id.oid == myid)
1624   {
1625     if (NULL == t->client)
1626     {
1627       /* got data packet for ownerless tunnel */
1628       GNUNET_break_op (0);
1629       return GNUNET_OK;
1630     }
1631     GNUNET_SERVER_notification_context_unicast (nc, t->client->handle, message,
1632                                                 GNUNET_YES);
1633     return GNUNET_OK;
1634   }
1635   peer_info = get_peer_info (&msg->oid);
1636   if (NULL == peer_info)
1637   {
1638     /* unknown origin of tunnel */
1639     GNUNET_break (0);
1640     return GNUNET_OK;
1641   }
1642   GNUNET_PEER_resolve (get_first_hop (peer_info->path), &id);
1643   msg = GNUNET_malloc (size);
1644   memcpy (msg, message, size);
1645   GNUNET_CORE_notify_transmit_ready (core_handle, 0, 0,
1646                                      GNUNET_TIME_UNIT_FOREVER_REL, &id, size,
1647                                      &send_core_data_raw, msg);
1648
1649   return GNUNET_OK;
1650 }
1651
1652
1653 /**
1654  * Core handler for path ACKs
1655  *
1656  * @param cls closure
1657  * @param message message
1658  * @param peer peer identity this notification is about
1659  * @param atsi performance data
1660  * @return GNUNET_OK to keep the connection open,
1661  *         GNUNET_SYSERR to close it (signal serious error)
1662  */
1663 static int
1664 handle_mesh_path_ack (void *cls, const struct GNUNET_PeerIdentity *peer,
1665                       const struct GNUNET_MessageHeader *message,
1666                       const struct GNUNET_TRANSPORT_ATS_Information *atsi)
1667 {
1668   struct GNUNET_MESH_PathACK *msg;
1669   struct GNUNET_PeerIdentity id;
1670   struct MeshTunnel *t;
1671   struct MeshPeerInfo *peer_info;
1672
1673   msg = (struct GNUNET_MESH_PathACK *) message;
1674   t = retrieve_tunnel (&msg->oid, msg->tid);
1675   if (NULL == t)
1676   {
1677     /* TODO notify that we don't know the tunnel */
1678     return GNUNET_OK;
1679   }
1680
1681   /* Message for us? */
1682   if (0 == memcmp (&msg->oid, &my_full_id, sizeof(struct GNUNET_PeerIdentity)))
1683   {
1684     struct GNUNET_MESH_PeerControl pc;
1685
1686     if (NULL == t->client)
1687     {
1688       GNUNET_break (0);
1689       return GNUNET_OK;
1690     }
1691     peer_info = get_peer_info (&msg->peer_id);
1692     if (NULL == peer_info)
1693     {
1694       GNUNET_break_op (0);
1695       return GNUNET_OK;
1696     }
1697     peer_info->state = MESH_PEER_READY;
1698     pc.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_ADD);
1699     pc.header.size = htons (sizeof (struct GNUNET_MESH_PeerControl));
1700     pc.tunnel_id = htonl (t->local_tid);
1701     GNUNET_PEER_resolve (peer_info->id, &pc.peer);
1702     GNUNET_SERVER_notification_context_unicast (nc, t->client->handle,
1703                                                 &pc.header, GNUNET_NO);
1704     return GNUNET_OK;
1705   }
1706
1707   peer_info = get_peer_info (&msg->oid);
1708   if (NULL == peer_info)
1709   {
1710     /* If we know the tunnel, we should DEFINITELY know the peer */
1711     GNUNET_break (0);
1712     return GNUNET_OK;
1713   }
1714   GNUNET_PEER_resolve (get_first_hop (peer_info->path), &id);
1715   msg = GNUNET_malloc (sizeof (struct GNUNET_MESH_PathACK));
1716   memcpy (msg, message, sizeof (struct GNUNET_MESH_PathACK));
1717   GNUNET_CORE_notify_transmit_ready (core_handle, 0, 0,
1718                                      GNUNET_TIME_UNIT_FOREVER_REL, &id,
1719                                      sizeof (struct GNUNET_MESH_PathACK),
1720                                      &send_core_data_raw, msg);
1721   return GNUNET_OK;
1722 }
1723
1724
1725 /**
1726  * Functions to handle messages from core
1727  */
1728 static struct GNUNET_CORE_MessageHandler core_handlers[] = {
1729   {&handle_mesh_path_create, GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE, 0},
1730   {&handle_mesh_data_unicast, GNUNET_MESSAGE_TYPE_MESH_UNICAST, 0},
1731   {&handle_mesh_data_multicast, GNUNET_MESSAGE_TYPE_MESH_MULTICAST, 0},
1732   {&handle_mesh_data_to_orig, GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN, 0},
1733   {&handle_mesh_path_ack, GNUNET_MESSAGE_TYPE_MESH_PATH_ACK,
1734    sizeof (struct GNUNET_MESH_PathACK)},
1735   {NULL, 0, 0}
1736 };
1737
1738
1739
1740 /******************************************************************************/
1741 /****************       MESH LOCAL HANDLER HELPERS      ***********************/
1742 /******************************************************************************/
1743
1744 /**
1745  * delete_tunnel_entry: iterator for deleting each tunnel that belongs to a
1746  * client when the client disconnects.
1747  * @param cls closure (client that is disconnecting)
1748  * @param key the hash of the local tunnel id (used to access the hashmap)
1749  * @param value the value stored at the key (tunnel to destroy)
1750  * @return GNUNET_OK on success
1751  */
1752 static int
1753 delete_tunnel_entry (void *cls, const GNUNET_HashCode * key, void *value)
1754 {
1755   int r;
1756
1757   r = destroy_tunnel ((struct MeshTunnel *) value);
1758   return r;
1759 }
1760
1761 #if LATER
1762 /**
1763  * notify_client_connection_failure: notify a client that the connection to the
1764  * requested remote peer is not possible (for instance, no route found)
1765  * Function called when the socket is ready to queue more data. "buf" will be
1766  * NULL and "size" zero if the socket was closed for writing in the meantime.
1767  *
1768  * @param cls closure
1769  * @param size number of bytes available in buf
1770  * @param buf where the callee should write the message
1771  * @return number of bytes written to buf
1772  */
1773 static size_t
1774 notify_client_connection_failure (void *cls, size_t size, void *buf)
1775 {
1776   int size_needed;
1777   struct MeshPeerInfo *peer_info;
1778   struct GNUNET_MESH_PeerControl *msg;
1779   struct GNUNET_PeerIdentity id;
1780
1781   if (0 == size && NULL == buf)
1782   {
1783     // TODO retry? cancel?
1784     return 0;
1785   }
1786
1787   size_needed = sizeof (struct GNUNET_MESH_PeerControl);
1788   peer_info = (struct MeshPeerInfo *) cls;
1789   msg = (struct GNUNET_MESH_PeerControl *) buf;
1790   msg->header.size = htons (sizeof (struct GNUNET_MESH_PeerControl));
1791   msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_DISCONNECTED);
1792 //     msg->tunnel_id = htonl(peer_info->t->tid);
1793   GNUNET_PEER_resolve (peer_info->id, &id);
1794   memcpy (&msg->peer, &id, sizeof (struct GNUNET_PeerIdentity));
1795
1796   return size_needed;
1797 }
1798 #endif
1799
1800
1801 /**
1802  * Send keepalive packets for a peer
1803  *
1804  * @param cls unused
1805  * @param tc unused
1806  */
1807 static void
1808 path_refresh (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1809 {
1810   struct MeshPeerInfo *peer_info = cls;
1811   struct GNUNET_PeerIdentity id;
1812
1813   if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN)
1814     return;
1815   GNUNET_PEER_resolve (get_first_hop (peer_info->path), &id);
1816   GNUNET_CORE_notify_transmit_ready (core_handle, 0, 0,
1817                                      GNUNET_TIME_UNIT_FOREVER_REL, &id,
1818                                      sizeof (struct GNUNET_MESH_ManipulatePath)
1819                                      +
1820                                      (peer_info->path->length *
1821                                       sizeof (struct GNUNET_PeerIdentity)),
1822                                      &send_core_create_path_for_peer,
1823                                      peer_info);
1824   peer_info->path_refresh_task =
1825       GNUNET_SCHEDULER_add_delayed (REFRESH_PATH_TIME, &path_refresh,
1826                                     peer_info);
1827   return;
1828 }
1829
1830
1831 /**
1832  * Function to process paths received for a new peer addition. The recorded
1833  * paths form the initial tunnel, which can be optimized later.
1834  * Called on each result obtained for the DHT search.
1835  *
1836  * @param cls closure
1837  * @param exp when will this value expire
1838  * @param key key of the result
1839  * @param get_path NULL-terminated array of pointers
1840  *                 to the peers on reverse GET path (or NULL if not recorded)
1841  * @param put_path NULL-terminated array of pointers
1842  *                 to the peers on the PUT path (or NULL if not recorded)
1843  * @param type type of the result
1844  * @param size number of bytes in data
1845  * @param data pointer to the result data
1846  */
1847 static void
1848 dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp,
1849                     const GNUNET_HashCode * key,
1850                     const struct GNUNET_PeerIdentity *const *get_path,
1851                     const struct GNUNET_PeerIdentity *const *put_path,
1852                     enum GNUNET_BLOCK_Type type, size_t size, const void *data)
1853 {
1854   struct MeshPeerInfo *peer_info = cls;
1855   struct MeshPath *p;
1856   struct GNUNET_PeerIdentity pi;
1857   int i;
1858
1859   if ((NULL == get_path || NULL == put_path) && NULL == peer_info->path)
1860   {
1861     // Find ourselves some alternate initial path to the destination: retry
1862     GNUNET_DHT_get_stop (peer_info->dhtget);
1863     GNUNET_PEER_resolve (peer_info->id, &pi);
1864     peer_info->dhtget = GNUNET_DHT_get_start (dht_handle, GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_BLOCK_TYPE_ANY, &pi.hashPubKey, 4,       /* replication level */
1865                                               GNUNET_DHT_RO_RECORD_ROUTE, NULL, /* bloom filter */
1866                                               0,        /* mutator */
1867                                               NULL,     /* xquery */
1868                                               0,        /* xquery bits */
1869                                               dht_get_id_handler,
1870                                               (void *) peer_info);
1871   }
1872
1873   p = GNUNET_malloc (sizeof (struct MeshPath));
1874   for (i = 0; get_path[i] != NULL; i++) ;
1875   for (i--; i >= 0; i--)
1876   {
1877     p->peers =
1878         GNUNET_realloc (p->peers, sizeof (GNUNET_PEER_Id) * (p->length + 1));
1879     p->peers[p->length] = GNUNET_PEER_intern (get_path[i]);
1880     p->length++;
1881   }
1882   for (i = 0; put_path[i] != NULL; i++) ;
1883   for (i--; i >= 0; i--)
1884   {
1885     p->peers =
1886         GNUNET_realloc (p->peers, sizeof (GNUNET_PEER_Id) * (p->length + 1));
1887     p->peers[p->length] = GNUNET_PEER_intern (put_path[i]);
1888     p->length++;
1889   }
1890   add_path_to_peer (peer_info, p);
1891   GNUNET_CORE_notify_transmit_ready (core_handle, 0, 0,
1892                                      GNUNET_TIME_UNIT_FOREVER_REL, get_path[1],
1893                                      sizeof (struct GNUNET_MESH_ManipulatePath)
1894                                      +
1895                                      (p->length *
1896                                       sizeof (struct GNUNET_PeerIdentity)),
1897                                      &send_core_create_path_for_peer,
1898                                      peer_info);
1899   if (0 == peer_info->path_refresh_task)
1900   {
1901     peer_info->path_refresh_task =
1902         GNUNET_SCHEDULER_add_delayed (REFRESH_PATH_TIME, &path_refresh,
1903                                       peer_info);
1904   }
1905   return;
1906 }
1907
1908
1909 /**
1910  * Function to process paths received for a new peer addition. The recorded
1911  * paths form the initial tunnel, which can be optimized later.
1912  * Called on each result obtained for the DHT search.
1913  *
1914  * @param cls closure
1915  * @param exp when will this value expire
1916  * @param key key of the result
1917  * @param get_path NULL-terminated array of pointers
1918  *                 to the peers on reverse GET path (or NULL if not recorded)
1919  * @param put_path NULL-terminated array of pointers
1920  *                 to the peers on the PUT path (or NULL if not recorded)
1921  * @param type type of the result
1922  * @param size number of bytes in data
1923  * @param data pointer to the result data
1924  */
1925 static void
1926 dht_get_type_handler (void *cls, struct GNUNET_TIME_Absolute exp,
1927                       const GNUNET_HashCode * key,
1928                       const struct GNUNET_PeerIdentity *const *get_path,
1929                       const struct GNUNET_PeerIdentity *const *put_path,
1930                       enum GNUNET_BLOCK_Type type, size_t size,
1931                       const void *data)
1932 {
1933   const struct GNUNET_PeerIdentity *pi = data;
1934   struct MeshTunnel *t = cls;
1935   struct MeshPeerInfo *peer_info;
1936   struct MeshPath *p;
1937   int i;
1938
1939
1940   if (size != sizeof (struct GNUNET_PeerIdentity))
1941   {
1942     GNUNET_break_op (0);
1943     return;
1944   }
1945   peer_info = get_peer_info (pi);
1946   GNUNET_CONTAINER_multihashmap_put (t->peers, &pi->hashPubKey, peer_info,
1947                                      GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
1948   if ((NULL == get_path || NULL == put_path) && NULL == peer_info->path)
1949   {
1950     /* we don't have a route to the peer, let's try a direct lookup */
1951     if (NULL == peer_info->dhtget)
1952     {
1953       peer_info->dhtget = GNUNET_DHT_get_start (dht_handle, GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_BLOCK_TYPE_ANY, &pi->hashPubKey, 10U,  /* replication level */
1954                                                 GNUNET_DHT_RO_RECORD_ROUTE, NULL,       /* bloom filter */
1955                                                 0,      /* mutator */
1956                                                 NULL,   /* xquery */
1957                                                 0,      /* xquery bits */
1958                                                 dht_get_id_handler, peer_info);
1959     }
1960   }
1961   /* TODO refactor */
1962   p = GNUNET_malloc (sizeof (struct MeshPath));
1963   for (i = 0; get_path[i] != NULL; i++) ;
1964   for (i--; i >= 0; i--)
1965   {
1966     p->peers =
1967         GNUNET_realloc (p->peers, sizeof (GNUNET_PEER_Id) * (p->length + 1));
1968     p->peers[p->length] = GNUNET_PEER_intern (get_path[i]);
1969     p->length++;
1970   }
1971   for (i = 0; put_path[i] != NULL; i++) ;
1972   for (i--; i >= 0; i--)
1973   {
1974     p->peers =
1975         GNUNET_realloc (p->peers, sizeof (GNUNET_PEER_Id) * (p->length + 1));
1976     p->peers[p->length] = GNUNET_PEER_intern (put_path[i]);
1977     p->length++;
1978   }
1979   add_path_to_peer (peer_info, p);
1980   GNUNET_CORE_notify_transmit_ready (core_handle, 0, 0,
1981                                      GNUNET_TIME_UNIT_FOREVER_REL, get_path[1],
1982                                      sizeof (struct GNUNET_MESH_ManipulatePath)
1983                                      +
1984                                      (p->length *
1985                                       sizeof (struct GNUNET_PeerIdentity)),
1986                                      &send_core_create_path_for_peer,
1987                                      peer_info);
1988
1989 }
1990
1991 /******************************************************************************/
1992 /*********************       MESH LOCAL HANDLES      **************************/
1993 /******************************************************************************/
1994
1995
1996 /**
1997  * Handler for client disconnection
1998  *
1999  * @param cls closure
2000  * @param client identification of the client; NULL
2001  *        for the last call when the server is destroyed
2002  */
2003 static void
2004 handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
2005 {
2006   struct MeshClient *c;
2007   struct MeshClient *next;
2008   unsigned int i;
2009   unsigned int j;
2010
2011   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: client disconnected\n");
2012   c = clients;
2013   while (NULL != c)
2014   {
2015     if (c->handle != client)
2016     {
2017       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH:    ... searching\n");
2018       c = c->next;
2019       continue;
2020     }
2021     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " matching client found, cleaning\n");
2022     GNUNET_CONTAINER_multihashmap_iterate (c->tunnels, &delete_tunnel_entry, c);
2023     GNUNET_CONTAINER_multihashmap_destroy (c->tunnels);
2024     if (0 != c->app_counter)
2025     {
2026       /* deregister clients applications */
2027       for (i = 0; i < c->app_counter; i++)
2028       {
2029         for (j = 0; j < n_apps; j++)
2030         {
2031           if (c->apps[i] == applications[j] && 0 == --applications_rc[j])
2032           {
2033             applications[j] = applications[n_apps - 1];
2034             GNUNET_array_grow (applications, n_apps, n_apps - 1);
2035             n_apps++;
2036             applications_rc[j] = applications_rc[n_apps - 1];
2037             GNUNET_array_grow (applications_rc, n_apps, n_apps - 1);
2038
2039           }
2040           break;
2041         }
2042       }
2043       GNUNET_free (c->apps);
2044       if (0 == n_apps)
2045       {
2046         GNUNET_SCHEDULER_cancel (announce_applications_task);
2047       }
2048     }
2049     if (0 != c->type_counter)
2050       GNUNET_free (c->types);
2051     GNUNET_CONTAINER_DLL_remove (clients, clients_tail, c);
2052     next = c->next;
2053     GNUNET_free (c);
2054     c = next;
2055   }
2056
2057   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH:    done!\n");
2058   return;
2059 }
2060
2061
2062 /**
2063  * Handler for new clients
2064  *
2065  * @param cls closure
2066  * @param client identification of the client
2067  * @param message the actual message, which includes messages the client wants
2068  */
2069 static void
2070 handle_local_new_client (void *cls, struct GNUNET_SERVER_Client *client,
2071                          const struct GNUNET_MessageHeader *message)
2072 {
2073   struct GNUNET_MESH_ClientConnect *cc_msg;
2074   struct MeshClient *c;
2075   unsigned int size;
2076   uint16_t types;
2077   uint16_t apps;
2078   uint16_t i;
2079   uint16_t j;
2080   int known;
2081
2082   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: new client connected\n");
2083   /* Check data sanity */
2084   size = ntohs (message->size) - sizeof (struct GNUNET_MESH_ClientConnect);
2085   cc_msg = (struct GNUNET_MESH_ClientConnect *) message;
2086   types = ntohs (cc_msg->types);
2087   apps = ntohs (cc_msg->applications);
2088   if (size !=
2089       types * sizeof (uint16_t) + apps * sizeof (GNUNET_MESH_ApplicationType))
2090   {
2091     GNUNET_break (0);
2092     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
2093     return;
2094   }
2095
2096   /* Create new client structure */
2097   c = GNUNET_malloc (sizeof (struct MeshClient));
2098   c->handle = client;
2099   if (types != 0)
2100   {
2101     c->type_counter = types;
2102     c->types = GNUNET_malloc (types * sizeof (uint16_t));
2103     memcpy (c->types, &message[1], types * sizeof (uint16_t));
2104   }
2105   if (apps != 0)
2106   {
2107     c->app_counter = apps;
2108     c->apps = GNUNET_malloc (apps * sizeof (GNUNET_MESH_ApplicationType));
2109     memcpy (c->apps, &message[1] + types * sizeof (uint16_t),
2110             apps * sizeof (GNUNET_MESH_ApplicationType));
2111   }
2112   for (i = 0; i < apps; i++)
2113   {
2114     known = GNUNET_NO;
2115     for (j = 0; i < n_apps; j++)
2116     {
2117       if (c->apps[i] == applications[j])
2118       {
2119         known = GNUNET_YES;
2120         applications_rc[j]++;
2121         break;
2122       }
2123     }
2124     if (!known)
2125     {
2126       /* Register previously unknown application */
2127       GNUNET_array_append (applications, n_apps, c->apps[i]);
2128       n_apps--;
2129       GNUNET_array_append (applications_rc, n_apps, 1);
2130       if (GNUNET_SCHEDULER_NO_TASK == announce_applications_task)
2131       {
2132         announce_applications_task =
2133             GNUNET_SCHEDULER_add_delayed (APP_ANNOUNCE_TIME,
2134                                           &announce_applications, NULL);
2135       }
2136     }
2137   }
2138   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2139               "MESH:  client has %u+%u subscriptions\n", c->type_counter,
2140               c->app_counter);
2141
2142   GNUNET_CONTAINER_DLL_insert (clients, clients_tail, c);
2143   c->tunnels = GNUNET_CONTAINER_multihashmap_create (32);
2144   GNUNET_SERVER_notification_context_add (nc, client);
2145
2146   GNUNET_SERVER_receive_done (client, GNUNET_OK);
2147
2148 }
2149
2150
2151 /**
2152  * Handler for requests of new tunnels
2153  *
2154  * @param cls closure
2155  * @param client identification of the client
2156  * @param message the actual message
2157  */
2158 static void
2159 handle_local_tunnel_create (void *cls, struct GNUNET_SERVER_Client *client,
2160                             const struct GNUNET_MessageHeader *message)
2161 {
2162   struct GNUNET_MESH_TunnelMessage *t_msg;
2163   struct MeshTunnel *t;
2164   struct MeshClient *c;
2165   GNUNET_HashCode hash;
2166
2167   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: new tunnel requested\n");
2168
2169   /* Sanity check for client registration */
2170   if (NULL == (c = retrieve_client (client)))
2171   {
2172     GNUNET_break (0);
2173     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
2174     return;
2175   }
2176
2177   /* Message sanity check */
2178   if (sizeof (struct GNUNET_MESH_TunnelMessage) != ntohs (message->size))
2179   {
2180     GNUNET_break (0);
2181     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
2182     return;
2183   }
2184
2185   t_msg = (struct GNUNET_MESH_TunnelMessage *) message;
2186   /* Sanity check for tunnel numbering */
2187   if (0 == (ntohl (t_msg->tunnel_id) & GNUNET_MESH_LOCAL_TUNNEL_ID_CLI))
2188   {
2189     GNUNET_break (0);
2190     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
2191     return;
2192   }
2193   /* Sanity check for duplicate tunnel IDs */
2194   if (NULL != retrieve_tunnel_by_local_id (c, ntohl (t_msg->tunnel_id)))
2195   {
2196     GNUNET_break (0);
2197     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
2198     return;
2199   }
2200
2201   t = GNUNET_malloc (sizeof (struct MeshTunnel));
2202   while (NULL != retrieve_tunnel_by_pi (myid, next_tid))
2203     next_tid = (next_tid + 1) & ~GNUNET_MESH_LOCAL_TUNNEL_ID_CLI;
2204   t->id.tid = next_tid++;
2205   t->id.oid = myid;
2206   t->local_tid = ntohl (t_msg->tunnel_id);
2207   t->client = c;
2208   t->peers = GNUNET_CONTAINER_multihashmap_create (32);
2209
2210   GNUNET_CRYPTO_hash (&t->local_tid, sizeof (MESH_TunnelNumber), &hash);
2211   if (GNUNET_OK !=
2212       GNUNET_CONTAINER_multihashmap_put (c->tunnels, &hash, t,
2213                                          GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
2214   {
2215     GNUNET_break (0);
2216     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
2217     return;
2218   }
2219
2220   GNUNET_CRYPTO_hash (&t->id, sizeof (struct MESH_TunnelID), &hash);
2221   if (GNUNET_OK !=
2222       GNUNET_CONTAINER_multihashmap_put (tunnels, &hash, t,
2223                                          GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
2224   {
2225     GNUNET_break (0);
2226     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
2227     return;
2228   }
2229
2230   GNUNET_SERVER_receive_done (client, GNUNET_OK);
2231   return;
2232 }
2233
2234
2235 /**
2236  * Handler for requests of deleting tunnels
2237  *
2238  * @param cls closure
2239  * @param client identification of the client
2240  * @param message the actual message
2241  */
2242 static void
2243 handle_local_tunnel_destroy (void *cls, struct GNUNET_SERVER_Client *client,
2244                              const struct GNUNET_MessageHeader *message)
2245 {
2246   struct GNUNET_MESH_TunnelMessage *tunnel_msg;
2247   struct MeshClient *c;
2248   struct MeshTunnel *t;
2249   MESH_TunnelNumber tid;
2250   GNUNET_HashCode hash;
2251
2252   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: destroying tunnel\n");
2253
2254   /* Sanity check for client registration */
2255   if (NULL == (c = retrieve_client (client)))
2256   {
2257     GNUNET_break (0);
2258     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
2259     return;
2260   }
2261   /* Message sanity check */
2262   if (sizeof (struct GNUNET_MESH_TunnelMessage) != ntohs (message->size))
2263   {
2264     GNUNET_break (0);
2265     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
2266     return;
2267   }
2268
2269   tunnel_msg = (struct GNUNET_MESH_TunnelMessage *) message;
2270
2271   /* Retrieve tunnel */
2272   tid = ntohl (tunnel_msg->tunnel_id);
2273
2274   /* Remove from local id hashmap */
2275   GNUNET_CRYPTO_hash (&tid, sizeof (MESH_TunnelNumber), &hash);
2276   t = GNUNET_CONTAINER_multihashmap_get (c->tunnels, &hash);
2277   GNUNET_CONTAINER_multihashmap_remove (c->tunnels, &hash, t);
2278
2279   /* Remove from global id hashmap */
2280   GNUNET_CRYPTO_hash (&t->id, sizeof (struct MESH_TunnelID), &hash);
2281   GNUNET_CONTAINER_multihashmap_remove (tunnels, &hash, t);
2282
2283 //     notify_tunnel_destroy(t);
2284   GNUNET_SERVER_receive_done (client, GNUNET_OK);
2285   return;
2286 }
2287
2288
2289 /**
2290  * Handler for connection requests to new peers
2291  *
2292  * @param cls closure
2293  * @param client identification of the client
2294  * @param message the actual message (PeerControl)
2295  */
2296 static void
2297 handle_local_connect_add (void *cls, struct GNUNET_SERVER_Client *client,
2298                           const struct GNUNET_MessageHeader *message)
2299 {
2300   struct GNUNET_MESH_PeerControl *peer_msg;
2301   struct MeshClient *c;
2302   struct MeshTunnel *t;
2303   MESH_TunnelNumber tid;
2304   struct MeshPeerInfo *peer_info;
2305
2306
2307   /* Sanity check for client registration */
2308   if (NULL == (c = retrieve_client (client)))
2309   {
2310     GNUNET_break (0);
2311     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
2312     return;
2313   }
2314
2315   peer_msg = (struct GNUNET_MESH_PeerControl *) message;
2316   /* Sanity check for message size */
2317   if (sizeof (struct GNUNET_MESH_PeerControl) != ntohs (peer_msg->header.size))
2318   {
2319     GNUNET_break (0);
2320     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
2321     return;
2322   }
2323
2324   /* Tunnel exists? */
2325   tid = ntohl (peer_msg->tunnel_id);
2326   t = retrieve_tunnel_by_local_id (c, tid);
2327   if (NULL == t)
2328   {
2329     GNUNET_break (0);
2330     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
2331     return;
2332   }
2333
2334   /* Does client own tunnel? */
2335   if (t->client->handle != client)
2336   {
2337     GNUNET_break (0);
2338     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
2339     return;
2340   }
2341
2342   t->peers_total++;
2343   peer_info = get_peer_info (&peer_msg->peer);
2344
2345   /* Start DHT search if needed */
2346   if (MESH_PEER_READY != peer_info->state && NULL == peer_info->dhtget)
2347   {
2348     peer_info->dhtget = GNUNET_DHT_get_start (dht_handle, GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_BLOCK_TYPE_ANY, &peer_msg->peer.hashPubKey, 4,   /* replication level */
2349                                               GNUNET_DHT_RO_RECORD_ROUTE, NULL, /* bloom filter */
2350                                               0,        /* mutator */
2351                                               NULL,     /* xquery */
2352                                               0,        /* xquery bits */
2353                                               dht_get_id_handler,
2354                                               (void *) peer_info);
2355   }
2356
2357   GNUNET_SERVER_receive_done (client, GNUNET_OK);
2358   return;
2359 }
2360
2361
2362 /**
2363  * Handler for disconnection requests of peers in a tunnel
2364  *
2365  * @param cls closure
2366  * @param client identification of the client
2367  * @param message the actual message (PeerControl)
2368  */
2369 static void
2370 handle_local_connect_del (void *cls, struct GNUNET_SERVER_Client *client,
2371                           const struct GNUNET_MessageHeader *message)
2372 {
2373   struct GNUNET_MESH_PeerControl *peer_msg;
2374   struct MeshClient *c;
2375   struct MeshTunnel *t;
2376   MESH_TunnelNumber tid;
2377
2378   /* Sanity check for client registration */
2379   if (NULL == (c = retrieve_client (client)))
2380   {
2381     GNUNET_break (0);
2382     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
2383     return;
2384   }
2385   peer_msg = (struct GNUNET_MESH_PeerControl *) message;
2386   /* Sanity check for message size */
2387   if (sizeof (struct GNUNET_MESH_PeerControl) != ntohs (peer_msg->header.size))
2388   {
2389     GNUNET_break (0);
2390     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
2391     return;
2392   }
2393
2394   /* Tunnel exists? */
2395   tid = ntohl (peer_msg->tunnel_id);
2396   t = retrieve_tunnel_by_local_id (c, tid);
2397   if (NULL == t)
2398   {
2399     GNUNET_break (0);
2400     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
2401     return;
2402   }
2403
2404   /* Does client own tunnel? */
2405   if (t->client->handle != client)
2406   {
2407     GNUNET_break (0);
2408     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
2409     return;
2410   }
2411
2412   /* Ok, delete peer from tunnel */
2413   GNUNET_CONTAINER_multihashmap_remove_all (t->peers,
2414                                             &peer_msg->peer.hashPubKey);
2415
2416   GNUNET_SERVER_receive_done (client, GNUNET_OK);
2417   return;
2418 }
2419
2420
2421 /**
2422  * Handler for connection requests to new peers by type
2423  *
2424  * @param cls closure
2425  * @param client identification of the client
2426  * @param message the actual message (ConnectPeerByType)
2427  */
2428 static void
2429 handle_local_connect_by_type (void *cls, struct GNUNET_SERVER_Client *client,
2430                               const struct GNUNET_MessageHeader *message)
2431 {
2432   struct GNUNET_MESH_ConnectPeerByType *connect_msg;
2433   struct MeshClient *c;
2434   struct MeshTunnel *t;
2435   GNUNET_HashCode hash;
2436   GNUNET_MESH_ApplicationType type;
2437   MESH_TunnelNumber tid;
2438   uint8_t buffer[12] = "MESH_APP";
2439   uint32_t *p;
2440   unsigned int i;
2441
2442   /* Sanity check for client registration */
2443   if (NULL == (c = retrieve_client (client)))
2444   {
2445     GNUNET_break (0);
2446     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
2447     return;
2448   }
2449
2450   connect_msg = (struct GNUNET_MESH_ConnectPeerByType *) message;
2451   /* Sanity check for message size */
2452   if (sizeof (struct GNUNET_MESH_PeerControl) !=
2453       ntohs (connect_msg->header.size))
2454   {
2455     GNUNET_break (0);
2456     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
2457     return;
2458   }
2459
2460   /* Tunnel exists? */
2461   tid = ntohl (connect_msg->tunnel_id);
2462   t = retrieve_tunnel_by_local_id (c, tid);
2463   if (NULL == t)
2464   {
2465     GNUNET_break (0);
2466     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
2467     return;
2468   }
2469
2470   /* Does client own tunnel? */
2471   if (t->client->handle != client)
2472   {
2473     GNUNET_break (0);
2474     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
2475     return;
2476   }
2477
2478   /* Do WE have the service? */
2479   type = ntohl (connect_msg->type);
2480   for (i = 0; i < n_apps; i++)
2481   {
2482     if (applications[i] == type)
2483     {
2484       /* Yes! Fast forward, add ourselves to the tunnel and send the
2485        * good news to the client
2486        */
2487       struct GNUNET_MESH_PeerControl pc;
2488
2489       pc.peer = my_full_id;
2490       GNUNET_CONTAINER_multihashmap_put (t->peers, &pc.peer.hashPubKey,
2491                                          get_peer_info (&pc.peer),
2492                                          GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
2493       pc.header.size = htons (sizeof (struct GNUNET_MESH_PeerControl));
2494       pc.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_ADD);
2495       pc.tunnel_id = htonl (t->local_tid);
2496       GNUNET_SERVER_notification_context_unicast (nc, client, NULL, GNUNET_NO);
2497     }
2498   }
2499   /* Ok, lets find a peer offering the service */
2500   p = (uint32_t *) & buffer[8];
2501   *p = connect_msg->type;       /* Already in Network Byte Order! */
2502   GNUNET_CRYPTO_hash (buffer, 12, &hash);
2503   if (c->dht_get_type)
2504   {
2505     GNUNET_DHT_get_stop (c->dht_get_type);
2506   }
2507   c->dht_get_type =
2508       GNUNET_DHT_get_start (dht_handle, GNUNET_TIME_UNIT_FOREVER_REL,
2509                             GNUNET_BLOCK_TYPE_ANY, &hash, 10U,
2510                             GNUNET_DHT_RO_RECORD_ROUTE, NULL, 0, NULL, 0,
2511                             &dht_get_type_handler, t);
2512
2513   GNUNET_SERVER_receive_done (client, GNUNET_OK);
2514   return;
2515 }
2516
2517
2518 /**
2519  * Handler for client traffic directed to one peer
2520  *
2521  * @param cls closure
2522  * @param client identification of the client
2523  * @param message the actual message
2524  */
2525 static void
2526 handle_local_unicast (void *cls, struct GNUNET_SERVER_Client *client,
2527                       const struct GNUNET_MessageHeader *message)
2528 {
2529   struct MeshClient *c;
2530   struct MeshTunnel *t;
2531   struct MeshPeerInfo *pi;
2532   struct GNUNET_MESH_Unicast *data_msg;
2533   struct GNUNET_PeerIdentity next_hop;
2534   struct MeshDataDescriptor *info;
2535   MESH_TunnelNumber tid;
2536   size_t data_size;
2537
2538   /* Sanity check for client registration */
2539   if (NULL == (c = retrieve_client (client)))
2540   {
2541     GNUNET_break (0);
2542     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
2543     return;
2544   }
2545   data_msg = (struct GNUNET_MESH_Unicast *) message;
2546   /* Sanity check for message size */
2547   if (sizeof (struct GNUNET_MESH_Unicast) +
2548       sizeof (struct GNUNET_MessageHeader) > ntohs (data_msg->header.size))
2549   {
2550     GNUNET_break (0);
2551     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
2552     return;
2553   }
2554
2555   /* Tunnel exists? */
2556   tid = ntohl (data_msg->tid);
2557   t = retrieve_tunnel_by_local_id (c, tid);
2558   if (NULL == t)
2559   {
2560     GNUNET_break (0);
2561     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
2562     return;
2563   }
2564
2565   /*  Is it a local tunnel? Then, does client own the tunnel? */
2566   if (t->client->handle != NULL && t->client->handle != client)
2567   {
2568     GNUNET_break (0);
2569     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
2570     return;
2571   }
2572
2573   pi = GNUNET_CONTAINER_multihashmap_get (t->peers,
2574                                           &data_msg->destination.hashPubKey);
2575   /* Is the selected peer in the tunnel? */
2576   if (NULL == pi)
2577   {
2578     GNUNET_break (0);
2579     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
2580     return;
2581   }
2582   if (pi->id == myid)
2583   {
2584     struct GNUNET_MESH_Unicast copy;
2585
2586     /* Work around const limitation */
2587     memcpy (&copy, data_msg, sizeof (struct GNUNET_MESH_Unicast));
2588     copy.oid = my_full_id;
2589     copy.tid = htonl(t->id.tid);
2590     handle_mesh_data_unicast (NULL, &my_full_id, &copy.header, NULL);
2591     return;
2592   }
2593   GNUNET_PEER_resolve (get_first_hop (pi->path), &next_hop);
2594   data_size = ntohs (message->size) - sizeof (struct GNUNET_MESH_Unicast);
2595   info = GNUNET_malloc (sizeof (struct MeshDataDescriptor) + data_size);
2596   memcpy (&info[1], &data_msg[1], data_size);
2597   info->destination = pi->id;
2598   info->origin = &t->id;
2599   info->size = data_size;
2600   info->client = client;
2601   GNUNET_CORE_notify_transmit_ready (core_handle, 0, 0,
2602                                      GNUNET_TIME_UNIT_FOREVER_REL, &next_hop,
2603                                      /* FIXME re-check types */
2604                                      data_size +
2605                                      sizeof (struct GNUNET_MESH_Unicast),
2606                                      &send_core_data_unicast, info);
2607   return;
2608 }
2609
2610 /**
2611  * Handler for client traffic directed to all peers in a tunnel
2612  *
2613  * @param cls closure
2614  * @param client identification of the client
2615  * @param message the actual message
2616  */
2617 static void
2618 handle_local_multicast (void *cls, struct GNUNET_SERVER_Client *client,
2619                         const struct GNUNET_MessageHeader *message)
2620 {
2621   struct MeshClient *c;
2622   struct MeshTunnel *t;
2623   struct GNUNET_MESH_Multicast *data_msg;
2624   MESH_TunnelNumber tid;
2625
2626   /* Sanity check for client registration */
2627   if (NULL == (c = retrieve_client (client)))
2628   {
2629     GNUNET_break (0);
2630     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
2631     return;
2632   }
2633   data_msg = (struct GNUNET_MESH_Multicast *) message;
2634   /* Sanity check for message size */
2635   if (sizeof (struct GNUNET_MESH_PeerControl) != ntohs (data_msg->header.size))
2636   {
2637     GNUNET_break (0);
2638     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
2639     return;
2640   }
2641
2642   /* Tunnel exists? */
2643   tid = ntohl (data_msg->tid);
2644   t = retrieve_tunnel_by_local_id (c, tid);
2645   if (NULL == t)
2646   {
2647     GNUNET_break (0);
2648     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
2649     return;
2650   }
2651
2652   /* Does client own tunnel? */
2653   if (t->client->handle != client)
2654   {
2655     GNUNET_break (0);
2656     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
2657     return;
2658   }
2659
2660   /*  TODO */
2661
2662   GNUNET_SERVER_receive_done (client, GNUNET_OK);
2663   return;
2664 }
2665
2666 /**
2667  * Functions to handle messages from clients
2668  */
2669 static struct GNUNET_SERVER_MessageHandler plugin_handlers[] = {
2670   {&handle_local_new_client, NULL, GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT, 0},
2671   {&handle_local_tunnel_create, NULL,
2672    GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_CREATE,
2673    sizeof (struct GNUNET_MESH_TunnelMessage)},
2674   {&handle_local_tunnel_destroy, NULL,
2675    GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_DESTROY,
2676    sizeof (struct GNUNET_MESH_TunnelMessage)},
2677   {&handle_local_connect_add, NULL,
2678    GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_ADD,
2679    sizeof (struct GNUNET_MESH_PeerControl)},
2680   {&handle_local_connect_del, NULL,
2681    GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_DEL,
2682    sizeof (struct GNUNET_MESH_PeerControl)},
2683   {&handle_local_connect_by_type, NULL,
2684    GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_ADD_BY_TYPE,
2685    sizeof (struct GNUNET_MESH_ConnectPeerByType)},
2686   {&handle_local_unicast, NULL,
2687    GNUNET_MESSAGE_TYPE_MESH_UNICAST, 0},
2688   {&handle_local_unicast, NULL,
2689    GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN, 0},
2690   {&handle_local_multicast, NULL,
2691    GNUNET_MESSAGE_TYPE_MESH_MULTICAST, 0},
2692   {NULL, NULL, 0, 0}
2693 };
2694
2695
2696 /**
2697  * To be called on core init/fail.
2698  *
2699  * @param cls service closure
2700  * @param server handle to the server for this service
2701  * @param identity the public identity of this peer
2702  * @param publicKey the public key of this peer
2703  */
2704 static void
2705 core_init (void *cls, struct GNUNET_CORE_Handle *server,
2706            const struct GNUNET_PeerIdentity *identity,
2707            const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *publicKey)
2708 {
2709   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: Core init\n");
2710   core_handle = server;
2711   my_full_id = *identity;
2712   myid = GNUNET_PEER_intern (identity);
2713   announce_id_task = GNUNET_SCHEDULER_add_now (&announce_id, cls);
2714   return;
2715 }
2716
2717 /**
2718  * Method called whenever a given peer connects.
2719  *
2720  * @param cls closure
2721  * @param peer peer identity this notification is about
2722  * @param atsi performance data for the connection
2723  */
2724 static void
2725 core_connect (void *cls, const struct GNUNET_PeerIdentity *peer,
2726               const struct GNUNET_TRANSPORT_ATS_Information *atsi)
2727 {
2728 //     GNUNET_PEER_Id              pid;
2729   struct MeshPeerInfo *peer_info;
2730   struct MeshPath *path;
2731
2732   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: Peer connected\n");
2733   peer_info = get_peer_info (peer);
2734   if (myid == peer_info->id)
2735   {
2736     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH:      (self)\n");
2737   }
2738   path = GNUNET_malloc (sizeof (struct MeshPath));
2739   path->length = 2;
2740   path->peers = GNUNET_malloc (sizeof (GNUNET_PEER_Id) * 2);
2741   path->peers[0] = myid;
2742   path->peers[1] = peer_info->id;
2743   add_path_to_peer (peer_info, path);
2744   return;
2745 }
2746
2747 /**
2748  * Method called whenever a peer disconnects.
2749  *
2750  * @param cls closure
2751  * @param peer peer identity this notification is about
2752  */
2753 static void
2754 core_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer)
2755 {
2756   struct MeshPeerInfo *pi;
2757   unsigned int i;
2758
2759   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: Peer disconnected\n");
2760   pi = GNUNET_CONTAINER_multihashmap_get (peers, &peer->hashPubKey);
2761   if (!pi)
2762   {
2763     GNUNET_break (0);
2764     return;
2765   }
2766   for (i = 0; i < CORE_QUEUE_SIZE; i++)
2767   {
2768     if (pi->core_transmit[i])
2769     {
2770       GNUNET_CORE_notify_transmit_ready_cancel (pi->core_transmit[i]);
2771       /* TODO: notify that tranmission has failed */
2772       GNUNET_free (pi->infos[i]);
2773     }
2774   }
2775   if (myid == pi->id)
2776   {
2777     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH:      (self)\n");
2778   }
2779   return;
2780 }
2781
2782
2783 /******************************************************************************/
2784 /************************      MAIN FUNCTIONS      ****************************/
2785 /******************************************************************************/
2786
2787 /**
2788  * Task run during shutdown.
2789  *
2790  * @param cls unused
2791  * @param tc unused
2792  */
2793 static void
2794 shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
2795 {
2796   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: shutting down\n");
2797   if (core_handle != NULL)
2798   {
2799     GNUNET_CORE_disconnect (core_handle);
2800     core_handle = NULL;
2801   }
2802   if (dht_handle != NULL)
2803   {
2804     GNUNET_DHT_disconnect (dht_handle);
2805     dht_handle = NULL;
2806   }
2807   if (nc != NULL)
2808   {
2809     GNUNET_SERVER_notification_context_destroy (nc);
2810     nc = NULL;
2811   }
2812   if (0 != announce_id_task)
2813   {
2814     GNUNET_SCHEDULER_cancel (announce_id_task);
2815     announce_id_task = 0;
2816   }
2817   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: shut down\n");
2818 }
2819
2820 /**
2821  * Process mesh requests.
2822  *
2823  * @param cls closure
2824  * @param server the initialized server
2825  * @param c configuration to use
2826  */
2827 static void
2828 run (void *cls, struct GNUNET_SERVER_Handle *server,
2829      const struct GNUNET_CONFIGURATION_Handle *c)
2830 {
2831   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: starting to run\n");
2832   GNUNET_SERVER_add_handlers (server, plugin_handlers);
2833   GNUNET_SERVER_disconnect_notify (server, &handle_client_disconnect, NULL);
2834   server_handle = server;
2835   core_handle = GNUNET_CORE_connect (c, /* Main configuration */
2836                                      CORE_QUEUE_SIZE,   /* queue size */
2837                                      NULL,      /* Closure passed to MESH functions */
2838                                      &core_init,        /* Call core_init once connected */
2839                                      &core_connect,     /* Handle connects */
2840                                      &core_disconnect,  /* remove peers on disconnects */
2841                                      NULL,      /* Do we care about "status" updates? */
2842                                      NULL,      /* Don't notify about all incoming messages */
2843                                      GNUNET_NO, /* For header only in notification */
2844                                      NULL,      /* Don't notify about all outbound messages */
2845                                      GNUNET_NO, /* For header-only out notification */
2846                                      core_handlers);    /* Register these handlers */
2847   if (core_handle == NULL)
2848   {
2849     GNUNET_break (0);
2850   }
2851   dht_handle = GNUNET_DHT_connect (c, 64);
2852   if (dht_handle == NULL)
2853   {
2854     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error connecting to DHT.\
2855                    Running without DHT has a severe\
2856                    impact in MESH capabilities.\n\
2857                    Plase check your configuretion and enable DHT.\n");
2858     GNUNET_break (0);
2859   }
2860
2861   next_tid = 0;
2862
2863   tunnels = GNUNET_CONTAINER_multihashmap_create (32);
2864   peers = GNUNET_CONTAINER_multihashmap_create (32);
2865   nc = GNUNET_SERVER_notification_context_create (server_handle,
2866                                                   LOCAL_QUEUE_SIZE);
2867   clients = NULL;
2868   clients_tail = NULL;
2869
2870   applications = NULL;
2871   applications_rc = NULL;
2872   n_apps = 0;
2873   announce_applications_task = 0;
2874
2875   /* Scheduled the task to clean up when shutdown is called */
2876   GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task,
2877                                 NULL);
2878
2879   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: end of run()\n");
2880 }
2881
2882 /**
2883  * The main function for the mesh service.
2884  *
2885  * @param argc number of arguments from the command line
2886  * @param argv command line arguments
2887  * @return 0 ok, 1 on error
2888  */
2889 int
2890 main (int argc, char *const *argv)
2891 {
2892   int ret;
2893
2894   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: main()\n");
2895   ret =
2896       (GNUNET_OK ==
2897        GNUNET_SERVICE_run (argc, argv, "mesh", GNUNET_SERVICE_OPTION_NONE, &run,
2898                            NULL)) ? 0 : 1;
2899   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: main() END\n");
2900   return ret;
2901 }