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