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