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