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