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