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