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