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