- use different contexts for differents search stages/branches
[oweals/gnunet.git] / src / mesh / gnunet-service-mesh_new.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  * - relay corking down to core
44  * - set ttl relative to tree depth
45  * TODO END
46  */
47
48 #include "platform.h"
49 #include "mesh.h"
50 #include "mesh_protocol.h"
51 #include "mesh_tunnel_tree.h"
52 #include "block_mesh.h"
53 #include "mesh_block_lib.h"
54 #include "gnunet_dht_service.h"
55 #include "gnunet_regex_lib.h"
56
57 /* TODO: move into configuration file */
58 #define REFRESH_PATH_TIME       GNUNET_TIME_relative_multiply(\
59                                     GNUNET_TIME_UNIT_SECONDS,\
60                                     300)
61 #define APP_ANNOUNCE_TIME       GNUNET_TIME_relative_multiply(\
62                                     GNUNET_TIME_UNIT_SECONDS,\
63                                     15)
64
65 #define ID_ANNOUNCE_TIME        GNUNET_TIME_relative_multiply(\
66                                     GNUNET_TIME_UNIT_SECONDS,\
67                                     15)
68
69 #define UNACKNOWLEDGED_WAIT     GNUNET_TIME_relative_multiply(\
70                                     GNUNET_TIME_UNIT_SECONDS,\
71                                     2)
72 #define DEFAULT_TTL             64
73
74 #define DHT_REPLICATION_LEVEL   10
75
76 /* TODO END */
77
78 #define MESH_BLOOM_SIZE         128
79
80 #define MESH_DEBUG_DHT          GNUNET_YES
81 #define MESH_DEBUG_CONNECTION   GNUNET_NO
82
83 #if MESH_DEBUG_CONNECTION
84 #define DEBUG_CONN(...) GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__)
85 #else
86 #define DEBUG_CONN(...)
87 #endif
88
89 #if MESH_DEBUG_DHT
90 #define DEBUG_DHT(...) GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__)
91 #else
92 #define DEBUG_DHT(...)
93 #endif
94
95 /******************************************************************************/
96 /************************      DATA STRUCTURES     ****************************/
97 /******************************************************************************/
98
99 /** FWD declaration */
100 struct MeshPeerInfo;
101
102
103 /**
104  * Struct representing a piece of data being sent to other peers
105  */
106 struct MeshData
107 {
108   /** Tunnel it belongs to. */
109   struct MeshTunnel *t;
110
111   /** In case of a multicast, task to allow a client to send more data if
112    * some neighbor is too slow. */
113   GNUNET_SCHEDULER_TaskIdentifier *task;
114
115   /** How many remaining neighbors we need to send this to. */
116   unsigned int *reference_counter;
117
118   /** Size of the data. */
119   size_t data_len;
120
121   /** Data itself */
122   void *data;
123 };
124
125
126 /**
127  * Struct containing info about a queued transmission to this peer
128  */
129 struct MeshPeerQueue
130 {
131     /**
132       * DLL next
133       */
134   struct MeshPeerQueue *next;
135
136     /**
137       * DLL previous
138       */
139   struct MeshPeerQueue *prev;
140
141     /**
142      * Peer this transmission is directed to.
143      */
144   struct MeshPeerInfo *peer;
145
146     /**
147      * Tunnel this message belongs to.
148      */
149   struct MeshTunnel *tunnel;
150
151     /**
152      * Pointer to info stucture used as cls.
153      */
154   void *cls;
155
156     /**
157      * Type of message
158      */
159   uint16_t type;
160
161     /**
162      * Size of the message
163      */
164   size_t size;
165 };
166
167
168 /**
169  * Struct containing all info possibly needed to build a package when called
170  * back by core.
171  */
172 struct MeshTransmissionDescriptor
173 {
174     /** ID of the tunnel this packet travels in */
175   struct MESH_TunnelID *origin;
176
177     /** Who was this message being sent to */
178   struct MeshPeerInfo *peer;
179
180     /** Ultimate destination of the packet */
181   GNUNET_PEER_Id destination;
182
183     /** Data descriptor */
184   struct MeshData* mesh_data;
185 };
186
187
188 /**
189  * Struct containing all information regarding a given peer
190  */
191 struct MeshPeerInfo
192 {
193     /**
194      * ID of the peer
195      */
196   GNUNET_PEER_Id id;
197
198     /**
199      * Last time we heard from this peer
200      */
201   struct GNUNET_TIME_Absolute last_contact;
202
203     /**
204      * Number of attempts to reconnect so far
205      */
206   int n_reconnect_attempts;
207
208     /**
209      * Paths to reach the peer, ordered by ascending hop count
210      */
211   struct MeshPeerPath *path_head;
212
213     /**
214      * Paths to reach the peer, ordered by ascending hop count
215      */
216   struct MeshPeerPath *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      * Closure given to the DHT GET
225      */
226   struct MeshPathInfo *dhtgetcls;
227
228     /**
229      * Array of tunnels this peer participates in
230      * (most probably a small amount, therefore not a hashmap)
231      * When the path to the peer changes, notify these tunnels to let them
232      * re-adjust their path trees.
233      */
234   struct MeshTunnel **tunnels;
235
236     /**
237      * Number of tunnels this peers participates in
238      */
239   unsigned int ntunnels;
240
241    /**
242     * Transmission queue to core DLL head
243     */
244   struct MeshPeerQueue *queue_head;
245
246    /**
247     * Transmission queue to core DLL tail
248     */
249    struct MeshPeerQueue *queue_tail;
250
251    /**
252     * How many messages are in the queue to this peer.
253     */
254    unsigned int queue_n;
255
256    /**
257     * Handle to for queued transmissions
258     */
259   struct GNUNET_CORE_TransmitHandle *core_transmit;
260 };
261
262
263 /**
264  * Globally unique tunnel identification (owner + number)
265  * DO NOT USE OVER THE NETWORK
266  */
267 struct MESH_TunnelID
268 {
269     /**
270      * Node that owns the tunnel
271      */
272   GNUNET_PEER_Id oid;
273
274     /**
275      * Tunnel number to differentiate all the tunnels owned by the node oid
276      * ( tid < GNUNET_MESH_LOCAL_TUNNEL_ID_CLI )
277      */
278   MESH_TunnelNumber tid;
279 };
280
281
282 struct MeshClient;              /* FWD declaration */
283
284 /**
285  * Struct containing all information regarding a tunnel
286  * For an intermediate node the improtant info used will be:
287  * - id        Tunnel unique identification
288  * - paths[0]  To know where to send it next
289  * - metainfo: ready, speeds, accounting
290  */
291 struct MeshTunnel
292 {
293     /**
294      * Tunnel ID
295      */
296   struct MESH_TunnelID id;
297
298     /**
299      * Local tunnel number ( >= GNUNET_MESH_LOCAL_TUNNEL_ID_CLI or 0 )
300      */
301   MESH_TunnelNumber local_tid;
302
303     /**
304      * Local tunnel number for local destination clients (incoming number)
305      * ( >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV or 0). All clients share the same
306      * number.
307      */
308   MESH_TunnelNumber local_tid_dest;
309
310     /**
311      * Global count ID of the last *multicast* packet seen/sent.
312      */
313   uint32_t mid;
314
315     /**
316      * Local count ID of the last packet seen/sent.
317      */
318   uint32_t pid;
319
320     /**
321      * SKIP value for this tunnel.
322      */
323   uint32_t skip;
324
325     /**
326      * How many messages are in the queue.
327      */
328    unsigned int queue_n;
329
330     /**
331      * How many messages do we accept in the queue.
332      */
333    unsigned int queue_max;
334
335     /**
336      * Last time the tunnel was used
337      */
338   struct GNUNET_TIME_Absolute timestamp;
339
340     /**
341      * Peers in the tunnel, indexed by PeerIdentity -> (MeshPeerInfo)
342      * containing peers added by id or by type, not intermediate peers.
343      */
344   struct GNUNET_CONTAINER_MultiHashMap *peers;
345
346     /**
347      * Number of peers that are connected and potentially ready to receive data
348      */
349   unsigned int peers_ready;
350
351     /**
352      * Number of peers that have been added to the tunnel
353      */
354   unsigned int peers_total;
355
356     /**
357      * Client owner of the tunnel, if any
358      */
359   struct MeshClient *owner;
360
361     /**
362      * Clients that have been informed about the tunnel, if any
363      */
364   struct MeshClient **clients;
365
366     /**
367      * Number of elements in clients
368      */
369   unsigned int nclients;
370
371     /**
372      * Clients that have requested to leave the tunnel
373      */
374   struct MeshClient **ignore;
375
376     /**
377      * Number of elements in clients
378      */
379   unsigned int nignore;
380
381     /**
382      * Blacklisted peers
383      */
384   GNUNET_PEER_Id *blacklisted;
385
386     /**
387      * Number of elements in blacklisted
388      */
389   unsigned int nblacklisted;
390
391   /**
392    * Bloomfilter (for peer identities) to stop circular routes
393    */
394   char bloomfilter[MESH_BLOOM_SIZE];
395
396   /**
397    * Tunnel paths
398    */
399   struct MeshTunnelTree *tree;
400
401   /**
402    * Application type we are looking for in this tunnel
403    */
404   GNUNET_MESH_ApplicationType type;
405
406     /**
407      * Used to search peers offering a service
408      */
409   struct GNUNET_DHT_GetHandle *dht_get_type;
410   
411     /**
412      * Context of the regex search for a connect_by_string
413      */
414   struct MeshRegexSearchContext *regex_ctx;
415
416   /**
417    * Task to keep the used paths alive
418    */
419   GNUNET_SCHEDULER_TaskIdentifier path_refresh_task;
420
421   /**
422    * Task to destroy the tunnel after timeout
423    *
424    * FIXME: merge the two? a tunnel will have either
425    * a path refresh OR a timeout, never both!
426    */
427   GNUNET_SCHEDULER_TaskIdentifier timeout_task;
428 };
429
430
431 /**
432  * Info needed to work with tunnel paths and peers
433  */
434 struct MeshPathInfo
435 {
436   /**
437    * Tunnel
438    */
439   struct MeshTunnel *t;
440
441   /**
442    * Neighbouring peer to whom we send the packet to
443    */
444   struct MeshPeerInfo *peer;
445
446   /**
447    * Path itself
448    */
449   struct MeshPeerPath *path;
450 };
451
452
453 /**
454  * Struct containing information about a client of the service
455  */
456 struct MeshClient
457 {
458     /**
459      * Linked list next
460      */
461   struct MeshClient *next;
462
463     /**
464      * Linked list prev
465      */
466   struct MeshClient *prev;
467
468     /**
469      * Tunnels that belong to this client, indexed by local id
470      */
471   struct GNUNET_CONTAINER_MultiHashMap *own_tunnels;
472
473    /**
474      * Tunnels this client has accepted, indexed by incoming local id
475      */
476   struct GNUNET_CONTAINER_MultiHashMap *incoming_tunnels;
477
478    /**
479      * Tunnels this client has rejected, indexed by incoming local id
480      */
481   struct GNUNET_CONTAINER_MultiHashMap *ignore_tunnels;
482     /**
483      * Handle to communicate with the client
484      */
485   struct GNUNET_SERVER_Client *handle;
486
487     /**
488      * Applications that this client has claimed to provide
489      */
490   struct GNUNET_CONTAINER_MultiHashMap *apps;
491
492     /**
493      * Messages that this client has declared interest in
494      */
495   struct GNUNET_CONTAINER_MultiHashMap *types;
496
497     /**
498      * Whether the client is active or shutting down (don't send confirmations
499      * to a client that is shutting down.
500      */
501   int shutting_down;
502
503     /**
504      * ID of the client, mainly for debug messages
505      */
506   unsigned int id;
507   
508     /**
509      * Regular expressions describing the services offered by this client.
510      */
511   char **regexes; // FIXME add timeout? API to remove a regex?
512
513     /**
514      * Number of regular expressions in regexes.
515      */
516   unsigned int n_regex;
517
518     /**
519      * Task to refresh all regular expresions in the DHT.
520      */
521   GNUNET_SCHEDULER_TaskIdentifier regex_announce_task;
522
523 };
524
525
526 /**
527  * Struct to keep information of searches of services described by a regex
528  * using a user-provided string service description.
529  */
530 struct MeshRegexSearchInfo
531 {
532     /**
533      * Which tunnel is this for
534      */
535   struct MeshTunnel *t;
536
537     /**
538      * User provided description of the searched service.
539      */
540   char *description;
541
542     /**
543      * Part of the description already consumed by the search.
544      */
545   size_t position;
546
547     /**
548      * Running DHT GETs.
549      */
550   struct GNUNET_CONTAINER_MultiHashMap *dht_get_handles;
551
552     /**
553      * Results from running DHT GETs.
554      */
555   struct GNUNET_CONTAINER_MultiHashMap *dht_get_results;
556
557     /**
558      * Contexts, for each running DHT GET. Free all on end of search.
559      */
560   struct MeshRegexSearchContext **copies;
561   
562     /**
563      * Number of contexts (branches/steps in search).
564      */
565   unsigned int n_copies;
566
567 };
568
569 /**
570  * Struct to keep state of running searches that have consumed a part of
571  * the inital string.
572  */
573 struct MeshRegexSearchContext
574 {
575     /**
576      * Part of the description already consumed by
577      * this particular search branch.
578      */
579   size_t position;
580
581     /**
582      * Information about the search.
583      */
584   struct MeshRegexSearchInfo *info;
585
586 };
587
588 /******************************************************************************/
589 /************************      DEBUG FUNCTIONS     ****************************/
590 /******************************************************************************/
591
592 #if MESH_DEBUG
593 /**
594  * GNUNET_SCHEDULER_Task for printing a message after some operation is done
595  * @param cls string to print
596  * @param success  GNUNET_OK if the PUT was transmitted,
597  *                GNUNET_NO on timeout,
598  *                GNUNET_SYSERR on disconnect from service
599  *                after the PUT message was transmitted
600  *                (so we don't know if it was received or not)
601  */
602
603 #if 0
604 static void
605 mesh_debug (void *cls, int success)
606 {
607   char *s = cls;
608
609   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%s (%d)\n", s, success);
610 }
611 #endif
612
613 #endif
614
615 /******************************************************************************/
616 /***********************      GLOBAL VARIABLES     ****************************/
617 /******************************************************************************/
618
619 /**
620  * All the clients
621  */
622 static struct MeshClient *clients;
623 static struct MeshClient *clients_tail;
624
625 /**
626  * Tunnels known, indexed by MESH_TunnelID (MeshTunnel)
627  */
628 static struct GNUNET_CONTAINER_MultiHashMap *tunnels;
629
630 /**
631  * Tunnels incoming, indexed by MESH_TunnelNumber
632  * (which is greater than GNUNET_MESH_LOCAL_TUNNEL_ID_SERV)
633  */
634 static struct GNUNET_CONTAINER_MultiHashMap *incoming_tunnels;
635
636 /**
637  * Peers known, indexed by PeerIdentity (MeshPeerInfo)
638  */
639 static struct GNUNET_CONTAINER_MultiHashMap *peers;
640
641 /*
642  * Handle to communicate with transport
643  */
644 // static struct GNUNET_TRANSPORT_Handle *transport_handle;
645
646 /**
647  * Handle to communicate with core
648  */
649 static struct GNUNET_CORE_Handle *core_handle;
650
651 /**
652  * Handle to use DHT
653  */
654 static struct GNUNET_DHT_Handle *dht_handle;
655
656 /**
657  * Handle to server
658  */
659 static struct GNUNET_SERVER_Handle *server_handle;
660
661 /**
662  * Notification context, to send messages to local clients
663  */
664 static struct GNUNET_SERVER_NotificationContext *nc;
665
666 /**
667  * Local peer own ID (memory efficient handle)
668  */
669 static GNUNET_PEER_Id myid;
670
671 /**
672  * Local peer own ID (full value)
673  */
674 static struct GNUNET_PeerIdentity my_full_id;
675
676 /**
677  * Own private key
678  */
679 static struct GNUNET_CRYPTO_RsaPrivateKey *my_private_key;
680
681 /**
682  * Own public key.
683  */
684 static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded my_public_key;
685
686 /**
687  * Tunnel ID for the next created tunnel (global tunnel number)
688  */
689 static MESH_TunnelNumber next_tid;
690
691 /**
692  * Tunnel ID for the next incoming tunnel (local tunnel number)
693  */
694 static MESH_TunnelNumber next_local_tid;
695
696 /**
697  * All application types provided by this peer
698  */
699 static struct GNUNET_CONTAINER_MultiHashMap *applications;
700
701 /**
702  * All message types clients of this peer are interested in
703  */
704 static struct GNUNET_CONTAINER_MultiHashMap *types;
705
706 /**
707  * Task to periodically announce provided applications
708  */
709 GNUNET_SCHEDULER_TaskIdentifier announce_applications_task;
710
711 /**
712  * Task to periodically announce itself in the network
713  */
714 GNUNET_SCHEDULER_TaskIdentifier announce_id_task;
715
716 /**
717  * Next ID to assign to a client
718  */
719 unsigned int next_client_id;
720
721
722
723 /******************************************************************************/
724 /************************         ITERATORS        ****************************/
725 /******************************************************************************/
726
727 /* FIXME move iterators here */
728 /**
729  * Iterator over hash map entries to cancel DHT GET requests after a
730  * successful connect_by_string.
731  *
732  * @param cls Closure (unused).
733  * @param key Current key code (unused).
734  * @param value Value in the hash map (get handle).
735  * @return GNUNET_YES if we should continue to iterate,
736  *         GNUNET_NO if not.
737  */
738 static int
739 regex_cancel_dht_get (void *cls,
740                       const struct GNUNET_HashCode * key,
741                       void *value)
742 {
743   struct GNUNET_DHT_GetHandle *h = value;
744
745   GNUNET_DHT_get_stop (h);
746   return GNUNET_YES;
747 }
748
749
750 /**
751  * Iterator over hash map entries to free MeshRegexBlocks stored during the
752  * search for connect_by_string.
753  *
754  * @param cls Closure (unused).
755  * @param key Current key code (unused).
756  * @param value MeshRegexBlock in the hash map.
757  * @return GNUNET_YES if we should continue to iterate,
758  *         GNUNET_NO if not.
759  */
760 static int
761 regex_free_result (void *cls,
762                    const struct GNUNET_HashCode * key,
763                    void *value)
764 {
765
766   GNUNET_free (value);
767   return GNUNET_YES;
768 }
769
770
771 /**
772  * Regex callback iterator to store own service description in the DHT.
773  *
774  * @param cls closure.
775  * @param key hash for current state.
776  * @param proof proof for current state.
777  * @param accepting GNUNET_YES if this is an accepting state, GNUNET_NO if not.
778  * @param num_edges number of edges leaving current state.
779  * @param edges edges leaving current state.
780  */
781 void
782 regex_iterator (void *cls, const struct GNUNET_HashCode *key, const char *proof,
783                 int accepting, unsigned int num_edges,
784                 const struct GNUNET_REGEX_Edge *edges)
785 {
786     struct MeshRegexBlock *block;
787     struct MeshRegexEdge *block_edge;
788     enum GNUNET_DHT_RouteOption opt;
789     size_t size;
790     size_t len;
791     unsigned int i;
792     unsigned int offset;
793     char *aux;
794
795     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
796                 "  regex dht put for state %s\n",
797                 GNUNET_h2s(key));
798     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
799                 "   proof: %s\n",
800                 proof);
801     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
802                 "   num edges: %u\n",
803                 num_edges);
804
805     opt = GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE;
806     if (GNUNET_YES == accepting)
807     {
808         struct MeshRegexAccept block;
809
810         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
811                     "   state %s is accepting, putting own id\n",
812                     GNUNET_h2s(key));
813         size = sizeof (block);
814         block.key = *key;
815         block.id = my_full_id;
816         (void)
817         GNUNET_DHT_put(dht_handle, key,
818                        DHT_REPLICATION_LEVEL,
819                        opt | GNUNET_DHT_RO_RECORD_ROUTE,
820                        GNUNET_BLOCK_TYPE_MESH_REGEX_ACCEPT,
821                        size,
822                        (char *) &block,
823                        GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (),
824                                                  APP_ANNOUNCE_TIME),
825                        APP_ANNOUNCE_TIME,
826                        NULL, NULL);
827     }
828     len = strlen(proof);
829     size = sizeof (struct MeshRegexBlock) + len;
830     block = GNUNET_malloc (size);
831
832     block->key = *key;
833     block->n_proof = htonl (len);
834     block->n_edges = htonl (num_edges);
835     block->accepting = htonl (accepting);
836
837     /* Store the proof at the end of the block. */
838     aux = (char *) &block[1];
839     memcpy (aux, proof, len);
840     aux = &aux[len];
841
842     /* Store each edge in a variable length MeshEdge struct at the
843      * very end of the MeshRegexBlock structure.
844      */
845     for (i = 0; i < num_edges; i++)
846     {
847         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
848                     "    edge %s towards %s\n",
849                     edges[i].label,
850                     GNUNET_h2s(&edges[i].destination));
851
852         /* aux points at the end of the last block */
853         len = strlen (edges[i].label);
854         size += sizeof (struct MeshRegexEdge) + len;
855         // Calculate offset FIXME is this ok? use size instead?
856         offset = aux - (char *) block;
857         block = GNUNET_realloc (block, size);
858         aux = &((char *) block)[offset];
859         block_edge = (struct MeshRegexEdge *) aux;
860         block_edge->key = edges[i].destination;
861         block_edge->n_token = htonl (len);
862         aux = (char *) &block_edge[1];
863         memcpy (aux, edges[i].label, len);
864         aux = &aux[len];
865     }
866     (void)
867     GNUNET_DHT_put(dht_handle, key,
868                    DHT_REPLICATION_LEVEL,
869                    opt,
870                    GNUNET_BLOCK_TYPE_MESH_REGEX, size,
871                    (char *) block,
872                    GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (),
873                                             APP_ANNOUNCE_TIME),
874                    APP_ANNOUNCE_TIME,
875                    NULL, NULL);
876     GNUNET_free (block);
877 }
878
879
880 /**
881  * Store the regular expression describing a local service into the DHT.
882  *
883  * @param regex The regular expresion.
884  */
885 static void
886 regex_put (const char *regex)
887 {
888   struct GNUNET_REGEX_Automaton *dfa;
889
890   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "regex_put (%s) start\n", regex);
891   dfa = GNUNET_REGEX_construct_dfa (regex, strlen(regex));
892   GNUNET_REGEX_iterate_all_edges (dfa, &regex_iterator, NULL);
893   GNUNET_REGEX_automaton_destroy (dfa);
894   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "regex_put (%s) end\n", regex);
895
896 }
897
898
899 /******************************************************************************/
900 /************************    PERIODIC FUNCTIONS    ****************************/
901 /******************************************************************************/
902
903 /**
904  * Announce iterator over for each application provided by the peer
905  *
906  * @param cls closure
907  * @param key current key code
908  * @param value value in the hash map
909  * @return GNUNET_YES if we should continue to
910  *         iterate,
911  *         GNUNET_NO if not.
912  */
913 static int
914 announce_application (void *cls, const struct GNUNET_HashCode * key, void *value)
915 {
916   struct PBlock block;
917   struct MeshClient *c;
918
919   block.id = my_full_id;
920   c =  GNUNET_CONTAINER_multihashmap_get (applications, key);
921   block.type = (long) GNUNET_CONTAINER_multihashmap_get (c->apps, key);
922   if (0 == block.type)
923   {
924     GNUNET_break(0);
925     return GNUNET_YES;
926   }
927   block.type = htonl (block.type);
928   /* FIXME are hashes in multihash map equal on all aquitectures? */
929   /* FIXME: keep return value of 'put' to possibly cancel!? */
930   GNUNET_DHT_put (dht_handle, key,
931                   DHT_REPLICATION_LEVEL,
932                   GNUNET_DHT_RO_RECORD_ROUTE |
933                   GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE,
934                   GNUNET_BLOCK_TYPE_MESH_PEER_BY_TYPE,
935                   sizeof (block),
936                   (const char *) &block,
937                   GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (),
938                                             APP_ANNOUNCE_TIME),
939                   APP_ANNOUNCE_TIME, NULL, NULL);
940   return GNUNET_OK;
941 }
942
943
944 /**
945  * Periodically announce what applications are provided by local clients
946  * (by regex)
947  *
948  * @param cls closure
949  * @param tc task context
950  */
951 static void
952 announce_regex (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
953 {
954   struct MeshClient *c = cls;
955   unsigned int i;
956
957   if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN)
958   {
959     c->regex_announce_task = GNUNET_SCHEDULER_NO_TASK;
960     return;
961   }
962
963   DEBUG_DHT ("Starting PUT for regex\n");
964
965   for (i = 0; i < c->n_regex; i++)
966   {
967     regex_put (c->regexes[i]);
968   }
969   c->regex_announce_task =
970       GNUNET_SCHEDULER_add_delayed (APP_ANNOUNCE_TIME, &announce_regex, cls);
971   DEBUG_DHT ("Finished PUT for regex\n");
972
973   return;
974 }
975
976
977 /**
978  * Periodically announce what applications are provided by local clients
979  * (by type)
980  *
981  * @param cls closure
982  * @param tc task context
983  */
984 static void
985 announce_applications (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
986 {
987   if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN)
988   {
989     announce_applications_task = GNUNET_SCHEDULER_NO_TASK;
990     return;
991   }
992  
993   DEBUG_DHT ("Starting PUT for apps\n");
994
995   GNUNET_CONTAINER_multihashmap_iterate (applications, &announce_application,
996                                          NULL);
997   announce_applications_task =
998       GNUNET_SCHEDULER_add_delayed (APP_ANNOUNCE_TIME, &announce_applications,
999                                     cls);
1000   DEBUG_DHT ("Finished PUT for apps\n");
1001
1002   return;
1003 }
1004
1005
1006 /**
1007  * Periodically announce self id in the DHT
1008  *
1009  * @param cls closure
1010  * @param tc task context
1011  */
1012 static void
1013 announce_id (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1014 {
1015   struct PBlock block;
1016
1017   if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN)
1018   {
1019     announce_id_task = GNUNET_SCHEDULER_NO_TASK;
1020     return;
1021   }
1022   /* TODO
1023    * - Set data expiration in function of X
1024    * - Adapt X to churn
1025    */
1026   DEBUG_DHT ("DHT_put for ID %s started.\n", GNUNET_i2s (&my_full_id));
1027
1028   block.id = my_full_id;
1029   block.type = htonl (0);
1030   GNUNET_DHT_put (dht_handle,   /* DHT handle */
1031                   &my_full_id.hashPubKey,       /* Key to use */
1032                   DHT_REPLICATION_LEVEL,     /* Replication level */
1033                   GNUNET_DHT_RO_RECORD_ROUTE | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE,    /* DHT options */
1034                   GNUNET_BLOCK_TYPE_MESH_PEER,       /* Block type */
1035                   sizeof (block),  /* Size of the data */
1036                   (const char *) &block, /* Data itself */
1037                   GNUNET_TIME_UNIT_FOREVER_ABS,  /* Data expiration */
1038                   GNUNET_TIME_UNIT_FOREVER_REL, /* Retry time */
1039                   NULL,         /* Continuation */
1040                   NULL);        /* Continuation closure */
1041   announce_id_task =
1042       GNUNET_SCHEDULER_add_delayed (ID_ANNOUNCE_TIME, &announce_id, cls);
1043 }
1044
1045
1046 /**
1047  * Function to process paths received for a new peer addition. The recorded
1048  * paths form the initial tunnel, which can be optimized later.
1049  * Called on each result obtained for the DHT search.
1050  *
1051  * @param cls closure
1052  * @param exp when will this value expire
1053  * @param key key of the result
1054  * @param type type of the result
1055  * @param size number of bytes in data
1056  * @param data pointer to the result data
1057  */
1058 static void
1059 dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp,
1060                     const struct GNUNET_HashCode * key,
1061                     const struct GNUNET_PeerIdentity *get_path,
1062                     unsigned int get_path_length,
1063                     const struct GNUNET_PeerIdentity *put_path,
1064                     unsigned int put_path_length, enum GNUNET_BLOCK_Type type,
1065                     size_t size, const void *data);
1066
1067
1068 /******************************************************************************/
1069 /******************      GENERAL HELPER FUNCTIONS      ************************/
1070 /******************************************************************************/
1071
1072 /**
1073  * Cancel an ongoing regex search in the DHT and free all resources.
1074  * 
1075  * @param ctx The search context.
1076  */
1077 static void
1078 regex_cancel_search(struct MeshRegexSearchContext *ctx)
1079 {
1080   struct MeshRegexSearchInfo *info = ctx->info;
1081   int i;
1082
1083   GNUNET_free (info->description);
1084   GNUNET_CONTAINER_multihashmap_iterate (info->dht_get_handles,
1085                                              &regex_cancel_dht_get, NULL);
1086   GNUNET_CONTAINER_multihashmap_iterate (info->dht_get_results,
1087                                          &regex_free_result, NULL);
1088   GNUNET_CONTAINER_multihashmap_destroy (info->dht_get_results);
1089   GNUNET_CONTAINER_multihashmap_destroy (info->dht_get_handles);
1090   info->t->regex_ctx = NULL;
1091   for (i = 0; i < info->n_copies; i++)
1092   {
1093     GNUNET_free (info->copies[i]);
1094   }
1095   GNUNET_free (info);
1096 }
1097
1098 /**
1099  * Search for a tunnel by global ID using full PeerIdentities
1100  *
1101  * @param oid owner of the tunnel
1102  * @param tid global tunnel number
1103  *
1104  * @return tunnel handler, NULL if doesn't exist
1105  */
1106 static struct MeshTunnel *
1107 tunnel_get (struct GNUNET_PeerIdentity *oid, MESH_TunnelNumber tid);
1108
1109
1110 /**
1111  * Delete an active client from the tunnel.
1112  * 
1113  * @param t Tunnel.
1114  * @param c Client.
1115  */
1116 static void
1117 tunnel_delete_active_client (struct MeshTunnel *t, const struct MeshClient *c);
1118
1119 /**
1120  * Notify a tunnel that a connection has broken that affects at least
1121  * some of its peers.
1122  *
1123  * @param t Tunnel affected.
1124  * @param p1 Peer that got disconnected from p2.
1125  * @param p2 Peer that got disconnected from p1.
1126  *
1127  * @return Short ID of the peer disconnected (either p1 or p2).
1128  *         0 if the tunnel remained unaffected.
1129  */
1130 static GNUNET_PEER_Id
1131 tunnel_notify_connection_broken (struct MeshTunnel *t, GNUNET_PEER_Id p1,
1132                                  GNUNET_PEER_Id p2);
1133
1134
1135 /**
1136  * Check if client has registered with the service and has not disconnected
1137  *
1138  * @param client the client to check
1139  *
1140  * @return non-NULL if client exists in the global DLL
1141  */
1142 static struct MeshClient *
1143 client_get (struct GNUNET_SERVER_Client *client)
1144 {
1145   struct MeshClient *c;
1146
1147   c = clients;
1148   while (NULL != c)
1149   {
1150     if (c->handle == client)
1151       return c;
1152     c = c->next;
1153   }
1154   return NULL;
1155 }
1156
1157
1158 /**
1159  * Checks if a given client has subscribed to certain message type
1160  *
1161  * @param message_type Type of message to check
1162  * @param c Client to check
1163  *
1164  * @return GNUNET_YES or GNUNET_NO, depending on subscription status
1165  *
1166  * TODO inline?
1167  */
1168 static int
1169 client_is_subscribed (uint16_t message_type, struct MeshClient *c)
1170 {
1171   struct GNUNET_HashCode hc;
1172
1173   GNUNET_CRYPTO_hash (&message_type, sizeof (uint16_t), &hc);
1174   return GNUNET_CONTAINER_multihashmap_contains (c->types, &hc);
1175 }
1176
1177
1178 /**
1179  * Allow a client to send more data after transmitting a multicast message
1180  * which some neighbor has not yet accepted altough a reasonable time has
1181  * passed.
1182  *
1183  * @param cls Closure (DataDescriptor containing the task identifier)
1184  * @param tc Task Context
1185  * 
1186  * FIXME reference counter cshould be just int
1187  */
1188 static void
1189 client_allow_send (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1190 {
1191   struct MeshData *mdata = cls;
1192
1193   if (GNUNET_SCHEDULER_REASON_SHUTDOWN == tc->reason)
1194     return;
1195   GNUNET_assert (NULL != mdata->reference_counter);
1196   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1197               "CLIENT ALLOW SEND DESPITE %u COPIES PENDING\n",
1198               *(mdata->reference_counter));
1199   *(mdata->task) = GNUNET_SCHEDULER_NO_TASK;
1200   GNUNET_SERVER_receive_done (mdata->t->owner->handle, GNUNET_OK);
1201 }
1202
1203
1204 /**
1205  * Check whether client wants traffic from a tunnel.
1206  *
1207  * @param c Client to check.
1208  * @param t Tunnel to be found.
1209  *
1210  * @return GNUNET_YES if client knows tunnel.
1211  * 
1212  * TODO look in client hashmap
1213  */
1214 static int
1215 client_wants_tunnel (struct MeshClient *c, struct MeshTunnel *t)
1216 {
1217   unsigned int i;
1218
1219   for (i = 0; i < t->nclients; i++)
1220     if (t->clients[i] == c)
1221       return GNUNET_YES;
1222   return GNUNET_NO;
1223 }
1224
1225
1226 /**
1227  * Check whether client has been informed about a tunnel.
1228  *
1229  * @param c Client to check.
1230  * @param t Tunnel to be found.
1231  *
1232  * @return GNUNET_YES if client knows tunnel.
1233  * 
1234  * TODO look in client hashmap
1235  */
1236 static int
1237 client_knows_tunnel (struct MeshClient *c, struct MeshTunnel *t)
1238 {
1239   unsigned int i;
1240
1241   for (i = 0; i < t->nignore; i++)
1242     if (t->ignore[i] == c)
1243       return GNUNET_YES;
1244   return client_wants_tunnel(c, t);
1245 }
1246
1247
1248 /**
1249  * Marks a client as uninterested in traffic from the tunnel, updating both
1250  * client and tunnel to reflect this.
1251  *
1252  * @param c Client that doesn't want traffic anymore.
1253  * @param t Tunnel which should be ignored.
1254  *
1255  * FIXME when to delete an incoming tunnel?
1256  */
1257 static void
1258 client_ignore_tunnel (struct MeshClient *c, struct MeshTunnel *t)
1259 {
1260   struct GNUNET_HashCode hash;
1261
1262   GNUNET_CRYPTO_hash(&t->local_tid_dest, sizeof (MESH_TunnelNumber), &hash);
1263   GNUNET_break (GNUNET_YES ==
1264                 GNUNET_CONTAINER_multihashmap_remove (c->incoming_tunnels,
1265                                                       &hash, t));
1266   GNUNET_break (GNUNET_YES ==
1267                 GNUNET_CONTAINER_multihashmap_put (c->ignore_tunnels, &hash, t,
1268                                                    GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST));
1269   tunnel_delete_active_client (t, c);
1270   GNUNET_array_append (t->ignore, t->nignore, c);
1271 }
1272
1273
1274 /**
1275  * Deletes a tunnel from a client (either owner or destination). To be used on
1276  * tunnel destroy, otherwise, use client_ignore_tunnel.
1277  *
1278  * @param c Client whose tunnel to delete.
1279  * @param t Tunnel which should be deleted.
1280  */
1281 static void
1282 client_delete_tunnel (struct MeshClient *c, struct MeshTunnel *t)
1283 {
1284   struct GNUNET_HashCode hash;
1285
1286   if (c == t->owner)
1287   {
1288     GNUNET_CRYPTO_hash(&t->local_tid, sizeof (MESH_TunnelNumber), &hash);
1289     GNUNET_assert (GNUNET_YES ==
1290                    GNUNET_CONTAINER_multihashmap_remove (c->own_tunnels,
1291                                                          &hash,
1292                                                          t));
1293   }
1294   else
1295   {
1296     GNUNET_CRYPTO_hash(&t->local_tid_dest, sizeof (MESH_TunnelNumber), &hash);
1297     // FIXME XOR?
1298     GNUNET_assert (GNUNET_YES ==
1299                    GNUNET_CONTAINER_multihashmap_remove (c->incoming_tunnels,
1300                                                          &hash,
1301                                                          t) ||
1302                    GNUNET_YES ==
1303                    GNUNET_CONTAINER_multihashmap_remove (c->ignore_tunnels,
1304                                                          &hash,
1305                                                          t));
1306   }
1307     
1308 }
1309
1310
1311 /**
1312  * Send the message to all clients that have subscribed to its type
1313  *
1314  * @param msg Pointer to the message itself
1315  * @param payload Pointer to the payload of the message.
1316  * @return number of clients this message was sent to
1317  */
1318 static unsigned int
1319 send_subscribed_clients (const struct GNUNET_MessageHeader *msg,
1320                          const struct GNUNET_MessageHeader *payload)
1321 {
1322   struct GNUNET_PeerIdentity *oid;
1323   struct MeshClient *c;
1324   struct MeshTunnel *t;
1325   MESH_TunnelNumber *tid;
1326   unsigned int count;
1327   uint16_t type;
1328   char cbuf[htons (msg->size)];
1329
1330   type = ntohs (payload->type);
1331   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending to clients...\n");
1332   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "message of type %u\n", type);
1333
1334   memcpy (cbuf, msg, sizeof (cbuf));
1335   switch (htons (msg->type))
1336   {
1337     struct GNUNET_MESH_Unicast *uc;
1338     struct GNUNET_MESH_Multicast *mc;
1339     struct GNUNET_MESH_ToOrigin *to;
1340
1341   case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
1342     uc = (struct GNUNET_MESH_Unicast *) cbuf;
1343     tid = &uc->tid;
1344     oid = &uc->oid;
1345     break;
1346   case GNUNET_MESSAGE_TYPE_MESH_MULTICAST:
1347     mc = (struct GNUNET_MESH_Multicast *) cbuf;
1348     tid = &mc->tid;
1349     oid = &mc->oid;
1350     break;
1351   case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN:
1352     to = (struct GNUNET_MESH_ToOrigin *) cbuf;
1353     tid = &to->tid;
1354     oid = &to->oid;
1355     break;
1356   default:
1357     GNUNET_break (0);
1358     return 0;
1359   }
1360   t = tunnel_get (oid, ntohl (*tid));
1361   if (NULL == t)
1362   {
1363     GNUNET_break (0);
1364     return 0;
1365   }
1366
1367   for (count = 0, c = clients; c != NULL; c = c->next)
1368   {
1369     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   client %u\n", c->id);
1370     if (client_is_subscribed (type, c))
1371     {
1372       if (htons (msg->type) == GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN)
1373       {
1374         if (c != t->owner)
1375           continue;
1376         *tid = htonl (t->local_tid);
1377       }
1378       else
1379       {
1380         if (GNUNET_NO == client_knows_tunnel (c, t))
1381         {
1382           /* This client doesn't know the tunnel */
1383           struct GNUNET_MESH_TunnelNotification tmsg;
1384           struct GNUNET_HashCode hash;
1385
1386           tmsg.header.size = htons (sizeof (tmsg));
1387           tmsg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_CREATE);
1388           GNUNET_PEER_resolve (t->id.oid, &tmsg.peer);
1389           tmsg.tunnel_id = htonl (t->local_tid_dest);
1390           GNUNET_SERVER_notification_context_unicast (nc, c->handle,
1391                                                       &tmsg.header, GNUNET_NO);
1392           GNUNET_array_append (t->clients, t->nclients, c);
1393           GNUNET_CRYPTO_hash (&t->local_tid_dest, sizeof (MESH_TunnelNumber),
1394                               &hash);
1395           GNUNET_break (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (
1396                                        c->incoming_tunnels, &hash, t,
1397                                        GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST));
1398         }
1399         *tid = htonl (t->local_tid_dest);
1400       }
1401
1402       /* Check if the client wants to get traffic from the tunnel */
1403       if (GNUNET_NO == client_wants_tunnel(c, t))
1404         continue;
1405       count++;
1406       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "     sending\n");
1407       GNUNET_SERVER_notification_context_unicast (nc, c->handle,
1408                                                   (struct GNUNET_MessageHeader
1409                                                    *) cbuf, GNUNET_YES);
1410     }
1411   }
1412   return count;
1413 }
1414
1415
1416 /**
1417  * Notify the client that owns the tunnel that a peer has connected to it
1418  * (the requested path to it has been confirmed).
1419  *
1420  * @param t Tunnel whose owner to notify
1421  * @param id Short id of the peer that has connected
1422  */
1423 static void
1424 send_client_peer_connected (const struct MeshTunnel *t, const GNUNET_PEER_Id id)
1425 {
1426   struct GNUNET_MESH_PeerControl pc;
1427
1428   pc.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_ADD);
1429   pc.header.size = htons (sizeof (struct GNUNET_MESH_PeerControl));
1430   pc.tunnel_id = htonl (t->local_tid);
1431   GNUNET_PEER_resolve (id, &pc.peer);
1432   GNUNET_SERVER_notification_context_unicast (nc, t->owner->handle, &pc.header,
1433                                               GNUNET_NO);
1434 }
1435
1436
1437 /**
1438  * Notify all clients (not depending on registration status) that the incoming
1439  * tunnel is no longer valid.
1440  *
1441  * @param t Tunnel that was destroyed.
1442  */
1443 static void
1444 send_clients_tunnel_destroy (struct MeshTunnel *t)
1445 {
1446   struct GNUNET_MESH_TunnelMessage msg;
1447
1448   msg.header.size = htons (sizeof (msg));
1449   msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_DESTROY);
1450   msg.tunnel_id = htonl (t->local_tid_dest);
1451   GNUNET_SERVER_notification_context_broadcast (nc, &msg.header, GNUNET_NO);
1452 }
1453
1454
1455 /**
1456  * Notify clients of tunnel disconnections, if needed.
1457  * In case the origin disconnects, the destination clients get a tunnel destroy
1458  * notification. If the last destination disconnects (only one remaining client
1459  * in tunnel), the origin gets a (local ID) peer disconnected.
1460  * Note that the function must be called BEFORE removing the client from
1461  * the tunnel.
1462  *
1463  * @param t Tunnel that was destroyed.
1464  * @param c Client that disconnected.
1465  */
1466 static void
1467 send_client_tunnel_disconnect (struct MeshTunnel *t, struct MeshClient *c)
1468 {
1469   unsigned int i;
1470
1471   if (c == t->owner)
1472   {
1473     struct GNUNET_MESH_TunnelMessage msg;
1474
1475     msg.header.size = htons (sizeof (msg));
1476     msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_DESTROY);
1477     msg.tunnel_id = htonl (t->local_tid_dest);
1478     for (i = 0; i < t->nclients; i++)
1479       GNUNET_SERVER_notification_context_unicast (nc, t->clients[i]->handle,
1480                                                   &msg.header, GNUNET_NO);
1481   }
1482   // FIXME when to disconnect an incoming tunnel?
1483   else if (1 == t->nclients && NULL != t->owner)
1484   {
1485     struct GNUNET_MESH_PeerControl msg;
1486
1487     msg.header.size = htons (sizeof (msg));
1488     msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_DEL);
1489     msg.tunnel_id = htonl (t->local_tid);
1490     msg.peer = my_full_id;
1491     GNUNET_SERVER_notification_context_unicast (nc, t->owner->handle,
1492                                                 &msg.header, GNUNET_NO);
1493   }
1494 }
1495
1496
1497 /**
1498  * Decrements the reference counter and frees all resources if needed
1499  *
1500  * @param mesh_data Data Descriptor used in a multicast message.
1501  *                  Freed no longer needed (last message).
1502  */
1503 static void
1504 data_descriptor_decrement_multicast (struct MeshData *mesh_data)
1505 {
1506   /* Make sure it's a multicast packet */
1507   GNUNET_assert (NULL != mesh_data->reference_counter);
1508
1509   if (0 == --(*(mesh_data->reference_counter)))
1510   {
1511     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Last copy!\n");
1512     if (NULL != mesh_data->task)
1513     {
1514       if (GNUNET_SCHEDULER_NO_TASK != *(mesh_data->task))
1515       {
1516         GNUNET_SCHEDULER_cancel (*(mesh_data->task));
1517         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " notifying client...\n");
1518         GNUNET_SERVER_receive_done (mesh_data->t->owner->handle, GNUNET_OK);
1519       }
1520       GNUNET_free (mesh_data->task);
1521     }
1522     GNUNET_free (mesh_data->reference_counter);
1523     GNUNET_free (mesh_data->data);
1524     GNUNET_free (mesh_data);
1525   }
1526 }
1527
1528
1529 /**
1530  * Retrieve the MeshPeerInfo stucture associated with the peer, create one
1531  * and insert it in the appropiate structures if the peer is not known yet.
1532  *
1533  * @param peer Full identity of the peer.
1534  *
1535  * @return Existing or newly created peer info.
1536  */
1537 static struct MeshPeerInfo *
1538 peer_info_get (const struct GNUNET_PeerIdentity *peer)
1539 {
1540   struct MeshPeerInfo *peer_info;
1541
1542   peer_info = GNUNET_CONTAINER_multihashmap_get (peers, &peer->hashPubKey);
1543   if (NULL == peer_info)
1544   {
1545     peer_info =
1546         (struct MeshPeerInfo *) GNUNET_malloc (sizeof (struct MeshPeerInfo));
1547     GNUNET_CONTAINER_multihashmap_put (peers, &peer->hashPubKey, peer_info,
1548                                        GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
1549     peer_info->id = GNUNET_PEER_intern (peer);
1550   }
1551
1552   return peer_info;
1553 }
1554
1555
1556 /**
1557  * Retrieve the MeshPeerInfo stucture associated with the peer, create one
1558  * and insert it in the appropiate structures if the peer is not known yet.
1559  *
1560  * @param peer Short identity of the peer.
1561  *
1562  * @return Existing or newly created peer info.
1563  */
1564 static struct MeshPeerInfo *
1565 peer_info_get_short (const GNUNET_PEER_Id peer)
1566 {
1567   struct GNUNET_PeerIdentity id;
1568
1569   GNUNET_PEER_resolve (peer, &id);
1570   return peer_info_get (&id);
1571 }
1572
1573
1574 /**
1575  * Iterator to remove the tunnel from the list of tunnels a peer participates
1576  * in.
1577  *
1578  * @param cls Closure (tunnel info)
1579  * @param key GNUNET_PeerIdentity of the peer (unused)
1580  * @param value PeerInfo of the peer
1581  *
1582  * @return always GNUNET_YES, to keep iterating
1583  */
1584 static int
1585 peer_info_delete_tunnel (void *cls, const struct GNUNET_HashCode * key, void *value)
1586 {
1587   struct MeshTunnel *t = cls;
1588   struct MeshPeerInfo *peer = value;
1589   unsigned int i;
1590
1591   for (i = 0; i < peer->ntunnels; i++)
1592   {
1593     if (0 ==
1594         memcmp (&peer->tunnels[i]->id, &t->id, sizeof (struct MESH_TunnelID)))
1595     {
1596       peer->ntunnels--;
1597       peer->tunnels[i] = peer->tunnels[peer->ntunnels];
1598       peer->tunnels = GNUNET_realloc (peer->tunnels, peer->ntunnels);
1599       return GNUNET_YES;
1600     }
1601   }
1602   return GNUNET_YES;
1603 }
1604
1605
1606 /**
1607  * Queue and pass message to core when possible.
1608  *
1609  * @param cls Closure (type dependant).
1610  * @param type Type of the message.
1611  * @param size Size of the message.
1612  * @param dst Neighbor to send message to.
1613  * @param t Tunnel this message belongs to.
1614  */
1615 static void
1616 queue_add (void *cls, uint16_t type, size_t size,
1617            struct MeshPeerInfo *dst, struct MeshTunnel *t);
1618
1619 /**
1620   * Core callback to write a pre-constructed data packet to core buffer
1621   *
1622   * @param cls Closure (MeshTransmissionDescriptor with data in "data" member).
1623   * @param size Number of bytes available in buf.
1624   * @param buf Where the to write the message.
1625   *
1626   * @return number of bytes written to buf
1627   */
1628 static size_t
1629 send_core_data_raw (void *cls, size_t size, void *buf)
1630 {
1631   struct MeshTransmissionDescriptor *info = cls;
1632   struct GNUNET_MessageHeader *msg;
1633   size_t total_size;
1634
1635   GNUNET_assert (NULL != info);
1636   GNUNET_assert (NULL != info->mesh_data);
1637   msg = (struct GNUNET_MessageHeader *) info->mesh_data->data;
1638   total_size = ntohs (msg->size);
1639
1640   if (total_size > size)
1641   {
1642     GNUNET_break (0);
1643     return 0;
1644   }
1645   memcpy (buf, msg, total_size);
1646   GNUNET_free (info->mesh_data);
1647   GNUNET_free (info);
1648   return total_size;
1649 }
1650
1651
1652 /**
1653  * Sends an already built unicast message to a peer, properly registrating
1654  * all used resources.
1655  *
1656  * @param message Message to send. Function makes a copy of it.
1657  * @param peer Short ID of the neighbor whom to send the message.
1658  * @param t Tunnel on which this message is transmitted.
1659  */
1660 static void
1661 send_message (const struct GNUNET_MessageHeader *message,
1662               const struct GNUNET_PeerIdentity *peer,
1663               struct MeshTunnel *t)
1664 {
1665   struct MeshTransmissionDescriptor *info;
1666   struct MeshPeerInfo *neighbor;
1667   struct MeshPeerPath *p;
1668   size_t size;
1669
1670 //   GNUNET_TRANSPORT_try_connect(); FIXME use?
1671
1672   size = ntohs (message->size);
1673   info = GNUNET_malloc (sizeof (struct MeshTransmissionDescriptor));
1674   info->mesh_data = GNUNET_malloc (sizeof (struct MeshData));
1675   info->mesh_data->data = GNUNET_malloc (size);
1676   memcpy (info->mesh_data->data, message, size);
1677   info->mesh_data->data_len = size;
1678   neighbor = peer_info_get (peer);
1679   for (p = neighbor->path_head; NULL != p; p = p->next)
1680   {
1681     if (2 == p->length)
1682     {
1683       break;
1684     }
1685   }
1686   if (NULL == p)
1687   {
1688     GNUNET_break (0);
1689     GNUNET_free (info->mesh_data->data);
1690     GNUNET_free (info->mesh_data);
1691     GNUNET_free (info);
1692     return;
1693   }
1694   info->peer = neighbor;
1695   queue_add (info,
1696              GNUNET_MESSAGE_TYPE_MESH_UNICAST,
1697              size,
1698              neighbor,
1699              t);
1700 }
1701
1702
1703 /**
1704  * Sends a CREATE PATH message for a path to a peer, properly registrating
1705  * all used resources.
1706  *
1707  * @param peer PeerInfo of the final peer for whom this path is being created.
1708  * @param p Path itself.
1709  * @param t Tunnel for which the path is created.
1710  */
1711 static void
1712 send_create_path (struct MeshPeerInfo *peer, struct MeshPeerPath *p,
1713                   struct MeshTunnel *t)
1714 {
1715   struct GNUNET_PeerIdentity id;
1716   struct MeshPathInfo *path_info;
1717   struct MeshPeerInfo *neighbor;
1718
1719   unsigned int i;
1720
1721   if (NULL == p)
1722   {
1723     p = tree_get_path_to_peer (t->tree, peer->id);
1724     if (NULL == p)
1725     {
1726       GNUNET_break (0);
1727       return;
1728     }
1729   }
1730   for (i = 0; i < p->length; i++)
1731   {
1732     if (p->peers[i] == myid)
1733       break;
1734   }
1735   if (i >= p->length - 1)
1736   {
1737     path_destroy (p);
1738     GNUNET_break (0);
1739     return;
1740   }
1741   GNUNET_PEER_resolve (p->peers[i + 1], &id);
1742
1743   path_info = GNUNET_malloc (sizeof (struct MeshPathInfo));
1744   path_info->path = p;
1745   path_info->t = t;
1746   neighbor = peer_info_get (&id);
1747   path_info->peer = neighbor;
1748   queue_add (path_info,
1749              GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE,
1750              sizeof (struct GNUNET_MESH_ManipulatePath) +
1751                 (p->length * sizeof (struct GNUNET_PeerIdentity)),
1752              neighbor,
1753              t);
1754 }
1755
1756
1757 /**
1758  * Sends a DESTROY PATH message to free resources for a path in a tunnel
1759  *
1760  * @param t Tunnel whose path to destroy.
1761  * @param destination Short ID of the peer to whom the path to destroy.
1762  */
1763 static void
1764 send_destroy_path (struct MeshTunnel *t, GNUNET_PEER_Id destination)
1765 {
1766   struct MeshPeerPath *p;
1767   size_t size;
1768
1769   p = tree_get_path_to_peer (t->tree, destination);
1770   if (NULL == p)
1771   {
1772     GNUNET_break (0);
1773     return;
1774   }
1775   size = sizeof (struct GNUNET_MESH_ManipulatePath);
1776   size += p->length * sizeof (struct GNUNET_PeerIdentity);
1777   {
1778     struct GNUNET_MESH_ManipulatePath *msg;
1779     struct GNUNET_PeerIdentity *pi;
1780     char cbuf[size];
1781     unsigned int i;
1782
1783     msg = (struct GNUNET_MESH_ManipulatePath *) cbuf;
1784     msg->header.size = htons (size);
1785     msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_PATH_DESTROY);
1786     msg->tid = htonl (t->id.tid);
1787     pi = (struct GNUNET_PeerIdentity *) &msg[1];
1788     for (i = 0; i < p->length; i++)
1789     {
1790       GNUNET_PEER_resolve (p->peers[i], &pi[i]);
1791     }
1792     send_message (&msg->header, tree_get_first_hop (t->tree, destination), t);
1793   }
1794   path_destroy (p);
1795 }
1796
1797
1798 /**
1799  * Try to establish a new connection to this peer.
1800  * Use the best path for the given tunnel.
1801  * If the peer doesn't have any path to it yet, try to get one.
1802  * If the peer already has some path, send a CREATE PATH towards it.
1803  *
1804  * @param peer PeerInfo of the peer.
1805  * @param t Tunnel for which to create the path, if possible.
1806  */
1807 static void
1808 peer_info_connect (struct MeshPeerInfo *peer, struct MeshTunnel *t)
1809 {
1810   struct MeshPeerPath *p;
1811   struct MeshPathInfo *path_info;
1812
1813   if (NULL != peer->path_head)
1814   {
1815     p = tree_get_path_to_peer (t->tree, peer->id);
1816     if (NULL == p)
1817     {
1818       GNUNET_break (0);
1819       return;
1820     }
1821
1822     // FIXME always send create path to self
1823     if (p->length > 1)
1824     {
1825       send_create_path (peer, p, t);
1826     }
1827     else
1828     {
1829       struct GNUNET_HashCode hash;
1830
1831       path_destroy (p);
1832       send_client_peer_connected (t, myid);
1833       t->local_tid_dest = next_local_tid++;
1834       GNUNET_CRYPTO_hash (&t->local_tid_dest, sizeof (MESH_TunnelNumber),
1835                           &hash);
1836       if (GNUNET_OK !=
1837           GNUNET_CONTAINER_multihashmap_put (incoming_tunnels, &hash, t,
1838                                              GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
1839       {
1840         GNUNET_break (0);
1841         return;
1842       }
1843     }
1844   }
1845   else if (NULL == peer->dhtget)
1846   {
1847     struct GNUNET_PeerIdentity id;
1848
1849     GNUNET_PEER_resolve (peer->id, &id);
1850     path_info = GNUNET_malloc (sizeof (struct MeshPathInfo));
1851     path_info->peer = peer;
1852     path_info->t = t;
1853     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1854                 "  Starting DHT GET for peer %s\n", GNUNET_i2s (&id));
1855     peer->dhtgetcls = path_info;
1856     peer->dhtget = GNUNET_DHT_get_start (dht_handle,    /* handle */
1857                                          GNUNET_BLOCK_TYPE_MESH_PEER, /* type */
1858                                          &id.hashPubKey,     /* key to search */
1859                                          DHT_REPLICATION_LEVEL, /* replication level */
1860                                          GNUNET_DHT_RO_RECORD_ROUTE |
1861                                          GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE,
1862                                          NULL,       /* xquery */ // FIXME BLOOMFILTER
1863                                          0,     /* xquery bits */ // FIXME BLOOMFILTER SIZE
1864                                          &dht_get_id_handler, path_info);
1865   }
1866   /* Otherwise, there is no path but the DHT get is already started. */
1867 }
1868
1869
1870 /**
1871  * Task to delay the connection of a peer
1872  *
1873  * @param cls Closure (path info with tunnel and peer to connect).
1874  *            Will be free'd on exection.
1875  * @param tc TaskContext
1876  */
1877 static void
1878 peer_info_connect_task (void *cls,
1879                         const struct GNUNET_SCHEDULER_TaskContext *tc)
1880 {
1881   struct MeshPathInfo *path_info = cls;
1882
1883   if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason))
1884   {
1885     GNUNET_free (cls);
1886     return;
1887   }
1888   peer_info_connect (path_info->peer, path_info->t);
1889   GNUNET_free (cls);
1890 }
1891
1892
1893 /**
1894  * Destroy the peer_info and free any allocated resources linked to it
1895  *
1896  * @param pi The peer_info to destroy.
1897  *
1898  * @return GNUNET_OK on success
1899  */
1900 static int
1901 peer_info_destroy (struct MeshPeerInfo *pi)
1902 {
1903   struct GNUNET_PeerIdentity id;
1904   struct MeshPeerPath *p;
1905   struct MeshPeerPath *nextp;
1906
1907   GNUNET_PEER_resolve (pi->id, &id);
1908   GNUNET_PEER_change_rc (pi->id, -1);
1909
1910   if (GNUNET_YES !=
1911       GNUNET_CONTAINER_multihashmap_remove (peers, &id.hashPubKey, pi))
1912   {
1913     GNUNET_break (0);
1914     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1915                 "removing peer %s, not in hashmap\n", GNUNET_i2s (&id));
1916   }
1917   if (NULL != pi->dhtget)
1918   {
1919     GNUNET_DHT_get_stop (pi->dhtget);
1920     GNUNET_free (pi->dhtgetcls);
1921   }
1922   p = pi->path_head;
1923   while (NULL != p)
1924   {
1925     nextp = p->next;
1926     GNUNET_CONTAINER_DLL_remove (pi->path_head, pi->path_tail, p);
1927     path_destroy (p);
1928     p = nextp;
1929   }
1930   GNUNET_free (pi);
1931   return GNUNET_OK;
1932 }
1933
1934
1935 /**
1936  * Remove all paths that rely on a direct connection between p1 and p2
1937  * from the peer itself and notify all tunnels about it.
1938  *
1939  * @param peer PeerInfo of affected peer.
1940  * @param p1 GNUNET_PEER_Id of one peer.
1941  * @param p2 GNUNET_PEER_Id of another peer that was connected to the first and
1942  *           no longer is.
1943  *
1944  * TODO: optimize (see below)
1945  */
1946 static void
1947 peer_info_remove_path (struct MeshPeerInfo *peer, GNUNET_PEER_Id p1,
1948                        GNUNET_PEER_Id p2)
1949 {
1950   struct MeshPeerPath *p;
1951   struct MeshPeerPath *aux;
1952   struct MeshPeerInfo *peer_d;
1953   GNUNET_PEER_Id d;
1954   unsigned int destroyed;
1955   unsigned int best;
1956   unsigned int cost;
1957   unsigned int i;
1958
1959   destroyed = 0;
1960   p = peer->path_head;
1961   while (NULL != p)
1962   {
1963     aux = p->next;
1964     for (i = 0; i < (p->length - 1); i++)
1965     {
1966       if ((p->peers[i] == p1 && p->peers[i + 1] == p2) ||
1967           (p->peers[i] == p2 && p->peers[i + 1] == p1))
1968       {
1969         GNUNET_CONTAINER_DLL_remove (peer->path_head, peer->path_tail, p);
1970         path_destroy (p);
1971         destroyed++;
1972         break;
1973       }
1974     }
1975     p = aux;
1976   }
1977   if (0 == destroyed)
1978     return;
1979
1980   for (i = 0; i < peer->ntunnels; i++)
1981   {
1982     d = tunnel_notify_connection_broken (peer->tunnels[i], p1, p2);
1983     if (0 == d)
1984       continue;
1985     /* TODO
1986      * Problem: one or more peers have been deleted from the tunnel tree.
1987      * We don't know who they are to try to add them again.
1988      * We need to try to find a new path for each of the disconnected peers.
1989      * Some of them might already have a path to reach them that does not
1990      * involve p1 and p2. Adding all anew might render in a better tree than
1991      * the trivial immediate fix.
1992      *
1993      * Trivial immiediate fix: try to reconnect to the disconnected node. All
1994      * its children will be reachable trough him.
1995      */
1996     peer_d = peer_info_get_short (d);
1997     best = UINT_MAX;
1998     aux = NULL;
1999     for (p = peer_d->path_head; NULL != p; p = p->next)
2000     {
2001       if ((cost = tree_get_path_cost (peer->tunnels[i]->tree, p)) < best)
2002       {
2003         best = cost;
2004         aux = p;
2005       }
2006     }
2007     if (NULL != aux)
2008     {
2009       /* No callback, as peer will be already disconnected and a connection
2010        * scheduled by tunnel_notify_connection_broken.
2011        */
2012       tree_add_path (peer->tunnels[i]->tree, aux, NULL, NULL);
2013     }
2014     else
2015     {
2016       peer_info_connect (peer_d, peer->tunnels[i]);
2017     }
2018   }
2019 }
2020
2021
2022 /**
2023  * Add the path to the peer and update the path used to reach it in case this
2024  * is the shortest.
2025  *
2026  * @param peer_info Destination peer to add the path to.
2027  * @param path New path to add. Last peer must be the peer in arg 1.
2028  *             Path will be either used of freed if already known.
2029  * @param trusted Do we trust that this path is real?
2030  */
2031 void
2032 peer_info_add_path (struct MeshPeerInfo *peer_info, struct MeshPeerPath *path,
2033                     int trusted)
2034 {
2035   struct MeshPeerPath *aux;
2036   unsigned int l;
2037   unsigned int l2;
2038
2039   if ((NULL == peer_info) || (NULL == path))
2040   {
2041     GNUNET_break (0);
2042     path_destroy (path);
2043     return;
2044   }
2045   if (path->peers[path->length - 1] != peer_info->id)
2046   {
2047     GNUNET_break (0);
2048     path_destroy (path);
2049     return;
2050   }
2051   if (path->length <= 2 && GNUNET_NO == trusted)
2052   {
2053     /* Only allow CORE to tell us about direct paths */
2054     path_destroy (path);
2055     return;
2056   }
2057   GNUNET_assert (peer_info->id == path->peers[path->length - 1]);
2058   for (l = 1; l < path->length; l++)
2059   {
2060     if (path->peers[l] == myid)
2061     {
2062       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "shortening path by %u\n", l);
2063       for (l2 = 0; l2 < path->length - l; l2++)
2064       {
2065         path->peers[l2] = path->peers[l + l2];
2066       }
2067       path->length -= l;
2068       l = 1;
2069       path->peers =
2070           GNUNET_realloc (path->peers, path->length * sizeof (GNUNET_PEER_Id));
2071     }
2072   }
2073 #if MESH_DEBUG
2074   {
2075     struct GNUNET_PeerIdentity id;
2076
2077     GNUNET_PEER_resolve (peer_info->id, &id);
2078     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "adding path [%u] to peer %s\n",
2079                 path->length, GNUNET_i2s (&id));
2080   }
2081 #endif
2082   l = path_get_length (path);
2083   if (0 == l)
2084   {
2085     GNUNET_free (path);
2086     return;
2087   }
2088
2089   GNUNET_assert (peer_info->id == path->peers[path->length - 1]);
2090   for (aux = peer_info->path_head; aux != NULL; aux = aux->next)
2091   {
2092     l2 = path_get_length (aux);
2093     if (l2 > l)
2094     {
2095       GNUNET_CONTAINER_DLL_insert_before (peer_info->path_head,
2096                                           peer_info->path_tail, aux, path);
2097       return;
2098     }
2099     else
2100     {
2101       if (l2 == l && memcmp (path->peers, aux->peers, l) == 0)
2102       {
2103         path_destroy (path);
2104         return;
2105       }
2106     }
2107   }
2108   GNUNET_CONTAINER_DLL_insert_tail (peer_info->path_head, peer_info->path_tail,
2109                                     path);
2110   return;
2111 }
2112
2113
2114 /**
2115  * Add the path to the origin peer and update the path used to reach it in case
2116  * this is the shortest.
2117  * The path is given in peer_info -> destination, therefore we turn the path
2118  * upside down first.
2119  *
2120  * @param peer_info Peer to add the path to, being the origin of the path.
2121  * @param path New path to add after being inversed.
2122  * @param trusted Do we trust that this path is real?
2123  */
2124 static void
2125 peer_info_add_path_to_origin (struct MeshPeerInfo *peer_info,
2126                               struct MeshPeerPath *path, int trusted)
2127 {
2128   path_invert (path);
2129   peer_info_add_path (peer_info, path, trusted);
2130 }
2131
2132
2133 /**
2134  * Build a PeerPath from the paths returned from the DHT, reversing the paths
2135  * to obtain a local peer -> destination path and interning the peer ids.
2136  *
2137  * @return Newly allocated and created path
2138  */
2139 static struct MeshPeerPath *
2140 path_build_from_dht (const struct GNUNET_PeerIdentity *get_path,
2141                      unsigned int get_path_length,
2142                      const struct GNUNET_PeerIdentity *put_path,
2143                      unsigned int put_path_length)
2144 {
2145   struct MeshPeerPath *p;
2146   GNUNET_PEER_Id id;
2147   int i;
2148
2149   p = path_new (1);
2150   p->peers[0] = myid;
2151   GNUNET_PEER_change_rc (myid, 1);
2152   i = get_path_length;
2153   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   GET has %d hops.\n", i);
2154   for (i--; i >= 0; i--)
2155   {
2156     id = GNUNET_PEER_intern (&get_path[i]);
2157     if (p->length > 0 && id == p->peers[p->length - 1])
2158     {
2159       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   Optimizing 1 hop out.\n");
2160       GNUNET_PEER_change_rc (id, -1);
2161     }
2162     else
2163     {
2164       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   Adding from GET: %s.\n",
2165                   GNUNET_i2s (&get_path[i]));
2166       p->length++;
2167       p->peers = GNUNET_realloc (p->peers, sizeof (GNUNET_PEER_Id) * p->length);
2168       p->peers[p->length - 1] = id;
2169     }
2170   }
2171   i = put_path_length;
2172   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   PUT has %d hops.\n", i);
2173   for (i--; i >= 0; i--)
2174   {
2175     id = GNUNET_PEER_intern (&put_path[i]);
2176     if (id == myid)
2177     {
2178       /* PUT path went through us, so discard the path up until now and start
2179        * from here to get a much shorter (and loop-free) path.
2180        */
2181       path_destroy (p);
2182       p = path_new (0);
2183     }
2184     if (p->length > 0 && id == p->peers[p->length - 1])
2185     {
2186       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   Optimizing 1 hop out.\n");
2187       GNUNET_PEER_change_rc (id, -1);
2188     }
2189     else
2190     {
2191       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   Adding from PUT: %s.\n",
2192                   GNUNET_i2s (&put_path[i]));
2193       p->length++;
2194       p->peers = GNUNET_realloc (p->peers, sizeof (GNUNET_PEER_Id) * p->length);
2195       p->peers[p->length - 1] = id;
2196     }
2197   }
2198 #if MESH_DEBUG
2199   if (get_path_length > 0)
2200     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   (first of GET: %s)\n",
2201                 GNUNET_i2s (&get_path[0]));
2202   if (put_path_length > 0)
2203     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   (first of PUT: %s)\n",
2204                 GNUNET_i2s (&put_path[0]));
2205   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   In total: %d hops\n",
2206               p->length);
2207   for (i = 0; i < p->length; i++)
2208   {
2209     struct GNUNET_PeerIdentity peer_id;
2210
2211     GNUNET_PEER_resolve (p->peers[i], &peer_id);
2212     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "       %u: %s\n", p->peers[i],
2213                 GNUNET_i2s (&peer_id));
2214   }
2215 #endif
2216   return p;
2217 }
2218
2219
2220 /**
2221  * Adds a path to the peer_infos of all the peers in the path
2222  *
2223  * @param p Path to process.
2224  * @param confirmed Whether we know if the path works or not. FIXME use
2225  */
2226 static void
2227 path_add_to_peers (struct MeshPeerPath *p, int confirmed)
2228 {
2229   unsigned int i;
2230
2231   /* TODO: invert and add */
2232   for (i = 0; i < p->length && p->peers[i] != myid; i++) /* skip'em */ ;
2233   for (i++; i < p->length; i++)
2234   {
2235     struct MeshPeerInfo *aux;
2236     struct MeshPeerPath *copy;
2237
2238     aux = peer_info_get_short (p->peers[i]);
2239     copy = path_duplicate (p);
2240     copy->length = i + 1;
2241     peer_info_add_path (aux, copy, GNUNET_NO);
2242   }
2243 }
2244
2245
2246 /**
2247  * Send keepalive packets for a peer
2248  *
2249  * @param cls Closure (tunnel for which to send the keepalive).
2250  * @param tc Notification context.
2251  *
2252  * TODO: implement explicit multicast keepalive?
2253  */
2254 static void
2255 path_refresh (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
2256
2257
2258 /**
2259  * Search for a tunnel among the incoming tunnels
2260  *
2261  * @param tid the local id of the tunnel
2262  *
2263  * @return tunnel handler, NULL if doesn't exist
2264  */
2265 static struct MeshTunnel *
2266 tunnel_get_incoming (MESH_TunnelNumber tid)
2267 {
2268   struct GNUNET_HashCode hash;
2269
2270   GNUNET_assert (tid >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV);
2271   GNUNET_CRYPTO_hash (&tid, sizeof (MESH_TunnelNumber), &hash);
2272   return GNUNET_CONTAINER_multihashmap_get (incoming_tunnels, &hash);
2273 }
2274
2275
2276 /**
2277  * Search for a tunnel among the tunnels for a client
2278  *
2279  * @param c the client whose tunnels to search in
2280  * @param tid the local id of the tunnel
2281  *
2282  * @return tunnel handler, NULL if doesn't exist
2283  */
2284 static struct MeshTunnel *
2285 tunnel_get_by_local_id (struct MeshClient *c, MESH_TunnelNumber tid)
2286 {
2287   if (tid >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV)
2288   {
2289     return tunnel_get_incoming (tid);
2290   }
2291   else
2292   {
2293     struct GNUNET_HashCode hash;
2294
2295     GNUNET_CRYPTO_hash (&tid, sizeof (MESH_TunnelNumber), &hash);
2296     return GNUNET_CONTAINER_multihashmap_get (c->own_tunnels, &hash);
2297   }
2298 }
2299
2300
2301 /**
2302  * Search for a tunnel by global ID using PEER_ID
2303  *
2304  * @param pi owner of the tunnel
2305  * @param tid global tunnel number
2306  *
2307  * @return tunnel handler, NULL if doesn't exist
2308  */
2309 static struct MeshTunnel *
2310 tunnel_get_by_pi (GNUNET_PEER_Id pi, MESH_TunnelNumber tid)
2311 {
2312   struct MESH_TunnelID id;
2313   struct GNUNET_HashCode hash;
2314
2315   id.oid = pi;
2316   id.tid = tid;
2317
2318   GNUNET_CRYPTO_hash (&id, sizeof (struct MESH_TunnelID), &hash);
2319   return GNUNET_CONTAINER_multihashmap_get (tunnels, &hash);
2320 }
2321
2322
2323 /**
2324  * Search for a tunnel by global ID using full PeerIdentities
2325  *
2326  * @param oid owner of the tunnel
2327  * @param tid global tunnel number
2328  *
2329  * @return tunnel handler, NULL if doesn't exist
2330  */
2331 static struct MeshTunnel *
2332 tunnel_get (struct GNUNET_PeerIdentity *oid, MESH_TunnelNumber tid)
2333 {
2334   return tunnel_get_by_pi (GNUNET_PEER_search (oid), tid);
2335 }
2336
2337
2338 /**
2339  * Delete an active client from the tunnel.
2340  * 
2341  * @param t Tunnel.
2342  * @param c Client.
2343  */
2344 static void
2345 tunnel_delete_active_client (struct MeshTunnel *t, const struct MeshClient *c)
2346 {
2347   unsigned int i;
2348
2349   for (i = 0; i < t->nclients; i++)
2350   {
2351     if (t->clients[i] == c)
2352     {
2353       t->clients[i] = t->clients[t->nclients - 1];
2354       GNUNET_array_grow (t->clients, t->nclients, t->nclients - 1);
2355       break;
2356     }
2357   }
2358 }
2359
2360
2361 /**
2362  * Delete an ignored client from the tunnel.
2363  * 
2364  * @param t Tunnel.
2365  * @param c Client.
2366  */
2367 static void
2368 tunnel_delete_ignored_client (struct MeshTunnel *t, const struct MeshClient *c)
2369 {
2370   unsigned int i;
2371
2372   for (i = 0; i < t->nignore; i++)
2373   {
2374     if (t->ignore[i] == c)
2375     {
2376       t->ignore[i] = t->ignore[t->nignore - 1];
2377       GNUNET_array_grow (t->ignore, t->nignore, t->nignore - 1);
2378       break;
2379     }
2380   }
2381 }
2382
2383
2384 /**
2385  * Delete a client from the tunnel. It should be only done on
2386  * client disconnection, otherwise use client_ignore_tunnel.
2387  * 
2388  * @param t Tunnel.
2389  * @param c Client.
2390  */
2391 static void
2392 tunnel_delete_client (struct MeshTunnel *t, const struct MeshClient *c)
2393 {
2394   tunnel_delete_ignored_client (t, c);
2395   tunnel_delete_active_client (t, c);
2396 }
2397
2398
2399 /**
2400  * Callback used to notify a client owner of a tunnel that a peer has
2401  * disconnected, most likely because of a path change.
2402  *
2403  * @param cls Closure (tunnel this notification is about).
2404  * @param peer_id Short ID of disconnected peer.
2405  */
2406 void
2407 notify_peer_disconnected (void *cls, GNUNET_PEER_Id peer_id)
2408 {
2409   struct MeshTunnel *t = cls;
2410   struct MeshPeerInfo *peer;
2411   struct MeshPathInfo *path_info;
2412
2413   if (NULL != t->owner && NULL != nc)
2414   {
2415     struct GNUNET_MESH_PeerControl msg;
2416
2417     msg.header.size = htons (sizeof (msg));
2418     msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_DEL);
2419     msg.tunnel_id = htonl (t->local_tid);
2420     GNUNET_PEER_resolve (peer_id, &msg.peer);
2421     GNUNET_SERVER_notification_context_unicast (nc, t->owner->handle,
2422                                                 &msg.header, GNUNET_NO);
2423   }
2424   peer = peer_info_get_short (peer_id);
2425   path_info = GNUNET_malloc (sizeof (struct MeshPathInfo));
2426   path_info->peer = peer;
2427   path_info->t = t;
2428   GNUNET_SCHEDULER_add_now (&peer_info_connect_task, path_info);
2429 }
2430
2431
2432 /**
2433  * Add a peer to a tunnel, accomodating paths accordingly and initializing all
2434  * needed rescources.
2435  * If peer already exists, reevaluate shortest path and change if different.
2436  *
2437  * @param t Tunnel we want to add a new peer to
2438  * @param peer PeerInfo of the peer being added
2439  *
2440  */
2441 static void
2442 tunnel_add_peer (struct MeshTunnel *t, struct MeshPeerInfo *peer)
2443 {
2444   struct GNUNET_PeerIdentity id;
2445   struct MeshPeerPath *best_p;
2446   struct MeshPeerPath *p;
2447   unsigned int best_cost;
2448   unsigned int cost;
2449
2450   GNUNET_PEER_resolve (peer->id, &id);
2451   if (GNUNET_NO ==
2452       GNUNET_CONTAINER_multihashmap_contains (t->peers, &id.hashPubKey))
2453   {
2454     t->peers_total++;
2455     GNUNET_array_append (peer->tunnels, peer->ntunnels, t);
2456     GNUNET_assert (GNUNET_OK ==
2457                    GNUNET_CONTAINER_multihashmap_put (t->peers, &id.hashPubKey,
2458                                                       peer,
2459                                                       GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST));
2460   }
2461
2462   if (NULL != (p = peer->path_head))
2463   {
2464     best_p = p;
2465     best_cost = tree_get_path_cost (t->tree, p);
2466     while (NULL != p)
2467     {
2468       if ((cost = tree_get_path_cost (t->tree, p)) < best_cost)
2469       {
2470         best_cost = cost;
2471         best_p = p;
2472       }
2473       p = p->next;
2474     }
2475     tree_add_path (t->tree, best_p, &notify_peer_disconnected, t);
2476     if (GNUNET_SCHEDULER_NO_TASK == t->path_refresh_task)
2477       t->path_refresh_task =
2478           GNUNET_SCHEDULER_add_delayed (REFRESH_PATH_TIME, &path_refresh, t);
2479   }
2480   else
2481   {
2482     /* Start a DHT get */
2483     peer_info_connect (peer, t);
2484   }
2485 }
2486
2487 /**
2488  * Add a path to a tunnel which we don't own, just to remember the next hop.
2489  * If destination node was already in the tunnel, the first hop information
2490  * will be replaced with the new path.
2491  *
2492  * @param t Tunnel we want to add a new peer to
2493  * @param p Path to add
2494  * @param own_pos Position of local node in path.
2495  *
2496  */
2497 static void
2498 tunnel_add_path (struct MeshTunnel *t, struct MeshPeerPath *p,
2499                  unsigned int own_pos)
2500 {
2501   struct GNUNET_PeerIdentity id;
2502
2503   GNUNET_assert (0 != own_pos);
2504   tree_add_path (t->tree, p, NULL, NULL);
2505   if (own_pos < p->length - 1)
2506   {
2507     GNUNET_PEER_resolve (p->peers[own_pos + 1], &id);
2508     tree_update_first_hops (t->tree, myid, &id);
2509   }
2510 }
2511
2512
2513 /**
2514  * Notifies a tunnel that a connection has broken that affects at least
2515  * some of its peers. Sends a notification towards the root of the tree.
2516  * In case the peer is the owner of the tree, notifies the client that owns
2517  * the tunnel and tries to reconnect.
2518  *
2519  * @param t Tunnel affected.
2520  * @param p1 Peer that got disconnected from p2.
2521  * @param p2 Peer that got disconnected from p1.
2522  *
2523  * @return Short ID of the peer disconnected (either p1 or p2).
2524  *         0 if the tunnel remained unaffected.
2525  */
2526 static GNUNET_PEER_Id
2527 tunnel_notify_connection_broken (struct MeshTunnel *t, GNUNET_PEER_Id p1,
2528                                  GNUNET_PEER_Id p2)
2529 {
2530   GNUNET_PEER_Id pid;
2531
2532   pid =
2533       tree_notify_connection_broken (t->tree, p1, p2, &notify_peer_disconnected,
2534                                      t);
2535   if (myid != p1 && myid != p2)
2536   {
2537     return pid;
2538   }
2539   if (pid != myid)
2540   {
2541     if (tree_get_predecessor (t->tree) != 0)
2542     {
2543       /* We are the peer still connected, notify owner of the disconnection. */
2544       struct GNUNET_MESH_PathBroken msg;
2545       struct GNUNET_PeerIdentity neighbor;
2546
2547       msg.header.size = htons (sizeof (msg));
2548       msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_PATH_BROKEN);
2549       GNUNET_PEER_resolve (t->id.oid, &msg.oid);
2550       msg.tid = htonl (t->id.tid);
2551       msg.peer1 = my_full_id;
2552       GNUNET_PEER_resolve (pid, &msg.peer2);
2553       GNUNET_PEER_resolve (tree_get_predecessor (t->tree), &neighbor);
2554       send_message (&msg.header, &neighbor, t);
2555     }
2556   }
2557   return pid;
2558 }
2559
2560
2561 /**
2562  * Send a multicast packet to a neighbor.
2563  *
2564  * @param cls Closure (Info about the multicast packet)
2565  * @param neighbor_id Short ID of the neighbor to send the packet to.
2566  */
2567 static void
2568 tunnel_send_multicast_iterator (void *cls, GNUNET_PEER_Id neighbor_id)
2569 {
2570   struct MeshData *mdata = cls;
2571   struct MeshTransmissionDescriptor *info;
2572   struct GNUNET_PeerIdentity neighbor;
2573
2574   info = GNUNET_malloc (sizeof (struct MeshTransmissionDescriptor));
2575
2576   info->mesh_data = mdata;
2577   (*(mdata->reference_counter)) ++;
2578   info->destination = neighbor_id;
2579   GNUNET_PEER_resolve (neighbor_id, &neighbor);
2580   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   sending to %s...\n",
2581               GNUNET_i2s (&neighbor));
2582   info->peer = peer_info_get (&neighbor);
2583   GNUNET_assert (NULL != info->peer);
2584   queue_add(info,
2585             GNUNET_MESSAGE_TYPE_MESH_MULTICAST,
2586             info->mesh_data->data_len,
2587             info->peer,
2588             mdata->t);
2589 }
2590
2591 /**
2592  * Send a message in a tunnel in multicast, sending a copy to each child node
2593  * down the local one in the tunnel tree.
2594  *
2595  * @param t Tunnel in which to send the data.
2596  * @param msg Message to be sent.
2597  * @param internal Has the service generated this message?
2598  */
2599 static void
2600 tunnel_send_multicast (struct MeshTunnel *t,
2601                        const struct GNUNET_MessageHeader *msg,
2602                        int internal)
2603 {
2604   struct MeshData *mdata;
2605
2606   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2607               " sending a multicast packet...\n");
2608   mdata = GNUNET_malloc (sizeof (struct MeshData));
2609   mdata->data_len = ntohs (msg->size);
2610   mdata->reference_counter = GNUNET_malloc (sizeof (unsigned int));
2611   mdata->t = t;
2612   mdata->data = GNUNET_malloc (mdata->data_len);
2613   memcpy (mdata->data, msg, mdata->data_len);
2614   if (ntohs (msg->type) == GNUNET_MESSAGE_TYPE_MESH_MULTICAST)
2615   {
2616     struct GNUNET_MESH_Multicast *mcast;
2617
2618     mcast = (struct GNUNET_MESH_Multicast *) mdata->data;
2619     mcast->ttl = htonl (ntohl (mcast->ttl) - 1);
2620     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  data packet, ttl: %u\n",
2621                 ntohl (mcast->ttl));
2622   }
2623   else
2624   {
2625     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  not a data packet, no ttl\n");
2626   }
2627   if (NULL != t->owner && GNUNET_YES != t->owner->shutting_down
2628       && GNUNET_NO == internal)
2629   {
2630     mdata->task = GNUNET_malloc (sizeof (GNUNET_SCHEDULER_TaskIdentifier));
2631     (*(mdata->task)) =
2632         GNUNET_SCHEDULER_add_delayed (UNACKNOWLEDGED_WAIT, &client_allow_send,
2633                                       mdata);
2634     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "timeout task %u\n",
2635                 *(mdata->task));
2636   }
2637
2638   tree_iterate_children (t->tree, &tunnel_send_multicast_iterator, mdata);
2639   if (*(mdata->reference_counter) == 0)
2640   {
2641     GNUNET_free (mdata->data);
2642     GNUNET_free (mdata->reference_counter);
2643     if (NULL != mdata->task)
2644     {
2645       GNUNET_SCHEDULER_cancel(*(mdata->task));
2646       GNUNET_free (mdata->task);
2647       GNUNET_SERVER_receive_done(t->owner->handle, GNUNET_OK);
2648     }
2649     // FIXME change order?
2650     GNUNET_free (mdata);
2651   }
2652   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2653               " sending a multicast packet done\n");
2654   return;
2655 }
2656
2657
2658 /**
2659  * Send a message to all peers in this tunnel that the tunnel is no longer
2660  * valid.
2661  *
2662  * @param t The tunnel whose peers to notify.
2663  */
2664 static void
2665 tunnel_send_destroy (struct MeshTunnel *t)
2666 {
2667   struct GNUNET_MESH_TunnelDestroy msg;
2668
2669   msg.header.size = htons (sizeof (msg));
2670   msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_TUNNEL_DESTROY);
2671   GNUNET_PEER_resolve (t->id.oid, &msg.oid);
2672   msg.tid = htonl (t->id.tid);
2673   tunnel_send_multicast (t, &msg.header, GNUNET_NO);
2674 }
2675
2676
2677
2678 /**
2679  * Destroy the tunnel and free any allocated resources linked to it.
2680  *
2681  * @param t the tunnel to destroy
2682  *
2683  * @return GNUNET_OK on success
2684  */
2685 static int
2686 tunnel_destroy (struct MeshTunnel *t)
2687 {
2688   struct MeshClient *c;
2689   struct GNUNET_HashCode hash;
2690   unsigned int i;
2691   int r;
2692
2693   if (NULL == t)
2694     return GNUNET_OK;
2695
2696   r = GNUNET_OK;
2697   c = t->owner;
2698 #if MESH_DEBUG
2699   {
2700     struct GNUNET_PeerIdentity id;
2701
2702     GNUNET_PEER_resolve (t->id.oid, &id);
2703     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "destroying tunnel %s [%x]\n",
2704                 GNUNET_i2s (&id), t->id.tid);
2705     if (NULL != c)
2706       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  by client %u\n", c->id);
2707   }
2708 #endif
2709
2710   GNUNET_CRYPTO_hash (&t->id, sizeof (struct MESH_TunnelID), &hash);
2711   if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_remove (tunnels, &hash, t))
2712   {
2713     r = GNUNET_SYSERR;
2714   }
2715
2716   GNUNET_CRYPTO_hash (&t->local_tid, sizeof (MESH_TunnelNumber), &hash);
2717   if (NULL != c &&
2718       GNUNET_YES !=
2719       GNUNET_CONTAINER_multihashmap_remove (c->own_tunnels, &hash, t))
2720   {
2721     r = GNUNET_SYSERR;
2722   }
2723   GNUNET_CRYPTO_hash (&t->local_tid_dest, sizeof (MESH_TunnelNumber), &hash);
2724   for (i = 0; i < t->nclients; i++)
2725   {
2726     c = t->clients[i];
2727     if (GNUNET_YES !=
2728           GNUNET_CONTAINER_multihashmap_remove (c->incoming_tunnels, &hash, t))
2729     {
2730       r = GNUNET_SYSERR;
2731     }
2732   }
2733   for (i = 0; i < t->nignore; i++)
2734   {
2735     c = t->ignore[i];
2736     if (GNUNET_YES !=
2737           GNUNET_CONTAINER_multihashmap_remove (c->ignore_tunnels, &hash, t))
2738     {
2739       r = GNUNET_SYSERR;
2740     }
2741   }
2742   if (t->nclients > 0)
2743   {
2744     if (GNUNET_YES !=
2745         GNUNET_CONTAINER_multihashmap_remove (incoming_tunnels, &hash, t))
2746     {
2747       r = GNUNET_SYSERR;
2748     }
2749     GNUNET_free (t->clients);
2750   }
2751   if (NULL != t->peers)
2752   {
2753     GNUNET_CONTAINER_multihashmap_iterate (t->peers, &peer_info_delete_tunnel,
2754                                            t);
2755     GNUNET_CONTAINER_multihashmap_destroy (t->peers);
2756   }
2757
2758   tree_destroy (t->tree);
2759   if (NULL != t->regex_ctx)
2760     regex_cancel_search (t->regex_ctx);
2761   if (NULL != t->dht_get_type)
2762     GNUNET_DHT_get_stop (t->dht_get_type);
2763   if (GNUNET_SCHEDULER_NO_TASK != t->timeout_task)
2764     GNUNET_SCHEDULER_cancel (t->timeout_task);
2765   if (GNUNET_SCHEDULER_NO_TASK != t->path_refresh_task)
2766     GNUNET_SCHEDULER_cancel (t->path_refresh_task);
2767   GNUNET_free (t);
2768   return r;
2769 }
2770
2771
2772 /**
2773  * Create a new tunnel
2774  * 
2775  * @param owner Who is the owner of the tunnel (short ID).
2776  * @param tid Tunnel Number of the tunnel.
2777  * @param client Clients that owns the tunnel, NULL for foreign tunnels.
2778  * @param local Tunnel Number for the tunnel, for the client point of view.
2779  * 
2780  */
2781 static struct MeshTunnel *
2782 tunnel_new (GNUNET_PEER_Id owner,
2783             MESH_TunnelNumber tid,
2784             struct MeshClient *client,
2785             MESH_TunnelNumber local)
2786 {
2787   struct MeshTunnel *t;
2788   struct GNUNET_HashCode hash;
2789
2790   t = GNUNET_malloc (sizeof (struct MeshTunnel));
2791   t->id.oid = owner;
2792   t->id.tid = tid;
2793   t->queue_max = 1000; // FIXME API parameter
2794   t->tree = tree_new (owner);
2795   t->owner = client;
2796   t->local_tid = local;
2797
2798   GNUNET_CRYPTO_hash (&t->id, sizeof (struct MESH_TunnelID), &hash);
2799   if (GNUNET_OK !=
2800       GNUNET_CONTAINER_multihashmap_put (tunnels, &hash, t,
2801                                          GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
2802   {
2803     GNUNET_break (0);
2804     tunnel_destroy (t);
2805     if (NULL != client)
2806       GNUNET_SERVER_receive_done (client->handle, GNUNET_SYSERR);
2807     return NULL;
2808   }
2809
2810   if (NULL != client)
2811   {
2812     GNUNET_CRYPTO_hash (&t->local_tid, sizeof (MESH_TunnelNumber), &hash);
2813     if (GNUNET_OK !=
2814         GNUNET_CONTAINER_multihashmap_put (client->own_tunnels, &hash, t,
2815                                           GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
2816     {
2817       GNUNET_break (0);
2818       tunnel_destroy (t);
2819       GNUNET_SERVER_receive_done (client->handle, GNUNET_SYSERR);
2820       return NULL;
2821     }
2822   }
2823
2824   return t;
2825 }
2826
2827
2828 /**
2829  * Removes an explicit path from a tunnel, freeing all intermediate nodes
2830  * that are no longer needed, as well as nodes of no longer reachable peers.
2831  * The tunnel itself is also destoyed if results in a remote empty tunnel.
2832  *
2833  * @param t Tunnel from which to remove the path.
2834  * @param peer Short id of the peer which should be removed.
2835  */
2836 static void
2837 tunnel_delete_peer (struct MeshTunnel *t, GNUNET_PEER_Id peer)
2838 {
2839   if (GNUNET_NO == tree_del_peer (t->tree, peer, NULL, NULL))
2840     tunnel_destroy (t);
2841 }
2842
2843
2844 /**
2845  * tunnel_destroy_iterator: iterator for deleting each tunnel that belongs to a
2846  * client when the client disconnects. If the client is not the owner, the
2847  * owner will get notified if no more clients are in the tunnel and the client
2848  * get removed from the tunnel's list.
2849  *
2850  * @param cls closure (client that is disconnecting)
2851  * @param key the hash of the local tunnel id (used to access the hashmap)
2852  * @param value the value stored at the key (tunnel to destroy)
2853  *
2854  * @return GNUNET_OK on success
2855  */
2856 static int
2857 tunnel_destroy_iterator (void *cls, const struct GNUNET_HashCode * key, void *value)
2858 {
2859   struct MeshTunnel *t = value;
2860   struct MeshClient *c = cls;
2861   int r;
2862
2863   send_client_tunnel_disconnect(t, c);
2864   if (c != t->owner)
2865   {
2866     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2867                 "Client %u is destination, keeping the tunnel alive.\n", c->id);
2868     tunnel_delete_client(t, c);
2869     client_delete_tunnel(c, t);
2870     return GNUNET_OK;
2871   }
2872   tunnel_send_destroy(t);
2873   r = tunnel_destroy (t);
2874   return r;
2875 }
2876
2877
2878 /**
2879  * Timeout function, destroys tunnel if called
2880  *
2881  * @param cls Closure (tunnel to destroy).
2882  * @param tc TaskContext
2883  */
2884 static void
2885 tunnel_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
2886 {
2887   struct MeshTunnel *t = cls;
2888
2889   if (GNUNET_SCHEDULER_REASON_SHUTDOWN == tc->reason)
2890     return;
2891   t->timeout_task = GNUNET_SCHEDULER_NO_TASK;
2892   tunnel_destroy (t);
2893 }
2894
2895 /**
2896  * Resets the tunnel timeout. Starts it if no timeout was running.
2897  *
2898  * @param t Tunnel whose timeout to reset.
2899  */
2900 static void
2901 tunnel_reset_timeout (struct MeshTunnel *t)
2902 {
2903   if (GNUNET_SCHEDULER_NO_TASK != t->timeout_task)
2904     GNUNET_SCHEDULER_cancel (t->timeout_task);
2905   t->timeout_task =
2906       GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
2907                                     (REFRESH_PATH_TIME, 4), &tunnel_timeout, t);
2908 }
2909
2910
2911 /******************************************************************************/
2912 /****************      MESH NETWORK HANDLER HELPERS     ***********************/
2913 /******************************************************************************/
2914
2915 /**
2916  * Function to send a create path packet to a peer.
2917  *
2918  * @param cls closure
2919  * @param size number of bytes available in buf
2920  * @param buf where the callee should write the message
2921  * @return number of bytes written to buf
2922  */
2923 static size_t
2924 send_core_path_create (void *cls, size_t size, void *buf)
2925 {
2926   struct MeshPathInfo *info = cls;
2927   struct GNUNET_MESH_ManipulatePath *msg;
2928   struct GNUNET_PeerIdentity *peer_ptr;
2929   struct MeshTunnel *t = info->t;
2930   struct MeshPeerPath *p = info->path;
2931   size_t size_needed;
2932   int i;
2933
2934   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CREATE PATH sending...\n");
2935   size_needed =
2936       sizeof (struct GNUNET_MESH_ManipulatePath) +
2937       p->length * sizeof (struct GNUNET_PeerIdentity);
2938
2939   if (size < size_needed || NULL == buf)
2940   {
2941     GNUNET_break (0);
2942     return 0;
2943   }
2944   msg = (struct GNUNET_MESH_ManipulatePath *) buf;
2945   msg->header.size = htons (size_needed);
2946   msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE);
2947   msg->tid = ntohl (t->id.tid);
2948
2949   peer_ptr = (struct GNUNET_PeerIdentity *) &msg[1];
2950   for (i = 0; i < p->length; i++)
2951   {
2952     GNUNET_PEER_resolve (p->peers[i], peer_ptr++);
2953   }
2954
2955   path_destroy (p);
2956   GNUNET_free (info);
2957
2958   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2959               "CREATE PATH (%u bytes long) sent!\n", size_needed);
2960   return size_needed;
2961 }
2962
2963
2964 /**
2965  * Fill the core buffer 
2966  *
2967  * @param cls closure (data itself)
2968  * @param size number of bytes available in buf
2969  * @param buf where the callee should write the message
2970  *
2971  * @return number of bytes written to buf
2972  */
2973 static size_t
2974 send_core_data_multicast (void *cls, size_t size, void *buf)
2975 {
2976   struct MeshTransmissionDescriptor *info = cls;
2977   size_t total_size;
2978
2979   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Multicast callback.\n");
2980   GNUNET_assert (NULL != info);
2981   GNUNET_assert (NULL != info->peer);
2982   total_size = info->mesh_data->data_len;
2983   GNUNET_assert (total_size < GNUNET_SERVER_MAX_MESSAGE_SIZE);
2984
2985   if (total_size > size)
2986   {
2987     GNUNET_break (0);
2988     return 0;
2989   }
2990   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " copying data...\n");
2991   memcpy (buf, info->mesh_data->data, total_size);
2992 #if MESH_DEBUG
2993   {
2994     struct GNUNET_MESH_Multicast *mc;
2995     struct GNUNET_MessageHeader *mh;
2996
2997     mh = buf;
2998     if (ntohs (mh->type) == GNUNET_MESSAGE_TYPE_MESH_MULTICAST)
2999     {
3000       mc = (struct GNUNET_MESH_Multicast *) mh;
3001       mh = (struct GNUNET_MessageHeader *) &mc[1];
3002       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3003                   " multicast, payload type %u\n", ntohs (mh->type));
3004       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3005                   " multicast, payload size %u\n", ntohs (mh->size));
3006     }
3007     else
3008     {
3009       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " type %u\n",
3010                   ntohs (mh->type));
3011     }
3012   }
3013 #endif
3014   data_descriptor_decrement_multicast (info->mesh_data);
3015   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "freeing info...\n");
3016   GNUNET_free (info);
3017   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "return %u\n", total_size);
3018   return total_size;
3019 }
3020
3021
3022 /**
3023  * Creates a path ack message in buf and frees all unused resources.
3024  *
3025  * @param cls closure (MeshTransmissionDescriptor)
3026  * @param size number of bytes available in buf
3027  * @param buf where the callee should write the message
3028  * @return number of bytes written to buf
3029  */
3030 static size_t
3031 send_core_path_ack (void *cls, size_t size, void *buf)
3032 {
3033   struct MeshTransmissionDescriptor *info = cls;
3034   struct GNUNET_MESH_PathACK *msg = buf;
3035
3036   GNUNET_assert (NULL != info);
3037   if (sizeof (struct GNUNET_MESH_PathACK) > size)
3038   {
3039     GNUNET_break (0);
3040     return 0;
3041   }
3042   msg->header.size = htons (sizeof (struct GNUNET_MESH_PathACK));
3043   msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_PATH_ACK);
3044   GNUNET_PEER_resolve (info->origin->oid, &msg->oid);
3045   msg->tid = htonl (info->origin->tid);
3046   msg->peer_id = my_full_id;
3047
3048   GNUNET_free (info);
3049   /* TODO add signature */
3050
3051   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "PATH ACK sent!\n");
3052   return sizeof (struct GNUNET_MESH_PathACK);
3053 }
3054
3055
3056 /**
3057  * Free a transmission that was already queued with all resources
3058  * associated to the request.
3059  *
3060  * @param queue Queue handler to cancel.
3061  * @param clear_cls Is it necessary to free associated cls?
3062  */
3063 static void
3064 queue_destroy (struct MeshPeerQueue *queue, int clear_cls)
3065 {
3066   struct MeshTransmissionDescriptor *dd;
3067   struct MeshPathInfo *path_info;
3068
3069   if (GNUNET_YES == clear_cls)
3070   {
3071     switch (queue->type)
3072     {
3073     case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
3074     case GNUNET_MESSAGE_TYPE_MESH_MULTICAST:
3075         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   type payload\n");
3076         dd = queue->cls;
3077         data_descriptor_decrement_multicast (dd->mesh_data);
3078         break;
3079     case GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE:
3080         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   type create path\n");
3081         path_info = queue->cls;
3082         path_destroy (path_info->path);
3083         break;
3084     default:
3085         GNUNET_break (0);
3086         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   type unknown!\n");
3087     }
3088     GNUNET_free_non_null (queue->cls);
3089   }
3090   GNUNET_CONTAINER_DLL_remove (queue->peer->queue_head,
3091                                queue->peer->queue_tail,
3092                                queue);
3093   GNUNET_free (queue);
3094 }
3095
3096
3097 /**
3098   * Core callback to write a queued packet to core buffer
3099   *
3100   * @param cls Closure (peer info).
3101   * @param size Number of bytes available in buf.
3102   * @param buf Where the to write the message.
3103   *
3104   * @return number of bytes written to buf
3105   */
3106 static size_t
3107 queue_send (void *cls, size_t size, void *buf)
3108 {
3109     struct MeshPeerInfo *peer = cls;
3110     struct MeshPeerQueue *queue;
3111     size_t data_size;
3112
3113     peer->core_transmit = NULL;
3114     queue = peer->queue_head;
3115
3116     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "********* Queue send\n");
3117
3118     /* If queue is empty, send should have been cancelled */
3119     if (NULL == queue)
3120     {
3121         GNUNET_break(0);
3122         return 0;
3123     }
3124     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*********   not empty\n");
3125
3126     /* Check if buffer size is enough for the message */
3127     if (queue->size > size)
3128     {
3129         struct GNUNET_PeerIdentity id;
3130
3131         GNUNET_PEER_resolve (peer->id, &id);
3132         peer->core_transmit =
3133             GNUNET_CORE_notify_transmit_ready(core_handle,
3134                                               0,
3135                                               0,
3136                                               GNUNET_TIME_UNIT_FOREVER_REL,
3137                                               &id,
3138                                               queue->size,
3139                                               &queue_send,
3140                                               peer);
3141         return 0;
3142     }
3143     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*********   size ok\n");
3144
3145     /* Fill buf */
3146     switch (queue->type)
3147     {
3148         case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
3149             GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*********   unicast\n");
3150             data_size = send_core_data_raw (queue->cls, size, buf);
3151             break;
3152         case GNUNET_MESSAGE_TYPE_MESH_MULTICAST:
3153             GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*********   multicast\n");
3154             data_size = send_core_data_multicast(queue->cls, size, buf);
3155             break;
3156         case GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE:
3157             GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*********   path create\n");
3158             data_size = send_core_path_create(queue->cls, size, buf);
3159             break;
3160         case GNUNET_MESSAGE_TYPE_MESH_PATH_ACK:
3161             GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*********   path ack\n");
3162             data_size = send_core_path_ack(queue->cls, size, buf);
3163             break;
3164         default:
3165             GNUNET_break (0);
3166             GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*********   type unknown\n");
3167             data_size = 0;
3168     }
3169     queue->tunnel->queue_n--;
3170
3171     /* Free queue, but cls was freed by send_core_* */
3172     queue_destroy(queue, GNUNET_NO);
3173
3174     /* If more data in queue, send next */
3175     if (NULL != peer->queue_head)
3176     {
3177         struct GNUNET_PeerIdentity id;
3178
3179         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*********   more data!\n");
3180         GNUNET_PEER_resolve (peer->id, &id);
3181         peer->core_transmit =
3182             GNUNET_CORE_notify_transmit_ready(core_handle,
3183                                               0,
3184                                               0,
3185                                               GNUNET_TIME_UNIT_FOREVER_REL,
3186                                               &id,
3187                                               peer->queue_head->size,
3188                                               &queue_send,
3189                                               peer);
3190     }
3191     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*********   return %d\n", data_size);
3192     return data_size;
3193 }
3194
3195
3196 /**
3197  * Queue and pass message to core when possible.
3198  *
3199  * @param cls Closure (type dependant).
3200  * @param type Type of the message.
3201  * @param size Size of the message.
3202  * @param dst Neighbor to send message to.
3203  * @param t Tunnel this message belongs to.
3204  */
3205 static void
3206 queue_add (void *cls, uint16_t type, size_t size,
3207            struct MeshPeerInfo *dst, struct MeshTunnel *t)
3208 {
3209     struct MeshPeerQueue *queue;
3210
3211     if (t->queue_n >= t->queue_max)
3212     {
3213       if (NULL == t->owner)
3214         GNUNET_break_op(0);       // TODO: kill connection?
3215       else
3216         GNUNET_break(0);
3217       return;                       // Drop message
3218     }
3219     t->queue_n++;
3220     queue = GNUNET_malloc (sizeof (struct MeshPeerQueue));
3221     queue->cls = cls;
3222     queue->type = type;
3223     queue->size = size;
3224     queue->peer = dst;
3225     queue->tunnel = t;
3226     GNUNET_CONTAINER_DLL_insert_tail (dst->queue_head, dst->queue_tail, queue);
3227     if (NULL == dst->core_transmit)
3228     {
3229         struct GNUNET_PeerIdentity id;
3230
3231         GNUNET_PEER_resolve (dst->id, &id);
3232         dst->core_transmit =
3233             GNUNET_CORE_notify_transmit_ready(core_handle,
3234                                               0,
3235                                               0,
3236                                               GNUNET_TIME_UNIT_FOREVER_REL,
3237                                               &id,
3238                                               size,
3239                                               &queue_send,
3240                                               dst);
3241     }
3242 }
3243
3244
3245 /******************************************************************************/
3246 /********************      MESH NETWORK HANDLERS     **************************/
3247 /******************************************************************************/
3248
3249
3250 /**
3251  * Core handler for path creation
3252  *
3253  * @param cls closure
3254  * @param message message
3255  * @param peer peer identity this notification is about
3256  * @param atsi performance data
3257  * @param atsi_count number of records in 'atsi'
3258  *
3259  * @return GNUNET_OK to keep the connection open,
3260  *         GNUNET_SYSERR to close it (signal serious error)
3261  */
3262 static int
3263 handle_mesh_path_create (void *cls, const struct GNUNET_PeerIdentity *peer,
3264                          const struct GNUNET_MessageHeader *message,
3265                          const struct GNUNET_ATS_Information *atsi,
3266                          unsigned int atsi_count)
3267 {
3268   unsigned int own_pos;
3269   uint16_t size;
3270   uint16_t i;
3271   MESH_TunnelNumber tid;
3272   struct GNUNET_MESH_ManipulatePath *msg;
3273   struct GNUNET_PeerIdentity *pi;
3274   struct GNUNET_HashCode hash;
3275   struct MeshPeerPath *path;
3276   struct MeshPeerInfo *dest_peer_info;
3277   struct MeshPeerInfo *orig_peer_info;
3278   struct MeshTunnel *t;
3279
3280   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3281               "Received a path create msg [%s]\n",
3282               GNUNET_i2s (&my_full_id));
3283   size = ntohs (message->size);
3284   if (size < sizeof (struct GNUNET_MESH_ManipulatePath))
3285   {
3286     GNUNET_break_op (0);
3287     return GNUNET_OK;
3288   }
3289
3290   size -= sizeof (struct GNUNET_MESH_ManipulatePath);
3291   if (size % sizeof (struct GNUNET_PeerIdentity))
3292   {
3293     GNUNET_break_op (0);
3294     return GNUNET_OK;
3295   }
3296   size /= sizeof (struct GNUNET_PeerIdentity);
3297   if (size < 2)
3298   {
3299     GNUNET_break_op (0);
3300     return GNUNET_OK;
3301   }
3302   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "    path has %u hops.\n", size);
3303   msg = (struct GNUNET_MESH_ManipulatePath *) message;
3304
3305   tid = ntohl (msg->tid);
3306   pi = (struct GNUNET_PeerIdentity *) &msg[1];
3307   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3308               "    path is for tunnel %s [%X].\n", GNUNET_i2s (pi), tid);
3309   t = tunnel_get (pi, tid);
3310   if (NULL == t) // FIXME only for INCOMING tunnels?
3311   {
3312     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  Creating tunnel\n");
3313     t = tunnel_new (GNUNET_PEER_intern (pi), tid, NULL, 0);
3314
3315     while (NULL != tunnel_get_incoming (next_local_tid))
3316       next_local_tid = (next_local_tid + 1) | GNUNET_MESH_LOCAL_TUNNEL_ID_SERV;
3317     t->local_tid_dest = next_local_tid++;
3318     next_local_tid = next_local_tid | GNUNET_MESH_LOCAL_TUNNEL_ID_SERV;
3319
3320     tunnel_reset_timeout (t);
3321     GNUNET_CRYPTO_hash (&t->local_tid_dest, sizeof (MESH_TunnelNumber), &hash);
3322     if (GNUNET_OK !=
3323         GNUNET_CONTAINER_multihashmap_put (incoming_tunnels, &hash, t,
3324                                            GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
3325     {
3326       tunnel_destroy (t);
3327       GNUNET_break (0);
3328       return GNUNET_OK;
3329     }
3330   }
3331   dest_peer_info =
3332       GNUNET_CONTAINER_multihashmap_get (peers, &pi[size - 1].hashPubKey);
3333   if (NULL == dest_peer_info)
3334   {
3335     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3336                 "  Creating PeerInfo for destination.\n");
3337     dest_peer_info = GNUNET_malloc (sizeof (struct MeshPeerInfo));
3338     dest_peer_info->id = GNUNET_PEER_intern (&pi[size - 1]);
3339     GNUNET_CONTAINER_multihashmap_put (peers, &pi[size - 1].hashPubKey,
3340                                        dest_peer_info,
3341                                        GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
3342   }
3343   orig_peer_info = GNUNET_CONTAINER_multihashmap_get (peers, &pi->hashPubKey);
3344   if (NULL == orig_peer_info)
3345   {
3346     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3347                 "  Creating PeerInfo for origin.\n");
3348     orig_peer_info = GNUNET_malloc (sizeof (struct MeshPeerInfo));
3349     orig_peer_info->id = GNUNET_PEER_intern (pi);
3350     GNUNET_CONTAINER_multihashmap_put (peers, &pi->hashPubKey, orig_peer_info,
3351                                        GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
3352   }
3353   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  Creating path...\n");
3354   path = path_new (size);
3355   own_pos = 0;
3356   for (i = 0; i < size; i++)
3357   {
3358     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  ... adding %s\n",
3359                 GNUNET_i2s (&pi[i]));
3360     path->peers[i] = GNUNET_PEER_intern (&pi[i]);
3361     if (path->peers[i] == myid)
3362       own_pos = i;
3363   }
3364   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  Own position: %u\n", own_pos);
3365   if (own_pos == 0)
3366   {
3367     /* cannot be self, must be 'not found' */
3368     /* create path: self not found in path through self */
3369     GNUNET_break_op (0);
3370     path_destroy (path);
3371     /* FIXME error. destroy tunnel? leave for timeout? */
3372     return 0;
3373   }
3374   path_add_to_peers (path, GNUNET_NO);
3375   tunnel_add_path (t, path, own_pos);
3376   if (own_pos == size - 1)
3377   {
3378     /* It is for us! Send ack. */
3379     struct MeshTransmissionDescriptor *info;
3380
3381     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  It's for us!\n");
3382     peer_info_add_path_to_origin (orig_peer_info, path, GNUNET_NO);
3383     if (NULL == t->peers)
3384     {
3385       /* New tunnel! Notify clients on data. */
3386       t->peers = GNUNET_CONTAINER_multihashmap_create (4);
3387     }
3388     GNUNET_break (GNUNET_OK ==
3389                   GNUNET_CONTAINER_multihashmap_put (t->peers,
3390                                                      &my_full_id.hashPubKey,
3391                                                      peer_info_get
3392                                                      (&my_full_id),
3393                                                      GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE));
3394     info = GNUNET_malloc (sizeof (struct MeshTransmissionDescriptor));
3395     info->origin = &t->id;
3396     info->peer = GNUNET_CONTAINER_multihashmap_get (peers, &peer->hashPubKey);
3397     GNUNET_assert (NULL != info->peer);
3398     queue_add(info,
3399               GNUNET_MESSAGE_TYPE_MESH_PATH_ACK,
3400               sizeof (struct GNUNET_MESH_PathACK),
3401               info->peer,
3402               t);
3403   }
3404   else
3405   {
3406     struct MeshPeerPath *path2;
3407
3408     /* It's for somebody else! Retransmit. */
3409     path2 = path_duplicate (path);
3410     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  Retransmitting.\n");
3411     peer_info_add_path (dest_peer_info, path2, GNUNET_NO);
3412     path2 = path_duplicate (path);
3413     peer_info_add_path_to_origin (orig_peer_info, path2, GNUNET_NO);
3414     send_create_path (dest_peer_info, path, t);
3415   }
3416   return GNUNET_OK;
3417 }
3418
3419
3420 /**
3421  * Core handler for path destruction
3422  *
3423  * @param cls closure
3424  * @param message message
3425  * @param peer peer identity this notification is about
3426  * @param atsi performance data
3427  * @param atsi_count number of records in 'atsi'
3428  *
3429  * @return GNUNET_OK to keep the connection open,
3430  *         GNUNET_SYSERR to close it (signal serious error)
3431  */
3432 static int
3433 handle_mesh_path_destroy (void *cls, const struct GNUNET_PeerIdentity *peer,
3434                           const struct GNUNET_MessageHeader *message,
3435                           const struct GNUNET_ATS_Information *atsi,
3436                           unsigned int atsi_count)
3437 {
3438   struct GNUNET_MESH_ManipulatePath *msg;
3439   struct GNUNET_PeerIdentity *pi;
3440   struct MeshPeerPath *path;
3441   struct MeshTunnel *t;
3442   unsigned int own_pos;
3443   unsigned int i;
3444   size_t size;
3445
3446   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3447               "Received a PATH DESTROY msg from %s\n", GNUNET_i2s (peer));
3448   size = ntohs (message->size);
3449   if (size < sizeof (struct GNUNET_MESH_ManipulatePath))
3450   {
3451     GNUNET_break_op (0);
3452     return GNUNET_OK;
3453   }
3454
3455   size -= sizeof (struct GNUNET_MESH_ManipulatePath);
3456   if (size % sizeof (struct GNUNET_PeerIdentity))
3457   {
3458     GNUNET_break_op (0);
3459     return GNUNET_OK;
3460   }
3461   size /= sizeof (struct GNUNET_PeerIdentity);
3462   if (size < 2)
3463   {
3464     GNUNET_break_op (0);
3465     return GNUNET_OK;
3466   }
3467   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "    path has %u hops.\n", size);
3468
3469   msg = (struct GNUNET_MESH_ManipulatePath *) message;
3470   pi = (struct GNUNET_PeerIdentity *) &msg[1];
3471   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3472               "    path is for tunnel %s [%X].\n", GNUNET_i2s (pi),
3473               msg->tid);
3474   t = tunnel_get (pi, ntohl (msg->tid));
3475   if (NULL == t)
3476   {
3477     /* TODO notify back: we don't know this tunnel */
3478     GNUNET_break_op (0);
3479     return GNUNET_OK;
3480   }
3481   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  Creating path...\n");
3482   path = path_new (size);
3483   own_pos = 0;
3484   for (i = 0; i < size; i++)
3485   {
3486     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  ... adding %s\n",
3487                 GNUNET_i2s (&pi[i]));
3488     path->peers[i] = GNUNET_PEER_intern (&pi[i]);
3489     if (path->peers[i] == myid)
3490       own_pos = i;
3491   }
3492   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  Own position: %u\n", own_pos);
3493   if (own_pos < path->length - 1)
3494     send_message (message, &pi[own_pos + 1], t);
3495   else
3496     send_client_tunnel_disconnect(t, NULL);
3497
3498   tunnel_delete_peer (t, path->peers[path->length - 1]);
3499   path_destroy (path);
3500   return GNUNET_OK;
3501 }
3502
3503
3504 /**
3505  * Core handler for notifications of broken paths
3506  *
3507  * @param cls closure
3508  * @param message message
3509  * @param peer peer identity this notification is about
3510  * @param atsi performance data
3511  * @param atsi_count number of records in 'atsi'
3512  *
3513  * @return GNUNET_OK to keep the connection open,
3514  *         GNUNET_SYSERR to close it (signal serious error)
3515  */
3516 static int
3517 handle_mesh_path_broken (void *cls, const struct GNUNET_PeerIdentity *peer,
3518                          const struct GNUNET_MessageHeader *message,
3519                          const struct GNUNET_ATS_Information *atsi,
3520                          unsigned int atsi_count)
3521 {
3522   struct GNUNET_MESH_PathBroken *msg;
3523   struct MeshTunnel *t;
3524
3525   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3526               "Received a PATH BROKEN msg from %s\n", GNUNET_i2s (peer));
3527   msg = (struct GNUNET_MESH_PathBroken *) message;
3528   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  regarding %s\n",
3529               GNUNET_i2s (&msg->peer1));
3530   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  regarding %s\n",
3531               GNUNET_i2s (&msg->peer2));
3532   t = tunnel_get (&msg->oid, ntohl (msg->tid));
3533   if (NULL == t)
3534   {
3535     GNUNET_break_op (0);
3536     return GNUNET_OK;
3537   }
3538   tunnel_notify_connection_broken (t, GNUNET_PEER_search (&msg->peer1),
3539                                    GNUNET_PEER_search (&msg->peer2));
3540   return GNUNET_OK;
3541
3542 }
3543
3544
3545 /**
3546  * Core handler for tunnel destruction
3547  *
3548  * @param cls closure
3549  * @param message message
3550  * @param peer peer identity this notification is about
3551  * @param atsi performance data
3552  * @param atsi_count number of records in 'atsi'
3553  *
3554  * @return GNUNET_OK to keep the connection open,
3555  *         GNUNET_SYSERR to close it (signal serious error)
3556  */
3557 static int
3558 handle_mesh_tunnel_destroy (void *cls, const struct GNUNET_PeerIdentity *peer,
3559                             const struct GNUNET_MessageHeader *message,
3560                             const struct GNUNET_ATS_Information *atsi,
3561                             unsigned int atsi_count)
3562 {
3563   struct GNUNET_MESH_TunnelDestroy *msg;
3564   struct MeshTunnel *t;
3565
3566   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3567               "Got a TUNNEL DESTROY packet from %s\n", GNUNET_i2s (peer));
3568   msg = (struct GNUNET_MESH_TunnelDestroy *) message;
3569   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  for tunnel %s [%u]\n",
3570               GNUNET_i2s (&msg->oid), ntohl (msg->tid));
3571   t = tunnel_get (&msg->oid, ntohl (msg->tid));
3572   if (NULL == t)
3573   {
3574     /* Probably already got the message from another path,
3575      * destroyed the tunnel and retransmitted to children.
3576      * Safe to ignore.
3577      */
3578     return GNUNET_OK;
3579   }
3580   if (t->id.oid == myid)
3581   {
3582     GNUNET_break_op (0);
3583     return GNUNET_OK;
3584   }
3585   if (t->local_tid_dest >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV)
3586   {
3587     /* Tunnel was incoming, notify clients */
3588     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "INCOMING TUNNEL %X %X\n",
3589                 t->local_tid, t->local_tid_dest);
3590     send_clients_tunnel_destroy (t);
3591   }
3592   tunnel_send_destroy (t);
3593   tunnel_destroy (t);
3594   return GNUNET_OK;
3595 }
3596
3597
3598 /**
3599  * Core handler for mesh network traffic going from the origin to a peer
3600  *
3601  * @param cls closure
3602  * @param peer peer identity this notification is about
3603  * @param message message
3604  * @param atsi performance data
3605  * @param atsi_count number of records in 'atsi'
3606  * @return GNUNET_OK to keep the connection open,
3607  *         GNUNET_SYSERR to close it (signal serious error)
3608  */
3609 static int
3610 handle_mesh_data_unicast (void *cls, const struct GNUNET_PeerIdentity *peer,
3611                           const struct GNUNET_MessageHeader *message,
3612                           const struct GNUNET_ATS_Information *atsi,
3613                           unsigned int atsi_count)
3614 {
3615   struct GNUNET_MESH_Unicast *msg;
3616   struct MeshTunnel *t;
3617   GNUNET_PEER_Id pid;
3618   size_t size;
3619
3620   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "got a unicast packet from %s\n",
3621               GNUNET_i2s (peer));
3622   size = ntohs (message->size);
3623   if (size <
3624       sizeof (struct GNUNET_MESH_Unicast) +
3625       sizeof (struct GNUNET_MessageHeader))
3626   {
3627     GNUNET_break (0);
3628     return GNUNET_OK;
3629   }
3630   msg = (struct GNUNET_MESH_Unicast *) message;
3631   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " of type %u\n",
3632               ntohs (msg[1].header.type));
3633   t = tunnel_get (&msg->oid, ntohl (msg->tid));
3634   if (NULL == t)
3635   {
3636     /* TODO notify back: we don't know this tunnel */
3637     GNUNET_break_op (0);
3638     return GNUNET_OK;
3639   }
3640   tunnel_reset_timeout (t);
3641   pid = GNUNET_PEER_search (&msg->destination);
3642   if (pid == myid)
3643   {
3644     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3645                 "  it's for us! sending to clients...\n");
3646     send_subscribed_clients (message, (struct GNUNET_MessageHeader *) &msg[1]);
3647     return GNUNET_OK;
3648   }
3649   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3650               "  not for us, retransmitting...\n");
3651   send_message (message, tree_get_first_hop (t->tree, pid), t);
3652   return GNUNET_OK;
3653 }
3654
3655
3656 /**
3657  * Core handler for mesh network traffic going from the origin to all peers
3658  *
3659  * @param cls closure
3660  * @param message message
3661  * @param peer peer identity this notification is about
3662  * @param atsi performance data
3663  * @param atsi_count number of records in 'atsi'
3664  * @return GNUNET_OK to keep the connection open,
3665  *         GNUNET_SYSERR to close it (signal serious error)
3666  *
3667  * TODO: Check who we got this from, to validate route.
3668  */
3669 static int
3670 handle_mesh_data_multicast (void *cls, const struct GNUNET_PeerIdentity *peer,
3671                             const struct GNUNET_MessageHeader *message,
3672                             const struct GNUNET_ATS_Information *atsi,
3673                             unsigned int atsi_count)
3674 {
3675   struct GNUNET_MESH_Multicast *msg;
3676   struct MeshTunnel *t;
3677   size_t size;
3678
3679   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "got a multicast packet from %s\n",
3680               GNUNET_i2s (peer));
3681   size = ntohs (message->size);
3682   if (sizeof (struct GNUNET_MESH_Multicast) +
3683       sizeof (struct GNUNET_MessageHeader) > size)
3684   {
3685     GNUNET_break_op (0);
3686     return GNUNET_OK;
3687   }
3688   msg = (struct GNUNET_MESH_Multicast *) message;
3689   t = tunnel_get (&msg->oid, ntohl (msg->tid));
3690
3691   if (NULL == t)
3692   {
3693     /* TODO notify that we dont know that tunnel */
3694     GNUNET_break_op (0);
3695     return GNUNET_OK;
3696   }
3697   if (t->mid == ntohl (msg->mid))
3698   {
3699     /* FIXME: already seen this packet, log dropping */
3700     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3701                 " Already seen mid %u, DROPPING!\n", t->mid);
3702     return GNUNET_OK;
3703   }
3704   else
3705   {
3706     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3707                 " mid %u not seen yet, forwarding\n", ntohl (msg->mid));
3708   }
3709   t->mid = ntohl (msg->mid);
3710   tunnel_reset_timeout (t);
3711
3712   /* Transmit to locally interested clients */
3713   if (NULL != t->peers &&
3714       GNUNET_CONTAINER_multihashmap_contains (t->peers, &my_full_id.hashPubKey))
3715   {
3716     send_subscribed_clients (message, &msg[1].header);
3717   }
3718   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   ttl: %u\n", ntohl (msg->ttl));
3719   if (ntohl (msg->ttl) == 0)
3720   {
3721     /* FIXME: ttl is 0, log dropping */
3722     GNUNET_log (GNUNET_ERROR_TYPE_WARNING, " TTL is 0, DROPPING!\n");
3723     return GNUNET_OK;
3724   }
3725   tunnel_send_multicast (t, message, GNUNET_NO);
3726   return GNUNET_OK;
3727 }
3728
3729
3730 /**
3731  * Core handler for mesh network traffic toward the owner of a tunnel
3732  *
3733  * @param cls closure
3734  * @param message message
3735  * @param peer peer identity this notification is about
3736  * @param atsi performance data
3737  * @param atsi_count number of records in 'atsi'
3738  *
3739  * @return GNUNET_OK to keep the connection open,
3740  *         GNUNET_SYSERR to close it (signal serious error)
3741  */
3742 static int
3743 handle_mesh_data_to_orig (void *cls, const struct GNUNET_PeerIdentity *peer,
3744                           const struct GNUNET_MessageHeader *message,
3745                           const struct GNUNET_ATS_Information *atsi,
3746                           unsigned int atsi_count)
3747 {
3748   struct GNUNET_MESH_ToOrigin *msg;
3749   struct GNUNET_PeerIdentity id;
3750   struct MeshPeerInfo *peer_info;
3751   struct MeshTunnel *t;
3752   size_t size;
3753
3754   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "got a ToOrigin packet from %s\n",
3755               GNUNET_i2s (peer));
3756   size = ntohs (message->size);
3757   if (size < sizeof (struct GNUNET_MESH_ToOrigin) +     /* Payload must be */
3758       sizeof (struct GNUNET_MessageHeader))     /* at least a header */
3759   {
3760     GNUNET_break_op (0);
3761     return GNUNET_OK;
3762   }
3763   msg = (struct GNUNET_MESH_ToOrigin *) message;
3764   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " of type %u\n",
3765               ntohs (msg[1].header.type));
3766   t = tunnel_get (&msg->oid, ntohl (msg->tid));
3767
3768   if (NULL == t)
3769   {
3770     /* TODO notify that we dont know this tunnel (whom)? */
3771     GNUNET_break_op (0);
3772     return GNUNET_OK;
3773   }
3774
3775   if (t->id.oid == myid)
3776   {
3777     char cbuf[size];
3778     struct GNUNET_MESH_ToOrigin *copy;
3779
3780     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3781                 "  it's for us! sending to clients...\n");
3782     if (NULL == t->owner)
3783     {
3784       /* got data packet for ownerless tunnel */
3785       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  no clients!\n");
3786       GNUNET_break_op (0);
3787       return GNUNET_OK;
3788     }
3789     /* TODO signature verification */
3790     memcpy (cbuf, message, size);
3791     copy = (struct GNUNET_MESH_ToOrigin *) cbuf;
3792     copy->tid = htonl (t->local_tid);
3793     GNUNET_SERVER_notification_context_unicast (nc, t->owner->handle,
3794                                                 &copy->header, GNUNET_YES);
3795     return GNUNET_OK;
3796   }
3797   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3798               "  not for us, retransmitting...\n");
3799
3800   peer_info = peer_info_get (&msg->oid);
3801   if (NULL == peer_info)
3802   {
3803     /* unknown origin of tunnel */
3804     GNUNET_break (0);
3805     return GNUNET_OK;
3806   }
3807   GNUNET_PEER_resolve (tree_get_predecessor (t->tree), &id);
3808   send_message (message, &id, t);
3809
3810   return GNUNET_OK;
3811 }
3812
3813
3814 /**
3815  * Core handler for path ACKs
3816  *
3817  * @param cls closure
3818  * @param message message
3819  * @param peer peer identity this notification is about
3820  * @param atsi performance data
3821  * @param atsi_count number of records in 'atsi'
3822  *
3823  * @return GNUNET_OK to keep the connection open,
3824  *         GNUNET_SYSERR to close it (signal serious error)
3825  */
3826 static int
3827 handle_mesh_path_ack (void *cls, const struct GNUNET_PeerIdentity *peer,
3828                       const struct GNUNET_MessageHeader *message,
3829                       const struct GNUNET_ATS_Information *atsi,
3830                       unsigned int atsi_count)
3831 {
3832   struct GNUNET_MESH_PathACK *msg;
3833   struct GNUNET_PeerIdentity id;
3834   struct MeshPeerInfo *peer_info;
3835   struct MeshPeerPath *p;
3836   struct MeshTunnel *t;
3837
3838   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received a path ACK msg [%s]\n",
3839               GNUNET_i2s (&my_full_id));
3840   msg = (struct GNUNET_MESH_PathACK *) message;
3841   t = tunnel_get (&msg->oid, msg->tid);
3842   if (NULL == t)
3843   {
3844     /* TODO notify that we don't know the tunnel */
3845     return GNUNET_OK;
3846   }
3847
3848   peer_info = peer_info_get (&msg->peer_id);
3849
3850   /* Add paths to peers? */
3851   p = tree_get_path_to_peer (t->tree, peer_info->id);
3852   if (NULL != p)
3853   {
3854     path_add_to_peers (p, GNUNET_YES);
3855     path_destroy (p);
3856   }
3857   else
3858   {
3859     GNUNET_break (0);
3860   }
3861
3862   /* Message for us? */
3863   if (0 == memcmp (&msg->oid, &my_full_id, sizeof (struct GNUNET_PeerIdentity)))
3864   {
3865     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  It's for us!\n");
3866     if (NULL == t->owner)
3867     {
3868       GNUNET_break_op (0);
3869       return GNUNET_OK;
3870     }
3871     if (NULL != t->dht_get_type)
3872     {
3873       GNUNET_DHT_get_stop (t->dht_get_type);
3874       t->dht_get_type = NULL;
3875     }
3876     if (tree_get_status (t->tree, peer_info->id) != MESH_PEER_READY)
3877     {
3878       tree_set_status (t->tree, peer_info->id, MESH_PEER_READY);
3879       send_client_peer_connected (t, peer_info->id);
3880     }
3881     return GNUNET_OK;
3882   }
3883
3884   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3885               "  not for us, retransmitting...\n");
3886   GNUNET_PEER_resolve (tree_get_predecessor (t->tree), &id);
3887   peer_info = peer_info_get (&msg->oid);
3888   if (NULL == peer_info)
3889   {
3890     /* If we know the tunnel, we should DEFINITELY know the peer */
3891     GNUNET_break (0);
3892     return GNUNET_OK;
3893   }
3894   send_message (message, &id, t);
3895   return GNUNET_OK;
3896 }
3897
3898
3899 /**
3900  * Functions to handle messages from core
3901  */
3902 static struct GNUNET_CORE_MessageHandler core_handlers[] = {
3903   {&handle_mesh_path_create, GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE, 0},
3904   {&handle_mesh_path_destroy, GNUNET_MESSAGE_TYPE_MESH_PATH_DESTROY, 0},
3905   {&handle_mesh_path_broken, GNUNET_MESSAGE_TYPE_MESH_PATH_BROKEN,
3906    sizeof (struct GNUNET_MESH_PathBroken)},
3907   {&handle_mesh_tunnel_destroy, GNUNET_MESSAGE_TYPE_MESH_TUNNEL_DESTROY, 0},
3908   {&handle_mesh_data_unicast, GNUNET_MESSAGE_TYPE_MESH_UNICAST, 0},
3909   {&handle_mesh_data_multicast, GNUNET_MESSAGE_TYPE_MESH_MULTICAST, 0},
3910   {&handle_mesh_data_to_orig, GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN, 0},
3911   {&handle_mesh_path_ack, GNUNET_MESSAGE_TYPE_MESH_PATH_ACK,
3912    sizeof (struct GNUNET_MESH_PathACK)},
3913   {NULL, 0, 0}
3914 };
3915
3916
3917
3918 /******************************************************************************/
3919 /****************       MESH LOCAL HANDLER HELPERS      ***********************/
3920 /******************************************************************************/
3921
3922 /**
3923  * deregister_app: iterator for removing each application registered by a client
3924  *
3925  * @param cls closure
3926  * @param key the hash of the application id (used to access the hashmap)
3927  * @param value the value stored at the key (client)
3928  *
3929  * @return GNUNET_OK on success
3930  */
3931 static int
3932 deregister_app (void *cls, const struct GNUNET_HashCode * key, void *value)
3933 {
3934   struct GNUNET_CONTAINER_MultiHashMap *h = cls;
3935   GNUNET_break (GNUNET_YES ==
3936                 GNUNET_CONTAINER_multihashmap_remove (h, key, value));
3937   return GNUNET_OK;
3938 }
3939
3940 #if LATER
3941 /**
3942  * notify_client_connection_failure: notify a client that the connection to the
3943  * requested remote peer is not possible (for instance, no route found)
3944  * Function called when the socket is ready to queue more data. "buf" will be
3945  * NULL and "size" zero if the socket was closed for writing in the meantime.
3946  *
3947  * @param cls closure
3948  * @param size number of bytes available in buf
3949  * @param buf where the callee should write the message
3950  * @return number of bytes written to buf
3951  */
3952 static size_t
3953 notify_client_connection_failure (void *cls, size_t size, void *buf)
3954 {
3955   int size_needed;
3956   struct MeshPeerInfo *peer_info;
3957   struct GNUNET_MESH_PeerControl *msg;
3958   struct GNUNET_PeerIdentity id;
3959
3960   if (0 == size && NULL == buf)
3961   {
3962     // TODO retry? cancel?
3963     return 0;
3964   }
3965
3966   size_needed = sizeof (struct GNUNET_MESH_PeerControl);
3967   peer_info = (struct MeshPeerInfo *) cls;
3968   msg = (struct GNUNET_MESH_PeerControl *) buf;
3969   msg->header.size = htons (sizeof (struct GNUNET_MESH_PeerControl));
3970   msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_DISCONNECTED);
3971 //     msg->tunnel_id = htonl(peer_info->t->tid);
3972   GNUNET_PEER_resolve (peer_info->id, &id);
3973   memcpy (&msg->peer, &id, sizeof (struct GNUNET_PeerIdentity));
3974
3975   return size_needed;
3976 }
3977 #endif
3978
3979
3980 /**
3981  * Send keepalive packets for a peer
3982  *
3983  * @param cls Closure (tunnel for which to send the keepalive).
3984  * @param tc Notification context.
3985  *
3986  * TODO: implement explicit multicast keepalive?
3987  */
3988 static void
3989 path_refresh (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
3990 {
3991   struct MeshTunnel *t = cls;
3992   struct GNUNET_MessageHeader *payload;
3993   struct GNUNET_MESH_Multicast *msg;
3994   size_t size =
3995       sizeof (struct GNUNET_MESH_Multicast) +
3996       sizeof (struct GNUNET_MessageHeader);
3997   char cbuf[size];
3998
3999   if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN)
4000   {
4001     return;
4002   }
4003   t->path_refresh_task = GNUNET_SCHEDULER_NO_TASK;
4004
4005   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4006               "sending keepalive for tunnel %d\n", t->id.tid);
4007
4008   msg = (struct GNUNET_MESH_Multicast *) cbuf;
4009   msg->header.size = htons (size);
4010   msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_MULTICAST);
4011   msg->oid = my_full_id;
4012   msg->tid = htonl (t->id.tid);
4013   msg->ttl = htonl (DEFAULT_TTL);
4014   msg->mid = htonl (t->mid + 1);
4015   t->mid++;
4016   payload = (struct GNUNET_MessageHeader *) &msg[1];
4017   payload->size = htons (sizeof (struct GNUNET_MessageHeader));
4018   payload->type = htons (GNUNET_MESSAGE_TYPE_MESH_PATH_KEEPALIVE);
4019   tunnel_send_multicast (t, &msg->header, GNUNET_YES);
4020
4021   t->path_refresh_task =
4022       GNUNET_SCHEDULER_add_delayed (REFRESH_PATH_TIME, &path_refresh, t);
4023   return;
4024 }
4025
4026
4027 /**
4028  * Function to process paths received for a new peer addition. The recorded
4029  * paths form the initial tunnel, which can be optimized later.
4030  * Called on each result obtained for the DHT search.
4031  *
4032  * @param cls closure
4033  * @param exp when will this value expire
4034  * @param key key of the result
4035  * @param get_path path of the get request
4036  * @param get_path_length lenght of get_path
4037  * @param put_path path of the put request
4038  * @param put_path_length length of the put_path
4039  * @param type type of the result
4040  * @param size number of bytes in data
4041  * @param data pointer to the result data
4042  *
4043  * TODO: re-issue the request after certain time? cancel after X results?
4044  */
4045 static void
4046 dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp,
4047                     const struct GNUNET_HashCode * key,
4048                     const struct GNUNET_PeerIdentity *get_path,
4049                     unsigned int get_path_length,
4050                     const struct GNUNET_PeerIdentity *put_path,
4051                     unsigned int put_path_length, enum GNUNET_BLOCK_Type type,
4052                     size_t size, const void *data)
4053 {
4054   struct MeshPathInfo *path_info = cls;
4055   struct MeshPeerPath *p;
4056   struct GNUNET_PeerIdentity pi;
4057   int i;
4058
4059   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got results from DHT!\n");
4060   GNUNET_PEER_resolve (path_info->peer->id, &pi);
4061   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  for %s\n", GNUNET_i2s (&pi));
4062
4063   p = path_build_from_dht (get_path, get_path_length, put_path,
4064                            put_path_length);
4065   path_add_to_peers (p, GNUNET_NO);
4066   path_destroy(p);
4067   for (i = 0; i < path_info->peer->ntunnels; i++)
4068   {
4069     tunnel_add_peer (path_info->peer->tunnels[i], path_info->peer);
4070     peer_info_connect (path_info->peer, path_info->t);
4071   }
4072
4073   return;
4074 }
4075
4076
4077 /**
4078  * Function to process paths received for a new peer addition. The recorded
4079  * paths form the initial tunnel, which can be optimized later.
4080  * Called on each result obtained for the DHT search.
4081  *
4082  * @param cls closure
4083  * @param exp when will this value expire
4084  * @param key key of the result
4085  * @param get_path path of the get request
4086  * @param get_path_length lenght of get_path
4087  * @param put_path path of the put request
4088  * @param put_path_length length of the put_path
4089  * @param type type of the result
4090  * @param size number of bytes in data
4091  * @param data pointer to the result data
4092  */
4093 static void
4094 dht_get_type_handler (void *cls, struct GNUNET_TIME_Absolute exp,
4095                       const struct GNUNET_HashCode * key,
4096                       const struct GNUNET_PeerIdentity *get_path,
4097                       unsigned int get_path_length,
4098                       const struct GNUNET_PeerIdentity *put_path,
4099                       unsigned int put_path_length, enum GNUNET_BLOCK_Type type,
4100                       size_t size, const void *data)
4101 {
4102   const struct PBlock *pb = data;
4103   const struct GNUNET_PeerIdentity *pi = &pb->id;
4104   struct MeshTunnel *t = cls;
4105   struct MeshPeerInfo *peer_info;
4106   struct MeshPeerPath *p;
4107
4108   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "got type DHT result!\n");
4109   if (size != sizeof (struct PBlock))
4110   {
4111     GNUNET_break_op (0);
4112     return;
4113   }
4114   if (ntohl(pb->type) != t->type)
4115   {
4116     GNUNET_break_op (0);
4117     return;
4118   }
4119   GNUNET_assert (NULL != t->owner);
4120   peer_info = peer_info_get (pi);
4121   (void) GNUNET_CONTAINER_multihashmap_put (t->peers, &pi->hashPubKey,
4122                                             peer_info,
4123                                             GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE);
4124
4125   p = path_build_from_dht (get_path, get_path_length, put_path,
4126                            put_path_length);
4127   path_add_to_peers (p, GNUNET_NO);
4128   path_destroy(p);
4129   tunnel_add_peer (t, peer_info);
4130   peer_info_connect (peer_info, t);
4131 }
4132
4133 /**
4134  * Function to process DHT string to regex matching.
4135  * Called on each result obtained for the DHT search.
4136  *
4137  * @param cls closure (search context)
4138  * @param exp when will this value expire
4139  * @param key key of the result
4140  * @param get_path path of the get request (not used)
4141  * @param get_path_length lenght of get_path (not used)
4142  * @param put_path path of the put request (not used)
4143  * @param put_path_length length of the put_path (not used)
4144  * @param type type of the result
4145  * @param size number of bytes in data
4146  * @param data pointer to the result data
4147  *
4148  * TODO: re-issue the request after certain time? cancel after X results?
4149  */
4150 static void
4151 dht_get_string_handler (void *cls, struct GNUNET_TIME_Absolute exp,
4152                         const struct GNUNET_HashCode * key,
4153                         const struct GNUNET_PeerIdentity *get_path,
4154                         unsigned int get_path_length,
4155                         const struct GNUNET_PeerIdentity *put_path,
4156                         unsigned int put_path_length, enum GNUNET_BLOCK_Type type,
4157                         size_t size, const void *data);
4158
4159 /**
4160  * Iterator over edges in a regex block retrieved from the DHT.
4161  *
4162  * @param cls Closure.
4163  * @param token Token that follows to next state.
4164  * @param len Lenght of token.
4165  * @param key Hash of next state.
4166  *
4167  * @return GNUNET_YES if should keep iterating, GNUNET_NO otherwise.
4168  */
4169 static int
4170 regex_edge_iterator (void *cls,
4171                      const char *token,
4172                      size_t len,
4173                      const struct GNUNET_HashCode *key);
4174 /**
4175  * Iterator over hash map entries.
4176  *
4177  * @param cls closure
4178  * @param key current key code
4179  * @param value value in the hash map
4180  * @return GNUNET_YES if we should continue to
4181  *         iterate,
4182  *         GNUNET_NO if not.
4183  */
4184 static int
4185 regex_result_iterator (void *cls,
4186                        const struct GNUNET_HashCode * key,
4187                        void *value)
4188 {
4189   struct MeshRegexBlock *block = value;
4190   struct MeshRegexSearchContext *ctx = cls;
4191
4192   // block was checked when stored, no need to check again
4193   (void) GNUNET_MESH_regex_block_iterate (block, SIZE_MAX,
4194                                           &regex_edge_iterator, ctx);
4195
4196   return GNUNET_YES;
4197 }
4198
4199 /**
4200  * Iterator over edges in a regex block retrieved from the DHT.
4201  *
4202  * @param cls Closure (context of the search).
4203  * @param token Token that follows to next state.
4204  * @param len Lenght of token.
4205  * @param key Hash of next state.
4206  *
4207  * @return GNUNET_YES if should keep iterating, GNUNET_NO otherwise.
4208  */
4209 static int
4210 regex_edge_iterator (void *cls,
4211                      const char *token,
4212                      size_t len,
4213                      const struct GNUNET_HashCode *key)
4214 {
4215   struct MeshRegexSearchContext *ctx = cls;
4216   struct MeshRegexSearchContext *new_ctx;
4217   struct MeshRegexSearchInfo *info = ctx->info;
4218   struct GNUNET_DHT_GetHandle *get_h;
4219   char *current;
4220   size_t current_len;
4221
4222   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*    Start of regex edge iterator\n");
4223   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*     descr : %s\n", info->description);
4224   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*     posit : %u\n", ctx->position);
4225   current = &info->description[ctx->position];
4226   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*     currt : %s\n", current);
4227   current_len = strlen (info->description) - ctx->position;
4228   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*     ctlen : %u\n", current_len);
4229   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*     tklen : %u\n", len);
4230   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*     tk[0] : %c\n", token[0]);
4231   if (len > current_len)
4232   {
4233     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*     Token too long, END\n");
4234     return GNUNET_YES; // Token too long, wont match
4235   }
4236   if (0 != strncmp (current, token, len))
4237   {
4238     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*     Token doesn't match, END\n");
4239     return GNUNET_YES; // Token doesn't match
4240   }
4241   new_ctx = GNUNET_malloc (sizeof (struct MeshRegexSearchContext));
4242   new_ctx->info = info;
4243   new_ctx->position += ctx->position + len;
4244   GNUNET_array_append (info->copies, info->n_copies, new_ctx);
4245   if (GNUNET_YES ==
4246       GNUNET_CONTAINER_multihashmap_contains(info->dht_get_handles, key))
4247   {
4248     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*     GET running, END\n");
4249     GNUNET_CONTAINER_multihashmap_get_multiple (info->dht_get_results, key,
4250                                                 &regex_result_iterator,
4251                                                 new_ctx);
4252     return GNUNET_YES; // We are already looking for it
4253   }
4254   /* Start search in DHT */
4255   get_h = 
4256       GNUNET_DHT_get_start (dht_handle,    /* handle */
4257                             GNUNET_BLOCK_TYPE_MESH_REGEX, /* type */
4258                             key,     /* key to search */
4259                             DHT_REPLICATION_LEVEL, /* replication level */
4260                             GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE,
4261                             NULL,       /* xquery */ // FIXME BLOOMFILTER
4262                             0,     /* xquery bits */ // FIXME BLOOMFILTER SIZE
4263                             &dht_get_string_handler, new_ctx);
4264   if (GNUNET_OK !=
4265       GNUNET_CONTAINER_multihashmap_put(info->dht_get_handles, key, get_h,
4266                                         GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
4267   {
4268     GNUNET_break (0);
4269     return GNUNET_YES;
4270   }
4271   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*    End of regex edge iterator\n");
4272   return GNUNET_YES;
4273 }
4274
4275
4276 /**
4277  * Function to process DHT string to regex matching.
4278  * Called on each result obtained for the DHT search.
4279  *
4280  * @param cls closure (search context)
4281  * @param exp when will this value expire
4282  * @param key key of the result
4283  * @param get_path path of the get request (not used)
4284  * @param get_path_length lenght of get_path (not used)
4285  * @param put_path path of the put request (not used)
4286  * @param put_path_length length of the put_path (not used)
4287  * @param type type of the result
4288  * @param size number of bytes in data
4289  * @param data pointer to the result data
4290  */
4291 static void
4292 dht_get_string_accept_handler (void *cls, struct GNUNET_TIME_Absolute exp,
4293                                const struct GNUNET_HashCode * key,
4294                                const struct GNUNET_PeerIdentity *get_path,
4295                                unsigned int get_path_length,
4296                                const struct GNUNET_PeerIdentity *put_path,
4297                                unsigned int put_path_length, enum GNUNET_BLOCK_Type type,
4298                                size_t size, const void *data)
4299 {
4300   const struct MeshRegexAccept *block = data;
4301   struct MeshRegexSearchContext *ctx = cls;
4302   struct MeshRegexSearchInfo *info = ctx->info;
4303   struct MeshPeerPath *p;
4304   struct MeshPeerInfo *peer_info;
4305
4306   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got results from DHT!\n");
4307
4308   peer_info = peer_info_get(&block->id);
4309   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  for %s\n", info->description);
4310
4311   p = path_build_from_dht (get_path, get_path_length, put_path,
4312                            put_path_length);
4313   path_add_to_peers (p, GNUNET_NO);
4314   path_destroy(p);
4315
4316   tunnel_add_peer (info->t, peer_info);
4317   peer_info_connect (peer_info, info->t);
4318
4319   // FIXME REGEX cancel only AFTER successful connection (received ACK)
4320   regex_cancel_search (ctx);
4321
4322   return;
4323 }
4324
4325
4326 /**
4327  * Function to process DHT string to regex matching..
4328  * Called on each result obtained for the DHT search.
4329  *
4330  * @param cls closure (search context)
4331  * @param exp when will this value expire
4332  * @param key key of the result
4333  * @param get_path path of the get request (not used)
4334  * @param get_path_length lenght of get_path (not used)
4335  * @param put_path path of the put request (not used)
4336  * @param put_path_length length of the put_path (not used)
4337  * @param type type of the result
4338  * @param size number of bytes in data
4339  * @param data pointer to the result data
4340  *
4341  * TODO: re-issue the request after certain time? cancel after X results?
4342  */
4343 static void
4344 dht_get_string_handler (void *cls, struct GNUNET_TIME_Absolute exp,
4345                         const struct GNUNET_HashCode * key,
4346                         const struct GNUNET_PeerIdentity *get_path,
4347                         unsigned int get_path_length,
4348                         const struct GNUNET_PeerIdentity *put_path,
4349                         unsigned int put_path_length, enum GNUNET_BLOCK_Type type,
4350                         size_t size, const void *data)
4351 {
4352   const struct MeshRegexBlock *block = data;
4353   struct MeshRegexSearchContext *ctx = cls;
4354   struct MeshRegexSearchInfo *info = ctx->info;
4355   void *copy;
4356   char *proof;
4357   size_t len;
4358
4359   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4360               "DHT GET STRING RETURNED RESULTS\n");
4361   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4362               "  key: %s\n", GNUNET_h2s (key));
4363
4364   copy = GNUNET_malloc (size);
4365   memcpy (copy, data, size);
4366   GNUNET_break (GNUNET_OK ==
4367                 GNUNET_CONTAINER_multihashmap_put(info->dht_get_results, key, copy,
4368                                                   GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
4369   len = ntohl (block->n_proof);
4370   proof = GNUNET_malloc (len + 1);
4371   memcpy (proof, &block[1], len);
4372   proof[len] = '\0';
4373   if (GNUNET_OK != GNUNET_REGEX_check_proof (proof, key))
4374   {
4375     GNUNET_break_op (0);
4376     return;
4377   }
4378   len = strlen (info->description);
4379   if (len == ctx->position) // String processed
4380   {
4381     if (GNUNET_YES == ntohl (block->accepting))
4382     {
4383       struct GNUNET_DHT_GetHandle *get_h;
4384       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found peer by service\n");
4385       get_h = GNUNET_DHT_get_start (dht_handle,    /* handle */
4386                                     GNUNET_BLOCK_TYPE_MESH_REGEX_ACCEPT, /* type */
4387                                     key,     /* key to search */
4388                                     DHT_REPLICATION_LEVEL, /* replication level */
4389                                     GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE |
4390                                     GNUNET_DHT_RO_RECORD_ROUTE,
4391                                     NULL,       /* xquery */ // FIXME BLOOMFILTER
4392                                     0,     /* xquery bits */ // FIXME BLOOMFILTER SIZE
4393                                     &dht_get_string_accept_handler, ctx);
4394       GNUNET_break (GNUNET_OK ==
4395                     GNUNET_CONTAINER_multihashmap_put(info->dht_get_handles,
4396                                                       key,
4397                                                       get_h,
4398                                                       GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
4399     }
4400     else
4401     {
4402       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  block not accepting!\n");
4403       // FIXME REGEX this block not successful, wait for more? start timeout?
4404     }
4405     return;
4406   }
4407   GNUNET_break (GNUNET_OK ==
4408                 GNUNET_MESH_regex_block_iterate (block, size,
4409                                                  &regex_edge_iterator, ctx));
4410   return;
4411 }
4412
4413 /******************************************************************************/
4414 /*********************       MESH LOCAL HANDLES      **************************/
4415 /******************************************************************************/
4416
4417
4418 /**
4419  * Handler for client disconnection
4420  *
4421  * @param cls closure
4422  * @param client identification of the client; NULL
4423  *        for the last call when the server is destroyed
4424  */
4425 static void
4426 handle_local_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
4427 {
4428   struct MeshClient *c;
4429   struct MeshClient *next;
4430   unsigned int i;
4431
4432   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "client disconnected\n");
4433   if (client == NULL)
4434   {
4435     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   (SERVER DOWN)\n");
4436     return;
4437   }
4438   c = clients;
4439   while (NULL != c)
4440   {
4441     if (c->handle != client)
4442     {
4443       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   ... searching\n");
4444       c = c->next;
4445       continue;
4446     }
4447     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "matching client found (%u)\n",
4448                 c->id);
4449     GNUNET_SERVER_client_drop (c->handle);
4450     c->shutting_down = GNUNET_YES;
4451     GNUNET_assert (NULL != c->own_tunnels);
4452     GNUNET_assert (NULL != c->incoming_tunnels);
4453     GNUNET_CONTAINER_multihashmap_iterate (c->own_tunnels,
4454                                            &tunnel_destroy_iterator, c);
4455     GNUNET_CONTAINER_multihashmap_iterate (c->incoming_tunnels,
4456                                            &tunnel_destroy_iterator, c);
4457     GNUNET_CONTAINER_multihashmap_iterate (c->ignore_tunnels,
4458                                            &tunnel_destroy_iterator, c);
4459     GNUNET_CONTAINER_multihashmap_destroy (c->own_tunnels);
4460     GNUNET_CONTAINER_multihashmap_destroy (c->incoming_tunnels);
4461     GNUNET_CONTAINER_multihashmap_destroy (c->ignore_tunnels);
4462
4463     /* deregister clients applications */
4464     if (NULL != c->apps)
4465     {
4466       GNUNET_CONTAINER_multihashmap_iterate (c->apps, &deregister_app, c->apps);
4467       GNUNET_CONTAINER_multihashmap_destroy (c->apps);
4468     }
4469     if (0 == GNUNET_CONTAINER_multihashmap_size (applications) &&
4470         GNUNET_SCHEDULER_NO_TASK != announce_applications_task)
4471     {
4472       GNUNET_SCHEDULER_cancel (announce_applications_task);
4473       announce_applications_task = GNUNET_SCHEDULER_NO_TASK;
4474     }
4475     if (NULL != c->types)
4476       GNUNET_CONTAINER_multihashmap_destroy (c->types);
4477     for (i = 0; i < c->n_regex; i++)
4478     {
4479       GNUNET_free (c->regexes[i]);
4480     }
4481     if (GNUNET_SCHEDULER_NO_TASK != c->regex_announce_task)
4482       GNUNET_SCHEDULER_cancel (c->regex_announce_task);
4483     next = c->next;
4484     GNUNET_CONTAINER_DLL_remove (clients, clients_tail, c);
4485     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  CLIENT FREE at %p\n", c);
4486     GNUNET_free (c);
4487     c = next;
4488   }
4489   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   done!\n");
4490   return;
4491 }
4492
4493
4494 /**
4495  * Handler for new clients
4496  *
4497  * @param cls closure
4498  * @param client identification of the client
4499  * @param message the actual message, which includes messages the client wants
4500  */
4501 static void
4502 handle_local_new_client (void *cls, struct GNUNET_SERVER_Client *client,
4503                          const struct GNUNET_MessageHeader *message)
4504 {
4505   struct GNUNET_MESH_ClientConnect *cc_msg;
4506   struct MeshClient *c;
4507   GNUNET_MESH_ApplicationType *a;
4508   unsigned int size;
4509   uint16_t ntypes;
4510   uint16_t *t;
4511   uint16_t napps;
4512   uint16_t i;
4513
4514   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "new client connected\n");
4515   /* Check data sanity */
4516   size = ntohs (message->size) - sizeof (struct GNUNET_MESH_ClientConnect);
4517   cc_msg = (struct GNUNET_MESH_ClientConnect *) message;
4518   ntypes = ntohs (cc_msg->types);
4519   napps = ntohs (cc_msg->applications);
4520   if (size !=
4521       ntypes * sizeof (uint16_t) + napps * sizeof (GNUNET_MESH_ApplicationType))
4522   {
4523     GNUNET_break (0);
4524     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
4525     return;
4526   }
4527
4528   /* Create new client structure */
4529   c = GNUNET_malloc (sizeof (struct MeshClient));
4530   c->id = next_client_id++;
4531   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  CLIENT NEW %u\n", c->id);
4532   c->handle = client;
4533   GNUNET_SERVER_client_keep (client);
4534   a = (GNUNET_MESH_ApplicationType *) &cc_msg[1];
4535   if (napps > 0)
4536   {
4537     GNUNET_MESH_ApplicationType at;
4538     struct GNUNET_HashCode hc;
4539
4540     c->apps = GNUNET_CONTAINER_multihashmap_create (napps);
4541     for (i = 0; i < napps; i++)
4542     {
4543       at = ntohl (a[i]);
4544       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  app type: %u\n", at);
4545       GNUNET_CRYPTO_hash (&at, sizeof (at), &hc);
4546       /* store in clients hashmap */
4547       GNUNET_CONTAINER_multihashmap_put (c->apps, &hc, (void *) (long) at,
4548                                          GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
4549       /* store in global hashmap, for announcements */
4550       GNUNET_CONTAINER_multihashmap_put (applications, &hc, c,
4551                                          GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
4552     }
4553     if (GNUNET_SCHEDULER_NO_TASK == announce_applications_task)
4554       announce_applications_task =
4555           GNUNET_SCHEDULER_add_now (&announce_applications, NULL);
4556
4557   }
4558   if (ntypes > 0)
4559   {
4560     uint16_t u16;
4561     struct GNUNET_HashCode hc;
4562
4563     t = (uint16_t *) & a[napps];
4564     c->types = GNUNET_CONTAINER_multihashmap_create (ntypes);
4565     for (i = 0; i < ntypes; i++)
4566     {
4567       u16 = ntohs (t[i]);
4568       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  msg type: %u\n", u16);
4569       GNUNET_CRYPTO_hash (&u16, sizeof (u16), &hc);
4570
4571       /* store in clients hashmap */
4572       GNUNET_CONTAINER_multihashmap_put (c->types, &hc, c,
4573                                          GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
4574       /* store in global hashmap */
4575       GNUNET_CONTAINER_multihashmap_put (types, &hc, c,
4576                                          GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
4577     }
4578   }
4579   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4580               " client has %u+%u subscriptions\n", napps, ntypes);
4581
4582   GNUNET_CONTAINER_DLL_insert (clients, clients_tail, c);
4583   c->own_tunnels = GNUNET_CONTAINER_multihashmap_create (32);
4584   c->incoming_tunnels = GNUNET_CONTAINER_multihashmap_create (32);
4585   c->ignore_tunnels = GNUNET_CONTAINER_multihashmap_create (32);
4586   GNUNET_SERVER_notification_context_add (nc, client);
4587
4588   GNUNET_SERVER_receive_done (client, GNUNET_OK);
4589   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "new client processed\n");
4590 }
4591
4592
4593 /**
4594  * Handler for clients announcing available services by a regular expression.
4595  *
4596  * @param cls closure
4597  * @param client identification of the client
4598  * @param message the actual message, which includes messages the client wants
4599  */
4600 static void
4601 handle_local_announce_regex (void *cls, struct GNUNET_SERVER_Client *client,
4602                              const struct GNUNET_MessageHeader *message)
4603 {
4604   struct MeshClient *c;
4605   char *regex;
4606   size_t len;
4607
4608   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "announce regex started\n");
4609
4610   /* Sanity check for client registration */
4611   if (NULL == (c = client_get (client)))
4612   {
4613     GNUNET_break (0);
4614     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
4615     return;
4616   }
4617   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  by client %u\n", c->id);
4618
4619   len = ntohs (message->size) - sizeof(struct GNUNET_MessageHeader);
4620   regex = GNUNET_malloc (len + 1);
4621   memcpy (regex, &message[1], len);
4622   regex[len] = '\0';
4623   GNUNET_array_append (c->regexes, c->n_regex, regex);
4624   if (GNUNET_SCHEDULER_NO_TASK == c->regex_announce_task)
4625   {
4626     c->regex_announce_task = GNUNET_SCHEDULER_add_now(&announce_regex, c);
4627   }
4628   else
4629   {
4630     regex_put(regex);
4631   }
4632   GNUNET_SERVER_receive_done (client, GNUNET_OK);
4633   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "announce regex processed\n");
4634 }
4635
4636
4637 /**
4638  * Handler for requests of new tunnels
4639  *
4640  * @param cls closure
4641  * @param client identification of the client
4642  * @param message the actual message
4643  */
4644 static void
4645 handle_local_tunnel_create (void *cls, struct GNUNET_SERVER_Client *client,
4646                             const struct GNUNET_MessageHeader *message)
4647 {
4648   struct GNUNET_MESH_TunnelMessage *t_msg;
4649   struct MeshTunnel *t;
4650   struct MeshClient *c;
4651
4652   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "new tunnel requested\n");
4653
4654   /* Sanity check for client registration */
4655   if (NULL == (c = client_get (client)))
4656   {
4657     GNUNET_break (0);
4658     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
4659     return;
4660   }
4661   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  by client %u\n", c->id);
4662
4663   /* Message sanity check */
4664   if (sizeof (struct GNUNET_MESH_TunnelMessage) != ntohs (message->size))
4665   {
4666     GNUNET_break (0);
4667     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
4668     return;
4669   }
4670
4671   t_msg = (struct GNUNET_MESH_TunnelMessage *) message;
4672   /* Sanity check for tunnel numbering */
4673   if (0 == (ntohl (t_msg->tunnel_id) & GNUNET_MESH_LOCAL_TUNNEL_ID_CLI))
4674   {
4675     GNUNET_break (0);
4676     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
4677     return;
4678   }
4679   /* Sanity check for duplicate tunnel IDs */
4680   if (NULL != tunnel_get_by_local_id (c, ntohl (t_msg->tunnel_id)))
4681   {
4682     GNUNET_break (0);
4683     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
4684     return;
4685   }
4686
4687   while (NULL != tunnel_get_by_pi (myid, next_tid))
4688     next_tid = (next_tid + 1) & ~GNUNET_MESH_LOCAL_TUNNEL_ID_CLI;
4689   t = tunnel_new (myid, next_tid++, c, ntohl (t_msg->tunnel_id));
4690   next_tid = next_tid & ~GNUNET_MESH_LOCAL_TUNNEL_ID_CLI;
4691   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CREATED TUNNEL %s [%x] (%x)\n",
4692               GNUNET_i2s (&my_full_id), t->id.tid, t->local_tid);
4693   t->peers = GNUNET_CONTAINER_multihashmap_create (32);
4694
4695   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "new tunnel created\n");
4696   GNUNET_SERVER_receive_done (client, GNUNET_OK);
4697   return;
4698 }
4699
4700
4701 /**
4702  * Handler for requests of deleting tunnels
4703  *
4704  * @param cls closure
4705  * @param client identification of the client
4706  * @param message the actual message
4707  */
4708 static void
4709 handle_local_tunnel_destroy (void *cls, struct GNUNET_SERVER_Client *client,
4710                              const struct GNUNET_MessageHeader *message)
4711 {
4712   struct GNUNET_MESH_TunnelMessage *tunnel_msg;
4713   struct MeshClient *c;
4714   struct MeshTunnel *t;
4715   MESH_TunnelNumber tid;
4716
4717   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4718               "Got a DESTROY TUNNEL from client!\n");
4719
4720   /* Sanity check for client registration */
4721   if (NULL == (c = client_get (client)))
4722   {
4723     GNUNET_break (0);
4724     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
4725     return;
4726   }
4727   /* Message sanity check */
4728   if (sizeof (struct GNUNET_MESH_TunnelMessage) != ntohs (message->size))
4729   {
4730     GNUNET_break (0);
4731     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
4732     return;
4733   }
4734   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  by client %u\n", c->id);
4735   tunnel_msg = (struct GNUNET_MESH_TunnelMessage *) message;
4736
4737   /* Retrieve tunnel */
4738   tid = ntohl (tunnel_msg->tunnel_id);
4739   t = tunnel_get_by_local_id(c, tid);
4740   if (NULL == t)
4741   {
4742     GNUNET_break (0);
4743     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "  tunnel %X not found\n", tid);
4744     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
4745     return;
4746   }
4747   if (c != t->owner || tid >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV)
4748   {
4749     client_ignore_tunnel (c, t);
4750 #if 0
4751     // TODO: when to destroy incoming tunnel?
4752     if (t->nclients == 0)
4753     {
4754       GNUNET_assert (GNUNET_YES ==
4755                      GNUNET_CONTAINER_multihashmap_remove (incoming_tunnels,
4756                                                            &hash, t));
4757       GNUNET_assert (GNUNET_YES ==
4758                      GNUNET_CONTAINER_multihashmap_remove (t->peers,
4759                                                            &my_full_id.hashPubKey,
4760                                                            t));
4761     }
4762 #endif
4763     GNUNET_SERVER_receive_done (client, GNUNET_OK);
4764     return;
4765   }
4766   send_client_tunnel_disconnect(t, c);
4767   client_delete_tunnel(c, t);
4768
4769   /* Don't try to ACK the client about the tunnel_destroy multicast packet */
4770   t->owner = NULL;
4771   tunnel_send_destroy (t);
4772   tunnel_destroy (t);
4773   GNUNET_SERVER_receive_done (client, GNUNET_OK);
4774   return;
4775 }
4776
4777
4778 /**
4779  * Handler for connection requests to new peers
4780  *
4781  * @param cls closure
4782  * @param client identification of the client
4783  * @param message the actual message (PeerControl)
4784  */
4785 static void
4786 handle_local_connect_add (void *cls, struct GNUNET_SERVER_Client *client,
4787                           const struct GNUNET_MessageHeader *message)
4788 {
4789   struct GNUNET_MESH_PeerControl *peer_msg;
4790   struct MeshPeerInfo *peer_info;
4791   struct MeshClient *c;
4792   struct MeshTunnel *t;
4793   MESH_TunnelNumber tid;
4794
4795   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got connection request\n");
4796   /* Sanity check for client registration */
4797   if (NULL == (c = client_get (client)))
4798   {
4799     GNUNET_break (0);
4800     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
4801     return;
4802   }
4803
4804   peer_msg = (struct GNUNET_MESH_PeerControl *) message;
4805   /* Sanity check for message size */
4806   if (sizeof (struct GNUNET_MESH_PeerControl) != ntohs (peer_msg->header.size))
4807   {
4808     GNUNET_break (0);
4809     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
4810     return;
4811   }
4812
4813   /* Tunnel exists? */
4814   tid = ntohl (peer_msg->tunnel_id);
4815   t = tunnel_get_by_local_id (c, tid);
4816   if (NULL == t)
4817   {
4818     GNUNET_break (0);
4819     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
4820     return;
4821   }
4822
4823   /* Does client own tunnel? */
4824   if (t->owner->handle != client)
4825   {
4826     GNUNET_break (0);
4827     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
4828     return;
4829   }
4830   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "     for %s\n",
4831               GNUNET_i2s (&peer_msg->peer));
4832   peer_info = peer_info_get (&peer_msg->peer);
4833
4834   tunnel_add_peer (t, peer_info);
4835   peer_info_connect (peer_info, t);
4836
4837   GNUNET_SERVER_receive_done (client, GNUNET_OK);
4838   return;
4839 }
4840
4841
4842 /**
4843  * Handler for disconnection requests of peers in a tunnel
4844  *
4845  * @param cls closure
4846  * @param client identification of the client
4847  * @param message the actual message (PeerControl)
4848  */
4849 static void
4850 handle_local_connect_del (void *cls, struct GNUNET_SERVER_Client *client,
4851                           const struct GNUNET_MessageHeader *message)
4852 {
4853   struct GNUNET_MESH_PeerControl *peer_msg;
4854   struct MeshPeerInfo *peer_info;
4855   struct MeshClient *c;
4856   struct MeshTunnel *t;
4857   MESH_TunnelNumber tid;
4858
4859   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got a PEER DEL request\n");
4860   /* Sanity check for client registration */
4861   if (NULL == (c = client_get (client)))
4862   {
4863     GNUNET_break (0);
4864     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
4865     return;
4866   }
4867   peer_msg = (struct GNUNET_MESH_PeerControl *) message;
4868   /* Sanity check for message size */
4869   if (sizeof (struct GNUNET_MESH_PeerControl) != ntohs (peer_msg->header.size))
4870   {
4871     GNUNET_break (0);
4872     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
4873     return;
4874   }
4875
4876   /* Tunnel exists? */
4877   tid = ntohl (peer_msg->tunnel_id);
4878   t = tunnel_get_by_local_id (c, tid);
4879   if (NULL == t)
4880   {
4881     GNUNET_break (0);
4882     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
4883     return;
4884   }
4885   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  on tunnel %X\n", t->id.tid);
4886
4887   /* Does client own tunnel? */
4888   if (t->owner->handle != client)
4889   {
4890     GNUNET_break (0);
4891     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
4892     return;
4893   }
4894
4895   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  for peer %s\n",
4896               GNUNET_i2s (&peer_msg->peer));
4897   /* Is the peer in the tunnel? */
4898   peer_info =
4899       GNUNET_CONTAINER_multihashmap_get (t->peers, &peer_msg->peer.hashPubKey);
4900   if (NULL == peer_info)
4901   {
4902     GNUNET_break (0);
4903     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
4904     return;
4905   }
4906
4907   /* Ok, delete peer from tunnel */
4908   GNUNET_CONTAINER_multihashmap_remove_all (t->peers,
4909                                             &peer_msg->peer.hashPubKey);
4910
4911   send_destroy_path (t, peer_info->id);
4912   tunnel_delete_peer (t, peer_info->id);
4913   GNUNET_SERVER_receive_done (client, GNUNET_OK);
4914   return;
4915 }
4916
4917 /**
4918  * Handler for blacklist requests of peers in a tunnel
4919  *
4920  * @param cls closure
4921  * @param client identification of the client
4922  * @param message the actual message (PeerControl)
4923  */
4924 static void
4925 handle_local_blacklist (void *cls, struct GNUNET_SERVER_Client *client,
4926                           const struct GNUNET_MessageHeader *message)
4927 {
4928   struct GNUNET_MESH_PeerControl *peer_msg;
4929   struct MeshClient *c;
4930   struct MeshTunnel *t;
4931   MESH_TunnelNumber tid;
4932
4933   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got a PEER BLACKLIST request\n");
4934   /* Sanity check for client registration */
4935   if (NULL == (c = client_get (client)))
4936   {
4937     GNUNET_break (0);
4938     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
4939     return;
4940   }
4941   peer_msg = (struct GNUNET_MESH_PeerControl *) message;
4942
4943   /* Sanity check for message size */
4944   if (sizeof (struct GNUNET_MESH_PeerControl) != ntohs (peer_msg->header.size))
4945   {
4946     GNUNET_break (0);
4947     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
4948     return;
4949   }
4950
4951   /* Tunnel exists? */
4952   tid = ntohl (peer_msg->tunnel_id);
4953   t = tunnel_get_by_local_id (c, tid);
4954   if (NULL == t)
4955   {
4956     GNUNET_break (0);
4957     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
4958     return;
4959   }
4960   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  on tunnel %X\n", t->id.tid);
4961
4962   GNUNET_array_append(t->blacklisted, t->nblacklisted,
4963                       GNUNET_PEER_intern(&peer_msg->peer));
4964 }
4965
4966
4967 /**
4968  * Handler for unblacklist requests of peers in a tunnel
4969  *
4970  * @param cls closure
4971  * @param client identification of the client
4972  * @param message the actual message (PeerControl)
4973  */
4974 static void
4975 handle_local_unblacklist (void *cls, struct GNUNET_SERVER_Client *client,
4976                           const struct GNUNET_MessageHeader *message)
4977 {
4978   struct GNUNET_MESH_PeerControl *peer_msg;
4979   struct MeshClient *c;
4980   struct MeshTunnel *t;
4981   MESH_TunnelNumber tid;
4982   GNUNET_PEER_Id pid;
4983   unsigned int i;
4984
4985   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got a PEER UNBLACKLIST request\n");
4986   /* Sanity check for client registration */
4987   if (NULL == (c = client_get (client)))
4988   {
4989     GNUNET_break (0);
4990     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
4991     return;
4992   }
4993   peer_msg = (struct GNUNET_MESH_PeerControl *) message;
4994
4995   /* Sanity check for message size */
4996   if (sizeof (struct GNUNET_MESH_PeerControl) != ntohs (peer_msg->header.size))
4997   {
4998     GNUNET_break (0);
4999     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5000     return;
5001   }
5002
5003   /* Tunnel exists? */
5004   tid = ntohl (peer_msg->tunnel_id);
5005   t = tunnel_get_by_local_id (c, tid);
5006   if (NULL == t)
5007   {
5008     GNUNET_break (0);
5009     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5010     return;
5011   }
5012   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  on tunnel %X\n", t->id.tid);
5013
5014   /* if peer is not known, complain */
5015   pid = GNUNET_PEER_search (&peer_msg->peer);
5016   if (0 == pid)
5017   {
5018     GNUNET_break (0);
5019     return;
5020   }
5021
5022   /* search and remove from list */
5023   for (i = 0; i < t->nblacklisted; i++)
5024   {
5025     if (t->blacklisted[i] == pid)
5026     {
5027       t->blacklisted[i] = t->blacklisted[t->nblacklisted - 1];
5028       GNUNET_array_grow (t->blacklisted, t->nblacklisted, t->nblacklisted - 1);
5029       return;
5030     }
5031   }
5032
5033   /* if peer hasn't been blacklisted, complain */
5034   GNUNET_break (0);
5035 }
5036
5037
5038 /**
5039  * Handler for connection requests to new peers by type
5040  *
5041  * @param cls closure
5042  * @param client identification of the client
5043  * @param message the actual message (ConnectPeerByType)
5044  */
5045 static void
5046 handle_local_connect_by_type (void *cls, struct GNUNET_SERVER_Client *client,
5047                               const struct GNUNET_MessageHeader *message)
5048 {
5049   struct GNUNET_MESH_ConnectPeerByType *connect_msg;
5050   struct MeshClient *c;
5051   struct MeshTunnel *t;
5052   struct GNUNET_HashCode hash;
5053   MESH_TunnelNumber tid;
5054
5055   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "got connect by type request\n");
5056   /* Sanity check for client registration */
5057   if (NULL == (c = client_get (client)))
5058   {
5059     GNUNET_break (0);
5060     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5061     return;
5062   }
5063
5064   connect_msg = (struct GNUNET_MESH_ConnectPeerByType *) message;
5065   /* Sanity check for message size */
5066   if (sizeof (struct GNUNET_MESH_ConnectPeerByType) !=
5067       ntohs (connect_msg->header.size))
5068   {
5069     GNUNET_break (0);
5070     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5071     return;
5072   }
5073
5074   /* Tunnel exists? */
5075   tid = ntohl (connect_msg->tunnel_id);
5076   t = tunnel_get_by_local_id (c, tid);
5077   if (NULL == t)
5078   {
5079     GNUNET_break (0);
5080     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5081     return;
5082   }
5083
5084   /* Does client own tunnel? */
5085   if (t->owner->handle != client)
5086   {
5087     GNUNET_break (0);
5088     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5089     return;
5090   }
5091
5092   /* Do WE have the service? */
5093   t->type = ntohl (connect_msg->type);
5094   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " type requested: %u\n", t->type);
5095   GNUNET_CRYPTO_hash (&t->type, sizeof (GNUNET_MESH_ApplicationType), &hash);
5096   if (GNUNET_CONTAINER_multihashmap_contains (applications, &hash) ==
5097       GNUNET_YES)
5098   {
5099     /* Yes! Fast forward, add ourselves to the tunnel and send the
5100      * good news to the client, and alert the destination client of
5101      * an incoming tunnel.
5102      *
5103      * FIXME send a path create to self, avoid code duplication
5104      */
5105     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " available locally\n");
5106     GNUNET_CONTAINER_multihashmap_put (t->peers, &my_full_id.hashPubKey,
5107                                        peer_info_get (&my_full_id),
5108                                        GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
5109
5110     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " notifying client\n");
5111     send_client_peer_connected (t, myid);
5112     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " Done\n");
5113     GNUNET_SERVER_receive_done (client, GNUNET_OK);
5114
5115     t->local_tid_dest = next_local_tid++;
5116     GNUNET_CRYPTO_hash (&t->local_tid_dest, sizeof (MESH_TunnelNumber), &hash);
5117     GNUNET_CONTAINER_multihashmap_put (incoming_tunnels, &hash, t,
5118                                        GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
5119
5120     return;
5121   }
5122   /* Ok, lets find a peer offering the service */
5123   if (NULL != t->dht_get_type)
5124   {
5125     GNUNET_DHT_get_stop (t->dht_get_type);
5126   }
5127   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " looking in DHT for %s\n",
5128               GNUNET_h2s (&hash));
5129   t->dht_get_type =
5130       GNUNET_DHT_get_start (dht_handle, 
5131                             GNUNET_BLOCK_TYPE_MESH_PEER_BY_TYPE,
5132                             &hash,
5133                             DHT_REPLICATION_LEVEL,
5134                             GNUNET_DHT_RO_RECORD_ROUTE |
5135                             GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE,
5136                             NULL, 0,
5137                             &dht_get_type_handler, t);
5138
5139   GNUNET_SERVER_receive_done (client, GNUNET_OK);
5140   return;
5141 }
5142
5143
5144 /**
5145  * Handler for connection requests to new peers by a string service description.
5146  *
5147  * @param cls closure
5148  * @param client identification of the client
5149  * @param message the actual message, which includes messages the client wants
5150  */
5151 static void
5152 handle_local_connect_by_string (void *cls, struct GNUNET_SERVER_Client *client,
5153                                 const struct GNUNET_MessageHeader *message)
5154 {
5155   struct GNUNET_MESH_ConnectPeerByString *msg;
5156   struct MeshRegexSearchContext *ctx;
5157   struct MeshRegexSearchInfo *info;
5158   struct GNUNET_DHT_GetHandle *get_h;
5159   struct GNUNET_HashCode key;
5160   struct MeshTunnel *t;
5161   struct MeshClient *c;
5162   MESH_TunnelNumber tid;
5163   const char *string;
5164   size_t size;
5165   size_t len;
5166   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5167               "Connect by string started\n");
5168   msg = (struct GNUNET_MESH_ConnectPeerByString *) message;
5169   size = htons (message->size);
5170
5171   /* Sanity check for client registration */
5172   if (NULL == (c = client_get (client)))
5173   {
5174     GNUNET_break (0);
5175     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5176     return;
5177   }
5178
5179   /* Message size sanity check */
5180   if (sizeof(struct GNUNET_MESH_ConnectPeerByString) >= size)
5181   {
5182       GNUNET_break (0);
5183       GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5184       return;
5185   }
5186
5187   /* Tunnel exists? */
5188   tid = ntohl (msg->tunnel_id);
5189   t = tunnel_get_by_local_id (c, tid);
5190   if (NULL == t)
5191   {
5192     GNUNET_break (0);
5193     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5194     return;
5195   }
5196
5197   /* Does client own tunnel? */
5198   if (t->owner->handle != client)
5199   {
5200     GNUNET_break (0);
5201     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5202     return;
5203   }
5204
5205   /* Only one connect_by_string allowed at the same time! */
5206   /* FIXME: allow more, return handle at api level to cancel, document */
5207   if (NULL != t->regex_ctx)
5208   {
5209     GNUNET_break (0);
5210     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5211     return;
5212   }
5213
5214   /* Find string itself */
5215   len = size - sizeof(struct GNUNET_MESH_ConnectPeerByString);
5216   string = (const char *) &msg[1];
5217
5218   /* Initialize context */
5219   size = GNUNET_REGEX_get_first_key(string, len, &key);
5220   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5221               "  consumed %u bits out of %u\n", size, len);
5222   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5223               "  looking for %s\n", GNUNET_h2s (&key));
5224
5225   info = GNUNET_malloc (sizeof (struct MeshRegexSearchInfo));
5226   info->t = t;
5227   info->description = GNUNET_malloc (len + 1);
5228   memcpy (info->description, string, len);
5229   info->description[len] = '\0';
5230   info->dht_get_handles = GNUNET_CONTAINER_multihashmap_create(32);
5231   info->dht_get_results = GNUNET_CONTAINER_multihashmap_create(32);
5232   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   string: %s\n", info->description);
5233
5234   ctx = GNUNET_malloc (sizeof (struct MeshRegexSearchContext));
5235   ctx->position = size;
5236   ctx->info = info;
5237   t->regex_ctx = ctx;
5238
5239   GNUNET_array_append (info->copies, info->n_copies, ctx);
5240
5241   /* Start search in DHT */
5242   get_h = GNUNET_DHT_get_start (dht_handle,    /* handle */
5243                                 GNUNET_BLOCK_TYPE_MESH_REGEX, /* type */
5244                                 &key,     /* key to search */
5245                                 DHT_REPLICATION_LEVEL, /* replication level */
5246                                 GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE,
5247                                 NULL,       /* xquery */ // FIXME BLOOMFILTER
5248                                 0,     /* xquery bits */ // FIXME BLOOMFILTER SIZE
5249                                 &dht_get_string_handler, ctx);
5250
5251   GNUNET_break (GNUNET_OK ==
5252                 GNUNET_CONTAINER_multihashmap_put(info->dht_get_handles,
5253                                                   &key,
5254                                                   get_h,
5255                                                   GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST));
5256
5257   GNUNET_SERVER_receive_done (client, GNUNET_OK);
5258   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "connect by string processed\n");
5259 }
5260
5261
5262 /**
5263  * Handler for client traffic directed to one peer
5264  *
5265  * @param cls closure
5266  * @param client identification of the client
5267  * @param message the actual message
5268  */
5269 static void
5270 handle_local_unicast (void *cls, struct GNUNET_SERVER_Client *client,
5271                       const struct GNUNET_MessageHeader *message)
5272 {
5273   struct MeshClient *c;
5274   struct MeshTunnel *t;
5275   struct MeshPeerInfo *pi;
5276   struct GNUNET_MESH_Unicast *data_msg;
5277   MESH_TunnelNumber tid;
5278   size_t size;
5279
5280   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5281               "Got a unicast request from a client!\n");
5282
5283   /* Sanity check for client registration */
5284   if (NULL == (c = client_get (client)))
5285   {
5286     GNUNET_break (0);
5287     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5288     return;
5289   }
5290   data_msg = (struct GNUNET_MESH_Unicast *) message;
5291   /* Sanity check for message size */
5292   size = ntohs (message->size);
5293   if (sizeof (struct GNUNET_MESH_Unicast) +
5294       sizeof (struct GNUNET_MessageHeader) > size)
5295   {
5296     GNUNET_break (0);
5297     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5298     return;
5299   }
5300
5301   /* Tunnel exists? */
5302   tid = ntohl (data_msg->tid);
5303   t = tunnel_get_by_local_id (c, tid);
5304   if (NULL == t)
5305   {
5306     GNUNET_break (0);
5307     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5308     return;
5309   }
5310
5311   /*  Is it a local tunnel? Then, does client own the tunnel? */
5312   if (t->owner->handle != client)
5313   {
5314     GNUNET_break (0);
5315     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5316     return;
5317   }
5318
5319   pi = GNUNET_CONTAINER_multihashmap_get (t->peers,
5320                                           &data_msg->destination.hashPubKey);
5321   /* Is the selected peer in the tunnel? */
5322   if (NULL == pi)
5323   {
5324     GNUNET_break (0);
5325     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5326     return;
5327   }
5328
5329   /* Ok, everything is correct, send the message
5330    * (pretend we got it from a mesh peer)
5331    */
5332   {
5333     char buf[ntohs (message->size)] GNUNET_ALIGN;
5334     struct GNUNET_MESH_Unicast *copy;
5335
5336     /* Work around const limitation */
5337     copy = (struct GNUNET_MESH_Unicast *) buf;
5338     memcpy (buf, data_msg, size);
5339     copy->oid = my_full_id;
5340     copy->tid = htonl (t->id.tid);
5341     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5342                 "  calling generic handler...\n");
5343     handle_mesh_data_unicast (NULL, &my_full_id, &copy->header, NULL, 0);
5344   }
5345   GNUNET_SERVER_receive_done (client, GNUNET_OK);
5346   return;
5347 }
5348
5349
5350 /**
5351  * Handler for client traffic directed to the origin
5352  *
5353  * @param cls closure
5354  * @param client identification of the client
5355  * @param message the actual message
5356  */
5357 static void
5358 handle_local_to_origin (void *cls, struct GNUNET_SERVER_Client *client,
5359                         const struct GNUNET_MessageHeader *message)
5360 {
5361   struct GNUNET_MESH_ToOrigin *data_msg;
5362   struct GNUNET_PeerIdentity id;
5363   struct MeshClient *c;
5364   struct MeshTunnel *t;
5365   MESH_TunnelNumber tid;
5366   size_t size;
5367
5368   /* Sanity check for client registration */
5369   if (NULL == (c = client_get (client)))
5370   {
5371     GNUNET_break (0);
5372     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5373     return;
5374   }
5375   data_msg = (struct GNUNET_MESH_ToOrigin *) message;
5376   /* Sanity check for message size */
5377   size = ntohs (message->size);
5378   if (sizeof (struct GNUNET_MESH_ToOrigin) +
5379       sizeof (struct GNUNET_MessageHeader) > size)
5380   {
5381     GNUNET_break (0);
5382     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5383     return;
5384   }
5385
5386   /* Tunnel exists? */
5387   tid = ntohl (data_msg->tid);
5388   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5389               "Got a ToOrigin request from a client! Tunnel %X\n", tid);
5390   if (tid < GNUNET_MESH_LOCAL_TUNNEL_ID_SERV)
5391   {
5392     GNUNET_break (0);
5393     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5394     return;
5395   }
5396   t = tunnel_get_by_local_id (c, tid);
5397   if (NULL == t)
5398   {
5399     GNUNET_break (0);
5400     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5401     return;
5402   }
5403
5404   /*  It should be sent by someone who has this as incoming tunnel. */
5405   if (-1 == client_knows_tunnel (c, t))
5406   {
5407     GNUNET_break (0);
5408     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5409     return;
5410   }
5411   GNUNET_PEER_resolve (t->id.oid, &id);
5412
5413   /* Ok, everything is correct, send the message
5414    * (pretend we got it from a mesh peer)
5415    */
5416   {
5417     char buf[ntohs (message->size)] GNUNET_ALIGN;
5418     struct GNUNET_MESH_ToOrigin *copy;
5419
5420     /* Work around const limitation */
5421     copy = (struct GNUNET_MESH_ToOrigin *) buf;
5422     memcpy (buf, data_msg, size);
5423     copy->oid = id;
5424     copy->tid = htonl (t->id.tid);
5425     copy->sender = my_full_id;
5426     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5427                 "  calling generic handler...\n");
5428     handle_mesh_data_to_orig (NULL, &my_full_id, &copy->header, NULL, 0);
5429   }
5430   GNUNET_SERVER_receive_done (client, GNUNET_OK);
5431   return;
5432 }
5433
5434
5435 /**
5436  * Handler for client traffic directed to all peers in a tunnel
5437  *
5438  * @param cls closure
5439  * @param client identification of the client
5440  * @param message the actual message
5441  */
5442 static void
5443 handle_local_multicast (void *cls, struct GNUNET_SERVER_Client *client,
5444                         const struct GNUNET_MessageHeader *message)
5445 {
5446   struct MeshClient *c;
5447   struct MeshTunnel *t;
5448   struct GNUNET_MESH_Multicast *data_msg;
5449   MESH_TunnelNumber tid;
5450
5451   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5452               "Got a multicast request from a client!\n");
5453
5454   /* Sanity check for client registration */
5455   if (NULL == (c = client_get (client)))
5456   {
5457     GNUNET_break (0);
5458     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5459     return;
5460   }
5461   data_msg = (struct GNUNET_MESH_Multicast *) message;
5462   /* Sanity check for message size */
5463   if (sizeof (struct GNUNET_MESH_Multicast) +
5464       sizeof (struct GNUNET_MessageHeader) > ntohs (data_msg->header.size))
5465   {
5466     GNUNET_break (0);
5467     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5468     return;
5469   }
5470
5471   /* Tunnel exists? */
5472   tid = ntohl (data_msg->tid);
5473   t = tunnel_get_by_local_id (c, tid);
5474   if (NULL == t)
5475   {
5476     GNUNET_break (0);
5477     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5478     return;
5479   }
5480
5481   /* Does client own tunnel? */
5482   if (t->owner->handle != client)
5483   {
5484     GNUNET_break (0);
5485     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5486     return;
5487   }
5488
5489   {
5490     char buf[ntohs (message->size)] GNUNET_ALIGN;
5491     struct GNUNET_MESH_Multicast *copy;
5492
5493     copy = (struct GNUNET_MESH_Multicast *) buf;
5494     memcpy (buf, message, ntohs (message->size));
5495     copy->oid = my_full_id;
5496     copy->tid = htonl (t->id.tid);
5497     copy->ttl = htonl (DEFAULT_TTL);
5498     copy->mid = htonl (t->mid + 1);
5499     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5500                 "  calling generic handler...\n");
5501     handle_mesh_data_multicast (client, &my_full_id, &copy->header, NULL, 0);
5502   }
5503
5504   /* receive done gets called when last copy is sent to a neighbor */
5505   return;
5506 }
5507
5508 /**
5509  * Functions to handle messages from clients
5510  */
5511 static struct GNUNET_SERVER_MessageHandler client_handlers[] = {
5512   {&handle_local_new_client, NULL,
5513    GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT, 0},
5514   {&handle_local_announce_regex, NULL,
5515    GNUNET_MESSAGE_TYPE_MESH_LOCAL_ANNOUNCE_REGEX, 0},
5516   {&handle_local_tunnel_create, NULL,
5517    GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_CREATE,
5518    sizeof (struct GNUNET_MESH_TunnelMessage)},
5519   {&handle_local_tunnel_destroy, NULL,
5520    GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_DESTROY,
5521    sizeof (struct GNUNET_MESH_TunnelMessage)},
5522   {&handle_local_connect_add, NULL,
5523    GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_ADD,
5524    sizeof (struct GNUNET_MESH_PeerControl)},
5525   {&handle_local_connect_del, NULL,
5526    GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_DEL,
5527    sizeof (struct GNUNET_MESH_PeerControl)},
5528   {&handle_local_blacklist, NULL,
5529    GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_BLACKLIST,
5530    sizeof (struct GNUNET_MESH_PeerControl)},
5531   {&handle_local_unblacklist, NULL,
5532    GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_UNBLACKLIST,
5533    sizeof (struct GNUNET_MESH_PeerControl)},
5534   {&handle_local_connect_by_type, NULL,
5535    GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_ADD_BY_TYPE,
5536    sizeof (struct GNUNET_MESH_ConnectPeerByType)},
5537   {&handle_local_connect_by_string, NULL,
5538    GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_ADD_BY_STRING, 0},
5539   {&handle_local_unicast, NULL,
5540    GNUNET_MESSAGE_TYPE_MESH_UNICAST, 0},
5541   {&handle_local_to_origin, NULL,
5542    GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN, 0},
5543   {&handle_local_multicast, NULL,
5544    GNUNET_MESSAGE_TYPE_MESH_MULTICAST, 0},
5545   {NULL, NULL, 0, 0}
5546 };
5547
5548
5549 /**
5550  * To be called on core init/fail.
5551  *
5552  * @param cls service closure
5553  * @param server handle to the server for this service
5554  * @param identity the public identity of this peer
5555  */
5556 static void
5557 core_init (void *cls, struct GNUNET_CORE_Handle *server,
5558            const struct GNUNET_PeerIdentity *identity)
5559 {
5560   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Core init\n");
5561   core_handle = server;
5562   if (0 != memcmp (identity, &my_full_id, sizeof (my_full_id)) ||
5563       NULL == server)
5564   {
5565     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Wrong CORE service\n"));
5566     GNUNET_SCHEDULER_shutdown ();
5567   }
5568   return;
5569 }
5570
5571 /**
5572  * Method called whenever a given peer connects.
5573  *
5574  * @param cls closure
5575  * @param peer peer identity this notification is about
5576  * @param atsi performance data for the connection
5577  * @param atsi_count number of records in 'atsi'
5578  */
5579 static void
5580 core_connect (void *cls, const struct GNUNET_PeerIdentity *peer,
5581               const struct GNUNET_ATS_Information *atsi,
5582               unsigned int atsi_count)
5583 {
5584   struct MeshPeerInfo *peer_info;
5585   struct MeshPeerPath *path;
5586
5587   DEBUG_CONN ("Peer connected\n");
5588   DEBUG_CONN ("     %s\n", GNUNET_i2s (&my_full_id));
5589   peer_info = peer_info_get (peer);
5590   if (myid == peer_info->id)
5591   {
5592     DEBUG_CONN ("     (self)\n");
5593     return;
5594   }
5595   else
5596   {
5597     DEBUG_CONN ("     %s\n", GNUNET_i2s (peer));
5598   }
5599   path = path_new (2);
5600   path->peers[0] = myid;
5601   path->peers[1] = peer_info->id;
5602   GNUNET_PEER_change_rc (myid, 1);
5603   GNUNET_PEER_change_rc (peer_info->id, 1);
5604   peer_info_add_path (peer_info, path, GNUNET_YES);
5605   return;
5606 }
5607
5608 /**
5609  * Method called whenever a peer disconnects.
5610  *
5611  * @param cls closure
5612  * @param peer peer identity this notification is about
5613  */
5614 static void
5615 core_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer)
5616 {
5617   struct MeshPeerInfo *pi;
5618   struct MeshPeerQueue *q;
5619   struct MeshPeerQueue *n;
5620
5621   DEBUG_CONN ("Peer disconnected\n");
5622   pi = GNUNET_CONTAINER_multihashmap_get (peers, &peer->hashPubKey);
5623   if (NULL == pi)
5624   {
5625     GNUNET_break (0);
5626     return;
5627   }
5628   q = pi->queue_head;
5629   while (NULL != q)
5630   {
5631       n = q->next;
5632       if (q->peer == pi)
5633       {
5634         /* try to reroute this traffic instead */
5635         queue_destroy(q, GNUNET_YES);
5636       }
5637       q = n;
5638   }
5639   peer_info_remove_path (pi, pi->id, myid);
5640   if (myid == pi->id)
5641   {
5642     DEBUG_CONN ("     (self)\n");
5643   }
5644   return;
5645 }
5646
5647
5648 /******************************************************************************/
5649 /************************      MAIN FUNCTIONS      ****************************/
5650 /******************************************************************************/
5651
5652 /**
5653  * Iterator over tunnel hash map entries to destroy the tunnel during shutdown.
5654  *
5655  * @param cls closure
5656  * @param key current key code
5657  * @param value value in the hash map
5658  * @return GNUNET_YES if we should continue to iterate,
5659  *         GNUNET_NO if not.
5660  */
5661 static int
5662 shutdown_tunnel (void *cls, const struct GNUNET_HashCode * key, void *value)
5663 {
5664   struct MeshTunnel *t = value;
5665
5666   tunnel_destroy (t);
5667   return GNUNET_YES;
5668 }
5669
5670 /**
5671  * Iterator over peer hash map entries to destroy the tunnel during shutdown.
5672  *
5673  * @param cls closure
5674  * @param key current key code
5675  * @param value value in the hash map
5676  * @return GNUNET_YES if we should continue to iterate,
5677  *         GNUNET_NO if not.
5678  */
5679 static int
5680 shutdown_peer (void *cls, const struct GNUNET_HashCode * key, void *value)
5681 {
5682   struct MeshPeerInfo *p = value;
5683   struct MeshPeerQueue *q;
5684   struct MeshPeerQueue *n;
5685
5686   q = p->queue_head;
5687   while (NULL != q)
5688   {
5689       n = q->next;
5690       if (q->peer == p)
5691       {
5692         queue_destroy(q, GNUNET_YES);
5693       }
5694       q = n;
5695   }
5696   peer_info_destroy (p);
5697   return GNUNET_YES;
5698 }
5699
5700 /**
5701  * Task run during shutdown.
5702  *
5703  * @param cls unused
5704  * @param tc unused
5705  */
5706 static void
5707 shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
5708 {
5709   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "shutting down\n");
5710
5711   if (core_handle != NULL)
5712   {
5713     GNUNET_CORE_disconnect (core_handle);
5714     core_handle = NULL;
5715   }
5716   GNUNET_CONTAINER_multihashmap_iterate (tunnels, &shutdown_tunnel, NULL);
5717   GNUNET_CONTAINER_multihashmap_iterate (peers, &shutdown_peer, NULL);
5718   if (dht_handle != NULL)
5719   {
5720     GNUNET_DHT_disconnect (dht_handle);
5721     dht_handle = NULL;
5722   }
5723   if (nc != NULL)
5724   {
5725     GNUNET_SERVER_notification_context_destroy (nc);
5726     nc = NULL;
5727   }
5728   if (GNUNET_SCHEDULER_NO_TASK != announce_id_task)
5729   {
5730     GNUNET_SCHEDULER_cancel (announce_id_task);
5731     announce_id_task = GNUNET_SCHEDULER_NO_TASK;
5732   }
5733   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "shut down\n");
5734 }
5735
5736 /**
5737  * Process mesh requests.
5738  *
5739  * @param cls closure
5740  * @param server the initialized server
5741  * @param c configuration to use
5742  */
5743 static void
5744 run (void *cls, struct GNUNET_SERVER_Handle *server,
5745      const struct GNUNET_CONFIGURATION_Handle *c)
5746 {
5747   struct MeshPeerInfo *peer;
5748   struct MeshPeerPath *p;
5749   char *keyfile;
5750
5751   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "starting to run\n");
5752   server_handle = server;
5753   core_handle = GNUNET_CORE_connect (c, /* Main configuration */
5754                                      NULL,      /* Closure passed to MESH functions */
5755                                      &core_init,        /* Call core_init once connected */
5756                                      &core_connect,     /* Handle connects */
5757                                      &core_disconnect,  /* remove peers on disconnects */
5758                                      NULL,      /* Don't notify about all incoming messages */
5759                                      GNUNET_NO, /* For header only in notification */
5760                                      NULL,      /* Don't notify about all outbound messages */
5761                                      GNUNET_NO, /* For header-only out notification */
5762                                      core_handlers);    /* Register these handlers */
5763
5764   if (core_handle == NULL)
5765   {
5766     GNUNET_break (0);
5767     GNUNET_SCHEDULER_shutdown ();
5768     return;
5769   }
5770
5771   if (GNUNET_OK !=
5772       GNUNET_CONFIGURATION_get_value_filename (c, "GNUNETD", "HOSTKEY",
5773                                                &keyfile))
5774   {
5775     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
5776                 _
5777                 ("Mesh service is lacking key configuration settings.  Exiting.\n"));
5778     GNUNET_SCHEDULER_shutdown ();
5779     return;
5780   }
5781   my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
5782   GNUNET_free (keyfile);
5783   if (my_private_key == NULL)
5784   {
5785     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
5786                 _("Mesh service could not access hostkey.  Exiting.\n"));
5787     GNUNET_SCHEDULER_shutdown ();
5788     return;
5789   }
5790   GNUNET_CRYPTO_rsa_key_get_public (my_private_key, &my_public_key);
5791   GNUNET_CRYPTO_hash (&my_public_key, sizeof (my_public_key),
5792                       &my_full_id.hashPubKey);
5793   myid = GNUNET_PEER_intern (&my_full_id);
5794
5795 //   transport_handle = GNUNET_TRANSPORT_connect(c,
5796 //                                               &my_full_id,
5797 //                                               NULL,
5798 //                                               NULL,
5799 //                                               NULL,
5800 //                                               NULL);
5801
5802   dht_handle = GNUNET_DHT_connect (c, 64);
5803   if (dht_handle == NULL)
5804   {
5805     GNUNET_break (0);
5806   }
5807
5808   next_tid = 0;
5809   next_local_tid = GNUNET_MESH_LOCAL_TUNNEL_ID_SERV;
5810
5811   tunnels = GNUNET_CONTAINER_multihashmap_create (32);
5812   incoming_tunnels = GNUNET_CONTAINER_multihashmap_create (32);
5813   peers = GNUNET_CONTAINER_multihashmap_create (32);
5814   applications = GNUNET_CONTAINER_multihashmap_create (32);
5815   types = GNUNET_CONTAINER_multihashmap_create (32);
5816
5817   GNUNET_SERVER_add_handlers (server_handle, client_handlers);
5818   nc = GNUNET_SERVER_notification_context_create (server_handle,
5819                                                   LOCAL_QUEUE_SIZE);
5820   GNUNET_SERVER_disconnect_notify (server_handle,
5821                                    &handle_local_client_disconnect, NULL);
5822
5823
5824   clients = NULL;
5825   clients_tail = NULL;
5826   next_client_id = 0;
5827
5828   announce_applications_task = GNUNET_SCHEDULER_NO_TASK;
5829   announce_id_task = GNUNET_SCHEDULER_add_now (&announce_id, cls);
5830
5831   /* Create a peer_info for the local peer */
5832   peer = peer_info_get (&my_full_id);
5833   p = path_new (1);
5834   p->peers[0] = myid;
5835   GNUNET_PEER_change_rc (myid, 1);
5836   peer_info_add_path (peer, p, GNUNET_YES);
5837
5838   /* Scheduled the task to clean up when shutdown is called */
5839   GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task,
5840                                 NULL);
5841
5842   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "end of run()\n");
5843 }
5844
5845 /**
5846  * The main function for the mesh service.
5847  *
5848  * @param argc number of arguments from the command line
5849  * @param argv command line arguments
5850  * @return 0 ok, 1 on error
5851  */
5852 int
5853 main (int argc, char *const *argv)
5854 {
5855   int ret;
5856
5857   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "main()\n");
5858   ret =
5859       (GNUNET_OK ==
5860        GNUNET_SERVICE_run (argc, argv, "mesh", GNUNET_SERVICE_OPTION_NONE, &run,
5861                            NULL)) ? 0 : 1;
5862   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "main() END\n");
5863
5864   return ret;
5865 }