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