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