- feedback about abort cause
[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.peer = NULL;
3412   fcinfo.fwd_ack = t->fwd_pid + 1;
3413   fcinfo.bck_ack = t->nobuffer ? 1 : INITIAL_WINDOW_SIZE - 1;
3414   fcinfo.fwd_pid = t->fwd_pid;
3415   fcinfo.bck_pid = (uint32_t) -1; // Expected next: 0
3416   fcinfo.fc_poll = GNUNET_SCHEDULER_NO_TASK;
3417   fcinfo.send_buffer = NULL;
3418   fcinfo.send_buffer_n = 0;
3419   fcinfo.send_buffer_start = 0;
3420   fcinfo.skip = t->fwd_pid;
3421   // FIXME fc buffering is done by context_notify. Confirm this is OK.
3422
3423   t->nclients--;
3424   GNUNET_array_append (t->clients_fc, t->nclients, fcinfo);
3425 }
3426
3427
3428 /**
3429  * Notifies a tunnel that a connection has broken that affects at least
3430  * some of its peers. Sends a notification towards the root of the tree.
3431  * In case the peer is the owner of the tree, notifies the client that owns
3432  * the tunnel and tries to reconnect.
3433  *
3434  * @param t Tunnel affected.
3435  * @param p1 Peer that got disconnected from p2.
3436  * @param p2 Peer that got disconnected from p1.
3437  *
3438  * @return Short ID of the peer disconnected (either p1 or p2).
3439  *         0 if the tunnel remained unaffected.
3440  */
3441 static GNUNET_PEER_Id
3442 tunnel_notify_connection_broken (struct MeshTunnel *t, GNUNET_PEER_Id p1,
3443                                  GNUNET_PEER_Id p2)
3444 {
3445   GNUNET_PEER_Id pid;
3446
3447   pid =
3448       tree_notify_connection_broken (t->tree, p1, p2,
3449                                      &tunnel_notify_client_peer_disconnected,
3450                                      t);
3451   if (myid != p1 && myid != p2)
3452   {
3453     return pid;
3454   }
3455   if (pid != myid)
3456   {
3457     if (tree_get_predecessor (t->tree) != 0)
3458     {
3459       /* We are the peer still connected, notify owner of the disconnection. */
3460       struct GNUNET_MESH_PathBroken msg;
3461       struct GNUNET_PeerIdentity neighbor;
3462
3463       msg.header.size = htons (sizeof (msg));
3464       msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_PATH_BROKEN);
3465       GNUNET_PEER_resolve (t->id.oid, &msg.oid);
3466       msg.tid = htonl (t->id.tid);
3467       msg.peer1 = my_full_id;
3468       GNUNET_PEER_resolve (pid, &msg.peer2);
3469       GNUNET_PEER_resolve (tree_get_predecessor (t->tree), &neighbor);
3470       send_prebuilt_message (&msg.header, &neighbor, t);
3471     }
3472   }
3473   return pid;
3474 }
3475
3476
3477 /**
3478  * Send a multicast packet to a neighbor.
3479  *
3480  * @param cls Closure (Info about the multicast packet)
3481  * @param neighbor_id Short ID of the neighbor to send the packet to.
3482  */
3483 static void
3484 tunnel_send_multicast_iterator (void *cls, GNUNET_PEER_Id neighbor_id)
3485 {
3486   struct MeshData *mdata = cls;
3487   struct MeshTransmissionDescriptor *info;
3488   struct GNUNET_PeerIdentity neighbor;
3489   struct GNUNET_MessageHeader *msg;
3490
3491   info = GNUNET_malloc (sizeof (struct MeshTransmissionDescriptor));
3492
3493   info->mesh_data = mdata;
3494   (mdata->reference_counter) ++;
3495   info->destination = neighbor_id;
3496   GNUNET_PEER_resolve (neighbor_id, &neighbor);
3497   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   sending to %s...\n",
3498               GNUNET_i2s (&neighbor));
3499   info->peer = peer_info_get (&neighbor);
3500   GNUNET_assert (NULL != info->peer);
3501   msg = (struct GNUNET_MessageHeader *) mdata->data;
3502   queue_add(info,
3503             ntohs (msg->type),
3504             info->mesh_data->data_len,
3505             info->peer,
3506             mdata->t);
3507 }
3508
3509
3510 /**
3511  * Queue a message in a tunnel in multicast, sending a copy to each child node
3512  * down the local one in the tunnel tree.
3513  *
3514  * @param t Tunnel in which to send the data.
3515  * @param msg Message to be sent.
3516  */
3517 static void
3518 tunnel_send_multicast (struct MeshTunnel *t,
3519                        const struct GNUNET_MessageHeader *msg)
3520 {
3521   struct MeshData *mdata;
3522
3523   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3524               " sending a multicast packet...\n");
3525
3526   mdata = GNUNET_malloc (sizeof (struct MeshData));
3527   mdata->data_len = ntohs (msg->size);
3528   mdata->t = t;
3529   mdata->data = GNUNET_malloc (mdata->data_len);
3530   memcpy (mdata->data, msg, mdata->data_len);
3531   if (ntohs (msg->type) == GNUNET_MESSAGE_TYPE_MESH_MULTICAST)
3532   {
3533     struct GNUNET_MESH_Multicast *mcast;
3534
3535     mcast = (struct GNUNET_MESH_Multicast *) mdata->data;
3536     if (t->fwd_queue_n >= t->fwd_queue_max)
3537     {
3538       GNUNET_break (0);
3539       GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "  queue full!\n");
3540       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3541                   "  message from %s!\n",
3542                   GNUNET_i2s(&mcast->oid));
3543       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3544                   "  message at %s!\n",
3545                   GNUNET_i2s(&my_full_id));
3546       GNUNET_free (mdata->data);
3547       GNUNET_free (mdata);
3548       return;
3549     }
3550     t->fwd_queue_n++;
3551     mcast->ttl = htonl (ntohl (mcast->ttl) - 1);
3552     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  data packet, ttl: %u\n",
3553                 ntohl (mcast->ttl));
3554   }
3555   else
3556   {
3557     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  not a data packet, no ttl\n");
3558   }
3559
3560   tree_iterate_children (t->tree, &tunnel_send_multicast_iterator, mdata);
3561   if (mdata->reference_counter == 0)
3562   {
3563     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3564               "  no one to send data to\n");
3565     GNUNET_free (mdata->data);
3566     GNUNET_free (mdata);
3567     t->fwd_queue_n--;
3568   }
3569   else
3570   {
3571     mdata->total_out = mdata->reference_counter;
3572   }
3573   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3574               " sending a multicast packet done\n");
3575   return;
3576 }
3577
3578
3579 /**
3580  * Increase the SKIP value of all peers that
3581  * have not received a unicast message.
3582  *
3583  * @param cls Closure (ID of the peer that HAS received the message).
3584  * @param key ID of the neighbor.
3585  * @param value FLow control information about the neighbor.
3586  *
3587  * @return GNUNET_YES to keep iterating.
3588  */
3589 static int
3590 tunnel_add_skip (void *cls,
3591                  const struct GNUNET_HashCode * key,
3592                  void *value)
3593 {
3594   struct GNUNET_PeerIdentity *neighbor = cls;
3595   struct MeshTunnelFlowControlInfo *fcinfo = value;
3596
3597   /* TODO compare only pointers? key == neighbor? */
3598   if (0 == memcmp (&neighbor->hashPubKey, key, sizeof (struct GNUNET_HashCode)))
3599   {
3600     return GNUNET_YES;
3601   }
3602   fcinfo->skip++;
3603   return GNUNET_YES;
3604 }
3605
3606
3607 /**
3608  * @brief Get neighbor's Flow Control information.
3609  *
3610  * Retrieves the MeshTunnelFlowControlInfo containing Flow Control data about
3611  * a direct descendant of the local node in a certain tunnel.
3612  * If the info is not yet there (recently created path), creates the data struct
3613  * and inserts it into the tunnel info, initialized to the current tunnel ACK
3614  * values.
3615  *
3616  * @param t Tunnel related.
3617  * @param peer Neighbor whose Flow Control info is needed.
3618  *
3619  * @return Neighbor's Flow Control info.
3620  */
3621 static struct MeshTunnelFlowControlInfo *
3622 tunnel_get_neighbor_fc (struct MeshTunnel *t,
3623                         const struct GNUNET_PeerIdentity *peer)
3624 {
3625   struct MeshTunnelFlowControlInfo *fcinfo;
3626
3627   if (NULL == t->children_fc)
3628     return NULL;
3629
3630   fcinfo = GNUNET_CONTAINER_multihashmap_get (t->children_fc,
3631                                              &peer->hashPubKey);
3632   if (NULL == fcinfo)
3633   {
3634     uint32_t delta;
3635
3636     fcinfo = GNUNET_malloc (sizeof (struct MeshTunnelFlowControlInfo));
3637     fcinfo->peer = peer_info_get(peer);
3638     fcinfo->skip = t->fwd_pid;
3639     fcinfo->t = t;
3640
3641     delta = t->nobuffer ? 1 : INITIAL_WINDOW_SIZE;
3642     fcinfo->fwd_ack = t->fwd_pid + delta;
3643     fcinfo->bck_ack = delta;
3644     fcinfo->bck_pid = -1;
3645
3646     fcinfo->send_buffer =
3647         GNUNET_malloc (sizeof(struct MeshPeerQueue *) * t->fwd_queue_max);
3648
3649     GNUNET_assert (GNUNET_OK ==
3650       GNUNET_CONTAINER_multihashmap_put (t->children_fc,
3651                                          &peer->hashPubKey,
3652                                          fcinfo,
3653                                          GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST));
3654   }
3655   return fcinfo;
3656 }
3657
3658
3659 /**
3660  * Get the Flow Control info of a client.
3661  * 
3662  * @param t Tunnel on which to look.
3663  * @param c Client whose ACK to get.
3664  * 
3665  * @return ACK value.
3666  */
3667 static struct MeshTunnelFlowControlInfo *
3668 tunnel_get_client_fc (struct MeshTunnel *t,
3669                       struct MeshClient *c)
3670 {
3671   unsigned int i;
3672
3673   for (i = 0; i < t->nclients; i++)
3674   {
3675     if (t->clients[i] != c)
3676       continue;
3677     return &t->clients_fc[i];
3678   }
3679   GNUNET_assert (0);
3680   return NULL; // won't get here. Just to avoid compiler / coverity complaints.
3681 }
3682
3683
3684 /**
3685  * Iterator to get the appropiate ACK value from all children nodes.
3686  *
3687  * @param cls Closue (tunnel).
3688  * @param id Id of the child node.
3689  */
3690 static void
3691 tunnel_get_child_fwd_ack (void *cls,
3692                           GNUNET_PEER_Id id)
3693 {
3694   struct GNUNET_PeerIdentity peer_id;
3695   struct MeshTunnelFlowControlInfo *fcinfo;
3696   struct MeshTunnelChildIteratorContext *ctx = cls;
3697   struct MeshTunnel *t = ctx->t;
3698   uint32_t ack;
3699
3700   GNUNET_PEER_resolve (id, &peer_id);
3701   fcinfo = tunnel_get_neighbor_fc (t, &peer_id);
3702   ack = fcinfo->fwd_ack;
3703
3704   ctx->nchildren++;
3705   if (GNUNET_NO == ctx->init)
3706   {
3707     ctx->max_child_ack = ack;
3708     ctx->init = GNUNET_YES;
3709   }
3710
3711   if (GNUNET_YES == t->speed_min)
3712   {
3713     ctx->max_child_ack = ctx->max_child_ack > ack ? ack : ctx->max_child_ack;
3714   }
3715   else
3716   {
3717     ctx->max_child_ack = ctx->max_child_ack > ack ? ctx->max_child_ack : ack;
3718   }
3719 }
3720
3721
3722 /**
3723  * Get the maximum PID allowed to transmit to any
3724  * tunnel child of the local peer, depending on the tunnel
3725  * buffering/speed settings.
3726  *
3727  * @param t Tunnel.
3728  *
3729  * @return Maximum PID allowed (uint32 MAX), -1LL if node has no children.
3730  */
3731 static int64_t
3732 tunnel_get_children_fwd_ack (struct MeshTunnel *t)
3733 {
3734   struct MeshTunnelChildIteratorContext ctx;
3735   ctx.t = t;
3736   ctx.max_child_ack = 0;
3737   ctx.nchildren = 0;
3738   ctx.init = GNUNET_NO;
3739   tree_iterate_children (t->tree, tunnel_get_child_fwd_ack, &ctx);
3740
3741   if (0 == ctx.nchildren)
3742   {
3743     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3744             "  tunnel has no children, no FWD ACK\n");
3745     return -1LL;
3746   }
3747
3748   if (GNUNET_YES == t->nobuffer && GMC_is_pid_bigger(ctx.max_child_ack, t->fwd_pid))
3749     ctx.max_child_ack = t->fwd_pid + 1; // Might overflow, it's ok.
3750
3751   return (int64_t) ctx.max_child_ack;
3752 }
3753
3754
3755 /**
3756  * Set the FWD ACK value of a client in a particular tunnel.
3757  * 
3758  * @param t Tunnel affected.
3759  * @param c Client whose ACK to set.
3760  * @param ack ACK value.
3761  */
3762 static void
3763 tunnel_set_client_fwd_ack (struct MeshTunnel *t,
3764                            struct MeshClient *c, 
3765                            uint32_t ack)
3766 {
3767   unsigned int i;
3768
3769   for (i = 0; i < t->nclients; i++)
3770   {
3771     if (t->clients[i] != c)
3772       continue;
3773     t->clients_fc[i].fwd_ack = ack;
3774     return;
3775   }
3776   GNUNET_break (0);
3777 }
3778
3779
3780 /**
3781  * Get the highest ACK value of all clients in a particular tunnel,
3782  * according to the buffering/speed settings.
3783  * 
3784  * @param t Tunnel on which to look.
3785  * 
3786  * @return Corresponding ACK value (max uint32_t).
3787  *         If no clients are suscribed, -1LL.
3788  */
3789 static int64_t
3790 tunnel_get_clients_fwd_ack (struct MeshTunnel *t)
3791 {
3792   unsigned int i;
3793   int64_t ack;
3794
3795   if (0 == t->nclients)
3796   {
3797     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3798                 "  tunnel has no clients, no FWD ACK\n");
3799     return -1LL;
3800   }
3801
3802   for (ack = -1LL, i = 0; i < t->nclients; i++)
3803   {
3804     if (-1LL == ack ||
3805         (GNUNET_YES == t->speed_min &&
3806          GNUNET_YES == GMC_is_pid_bigger (ack, t->clients_fc[i].fwd_ack)) ||
3807         (GNUNET_NO == t->speed_min &&
3808          GNUNET_YES == GMC_is_pid_bigger (t->clients_fc[i].fwd_ack, ack)))
3809     {
3810       ack = t->clients_fc[i].fwd_ack;
3811     }
3812   }
3813
3814   if (GNUNET_YES == t->nobuffer && GMC_is_pid_bigger(ack, t->fwd_pid))
3815     ack = (uint32_t) t->fwd_pid + 1; // Might overflow, it's ok.
3816
3817   return (uint32_t) ack;
3818 }
3819
3820
3821 /**
3822  * Get the current fwd ack value for a tunnel, taking in account the tunnel
3823  * mode and the status of all children nodes.
3824  *
3825  * @param t Tunnel.
3826  *
3827  * @return Maximum PID allowed.
3828  */
3829 static uint32_t
3830 tunnel_get_fwd_ack (struct MeshTunnel *t)
3831 {
3832   uint32_t ack;
3833   uint32_t count;
3834   uint32_t buffer_free;
3835   int64_t child_ack;
3836   int64_t client_ack;
3837
3838   count = t->fwd_pid - t->skip;
3839   buffer_free = t->fwd_queue_max - t->fwd_queue_n;
3840   child_ack = tunnel_get_children_fwd_ack (t);
3841   client_ack = tunnel_get_clients_fwd_ack (t);
3842   if (GNUNET_YES == t->nobuffer)
3843   {
3844     ack = count;
3845     if (-1LL == child_ack)
3846       child_ack = client_ack;
3847     if (-1LL == child_ack)
3848     {
3849       GNUNET_break (0);
3850       client_ack = child_ack = ack;
3851     }
3852   }
3853   else
3854   {
3855     ack = count + buffer_free; // Overflow? OK!
3856   }
3857   if (-1LL == child_ack)
3858   {
3859     // Node has no children, child_ack AND core buffer are irrelevant.
3860     GNUNET_break (-1LL != client_ack); // No children AND no clients? Not good!
3861     return (uint32_t) client_ack;
3862   }
3863   if (-1LL == client_ack)
3864   {
3865     client_ack = ack;
3866   }
3867   if (GNUNET_YES == t->speed_min)
3868   {
3869     ack = GMC_min_pid ((uint32_t) child_ack, ack);
3870     ack = GMC_min_pid ((uint32_t) client_ack, ack);
3871   }
3872   else
3873   {
3874     ack = GMC_max_pid ((uint32_t) child_ack, ack);
3875     ack = GMC_max_pid ((uint32_t) client_ack, ack);
3876   }
3877   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3878               "c %u, bf %u, ch %lld, cl %lld, ACK: %u\n",
3879               count, buffer_free, child_ack, client_ack, ack);
3880   return ack;
3881 }
3882
3883
3884 /**
3885  * Build a local ACK message and send it to a local client.
3886  * 
3887  * @param t Tunnel on which to send the ACK.
3888  * @param c Client to whom send the ACK.
3889  * @param ack Value of the ACK.
3890  */
3891 static void
3892 send_local_ack (struct MeshTunnel *t, struct MeshClient *c, uint32_t ack)
3893 {
3894   struct GNUNET_MESH_LocalAck msg;
3895
3896   msg.header.size = htons (sizeof (msg));
3897   msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK);
3898   msg.tunnel_id = htonl (t->owner == c ? t->local_tid : t->local_tid_dest);
3899   msg.max_pid = htonl (ack); 
3900   GNUNET_SERVER_notification_context_unicast(nc,
3901                                               c->handle,
3902                                               &msg.header,
3903                                               GNUNET_NO);
3904 }
3905
3906 /**
3907  * Build an ACK message and queue it to send to the given peer.
3908  * 
3909  * @param t Tunnel on which to send the ACK.
3910  * @param peer Peer to whom send the ACK.
3911  * @param ack Value of the ACK.
3912  */
3913 static void
3914 send_ack (struct MeshTunnel *t, struct GNUNET_PeerIdentity *peer,  uint32_t ack)
3915 {
3916   struct GNUNET_MESH_ACK msg;
3917
3918   GNUNET_PEER_resolve (t->id.oid, &msg.oid);
3919   msg.header.size = htons (sizeof (msg));
3920   msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_ACK);
3921   msg.pid = htonl (ack);
3922   msg.tid = htonl (t->id.tid);
3923
3924   send_prebuilt_message (&msg.header, peer, t);
3925 }
3926
3927
3928 /**
3929  * Notify a the owner of a tunnel about how many more
3930  * payload packages will we accept on a given tunnel.
3931  *
3932  * @param t Tunnel on which to send the ACK.
3933  */
3934 static void
3935 tunnel_send_client_fwd_ack (struct MeshTunnel *t)
3936 {
3937   uint32_t ack;
3938
3939   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3940               "Sending client FWD ACK on tunnel %X\n",
3941               t->local_tid);
3942
3943   ack = tunnel_get_fwd_ack (t);
3944
3945   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " ack %u\n", ack);
3946   if (t->last_fwd_ack == ack)
3947   {
3948     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " same as last, not sending!\n");
3949     return;
3950   }
3951
3952   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " sending!\n");
3953   t->last_fwd_ack = ack;
3954   send_local_ack (t, t->owner, ack);
3955 }
3956
3957
3958 /**
3959  * Send an ACK informing the predecessor about the available buffer space.
3960  * In case there is no predecessor, inform the owning client.
3961  * If buffering is off, send only on behalf of children or self if endpoint.
3962  * If buffering is on, send when sent to children and buffer space is free.
3963  * Note that although the name is fwd_ack, the FWD mean forward *traffic*,
3964  * the ACK itself goes "back" (towards root).
3965  * 
3966  * @param t Tunnel on which to send the ACK.
3967  * @param type Type of message that triggered the ACK transmission.
3968  */
3969 static void
3970 tunnel_send_fwd_ack (struct MeshTunnel *t, uint16_t type)
3971 {
3972   struct GNUNET_PeerIdentity id;
3973   uint32_t ack;
3974
3975   if (NULL != t->owner)
3976   {
3977     tunnel_send_client_fwd_ack (t);
3978     return;
3979   }
3980   /* Is it after unicast / multicast retransmission? */
3981   switch (type)
3982   {
3983     case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
3984     case GNUNET_MESSAGE_TYPE_MESH_MULTICAST:
3985       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3986                   "ACK due to FWD DATA retransmission\n");
3987       if (GNUNET_YES == t->nobuffer)
3988       {
3989         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Not sending ACK, nobuffer\n");
3990         return;
3991       }
3992       break;
3993     case GNUNET_MESSAGE_TYPE_MESH_ACK:
3994     case GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK:
3995       break;
3996     default:
3997       GNUNET_break (0);
3998   }
3999
4000   /* Check if we need no retransmit the ACK */
4001   if (t->fwd_queue_max > t->fwd_queue_n * 4 &&
4002       GMC_is_pid_bigger(t->last_fwd_ack, t->fwd_pid))
4003   {
4004     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Not sending ACK, buffer free\n");
4005     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4006                 "  t->qmax: %u, t->qn: %u\n",
4007                 t->fwd_queue_max, t->fwd_queue_n);
4008     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4009                 "  t->pid: %u, t->ack: %u\n",
4010                 t->fwd_pid, t->last_fwd_ack);
4011     return;
4012   }
4013
4014   /* Ok, ACK might be necessary, what PID to ACK? */
4015   ack = tunnel_get_fwd_ack (t);
4016
4017   /* If speed_min and not all children have ack'd, dont send yet */
4018   if (ack == t->last_fwd_ack)
4019   {
4020     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Not sending FWD ACK, not ready\n");
4021     return;
4022   }
4023
4024   t->last_fwd_ack = ack;
4025   GNUNET_PEER_resolve (tree_get_predecessor (t->tree), &id);
4026   send_ack (t, &id, ack);
4027   debug_fwd_ack++;
4028 }
4029
4030
4031 /**
4032  * Iterator to send a child node a BCK ACK to allow him to send more
4033  * to_origin data.
4034  *
4035  * @param cls Closure (tunnel).
4036  * @param id Id of the child node.
4037  */
4038 static void
4039 tunnel_send_child_bck_ack (void *cls,
4040                            GNUNET_PEER_Id id)
4041 {
4042   struct MeshTunnel *t = cls;
4043   struct MeshTunnelFlowControlInfo *fcinfo;
4044   struct GNUNET_PeerIdentity peer;
4045   uint32_t ack;
4046
4047   GNUNET_PEER_resolve (id, &peer);
4048   fcinfo = tunnel_get_neighbor_fc (t, &peer);
4049   ack = fcinfo->bck_pid + t->bck_queue_max - t->bck_queue_n;
4050
4051
4052   if (fcinfo->bck_ack == ack)
4053   {
4054     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4055                 "    Not sending ACK, not needed\n");
4056     return;
4057   }
4058   fcinfo->bck_ack = ack;
4059
4060   fcinfo->bck_ack = fcinfo->bck_pid + t->bck_queue_max - t->bck_queue_n;
4061   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4062               "    Sending BCK ACK %u (last sent: %u)\n",
4063               ack, fcinfo->bck_ack);
4064   send_ack (t, &peer, ack);
4065 }
4066
4067
4068 /**
4069  * @brief Send BCK ACKs to clients to allow them more to_origin traffic
4070  * 
4071  * Iterates over all clients and sends BCK ACKs to the ones that need it.
4072  *
4073  * FIXME fc: what happens if we have 2 clients but q_size is 1?
4074  *           - implement a size 1 buffer in each client_fc AND children_fc
4075  *           to hold at least 1 message per "child".
4076  *             problem: violates no buffer policy
4077  *           - ack 0 and make "children" poll for transmission slots
4078  *             problem: big overhead, extra latency even in low traffic
4079  *                      settings
4080  * 
4081  * @param t Tunnel on which to send the BCK ACKs.
4082  */
4083 static void
4084 tunnel_send_clients_bck_ack (struct MeshTunnel *t)
4085 {
4086   unsigned int i;
4087   unsigned int tunnel_delta;
4088
4089   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  Sending BCK ACK to clients\n");
4090
4091   tunnel_delta = t->bck_queue_max - t->bck_queue_n;
4092   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   tunnel delta: %u\n", tunnel_delta);
4093
4094   /* Find client whom to allow to send to origin (with lowest buffer space) */
4095   for (i = 0; i < t->nclients; i++)
4096   {
4097     struct MeshTunnelFlowControlInfo *fcinfo;
4098     unsigned int delta;
4099
4100     fcinfo = &t->clients_fc[i];
4101     delta = fcinfo->bck_ack - fcinfo->bck_pid;
4102     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "    client %u delta: %u\n",
4103          t->clients[i]->id, delta);
4104
4105     if ((GNUNET_NO == t->nobuffer && tunnel_delta > delta) ||
4106         (GNUNET_YES == t->nobuffer && 0 == delta))
4107     {
4108       uint32_t ack;
4109
4110       ack = fcinfo->bck_pid;
4111       ack += t->nobuffer ? 1 : tunnel_delta;
4112       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4113                   "    sending ack to client %u: %u\n",
4114                   t->clients[i]->id, ack);
4115       send_local_ack (t, t->clients[i], ack);
4116       fcinfo->bck_ack = ack;
4117     }
4118     else
4119     {
4120       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4121                   "    not sending ack to client %u (td %u, d %u)\n",
4122                   t->clients[i]->id, tunnel_delta, delta);
4123     }
4124   }
4125 }
4126
4127
4128 /**
4129  * Send an ACK informing the children nodes and destination clients about
4130  * the available buffer space.
4131  * If buffering is off, send only on behalf of root (can be self).
4132  * If buffering is on, send when sent to predecessor and buffer space is free.
4133  * Note that although the name is bck_ack, the BCK mean backwards *traffic*,
4134  * the ACK itself goes "forward" (towards children/clients).
4135  * 
4136  * @param t Tunnel on which to send the ACK.
4137  * @param type Type of message that triggered the ACK transmission.
4138  */
4139 static void
4140 tunnel_send_bck_ack (struct MeshTunnel *t, uint16_t type)
4141 {
4142   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4143               "Sending BCK ACK on tunnel %u [%u] due to %s\n",
4144               t->id.oid, t->id.tid, GNUNET_MESH_DEBUG_M2S(type));
4145   /* Is it after data to_origin retransmission? */
4146   switch (type)
4147   {
4148     case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN:
4149       if (GNUNET_YES == t->nobuffer)
4150       {
4151         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4152                     "    Not sending ACK, nobuffer\n");
4153         return;
4154       }
4155       break;
4156     case GNUNET_MESSAGE_TYPE_MESH_ACK:
4157     case GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK:
4158     case GNUNET_MESSAGE_TYPE_MESH_POLL:
4159       break;
4160     default:
4161       GNUNET_break (0);
4162   }
4163
4164   tunnel_send_clients_bck_ack (t);
4165   tree_iterate_children (t->tree, &tunnel_send_child_bck_ack, t);
4166 }
4167
4168
4169 /**
4170  * @brief Re-initiate traffic to this peer if necessary.
4171  *
4172  * Check if there is traffic queued towards this peer
4173  * and the core transmit handle is NULL (traffic was stalled).
4174  * If so, call core tmt rdy.
4175  *
4176  * @param cls Closure (unused)
4177  * @param peer_id Short ID of peer to which initiate traffic.
4178  */
4179 static void
4180 peer_unlock_queue(void *cls, GNUNET_PEER_Id peer_id)
4181 {
4182   struct MeshPeerInfo *peer;
4183   struct GNUNET_PeerIdentity id;
4184   struct MeshPeerQueue *q;
4185   size_t size;
4186
4187   peer = peer_info_get_short(peer_id);
4188   if (NULL != peer->core_transmit)
4189     return;
4190
4191   q = queue_get_next(peer);
4192   if (NULL == q)
4193   {
4194     /* Might br multicast traffic already sent to this particular peer but
4195      * not to other children in this tunnel.
4196      * This way t->queue_n would be > 0 but the queue of this particular peer
4197      * would be empty.
4198      */
4199     return;
4200   }
4201   size = q->size;
4202   GNUNET_PEER_resolve (peer->id, &id);
4203   peer->core_transmit =
4204         GNUNET_CORE_notify_transmit_ready(core_handle,
4205                                           0,
4206                                           0,
4207                                           GNUNET_TIME_UNIT_FOREVER_REL,
4208                                           &id,
4209                                           size,
4210                                           &queue_send,
4211                                           peer);
4212         return;
4213 }
4214
4215
4216 /**
4217  * @brief Allow transmission of FWD traffic on this tunnel
4218  *
4219  * Check if there is traffic queued towards any children
4220  * and the core transmit handle is NULL, and if so, call core tmt rdy.
4221  *
4222  * @param t Tunnel on which to unlock FWD traffic.
4223  */
4224 static void
4225 tunnel_unlock_fwd_queues (struct MeshTunnel *t)
4226 {
4227   if (0 == t->fwd_queue_n)
4228     return;
4229
4230   tree_iterate_children (t->tree, &peer_unlock_queue, NULL);
4231 }
4232
4233
4234 /**
4235  * @brief Allow transmission of BCK traffic on this tunnel
4236  *
4237  * Check if there is traffic queued towards the root of the tree
4238  * and the core transmit handle is NULL, and if so, call core tmt rdy.
4239  *
4240  * @param t Tunnel on which to unlock BCK traffic.
4241  */
4242 static void
4243 tunnel_unlock_bck_queue (struct MeshTunnel *t)
4244 {
4245   if (0 == t->bck_queue_n)
4246     return;
4247
4248   peer_unlock_queue(NULL, tree_get_predecessor(t->tree));
4249 }
4250
4251
4252 /**
4253  * Send a message to all peers in this tunnel that the tunnel is no longer
4254  * valid.
4255  *
4256  * @param t The tunnel whose peers to notify.
4257  */
4258 static void
4259 tunnel_send_destroy (struct MeshTunnel *t)
4260 {
4261   struct GNUNET_MESH_TunnelDestroy msg;
4262
4263   msg.header.size = htons (sizeof (msg));
4264   msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_TUNNEL_DESTROY);
4265   GNUNET_PEER_resolve (t->id.oid, &msg.oid);
4266   msg.tid = htonl (t->id.tid);
4267   tunnel_send_multicast (t, &msg.header);
4268 }
4269
4270
4271 /**
4272  * Cancel all transmissions towards a neighbor that belong to a certain tunnel.
4273  *
4274  * @param cls Closure (Tunnel which to cancel).
4275  * @param neighbor_id Short ID of the neighbor to whom cancel the transmissions.
4276  */
4277 static void
4278 tunnel_cancel_queues (void *cls, GNUNET_PEER_Id neighbor_id)
4279 {
4280   struct MeshTunnel *t = cls;
4281   struct MeshPeerInfo *peer_info;
4282   struct MeshPeerQueue *pq;
4283   struct MeshPeerQueue *next;
4284
4285   peer_info = peer_info_get_short (neighbor_id);
4286   for (pq = peer_info->queue_head; NULL != pq; pq = next)
4287   {
4288     next = pq->next;
4289     if (pq->tunnel == t)
4290     {
4291       if (GNUNET_MESSAGE_TYPE_MESH_MULTICAST == pq->type ||
4292           GNUNET_MESSAGE_TYPE_MESH_UNICAST == pq->type ||
4293           GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN == pq->type)
4294       {
4295         // Should have been removed on destroy children
4296         GNUNET_break (0);
4297       }
4298       queue_destroy (pq, GNUNET_YES);
4299     }
4300   }
4301   if (NULL == peer_info->queue_head && NULL != peer_info->core_transmit)
4302   {
4303     GNUNET_CORE_notify_transmit_ready_cancel(peer_info->core_transmit);
4304     peer_info->core_transmit = NULL;
4305   }
4306 }
4307
4308 /**
4309  * Destroy the tunnel and free any allocated resources linked to it.
4310  *
4311  * @param t the tunnel to destroy
4312  *
4313  * @return GNUNET_OK on success
4314  */
4315 static int
4316 tunnel_destroy (struct MeshTunnel *t)
4317 {
4318   struct MeshClient *c;
4319   struct GNUNET_HashCode hash;
4320   unsigned int i;
4321   int r;
4322
4323   if (NULL == t)
4324     return GNUNET_OK;
4325
4326   r = GNUNET_OK;
4327   c = t->owner;
4328 #if MESH_DEBUG
4329   {
4330     struct GNUNET_PeerIdentity id;
4331
4332     GNUNET_PEER_resolve (t->id.oid, &id);
4333     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "destroying tunnel %s [%x]\n",
4334                 GNUNET_i2s (&id), t->id.tid);
4335     if (NULL != c)
4336       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  by client %u\n", c->id);
4337   }
4338 #endif
4339
4340   GNUNET_CRYPTO_hash (&t->id, sizeof (struct MESH_TunnelID), &hash);
4341   if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_remove (tunnels, &hash, t))
4342   {
4343     GNUNET_break (0);
4344     r = GNUNET_SYSERR;
4345   }
4346
4347   if (NULL != c)
4348   {
4349     GNUNET_CRYPTO_hash (&t->local_tid, sizeof (MESH_TunnelNumber), &hash);
4350     if (GNUNET_YES !=
4351         GNUNET_CONTAINER_multihashmap_remove (c->own_tunnels, &hash, t))
4352     {
4353       GNUNET_break (0);
4354       r = GNUNET_SYSERR;
4355     }
4356   }
4357
4358   GNUNET_CRYPTO_hash (&t->local_tid_dest, sizeof (MESH_TunnelNumber), &hash);
4359   for (i = 0; i < t->nclients; i++)
4360   {
4361     c = t->clients[i];
4362     if (GNUNET_YES !=
4363           GNUNET_CONTAINER_multihashmap_remove (c->incoming_tunnels, &hash, t))
4364     {
4365       GNUNET_break (0);
4366       r = GNUNET_SYSERR;
4367     }
4368   }
4369   for (i = 0; i < t->nignore; i++)
4370   {
4371     c = t->ignore[i];
4372     if (GNUNET_YES !=
4373           GNUNET_CONTAINER_multihashmap_remove (c->ignore_tunnels, &hash, t))
4374     {
4375       GNUNET_break (0);
4376       r = GNUNET_SYSERR;
4377     }
4378   }
4379
4380   if (t->nclients > 0)
4381   {
4382     if (GNUNET_YES !=
4383         GNUNET_CONTAINER_multihashmap_remove (incoming_tunnels, &hash, t))
4384     {
4385       GNUNET_break (0);
4386       r = GNUNET_SYSERR;
4387     }
4388     GNUNET_free (t->clients);
4389     GNUNET_free (t->clients_fc);
4390   }
4391
4392   if (NULL != t->peers)
4393   {
4394     GNUNET_CONTAINER_multihashmap_iterate (t->peers, &peer_info_delete_tunnel,
4395                                            t);
4396     GNUNET_CONTAINER_multihashmap_destroy (t->peers);
4397   }
4398
4399   GNUNET_CONTAINER_multihashmap_iterate (t->children_fc,
4400                                          &tunnel_destroy_child,
4401                                          t);
4402   GNUNET_CONTAINER_multihashmap_destroy (t->children_fc);
4403   t->children_fc = NULL;
4404
4405   tree_iterate_children (t->tree, &tunnel_cancel_queues, t);
4406   tree_destroy (t->tree);
4407
4408   if (NULL != t->regex_ctx)
4409     regex_cancel_search (t->regex_ctx);
4410   if (NULL != t->dht_get_type)
4411     GNUNET_DHT_get_stop (t->dht_get_type);
4412   if (GNUNET_SCHEDULER_NO_TASK != t->timeout_task)
4413     GNUNET_SCHEDULER_cancel (t->timeout_task);
4414   if (GNUNET_SCHEDULER_NO_TASK != t->path_refresh_task)
4415     GNUNET_SCHEDULER_cancel (t->path_refresh_task);
4416
4417   n_tunnels--;
4418   GNUNET_STATISTICS_update (stats, "# tunnels", -1, GNUNET_NO);
4419   GNUNET_free (t);
4420   return r;
4421 }
4422
4423
4424 /**
4425  * Create a new tunnel
4426  * 
4427  * @param owner Who is the owner of the tunnel (short ID).
4428  * @param tid Tunnel Number of the tunnel.
4429  * @param client Clients that owns the tunnel, NULL for foreign tunnels.
4430  * @param local Tunnel Number for the tunnel, for the client point of view.
4431  * 
4432  * @return A new initialized tunnel. NULL on error.
4433  */
4434 static struct MeshTunnel *
4435 tunnel_new (GNUNET_PEER_Id owner,
4436             MESH_TunnelNumber tid,
4437             struct MeshClient *client,
4438             MESH_TunnelNumber local)
4439 {
4440   struct MeshTunnel *t;
4441   struct GNUNET_HashCode hash;
4442
4443   if (n_tunnels >= max_tunnels && NULL == client)
4444     return NULL;
4445
4446   t = GNUNET_malloc (sizeof (struct MeshTunnel));
4447   t->id.oid = owner;
4448   t->id.tid = tid;
4449   t->fwd_queue_max = (max_msgs_queue / max_tunnels) + 1;
4450   t->bck_queue_max = t->fwd_queue_max;
4451   t->tree = tree_new (owner);
4452   t->owner = client;
4453   t->fwd_pid = (uint32_t) -1; // Next (expected) = 0
4454   t->bck_pid = (uint32_t) -1; // Next (expected) = 0
4455   t->bck_ack = INITIAL_WINDOW_SIZE - 1;
4456   t->last_fwd_ack = INITIAL_WINDOW_SIZE - 1;
4457   t->local_tid = local;
4458   t->children_fc = GNUNET_CONTAINER_multihashmap_create (8, GNUNET_NO);
4459   n_tunnels++;
4460   GNUNET_STATISTICS_update (stats, "# tunnels", 1, GNUNET_NO);
4461
4462   GNUNET_CRYPTO_hash (&t->id, sizeof (struct MESH_TunnelID), &hash);
4463   if (GNUNET_OK !=
4464       GNUNET_CONTAINER_multihashmap_put (tunnels, &hash, t,
4465                                          GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
4466   {
4467     GNUNET_break (0);
4468     tunnel_destroy (t);
4469     if (NULL != client)
4470     {
4471       GNUNET_break (0);
4472       GNUNET_SERVER_receive_done (client->handle, GNUNET_SYSERR);
4473     }
4474     return NULL;
4475   }
4476
4477   if (NULL != client)
4478   {
4479     GNUNET_CRYPTO_hash (&t->local_tid, sizeof (MESH_TunnelNumber), &hash);
4480     if (GNUNET_OK !=
4481         GNUNET_CONTAINER_multihashmap_put (client->own_tunnels, &hash, t,
4482                                           GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
4483     {
4484       tunnel_destroy (t);
4485       GNUNET_break (0);
4486       GNUNET_SERVER_receive_done (client->handle, GNUNET_SYSERR);
4487       return NULL;
4488     }
4489   }
4490
4491   return t;
4492 }
4493
4494
4495 /**
4496  * Removes an explicit path from a tunnel, freeing all intermediate nodes
4497  * that are no longer needed, as well as nodes of no longer reachable peers.
4498  * The tunnel itself is also destoyed if results in a remote empty tunnel.
4499  *
4500  * @param t Tunnel from which to remove the path.
4501  * @param peer Short id of the peer which should be removed.
4502  */
4503 static void
4504 tunnel_delete_peer (struct MeshTunnel *t, GNUNET_PEER_Id peer)
4505 {
4506   if (GNUNET_NO == tree_del_peer (t->tree, peer, NULL, NULL))
4507     tunnel_destroy (t);
4508 }
4509
4510
4511 /**
4512  * tunnel_destroy_iterator: iterator for deleting each tunnel that belongs to a
4513  * client when the client disconnects. If the client is not the owner, the
4514  * owner will get notified if no more clients are in the tunnel and the client
4515  * get removed from the tunnel's list.
4516  *
4517  * @param cls closure (client that is disconnecting)
4518  * @param key the hash of the local tunnel id (used to access the hashmap)
4519  * @param value the value stored at the key (tunnel to destroy)
4520  *
4521  * @return GNUNET_OK, keep iterating.
4522  */
4523 static int
4524 tunnel_destroy_iterator (void *cls, const struct GNUNET_HashCode * key, void *value)
4525 {
4526   struct MeshTunnel *t = value;
4527   struct MeshClient *c = cls;
4528
4529   send_client_tunnel_disconnect(t, c);
4530   if (c != t->owner)
4531   {
4532     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4533                 "Client %u is destination, keeping the tunnel alive.\n", c->id);
4534     tunnel_delete_client(t, c);
4535     client_delete_tunnel(c, t);
4536     return GNUNET_OK;
4537   }
4538   tunnel_send_destroy(t);
4539   t->owner = NULL;
4540   t->destroy = GNUNET_YES;
4541
4542   return GNUNET_OK;
4543 }
4544
4545
4546 /**
4547  * Timeout function, destroys tunnel if called
4548  *
4549  * @param cls Closure (tunnel to destroy).
4550  * @param tc TaskContext
4551  */
4552 static void
4553 tunnel_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
4554 {
4555   struct MeshTunnel *t = cls;
4556   struct GNUNET_PeerIdentity id;
4557
4558   t->timeout_task = GNUNET_SCHEDULER_NO_TASK;
4559   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
4560     return;
4561   GNUNET_PEER_resolve(t->id.oid, &id);
4562   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
4563               "Tunnel %s [%X] timed out. Destroying.\n",
4564               GNUNET_i2s(&id), t->id.tid);
4565   send_clients_tunnel_destroy (t);
4566   tunnel_destroy (t);
4567 }
4568
4569 /**
4570  * Resets the tunnel timeout. Starts it if no timeout was running.
4571  *
4572  * @param t Tunnel whose timeout to reset.
4573  *
4574  * TODO use heap to improve efficiency of scheduler.
4575  */
4576 static void
4577 tunnel_reset_timeout (struct MeshTunnel *t)
4578 {
4579   if (GNUNET_SCHEDULER_NO_TASK != t->timeout_task)
4580     GNUNET_SCHEDULER_cancel (t->timeout_task);
4581   t->timeout_task =
4582       GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
4583                                     (refresh_path_time, 4), &tunnel_timeout, t);
4584 }
4585
4586
4587 /******************************************************************************/
4588 /****************      MESH NETWORK HANDLER HELPERS     ***********************/
4589 /******************************************************************************/
4590
4591 /**
4592  * Function to send a create path packet to a peer.
4593  *
4594  * @param cls closure
4595  * @param size number of bytes available in buf
4596  * @param buf where the callee should write the message
4597  * @return number of bytes written to buf
4598  */
4599 static size_t
4600 send_core_path_create (void *cls, size_t size, void *buf)
4601 {
4602   struct MeshPathInfo *info = cls;
4603   struct GNUNET_MESH_ManipulatePath *msg;
4604   struct GNUNET_PeerIdentity *peer_ptr;
4605   struct MeshTunnel *t = info->t;
4606   struct MeshPeerPath *p = info->path;
4607   size_t size_needed;
4608   uint32_t opt;
4609   int i;
4610
4611   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CREATE PATH sending...\n");
4612   size_needed =
4613       sizeof (struct GNUNET_MESH_ManipulatePath) +
4614       p->length * sizeof (struct GNUNET_PeerIdentity);
4615
4616   if (size < size_needed || NULL == buf)
4617   {
4618     GNUNET_break (0);
4619     return 0;
4620   }
4621   msg = (struct GNUNET_MESH_ManipulatePath *) buf;
4622   msg->header.size = htons (size_needed);
4623   msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE);
4624   msg->tid = ntohl (t->id.tid);
4625
4626   opt = 0;
4627   if (GNUNET_YES == t->speed_min)
4628     opt |= MESH_TUNNEL_OPT_SPEED_MIN;
4629   if (GNUNET_YES == t->nobuffer)
4630     opt |= MESH_TUNNEL_OPT_NOBUFFER;
4631   msg->opt = htonl(opt);
4632   msg->reserved = 0;
4633
4634   peer_ptr = (struct GNUNET_PeerIdentity *) &msg[1];
4635   for (i = 0; i < p->length; i++)
4636   {
4637     GNUNET_PEER_resolve (p->peers[i], peer_ptr++);
4638   }
4639
4640   path_destroy (p);
4641   GNUNET_free (info);
4642
4643   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4644               "CREATE PATH (%u bytes long) sent!\n", size_needed);
4645   return size_needed;
4646 }
4647
4648
4649 /**
4650  * Fill the core buffer 
4651  *
4652  * @param cls closure (data itself)
4653  * @param size number of bytes available in buf
4654  * @param buf where the callee should write the message
4655  *
4656  * @return number of bytes written to buf
4657  */
4658 static size_t
4659 send_core_data_multicast (void *cls, size_t size, void *buf)
4660 {
4661   struct MeshTransmissionDescriptor *info = cls;
4662   size_t total_size;
4663
4664   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Multicast callback.\n");
4665   GNUNET_assert (NULL != info);
4666   GNUNET_assert (NULL != info->peer);
4667   total_size = info->mesh_data->data_len;
4668   GNUNET_assert (total_size < GNUNET_SERVER_MAX_MESSAGE_SIZE);
4669
4670   if (total_size > size)
4671   {
4672     GNUNET_break (0);
4673     return 0;
4674   }
4675   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " copying data...\n");
4676   memcpy (buf, info->mesh_data->data, total_size);
4677 #if MESH_DEBUG
4678   {
4679     struct GNUNET_MESH_Multicast *mc;
4680     struct GNUNET_MessageHeader *mh;
4681
4682     mh = buf;
4683     if (ntohs (mh->type) == GNUNET_MESSAGE_TYPE_MESH_MULTICAST)
4684     {
4685       mc = (struct GNUNET_MESH_Multicast *) mh;
4686       mh = (struct GNUNET_MessageHeader *) &mc[1];
4687       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4688                   " multicast, payload type %s\n",
4689                   GNUNET_MESH_DEBUG_M2S (ntohs (mh->type)));
4690       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4691                   " multicast, payload size %u\n", ntohs (mh->size));
4692     }
4693     else
4694     {
4695       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " type %s\n",
4696                   GNUNET_MESH_DEBUG_M2S (ntohs (mh->type)));
4697     }
4698   }
4699 #endif
4700   data_descriptor_decrement_rc (info->mesh_data);
4701   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "freeing info...\n");
4702   GNUNET_free (info);
4703   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "return %u\n", total_size);
4704   return total_size;
4705 }
4706
4707
4708 /**
4709  * Creates a path ack message in buf and frees all unused resources.
4710  *
4711  * @param cls closure (MeshTransmissionDescriptor)
4712  * @param size number of bytes available in buf
4713  * @param buf where the callee should write the message
4714  * @return number of bytes written to buf
4715  */
4716 static size_t
4717 send_core_path_ack (void *cls, size_t size, void *buf)
4718 {
4719   struct MeshTransmissionDescriptor *info = cls;
4720   struct GNUNET_MESH_PathACK *msg = buf;
4721
4722   GNUNET_assert (NULL != info);
4723   if (sizeof (struct GNUNET_MESH_PathACK) > size)
4724   {
4725     GNUNET_break (0);
4726     return 0;
4727   }
4728   msg->header.size = htons (sizeof (struct GNUNET_MESH_PathACK));
4729   msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_PATH_ACK);
4730   GNUNET_PEER_resolve (info->origin->oid, &msg->oid);
4731   msg->tid = htonl (info->origin->tid);
4732   msg->peer_id = my_full_id;
4733
4734   GNUNET_free (info);
4735   /* TODO add signature */
4736
4737   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "PATH ACK sent!\n");
4738   return sizeof (struct GNUNET_MESH_PathACK);
4739 }
4740
4741
4742 /**
4743  * Free a transmission that was already queued with all resources
4744  * associated to the request.
4745  *
4746  * @param queue Queue handler to cancel.
4747  * @param clear_cls Is it necessary to free associated cls?
4748  */
4749 static void
4750 queue_destroy (struct MeshPeerQueue *queue, int clear_cls)
4751 {
4752   struct MeshTransmissionDescriptor *dd;
4753   struct MeshPathInfo *path_info;
4754   struct MeshTunnelFlowControlInfo *fcinfo;
4755   struct GNUNET_PeerIdentity id;
4756   unsigned int i;
4757   unsigned int max;
4758
4759   if (GNUNET_YES == clear_cls)
4760   {
4761     switch (queue->type)
4762     {
4763       case GNUNET_MESSAGE_TYPE_MESH_TUNNEL_DESTROY:
4764         GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "   cancelling TUNNEL_DESTROY\n");
4765         GNUNET_assert (GNUNET_YES == queue->tunnel->destroy);
4766         /* FIXME: don't cancel, send and destroy tunnel in queue_send */
4767         /* fall through */
4768       case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
4769       case GNUNET_MESSAGE_TYPE_MESH_MULTICAST:
4770       case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN:
4771       case GNUNET_MESSAGE_TYPE_MESH_ACK:
4772       case GNUNET_MESSAGE_TYPE_MESH_PATH_KEEPALIVE:
4773         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4774                     "   prebuilt message\n");
4775         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4776                     "   type %s\n",
4777                     GNUNET_MESH_DEBUG_M2S(queue->type));
4778         dd = queue->cls;
4779         data_descriptor_decrement_rc (dd->mesh_data);
4780         break;
4781       case GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE:
4782         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   type create path\n");
4783         path_info = queue->cls;
4784         path_destroy (path_info->path);
4785         break;
4786       default:
4787         GNUNET_break (0);
4788         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
4789                     "   type %s unknown!\n",
4790                     GNUNET_MESH_DEBUG_M2S(queue->type));
4791     }
4792     GNUNET_free_non_null (queue->cls);
4793   }
4794   GNUNET_CONTAINER_DLL_remove (queue->peer->queue_head,
4795                                queue->peer->queue_tail,
4796                                queue);
4797
4798   /* Delete from child_fc in the appropiate tunnel */
4799   max = queue->tunnel->fwd_queue_max;
4800   GNUNET_PEER_resolve (queue->peer->id, &id);
4801   fcinfo = tunnel_get_neighbor_fc (queue->tunnel, &id);
4802   if (NULL != fcinfo)
4803   {
4804     GNUNET_assert (NULL != fcinfo->peer);
4805     for (i = 0; i < fcinfo->send_buffer_n; i++)
4806     {
4807       unsigned int i2;
4808       i2 = (fcinfo->send_buffer_start + i) % max;
4809       if (fcinfo->send_buffer[i2] == queue)
4810       {
4811         /* Found corresponding entry in the send_buffer. Move all others back. */
4812         unsigned int j;
4813         unsigned int j2;
4814         unsigned int j3;
4815
4816         for (j = i, j2 = 0, j3 = 0; j < fcinfo->send_buffer_n - 1; j++)
4817         {
4818           j2 = (fcinfo->send_buffer_start + j) % max;
4819           j3 = (fcinfo->send_buffer_start + j + 1) % max;
4820           fcinfo->send_buffer[j2] = fcinfo->send_buffer[j3];
4821         }
4822
4823         fcinfo->send_buffer[j3] = NULL;
4824         fcinfo->send_buffer_n--;
4825       }
4826     }
4827   }
4828
4829   GNUNET_free (queue);
4830 }
4831
4832
4833 /**
4834  * @brief Get the next transmittable message from the queue.
4835  *
4836  * This will be the head, except in the case of being a data packet
4837  * not allowed by the destination peer.
4838  *
4839  * @param peer Destination peer.
4840  *
4841  * @return The next viable MeshPeerQueue element to send to that peer.
4842  *         NULL when there are no transmittable messages.
4843  */
4844 struct MeshPeerQueue *
4845 queue_get_next (const struct MeshPeerInfo *peer)
4846 {
4847   struct MeshPeerQueue *q;
4848   struct MeshTunnel *t;
4849   struct MeshTransmissionDescriptor *info;
4850   struct MeshTunnelFlowControlInfo *fcinfo;
4851   struct GNUNET_MESH_Unicast *ucast;
4852   struct GNUNET_MESH_ToOrigin *to_orig;
4853   struct GNUNET_MESH_Multicast *mcast;
4854   struct GNUNET_PeerIdentity id;
4855   uint32_t pid;
4856   uint32_t ack;
4857
4858   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*********   selecting message\n");
4859   for (q = peer->queue_head; NULL != q; q = q->next)
4860   {
4861     t = q->tunnel;
4862     info = q->cls;
4863     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4864                 "*********     %s\n",
4865                 GNUNET_MESH_DEBUG_M2S(q->type));
4866     switch (q->type)
4867     {
4868       case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
4869         ucast = (struct GNUNET_MESH_Unicast *) info->mesh_data->data;
4870         pid = ntohl (ucast->pid);
4871         GNUNET_PEER_resolve (info->peer->id, &id);
4872         fcinfo = tunnel_get_neighbor_fc (t, &id);
4873         ack = fcinfo->fwd_ack;
4874         break;
4875       case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN:
4876         to_orig = (struct GNUNET_MESH_ToOrigin *) info->mesh_data->data;
4877         pid = ntohl (to_orig->pid);
4878         ack = t->bck_ack;
4879         break;
4880       case GNUNET_MESSAGE_TYPE_MESH_MULTICAST:
4881         mcast = (struct GNUNET_MESH_Multicast *) info->mesh_data->data;
4882         if (GNUNET_MESSAGE_TYPE_MESH_MULTICAST != ntohs(mcast->header.type)) 
4883         {
4884           // Not a multicast payload: multicast control traffic (destroy, etc)
4885           return q;
4886         }
4887         pid = ntohl (mcast->pid);
4888         GNUNET_PEER_resolve (info->peer->id, &id);
4889         fcinfo = tunnel_get_neighbor_fc (t, &id);
4890         ack = fcinfo->fwd_ack;
4891         break;
4892       default:
4893         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4894                     "*********   OK!\n");
4895         return q;
4896     }
4897         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4898                     "*********     ACK: %u, PID: %u\n",
4899                     ack, pid);
4900     if (GNUNET_NO == GMC_is_pid_bigger(pid, ack))
4901     {
4902       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4903                   "*********   OK!\n");
4904       return q;
4905     }
4906     else
4907     {
4908       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4909                   "*********     NEXT!\n");
4910     }
4911   }
4912   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4913                 "*********   nothing found\n");
4914   return NULL;
4915 }
4916
4917
4918 /**
4919   * Core callback to write a queued packet to core buffer
4920   *
4921   * @param cls Closure (peer info).
4922   * @param size Number of bytes available in buf.
4923   * @param buf Where the to write the message.
4924   *
4925   * @return number of bytes written to buf
4926   */
4927 static size_t
4928 queue_send (void *cls, size_t size, void *buf)
4929 {
4930     struct MeshPeerInfo *peer = cls;
4931     struct GNUNET_MessageHeader *msg;
4932     struct MeshPeerQueue *queue;
4933     struct MeshTunnel *t;
4934     struct MeshTunnelFlowControlInfo *fcinfo;
4935     struct GNUNET_PeerIdentity dst_id;
4936     size_t data_size;
4937
4938     peer->core_transmit = NULL;
4939     fcinfo = NULL;
4940
4941     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "********* Queue send\n");
4942     queue = queue_get_next (peer);
4943
4944     /* Queue has no internal mesh traffic nor sendable payload */
4945     if (NULL == queue)
4946     {
4947       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*********   not ready, return\n");
4948       if (NULL == peer->queue_head)
4949         GNUNET_break (0); // Should've been canceled
4950       return 0;
4951     }
4952     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*********   not empty\n");
4953
4954     GNUNET_PEER_resolve (peer->id, &dst_id);
4955     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4956                 "*********   towards %s\n",
4957                 GNUNET_i2s(&dst_id));
4958     /* Check if buffer size is enough for the message */
4959     if (queue->size > size)
4960     {
4961         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4962                     "*********   not enough room, reissue\n");
4963         peer->core_transmit =
4964             GNUNET_CORE_notify_transmit_ready (core_handle,
4965                                                0,
4966                                                0,
4967                                                GNUNET_TIME_UNIT_FOREVER_REL,
4968                                                &dst_id,
4969                                                queue->size,
4970                                                &queue_send,
4971                                                peer);
4972         return 0;
4973     }
4974     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*********   size ok\n");
4975
4976     t = queue->tunnel;
4977     if (GNUNET_MESSAGE_TYPE_MESH_UNICAST == queue->type)
4978     {
4979       t->fwd_queue_n--;
4980       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4981                   "*********   unicast: t->q (%u/%u)\n",
4982                   t->fwd_queue_n, t->fwd_queue_max);
4983     }
4984     else if (GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN == queue->type)
4985     {
4986       t->bck_queue_n--;
4987       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*********   to origin\n");
4988     }
4989
4990     /* Fill buf */
4991     switch (queue->type)
4992     {
4993       case 0:
4994       case GNUNET_MESSAGE_TYPE_MESH_ACK:
4995       case GNUNET_MESSAGE_TYPE_MESH_POLL:
4996       case GNUNET_MESSAGE_TYPE_MESH_PATH_BROKEN:
4997       case GNUNET_MESSAGE_TYPE_MESH_PATH_DESTROY:
4998       case GNUNET_MESSAGE_TYPE_MESH_TUNNEL_DESTROY:
4999         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5000                     "*********   raw: %s\n",
5001                     GNUNET_MESH_DEBUG_M2S (queue->type));
5002         /* Fall through */
5003       case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
5004       case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN:
5005         data_size = send_core_data_raw (queue->cls, size, buf);
5006         msg = (struct GNUNET_MessageHeader *) buf;
5007         switch (ntohs (msg->type)) // Type of preconstructed message
5008         {
5009           case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
5010             tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_UNICAST);
5011             break;
5012           case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN:
5013             tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN);
5014             break;
5015           default:
5016               break;
5017         }
5018         break;
5019       case GNUNET_MESSAGE_TYPE_MESH_MULTICAST:
5020         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*********   multicast\n");
5021         {
5022           struct MeshTransmissionDescriptor *info = queue->cls;
5023
5024           if ((1 == info->mesh_data->reference_counter
5025               && GNUNET_YES == t->speed_min)
5026               ||
5027               (info->mesh_data->total_out == info->mesh_data->reference_counter
5028               && GNUNET_NO == t->speed_min))
5029           {
5030             GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5031                         "*********   considered sent\n");
5032             t->fwd_queue_n--;
5033           }
5034         }
5035         data_size = send_core_data_multicast(queue->cls, size, buf);
5036         tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_MULTICAST);
5037         break;
5038       case GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE:
5039         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*********   path create\n");
5040         data_size = send_core_path_create (queue->cls, size, buf);
5041         break;
5042       case GNUNET_MESSAGE_TYPE_MESH_PATH_ACK:
5043         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*********   path ack\n");
5044         data_size = send_core_path_ack (queue->cls, size, buf);
5045         break;
5046       case GNUNET_MESSAGE_TYPE_MESH_PATH_KEEPALIVE:
5047         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*********   path keepalive\n");
5048         data_size = send_core_data_multicast (queue->cls, size, buf);
5049         break;
5050       default:
5051         GNUNET_break (0);
5052         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
5053                     "*********   type unknown: %u\n",
5054                     queue->type);
5055         data_size = 0;
5056     }
5057     switch (queue->type)
5058     {
5059       case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
5060       case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN:
5061       case GNUNET_MESSAGE_TYPE_MESH_MULTICAST:
5062         fcinfo = tunnel_get_neighbor_fc (t, &dst_id);
5063         if (fcinfo->send_buffer[fcinfo->send_buffer_start] != queue)
5064         {
5065           GNUNET_break (0);
5066           GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
5067                       "at pos %u (%p) != %p\n",
5068                       fcinfo->send_buffer_start,
5069                       fcinfo->send_buffer[fcinfo->send_buffer_start],
5070                       queue);
5071         }
5072         if (fcinfo->send_buffer_n > 0)
5073         {
5074           fcinfo->send_buffer[fcinfo->send_buffer_start] = NULL;
5075           fcinfo->send_buffer_n--;
5076           fcinfo->send_buffer_start++;
5077           fcinfo->send_buffer_start %= t->fwd_queue_max;
5078         }
5079         else
5080         {
5081           GNUNET_break (0);
5082         }
5083         break;
5084       default:
5085         break;
5086     }
5087
5088     /* Free queue, but cls was freed by send_core_* */
5089     queue_destroy (queue, GNUNET_NO);
5090
5091     if (GNUNET_YES == t->destroy)
5092     {
5093       // FIXME fc tunnel destroy all pending traffic? wait for it?
5094       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*********  destroying tunnel!\n");
5095       tunnel_destroy (t);
5096     }
5097
5098     /* If more data in queue, send next */
5099     queue = queue_get_next(peer);
5100     if (NULL != queue)
5101     {
5102         struct GNUNET_PeerIdentity id;
5103
5104         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*********   more data!\n");
5105         GNUNET_PEER_resolve (peer->id, &id);
5106         peer->core_transmit =
5107             GNUNET_CORE_notify_transmit_ready(core_handle,
5108                                               0,
5109                                               0,
5110                                               GNUNET_TIME_UNIT_FOREVER_REL,
5111                                               &id,
5112                                               queue->size,
5113                                               &queue_send,
5114                                               peer);
5115     }
5116     else
5117     {
5118       if (NULL != peer->queue_head)
5119       {
5120         GNUNET_log (GNUNET_ERROR_TYPE_INFO,
5121                     "*********   %s stalled\n",
5122                     GNUNET_i2s(&my_full_id));
5123         if (NULL == fcinfo)
5124           fcinfo = tunnel_get_neighbor_fc (t, &dst_id);
5125         fcinfo->fc_poll = GNUNET_SCHEDULER_add_delayed(GNUNET_TIME_UNIT_SECONDS,
5126                                                      &tunnel_poll, fcinfo);
5127       }
5128     }
5129     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*********   return %d\n", data_size);
5130     return data_size;
5131 }
5132
5133
5134 /**
5135  * @brief Queue and pass message to core when possible.
5136  * 
5137  * If type is payload (UNICAST, TO_ORIGIN, MULTICAST) checks for queue status
5138  * and accounts for it. In case the queue is full, the message is dropped and
5139  * a break issued.
5140  * 
5141  * Otherwise, message is treated as internal and allowed to go regardless of 
5142  * queue status.
5143  *
5144  * @param cls Closure (@c type dependant). It will be used by queue_send to
5145  *            build the message to be sent if not already prebuilt.
5146  * @param type Type of the message, 0 for a raw message.
5147  * @param size Size of the message.
5148  * @param dst Neighbor to send message to.
5149  * @param t Tunnel this message belongs to.
5150  */
5151 static void
5152 queue_add (void *cls, uint16_t type, size_t size,
5153            struct MeshPeerInfo *dst, struct MeshTunnel *t)
5154 {
5155   struct MeshPeerQueue *queue;
5156   struct MeshTunnelFlowControlInfo *fcinfo;
5157   struct GNUNET_PeerIdentity id;
5158   unsigned int *max;
5159   unsigned int *n;
5160   unsigned int i;
5161
5162   n = NULL;
5163   if (GNUNET_MESSAGE_TYPE_MESH_UNICAST == type ||
5164       GNUNET_MESSAGE_TYPE_MESH_MULTICAST == type)
5165   {
5166     n = &t->fwd_queue_n;
5167     max = &t->fwd_queue_max;
5168   }
5169   else if (GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN == type)
5170   {
5171     n = &t->bck_queue_n;
5172     max = &t->bck_queue_max;
5173   }
5174   if (NULL != n)
5175   {
5176     if (*n >= *max)
5177     {
5178       struct MeshTransmissionDescriptor *td = cls;
5179       struct GNUNET_MESH_ToOrigin *to;
5180
5181       to = td->mesh_data->data;
5182       GNUNET_break(0);
5183       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
5184                   "bck pid %u, bck ack %u, msg pid %u\n",
5185                   t->bck_pid, t->bck_ack, ntohl(to->pid));
5186       GNUNET_STATISTICS_update(stats, "# messages dropped (buffer full)",
5187                                1, GNUNET_NO);
5188       return;                       // Drop message
5189     }
5190     (*n)++;
5191   }
5192   queue = GNUNET_malloc (sizeof (struct MeshPeerQueue));
5193   queue->cls = cls;
5194   queue->type = type;
5195   queue->size = size;
5196   queue->peer = dst;
5197   queue->tunnel = t;
5198   GNUNET_CONTAINER_DLL_insert_tail (dst->queue_head, dst->queue_tail, queue);
5199   GNUNET_PEER_resolve (dst->id, &id);
5200   if (NULL == dst->core_transmit)
5201   {
5202       dst->core_transmit =
5203           GNUNET_CORE_notify_transmit_ready (core_handle,
5204                                              0,
5205                                              0,
5206                                              GNUNET_TIME_UNIT_FOREVER_REL,
5207                                              &id,
5208                                              size,
5209                                              &queue_send,
5210                                              dst);
5211   }
5212   if (NULL == n) // Is this internal mesh traffic?
5213     return;
5214
5215   // It's payload, keep track of buffer per peer.
5216   fcinfo = tunnel_get_neighbor_fc (t, &id);
5217   i = (fcinfo->send_buffer_start + fcinfo->send_buffer_n) % t->fwd_queue_max;
5218   if (NULL != fcinfo->send_buffer[i])
5219   {
5220     GNUNET_break (fcinfo->send_buffer_n == t->fwd_queue_max); // aka i == start
5221     queue_destroy (fcinfo->send_buffer[fcinfo->send_buffer_start], GNUNET_YES);
5222     fcinfo->send_buffer_start++;
5223     fcinfo->send_buffer_start %= t->fwd_queue_max;
5224   }
5225   else
5226   {
5227     fcinfo->send_buffer_n++;
5228   }
5229   fcinfo->send_buffer[i] = queue;
5230   if (fcinfo->send_buffer_n > t->fwd_queue_max)
5231   {
5232     GNUNET_break (0);
5233     fcinfo->send_buffer_n = t->fwd_queue_max;
5234   }
5235 }
5236
5237
5238 /******************************************************************************/
5239 /********************      MESH NETWORK HANDLERS     **************************/
5240 /******************************************************************************/
5241
5242
5243 /**
5244  * Core handler for path creation
5245  *
5246  * @param cls closure
5247  * @param message message
5248  * @param peer peer identity this notification is about
5249  * @param atsi performance data
5250  * @param atsi_count number of records in 'atsi'
5251  *
5252  * @return GNUNET_OK to keep the connection open,
5253  *         GNUNET_SYSERR to close it (signal serious error)
5254  */
5255 static int
5256 handle_mesh_path_create (void *cls, const struct GNUNET_PeerIdentity *peer,
5257                          const struct GNUNET_MessageHeader *message,
5258                          const struct GNUNET_ATS_Information *atsi,
5259                          unsigned int atsi_count)
5260 {
5261   unsigned int own_pos;
5262   uint16_t size;
5263   uint16_t i;
5264   MESH_TunnelNumber tid;
5265   struct GNUNET_MESH_ManipulatePath *msg;
5266   struct GNUNET_PeerIdentity *pi;
5267   struct GNUNET_HashCode hash;
5268   struct MeshPeerPath *path;
5269   struct MeshPeerInfo *dest_peer_info;
5270   struct MeshPeerInfo *orig_peer_info;
5271   struct MeshTunnel *t;
5272
5273   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5274               "Received a path create msg [%s]\n",
5275               GNUNET_i2s (&my_full_id));
5276   size = ntohs (message->size);
5277   if (size < sizeof (struct GNUNET_MESH_ManipulatePath))
5278   {
5279     GNUNET_break_op (0);
5280     return GNUNET_OK;
5281   }
5282
5283   size -= sizeof (struct GNUNET_MESH_ManipulatePath);
5284   if (size % sizeof (struct GNUNET_PeerIdentity))
5285   {
5286     GNUNET_break_op (0);
5287     return GNUNET_OK;
5288   }
5289   size /= sizeof (struct GNUNET_PeerIdentity);
5290   if (size < 2)
5291   {
5292     GNUNET_break_op (0);
5293     return GNUNET_OK;
5294   }
5295   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "    path has %u hops.\n", size);
5296   msg = (struct GNUNET_MESH_ManipulatePath *) message;
5297
5298   tid = ntohl (msg->tid);
5299   pi = (struct GNUNET_PeerIdentity *) &msg[1];
5300   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5301               "    path is for tunnel %s [%X].\n", GNUNET_i2s (pi), tid);
5302   t = tunnel_get (pi, tid);
5303   if (NULL == t) // FIXME only for INCOMING tunnels?
5304   {
5305     uint32_t opt;
5306
5307     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  Creating tunnel\n");
5308     t = tunnel_new (GNUNET_PEER_intern (pi), tid, NULL, 0);
5309     if (NULL == t)
5310     {
5311       // FIXME notify failure
5312       return GNUNET_OK;
5313     }
5314     opt = ntohl (msg->opt);
5315     t->speed_min = (0 != (opt & MESH_TUNNEL_OPT_SPEED_MIN)) ?
5316                    GNUNET_YES : GNUNET_NO;
5317     if (0 != (opt & MESH_TUNNEL_OPT_NOBUFFER))
5318     {
5319       t->nobuffer = GNUNET_YES;
5320       t->last_fwd_ack = t->fwd_pid + 1;
5321     }
5322     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5323                 "  speed_min: %d, nobuffer:%d\n",
5324                 t->speed_min, t->nobuffer);
5325
5326     if (GNUNET_YES == t->nobuffer)
5327     {
5328       t->bck_queue_max = 1;
5329       t->fwd_queue_max = 1;
5330     }
5331
5332     // FIXME only assign a local tid if a local client is interested (on demand)
5333     while (NULL != tunnel_get_incoming (next_local_tid))
5334       next_local_tid = (next_local_tid + 1) | GNUNET_MESH_LOCAL_TUNNEL_ID_SERV;
5335     t->local_tid_dest = next_local_tid++;
5336     next_local_tid = next_local_tid | GNUNET_MESH_LOCAL_TUNNEL_ID_SERV;
5337     // FIXME end
5338
5339     tunnel_reset_timeout (t);
5340     GNUNET_CRYPTO_hash (&t->local_tid_dest, sizeof (MESH_TunnelNumber), &hash);
5341     if (GNUNET_OK !=
5342         GNUNET_CONTAINER_multihashmap_put (incoming_tunnels, &hash, t,
5343                                            GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
5344     {
5345       tunnel_destroy (t);
5346       GNUNET_break (0);
5347       return GNUNET_OK;
5348     }
5349   }
5350   dest_peer_info =
5351       GNUNET_CONTAINER_multihashmap_get (peers, &pi[size - 1].hashPubKey);
5352   if (NULL == dest_peer_info)
5353   {
5354     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5355                 "  Creating PeerInfo for destination.\n");
5356     dest_peer_info = GNUNET_malloc (sizeof (struct MeshPeerInfo));
5357     dest_peer_info->id = GNUNET_PEER_intern (&pi[size - 1]);
5358     GNUNET_CONTAINER_multihashmap_put (peers, &pi[size - 1].hashPubKey,
5359                                        dest_peer_info,
5360                                        GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
5361   }
5362   orig_peer_info = GNUNET_CONTAINER_multihashmap_get (peers, &pi->hashPubKey);
5363   if (NULL == orig_peer_info)
5364   {
5365     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5366                 "  Creating PeerInfo for origin.\n");
5367     orig_peer_info = GNUNET_malloc (sizeof (struct MeshPeerInfo));
5368     orig_peer_info->id = GNUNET_PEER_intern (pi);
5369     GNUNET_CONTAINER_multihashmap_put (peers, &pi->hashPubKey, orig_peer_info,
5370                                        GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
5371   }
5372   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  Creating path...\n");
5373   path = path_new (size);
5374   own_pos = 0;
5375   for (i = 0; i < size; i++)
5376   {
5377     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  ... adding %s\n",
5378                 GNUNET_i2s (&pi[i]));
5379     path->peers[i] = GNUNET_PEER_intern (&pi[i]);
5380     if (path->peers[i] == myid)
5381       own_pos = i;
5382   }
5383   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  Own position: %u\n", own_pos);
5384   if (own_pos == 0)
5385   {
5386     /* cannot be self, must be 'not found' */
5387     /* create path: self not found in path through self */
5388     GNUNET_break_op (0);
5389     path_destroy (path);
5390     tunnel_destroy (t);
5391     return GNUNET_OK;
5392   }
5393   path_add_to_peers (path, GNUNET_NO);
5394   tunnel_add_path (t, path, own_pos);
5395   if (own_pos == size - 1)
5396   {
5397     /* It is for us! Send ack. */
5398     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  It's for us!\n");
5399     peer_info_add_path_to_origin (orig_peer_info, path, GNUNET_NO);
5400     if (NULL == t->peers)
5401     {
5402       /* New tunnel! Notify clients on first payload message. */
5403       t->peers = GNUNET_CONTAINER_multihashmap_create (4, GNUNET_NO);
5404     }
5405     GNUNET_break (GNUNET_SYSERR !=
5406                   GNUNET_CONTAINER_multihashmap_put (t->peers,
5407                                                      &my_full_id.hashPubKey,
5408                                                      peer_info_get
5409                                                      (&my_full_id),
5410                                                      GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE));
5411     send_path_ack (t);
5412   }
5413   else
5414   {
5415     struct MeshPeerPath *path2;
5416
5417     /* It's for somebody else! Retransmit. */
5418     path2 = path_duplicate (path);
5419     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  Retransmitting.\n");
5420     peer_info_add_path (dest_peer_info, path2, GNUNET_NO);
5421     path2 = path_duplicate (path);
5422     peer_info_add_path_to_origin (orig_peer_info, path2, GNUNET_NO);
5423     send_create_path (dest_peer_info, path, t);
5424   }
5425   return GNUNET_OK;
5426 }
5427
5428
5429 /**
5430  * Core handler for path destruction
5431  *
5432  * @param cls closure
5433  * @param message message
5434  * @param peer peer identity this notification is about
5435  * @param atsi performance data
5436  * @param atsi_count number of records in 'atsi'
5437  *
5438  * @return GNUNET_OK to keep the connection open,
5439  *         GNUNET_SYSERR to close it (signal serious error)
5440  */
5441 static int
5442 handle_mesh_path_destroy (void *cls, const struct GNUNET_PeerIdentity *peer,
5443                           const struct GNUNET_MessageHeader *message,
5444                           const struct GNUNET_ATS_Information *atsi,
5445                           unsigned int atsi_count)
5446 {
5447   struct GNUNET_MESH_ManipulatePath *msg;
5448   struct GNUNET_PeerIdentity *pi;
5449   struct MeshPeerPath *path;
5450   struct MeshTunnel *t;
5451   unsigned int own_pos;
5452   unsigned int i;
5453   size_t size;
5454
5455   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5456               "Received a PATH DESTROY msg from %s\n", GNUNET_i2s (peer));
5457   size = ntohs (message->size);
5458   if (size < sizeof (struct GNUNET_MESH_ManipulatePath))
5459   {
5460     GNUNET_break_op (0);
5461     return GNUNET_OK;
5462   }
5463
5464   size -= sizeof (struct GNUNET_MESH_ManipulatePath);
5465   if (size % sizeof (struct GNUNET_PeerIdentity))
5466   {
5467     GNUNET_break_op (0);
5468     return GNUNET_OK;
5469   }
5470   size /= sizeof (struct GNUNET_PeerIdentity);
5471   if (size < 2)
5472   {
5473     GNUNET_break_op (0);
5474     return GNUNET_OK;
5475   }
5476   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "    path has %u hops.\n", size);
5477
5478   msg = (struct GNUNET_MESH_ManipulatePath *) message;
5479   pi = (struct GNUNET_PeerIdentity *) &msg[1];
5480   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5481               "    path is for tunnel %s [%X].\n", GNUNET_i2s (pi),
5482               msg->tid);
5483   t = tunnel_get (pi, ntohl (msg->tid));
5484   if (NULL == t)
5485   {
5486     /* TODO notify back: we don't know this tunnel */
5487     GNUNET_break_op (0);
5488     return GNUNET_OK;
5489   }
5490   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  Creating path...\n");
5491   path = path_new (size);
5492   own_pos = 0;
5493   for (i = 0; i < size; i++)
5494   {
5495     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  ... adding %s\n",
5496                 GNUNET_i2s (&pi[i]));
5497     path->peers[i] = GNUNET_PEER_intern (&pi[i]);
5498     if (path->peers[i] == myid)
5499       own_pos = i;
5500   }
5501   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  Own position: %u\n", own_pos);
5502   if (own_pos < path->length - 1)
5503     send_prebuilt_message (message, &pi[own_pos + 1], t);
5504   else
5505     send_client_tunnel_disconnect(t, NULL);
5506
5507   tunnel_delete_peer (t, path->peers[path->length - 1]);
5508   path_destroy (path);
5509   return GNUNET_OK;
5510 }
5511
5512
5513 /**
5514  * Core handler for notifications of broken paths
5515  *
5516  * @param cls closure
5517  * @param message message
5518  * @param peer peer identity this notification is about
5519  * @param atsi performance data
5520  * @param atsi_count number of records in 'atsi'
5521  *
5522  * @return GNUNET_OK to keep the connection open,
5523  *         GNUNET_SYSERR to close it (signal serious error)
5524  */
5525 static int
5526 handle_mesh_path_broken (void *cls, const struct GNUNET_PeerIdentity *peer,
5527                          const struct GNUNET_MessageHeader *message,
5528                          const struct GNUNET_ATS_Information *atsi,
5529                          unsigned int atsi_count)
5530 {
5531   struct GNUNET_MESH_PathBroken *msg;
5532   struct MeshTunnel *t;
5533
5534   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5535               "Received a PATH BROKEN msg from %s\n", GNUNET_i2s (peer));
5536   msg = (struct GNUNET_MESH_PathBroken *) message;
5537   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  regarding %s\n",
5538               GNUNET_i2s (&msg->peer1));
5539   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  regarding %s\n",
5540               GNUNET_i2s (&msg->peer2));
5541   t = tunnel_get (&msg->oid, ntohl (msg->tid));
5542   if (NULL == t)
5543   {
5544     GNUNET_break_op (0);
5545     return GNUNET_OK;
5546   }
5547   tunnel_notify_connection_broken (t, GNUNET_PEER_search (&msg->peer1),
5548                                    GNUNET_PEER_search (&msg->peer2));
5549   return GNUNET_OK;
5550
5551 }
5552
5553
5554 /**
5555  * Core handler for tunnel destruction
5556  *
5557  * @param cls closure
5558  * @param message message
5559  * @param peer peer identity this notification is about
5560  * @param atsi performance data
5561  * @param atsi_count number of records in 'atsi'
5562  *
5563  * @return GNUNET_OK to keep the connection open,
5564  *         GNUNET_SYSERR to close it (signal serious error)
5565  */
5566 static int
5567 handle_mesh_tunnel_destroy (void *cls, const struct GNUNET_PeerIdentity *peer,
5568                             const struct GNUNET_MessageHeader *message,
5569                             const struct GNUNET_ATS_Information *atsi,
5570                             unsigned int atsi_count)
5571 {
5572   struct GNUNET_MESH_TunnelDestroy *msg;
5573   struct MeshTunnel *t;
5574
5575   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5576               "Got a TUNNEL DESTROY packet from %s\n", GNUNET_i2s (peer));
5577   msg = (struct GNUNET_MESH_TunnelDestroy *) message;
5578   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  for tunnel %s [%u]\n",
5579               GNUNET_i2s (&msg->oid), ntohl (msg->tid));
5580   t = tunnel_get (&msg->oid, ntohl (msg->tid));
5581   if (NULL == t)
5582   {
5583     /* Probably already got the message from another path,
5584      * destroyed the tunnel and retransmitted to children.
5585      * Safe to ignore.
5586      */
5587     GNUNET_STATISTICS_update (stats, "# control on unknown tunnel", 1, GNUNET_NO);
5588     return GNUNET_OK;
5589   }
5590   if (t->id.oid == myid)
5591   {
5592     GNUNET_break_op (0);
5593     return GNUNET_OK;
5594   }
5595   if (t->local_tid_dest >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV)
5596   {
5597     /* Tunnel was incoming, notify clients */
5598     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "INCOMING TUNNEL %X %X\n",
5599                 t->local_tid, t->local_tid_dest);
5600     send_clients_tunnel_destroy (t);
5601   }
5602   tunnel_send_destroy (t);
5603   t->destroy = GNUNET_YES;
5604   // TODO: add timeout to destroy the tunnel anyway
5605   return GNUNET_OK;
5606 }
5607
5608
5609 /**
5610  * Core handler for mesh network traffic going from the origin to a peer
5611  *
5612  * @param cls closure
5613  * @param peer peer identity this notification is about
5614  * @param message message
5615  * @param atsi performance data
5616  * @param atsi_count number of records in 'atsi'
5617  * @return GNUNET_OK to keep the connection open,
5618  *         GNUNET_SYSERR to close it (signal serious error)
5619  */
5620 static int
5621 handle_mesh_data_unicast (void *cls, const struct GNUNET_PeerIdentity *peer,
5622                           const struct GNUNET_MessageHeader *message,
5623                           const struct GNUNET_ATS_Information *atsi,
5624                           unsigned int atsi_count)
5625 {
5626   struct GNUNET_MESH_Unicast *msg;
5627   struct GNUNET_PeerIdentity *neighbor;
5628   struct MeshTunnelFlowControlInfo *fcinfo;
5629   struct MeshTunnel *t;
5630   GNUNET_PEER_Id dest_id;
5631   uint32_t pid;
5632   uint32_t ttl;
5633   size_t size;
5634
5635   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "got a unicast packet from %s\n",
5636               GNUNET_i2s (peer));
5637   /* Check size */
5638   size = ntohs (message->size);
5639   if (size <
5640       sizeof (struct GNUNET_MESH_Unicast) +
5641       sizeof (struct GNUNET_MessageHeader))
5642   {
5643     GNUNET_break (0);
5644     return GNUNET_OK;
5645   }
5646   msg = (struct GNUNET_MESH_Unicast *) message;
5647   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " of type %s\n",
5648               GNUNET_MESH_DEBUG_M2S (ntohs (msg[1].header.type)));
5649   /* Check tunnel */
5650   t = tunnel_get (&msg->oid, ntohl (msg->tid));
5651   if (NULL == t)
5652   {
5653     /* TODO notify back: we don't know this tunnel */
5654     GNUNET_STATISTICS_update (stats, "# data on unknown tunnel", 1, GNUNET_NO);
5655     GNUNET_break_op (0);
5656     return GNUNET_OK;
5657   }
5658   pid = ntohl (msg->pid);
5659   if (t->fwd_pid == pid)
5660   {
5661     GNUNET_STATISTICS_update (stats, "# duplicate PID drops", 1, GNUNET_NO);
5662     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
5663                 " Already seen pid %u, DROPPING!\n", pid);
5664     return GNUNET_OK;
5665   }
5666   else
5667   {
5668     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5669                 " pid %u not seen yet, forwarding\n", pid);
5670   }
5671
5672   t->skip += (pid - t->fwd_pid) - 1;
5673   t->fwd_pid = pid;
5674
5675   if (GMC_is_pid_bigger (pid, t->last_fwd_ack))
5676   {
5677     GNUNET_STATISTICS_update (stats, "# unsolicited unicast", 1, GNUNET_NO);
5678     GNUNET_break_op (0);
5679     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5680                 "Received PID %u, ACK %u\n",
5681                 pid, t->last_fwd_ack);
5682     return GNUNET_OK;
5683   }
5684
5685   tunnel_reset_timeout (t);
5686   dest_id = GNUNET_PEER_search (&msg->destination);
5687   if (dest_id == myid)
5688   {
5689     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5690                 "  it's for us! sending to clients...\n");
5691     GNUNET_STATISTICS_update (stats, "# unicast received", 1, GNUNET_NO);
5692     send_subscribed_clients (message, &msg[1].header, t);
5693     tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_UNICAST);
5694     return GNUNET_OK;
5695   }
5696   ttl = ntohl (msg->ttl);
5697   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   ttl: %u\n", ttl);
5698   if (ttl == 0)
5699   {
5700     GNUNET_STATISTICS_update (stats, "# TTL drops", 1, GNUNET_NO);
5701     GNUNET_log (GNUNET_ERROR_TYPE_WARNING, " TTL is 0, DROPPING!\n");
5702     tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_ACK);
5703     return GNUNET_OK;
5704   }
5705   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5706               "  not for us, retransmitting...\n");
5707
5708   neighbor = tree_get_first_hop (t->tree, dest_id);
5709   fcinfo = tunnel_get_neighbor_fc (t, neighbor);
5710   fcinfo->fwd_pid = pid;
5711   GNUNET_CONTAINER_multihashmap_iterate (t->children_fc,
5712                                          &tunnel_add_skip,
5713                                          &neighbor);
5714   if (GNUNET_YES == t->nobuffer &&
5715       GNUNET_YES == GMC_is_pid_bigger (pid, fcinfo->fwd_ack))
5716   {
5717     GNUNET_STATISTICS_update (stats, "# unsolicited unicast", 1, GNUNET_NO);
5718     GNUNET_log (GNUNET_ERROR_TYPE_INFO, "  %u > %u\n", pid, fcinfo->fwd_ack);
5719     GNUNET_break_op (0);
5720     return GNUNET_OK;
5721   }
5722   send_prebuilt_message (message, neighbor, t);
5723   GNUNET_STATISTICS_update (stats, "# unicast forwarded", 1, GNUNET_NO);
5724   return GNUNET_OK;
5725 }
5726
5727
5728 /**
5729  * Core handler for mesh network traffic going from the origin to all peers
5730  *
5731  * @param cls closure
5732  * @param message message
5733  * @param peer peer identity this notification is about
5734  * @param atsi performance data
5735  * @param atsi_count number of records in 'atsi'
5736  * @return GNUNET_OK to keep the connection open,
5737  *         GNUNET_SYSERR to close it (signal serious error)
5738  *
5739  * TODO: Check who we got this from, to validate route.
5740  */
5741 static int
5742 handle_mesh_data_multicast (void *cls, const struct GNUNET_PeerIdentity *peer,
5743                             const struct GNUNET_MessageHeader *message,
5744                             const struct GNUNET_ATS_Information *atsi,
5745                             unsigned int atsi_count)
5746 {
5747   struct GNUNET_MESH_Multicast *msg;
5748   struct MeshTunnel *t;
5749   size_t size;
5750   uint32_t pid;
5751
5752   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "got a multicast packet from %s\n",
5753               GNUNET_i2s (peer));
5754   size = ntohs (message->size);
5755   if (sizeof (struct GNUNET_MESH_Multicast) +
5756       sizeof (struct GNUNET_MessageHeader) > size)
5757   {
5758     GNUNET_break_op (0);
5759     return GNUNET_OK;
5760   }
5761   msg = (struct GNUNET_MESH_Multicast *) message;
5762   t = tunnel_get (&msg->oid, ntohl (msg->tid));
5763
5764   if (NULL == t)
5765   {
5766     /* TODO notify that we dont know that tunnel */
5767     GNUNET_STATISTICS_update (stats, "# data on unknown tunnel", 1, GNUNET_NO);
5768     GNUNET_break_op (0);
5769     return GNUNET_OK;
5770   }
5771   pid = ntohl (msg->pid);
5772   if (t->fwd_pid == pid)
5773   {
5774     /* already seen this packet, drop */
5775     GNUNET_STATISTICS_update (stats, "# duplicate PID drops", 1, GNUNET_NO);
5776     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5777                 " Already seen pid %u, DROPPING!\n", pid);
5778     tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_ACK);
5779     return GNUNET_OK;
5780   }
5781   else
5782   {
5783     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5784                 " pid %u not seen yet, forwarding\n", pid);
5785   }
5786   t->skip += (pid - t->fwd_pid) - 1;
5787   t->fwd_pid = pid;
5788   tunnel_reset_timeout (t);
5789
5790   /* Transmit to locally interested clients */
5791   if (NULL != t->peers &&
5792       GNUNET_CONTAINER_multihashmap_contains (t->peers, &my_full_id.hashPubKey))
5793   {
5794     GNUNET_STATISTICS_update (stats, "# multicast received", 1, GNUNET_NO);
5795     send_subscribed_clients (message, &msg[1].header, t);
5796     tunnel_send_fwd_ack(t, GNUNET_MESSAGE_TYPE_MESH_MULTICAST);
5797   }
5798   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   ttl: %u\n", ntohl (msg->ttl));
5799   if (ntohl (msg->ttl) == 0)
5800   {
5801     GNUNET_STATISTICS_update (stats, "# TTL drops", 1, GNUNET_NO);
5802     GNUNET_log (GNUNET_ERROR_TYPE_WARNING, " TTL is 0, DROPPING!\n");
5803     tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_ACK);
5804     return GNUNET_OK;
5805   }
5806   GNUNET_STATISTICS_update (stats, "# multicast forwarded", 1, GNUNET_NO);
5807   tunnel_send_multicast (t, message);
5808   return GNUNET_OK;
5809 }
5810
5811
5812 /**
5813  * Core handler for mesh network traffic toward the owner of a tunnel
5814  *
5815  * @param cls closure
5816  * @param message message
5817  * @param peer peer identity this notification is about
5818  * @param atsi performance data
5819  * @param atsi_count number of records in 'atsi'
5820  *
5821  * @return GNUNET_OK to keep the connection open,
5822  *         GNUNET_SYSERR to close it (signal serious error)
5823  */
5824 static int
5825 handle_mesh_data_to_orig (void *cls, const struct GNUNET_PeerIdentity *peer,
5826                           const struct GNUNET_MessageHeader *message,
5827                           const struct GNUNET_ATS_Information *atsi,
5828                           unsigned int atsi_count)
5829 {
5830   struct GNUNET_MESH_ToOrigin *msg;
5831   struct GNUNET_PeerIdentity id;
5832   struct MeshPeerInfo *peer_info;
5833   struct MeshTunnel *t;
5834   struct MeshTunnelFlowControlInfo *fcinfo;
5835   size_t size;
5836   uint32_t pid;
5837
5838   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "got a ToOrigin packet from %s\n",
5839               GNUNET_i2s (peer));
5840   size = ntohs (message->size);
5841   if (size < sizeof (struct GNUNET_MESH_ToOrigin) +     /* Payload must be */
5842       sizeof (struct GNUNET_MessageHeader))     /* at least a header */
5843   {
5844     GNUNET_break_op (0);
5845     return GNUNET_OK;
5846   }
5847   msg = (struct GNUNET_MESH_ToOrigin *) message;
5848   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " of type %s\n",
5849               GNUNET_MESH_DEBUG_M2S (ntohs (msg[1].header.type)));
5850   t = tunnel_get (&msg->oid, ntohl (msg->tid));
5851   pid = ntohl (msg->pid);
5852
5853   if (NULL == t)
5854   {
5855     /* TODO notify that we dont know this tunnel (whom)? */
5856     GNUNET_STATISTICS_update (stats, "# data on unknown tunnel", 1, GNUNET_NO);
5857     GNUNET_break_op (0);
5858     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5859                 "Received to_origin with PID %u on unknown tunnel\n",
5860                 pid);
5861     return GNUNET_OK;
5862   }
5863
5864   fcinfo = tunnel_get_neighbor_fc (t, peer);
5865   if (NULL == fcinfo)
5866   {
5867     GNUNET_break (0);
5868     return GNUNET_OK;
5869   }
5870
5871   if (fcinfo->bck_pid == pid)
5872   {
5873     /* already seen this packet, drop */
5874     GNUNET_STATISTICS_update (stats, "# duplicate PID drops BCK", 1, GNUNET_NO);
5875     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5876                 " Already seen pid %u, DROPPING!\n", pid);
5877     tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_ACK);
5878     return GNUNET_OK;
5879   }
5880
5881   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5882               " pid %u not seen yet, forwarding\n", pid);
5883   fcinfo->bck_pid = pid;
5884
5885   if (NULL != t->owner)
5886   {
5887     char cbuf[size];
5888     struct GNUNET_MESH_ToOrigin *copy;
5889
5890     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5891                 "  it's for us! sending to clients...\n");
5892     /* TODO signature verification */
5893     memcpy (cbuf, message, size);
5894     copy = (struct GNUNET_MESH_ToOrigin *) cbuf;
5895     copy->tid = htonl (t->local_tid);
5896     t->bck_pid++;
5897     copy->pid = htonl (t->bck_pid);
5898     GNUNET_STATISTICS_update (stats, "# to origin received", 1, GNUNET_NO);
5899     GNUNET_SERVER_notification_context_unicast (nc, t->owner->handle,
5900                                                 &copy->header, GNUNET_NO);
5901     tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN);
5902     return GNUNET_OK;
5903   }
5904   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5905               "  not for us, retransmitting...\n");
5906
5907   peer_info = peer_info_get (&msg->oid);
5908   if (NULL == peer_info)
5909   {
5910     /* unknown origin of tunnel */
5911     GNUNET_break (0);
5912     return GNUNET_OK;
5913   }
5914   GNUNET_PEER_resolve (tree_get_predecessor (t->tree), &id);
5915   send_prebuilt_message (message, &id, t);
5916   GNUNET_STATISTICS_update (stats, "# to origin forwarded", 1, GNUNET_NO);
5917
5918   return GNUNET_OK;
5919 }
5920
5921
5922 /**
5923  * Core handler for mesh network traffic point-to-point acks.
5924  *
5925  * @param cls closure
5926  * @param message message
5927  * @param peer peer identity this notification is about
5928  * @param atsi performance data
5929  * @param atsi_count number of records in 'atsi'
5930  *
5931  * @return GNUNET_OK to keep the connection open,
5932  *         GNUNET_SYSERR to close it (signal serious error)
5933  */
5934 static int
5935 handle_mesh_ack (void *cls, const struct GNUNET_PeerIdentity *peer,
5936                  const struct GNUNET_MessageHeader *message,
5937                  const struct GNUNET_ATS_Information *atsi,
5938                  unsigned int atsi_count)
5939 {
5940   struct GNUNET_MESH_ACK *msg;
5941   struct MeshTunnel *t;
5942   uint32_t ack;
5943
5944   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got an ACK packet from %s!\n",
5945               GNUNET_i2s (peer));
5946   msg = (struct GNUNET_MESH_ACK *) message;
5947
5948   t = tunnel_get (&msg->oid, ntohl (msg->tid));
5949
5950   if (NULL == t)
5951   {
5952     /* TODO notify that we dont know this tunnel (whom)? */
5953     GNUNET_STATISTICS_update (stats, "# ack on unknown tunnel", 1, GNUNET_NO);
5954     GNUNET_break_op (0);
5955     return GNUNET_OK;
5956   }
5957   ack = ntohl (msg->pid);
5958   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  ACK %u\n", ack);
5959
5960   /* Is this a forward or backward ACK? */
5961   if (tree_get_predecessor(t->tree) != GNUNET_PEER_search(peer))
5962   {
5963     struct MeshTunnelFlowControlInfo *fcinfo;
5964
5965     debug_bck_ack++;
5966     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  FWD ACK\n");
5967     fcinfo = tunnel_get_neighbor_fc (t, peer);
5968     fcinfo->fwd_ack = ack;
5969     tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_ACK);
5970     tunnel_unlock_fwd_queues (t);
5971   }
5972   else
5973   {
5974     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  BCK ACK\n");
5975     t->bck_ack = ack;
5976     tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_ACK);
5977     tunnel_unlock_bck_queue (t);
5978   }
5979   return GNUNET_OK;
5980 }
5981
5982
5983 /**
5984  * Core handler for mesh network traffic point-to-point ack polls.
5985  *
5986  * @param cls closure
5987  * @param message message
5988  * @param peer peer identity this notification is about
5989  * @param atsi performance data
5990  * @param atsi_count number of records in 'atsi'
5991  *
5992  * @return GNUNET_OK to keep the connection open,
5993  *         GNUNET_SYSERR to close it (signal serious error)
5994  */
5995 static int
5996 handle_mesh_poll (void *cls, const struct GNUNET_PeerIdentity *peer,
5997                   const struct GNUNET_MessageHeader *message,
5998                   const struct GNUNET_ATS_Information *atsi,
5999                   unsigned int atsi_count)
6000 {
6001   struct GNUNET_MESH_Poll *msg;
6002   struct MeshTunnel *t;
6003
6004   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got an POLL packet from %s!\n",
6005               GNUNET_i2s (peer));
6006
6007   msg = (struct GNUNET_MESH_Poll *) message;
6008
6009   t = tunnel_get (&msg->oid, ntohl (msg->tid));
6010
6011   if (NULL == t)
6012   {
6013     /* TODO notify that we dont know this tunnel (whom)? */
6014     GNUNET_STATISTICS_update (stats, "# poll on unknown tunnel", 1, GNUNET_NO);
6015     GNUNET_break_op (0);
6016     return GNUNET_OK;
6017   }
6018
6019   /* Is this a forward or backward ACK? */
6020   if (tree_get_predecessor(t->tree) != GNUNET_PEER_search(peer))
6021   {
6022     struct MeshTunnelFlowControlInfo *fcinfo;
6023
6024     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  from FWD\n");
6025     fcinfo = tunnel_get_neighbor_fc (t, peer);
6026     fcinfo->bck_ack = fcinfo->fwd_pid; // mark as ready to send
6027     tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_POLL);
6028   }
6029   else
6030   {
6031     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  from BCK\n");
6032     tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_POLL);
6033   }
6034
6035   return GNUNET_OK;
6036 }
6037
6038
6039 /**
6040  * Core handler for path ACKs
6041  *
6042  * @param cls closure
6043  * @param message message
6044  * @param peer peer identity this notification is about
6045  * @param atsi performance data
6046  * @param atsi_count number of records in 'atsi'
6047  *
6048  * @return GNUNET_OK to keep the connection open,
6049  *         GNUNET_SYSERR to close it (signal serious error)
6050  */
6051 static int
6052 handle_mesh_path_ack (void *cls, const struct GNUNET_PeerIdentity *peer,
6053                       const struct GNUNET_MessageHeader *message,
6054                       const struct GNUNET_ATS_Information *atsi,
6055                       unsigned int atsi_count)
6056 {
6057   struct GNUNET_MESH_PathACK *msg;
6058   struct GNUNET_PeerIdentity id;
6059   struct MeshPeerInfo *peer_info;
6060   struct MeshPeerPath *p;
6061   struct MeshTunnel *t;
6062
6063   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received a path ACK msg [%s]\n",
6064               GNUNET_i2s (&my_full_id));
6065   msg = (struct GNUNET_MESH_PathACK *) message;
6066   t = tunnel_get (&msg->oid, ntohl(msg->tid));
6067   if (NULL == t)
6068   {
6069     /* TODO notify that we don't know the tunnel */
6070     GNUNET_STATISTICS_update (stats, "# control on unknown tunnel", 1, GNUNET_NO);
6071     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  don't know the tunnel %s [%X]!\n",
6072                 GNUNET_i2s (&msg->oid), ntohl(msg->tid));
6073     return GNUNET_OK;
6074   }
6075   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  on tunnel %s [%X]\n",
6076               GNUNET_i2s (&msg->oid), ntohl(msg->tid));
6077
6078   peer_info = peer_info_get (&msg->peer_id);
6079   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  by peer %s\n",
6080               GNUNET_i2s (&msg->peer_id));
6081   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  via peer %s\n",
6082               GNUNET_i2s (peer));
6083
6084   if (NULL != t->regex_ctx && t->regex_ctx->info->peer == peer_info->id)
6085   {
6086     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
6087                 "connect_by_string completed, stopping search\n");
6088     regex_cancel_search (t->regex_ctx);
6089     t->regex_ctx = NULL;
6090   }
6091
6092   /* Add paths to peers? */
6093   p = tree_get_path_to_peer (t->tree, peer_info->id);
6094   if (NULL != p)
6095   {
6096     path_add_to_peers (p, GNUNET_YES);
6097     path_destroy (p);
6098   }
6099   else
6100   {
6101     GNUNET_break (0);
6102   }
6103
6104   /* Message for us? */
6105   if (0 == memcmp (&msg->oid, &my_full_id, sizeof (struct GNUNET_PeerIdentity)))
6106   {
6107     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  It's for us!\n");
6108     if (NULL == t->owner)
6109     {
6110       GNUNET_break_op (0);
6111       return GNUNET_OK;
6112     }
6113     if (NULL != t->dht_get_type)
6114     {
6115       GNUNET_DHT_get_stop (t->dht_get_type);
6116       t->dht_get_type = NULL;
6117     }
6118     if (tree_get_status (t->tree, peer_info->id) != MESH_PEER_READY)
6119     {
6120       tree_set_status (t->tree, peer_info->id, MESH_PEER_READY);
6121       send_client_peer_connected (t, peer_info->id);
6122     }
6123     return GNUNET_OK;
6124   }
6125
6126   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
6127               "  not for us, retransmitting...\n");
6128   GNUNET_PEER_resolve (tree_get_predecessor (t->tree), &id);
6129   peer_info = peer_info_get (&msg->oid);
6130   if (NULL == peer_info)
6131   {
6132     /* If we know the tunnel, we should DEFINITELY know the peer */
6133     GNUNET_break (0);
6134     return GNUNET_OK;
6135   }
6136   send_prebuilt_message (message, &id, t);
6137   return GNUNET_OK;
6138 }
6139
6140
6141 /**
6142  * Core handler for mesh keepalives.
6143  *
6144  * @param cls closure
6145  * @param message message
6146  * @param peer peer identity this notification is about
6147  * @param atsi performance data
6148  * @param atsi_count number of records in 'atsi'
6149  * @return GNUNET_OK to keep the connection open,
6150  *         GNUNET_SYSERR to close it (signal serious error)
6151  *
6152  * TODO: Check who we got this from, to validate route.
6153  */
6154 static int
6155 handle_mesh_keepalive (void *cls, const struct GNUNET_PeerIdentity *peer,
6156                        const struct GNUNET_MessageHeader *message,
6157                        const struct GNUNET_ATS_Information *atsi,
6158                        unsigned int atsi_count)
6159 {
6160   struct GNUNET_MESH_TunnelKeepAlive *msg;
6161   struct MeshTunnel *t;
6162
6163   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "got a keepalive packet from %s\n",
6164               GNUNET_i2s (peer));
6165
6166   msg = (struct GNUNET_MESH_TunnelKeepAlive *) message;
6167   t = tunnel_get (&msg->oid, ntohl (msg->tid));
6168
6169   if (NULL == t)
6170   {
6171     /* TODO notify that we dont know that tunnel */
6172     GNUNET_STATISTICS_update (stats, "# keepalive on unknown tunnel", 1, GNUNET_NO);
6173     GNUNET_break_op (0);
6174     return GNUNET_OK;
6175   }
6176
6177   tunnel_reset_timeout (t);
6178
6179   GNUNET_STATISTICS_update (stats, "# keepalives forwarded", 1, GNUNET_NO);
6180   tunnel_send_multicast (t, message);
6181   return GNUNET_OK;
6182   }
6183
6184
6185
6186 /**
6187  * Functions to handle messages from core
6188  */
6189 static struct GNUNET_CORE_MessageHandler core_handlers[] = {
6190   {&handle_mesh_path_create, GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE, 0},
6191   {&handle_mesh_path_destroy, GNUNET_MESSAGE_TYPE_MESH_PATH_DESTROY, 0},
6192   {&handle_mesh_path_broken, GNUNET_MESSAGE_TYPE_MESH_PATH_BROKEN,
6193    sizeof (struct GNUNET_MESH_PathBroken)},
6194   {&handle_mesh_tunnel_destroy, GNUNET_MESSAGE_TYPE_MESH_TUNNEL_DESTROY,
6195    sizeof (struct GNUNET_MESH_TunnelDestroy)},
6196   {&handle_mesh_data_unicast, GNUNET_MESSAGE_TYPE_MESH_UNICAST, 0},
6197   {&handle_mesh_data_multicast, GNUNET_MESSAGE_TYPE_MESH_MULTICAST, 0},
6198   {&handle_mesh_keepalive, GNUNET_MESSAGE_TYPE_MESH_PATH_KEEPALIVE,
6199     sizeof (struct GNUNET_MESH_TunnelKeepAlive)},
6200   {&handle_mesh_data_to_orig, GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN, 0},
6201   {&handle_mesh_ack, GNUNET_MESSAGE_TYPE_MESH_ACK,
6202     sizeof (struct GNUNET_MESH_ACK)},
6203   {&handle_mesh_poll, GNUNET_MESSAGE_TYPE_MESH_POLL,
6204     sizeof (struct GNUNET_MESH_Poll)},
6205   {&handle_mesh_path_ack, GNUNET_MESSAGE_TYPE_MESH_PATH_ACK,
6206    sizeof (struct GNUNET_MESH_PathACK)},
6207   {NULL, 0, 0}
6208 };
6209
6210
6211
6212 /******************************************************************************/
6213 /****************       MESH LOCAL HANDLER HELPERS      ***********************/
6214 /******************************************************************************/
6215
6216 /**
6217  * deregister_app: iterator for removing each application registered by a client
6218  *
6219  * @param cls closure
6220  * @param key the hash of the application id (used to access the hashmap)
6221  * @param value the value stored at the key (client)
6222  *
6223  * @return GNUNET_OK on success
6224  */
6225 static int
6226 deregister_app (void *cls, const struct GNUNET_HashCode * key, void *value)
6227 {
6228   struct GNUNET_CONTAINER_MultiHashMap *h = cls;
6229   GNUNET_break (GNUNET_YES ==
6230                 GNUNET_CONTAINER_multihashmap_remove (h, key, value));
6231   return GNUNET_OK;
6232 }
6233
6234 #if LATER
6235 /**
6236  * notify_client_connection_failure: notify a client that the connection to the
6237  * requested remote peer is not possible (for instance, no route found)
6238  * Function called when the socket is ready to queue more data. "buf" will be
6239  * NULL and "size" zero if the socket was closed for writing in the meantime.
6240  *
6241  * @param cls closure
6242  * @param size number of bytes available in buf
6243  * @param buf where the callee should write the message
6244  * @return number of bytes written to buf
6245  */
6246 static size_t
6247 notify_client_connection_failure (void *cls, size_t size, void *buf)
6248 {
6249   int size_needed;
6250   struct MeshPeerInfo *peer_info;
6251   struct GNUNET_MESH_PeerControl *msg;
6252   struct GNUNET_PeerIdentity id;
6253
6254   if (0 == size && NULL == buf)
6255   {
6256     // TODO retry? cancel?
6257     return 0;
6258   }
6259
6260   size_needed = sizeof (struct GNUNET_MESH_PeerControl);
6261   peer_info = (struct MeshPeerInfo *) cls;
6262   msg = (struct GNUNET_MESH_PeerControl *) buf;
6263   msg->header.size = htons (sizeof (struct GNUNET_MESH_PeerControl));
6264   msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_DISCONNECTED);
6265 //     msg->tunnel_id = htonl(peer_info->t->tid);
6266   GNUNET_PEER_resolve (peer_info->id, &id);
6267   memcpy (&msg->peer, &id, sizeof (struct GNUNET_PeerIdentity));
6268
6269   return size_needed;
6270 }
6271 #endif
6272
6273
6274 /**
6275  * Send keepalive packets for a peer
6276  *
6277  * @param cls Closure (tunnel for which to send the keepalive).
6278  * @param tc Notification context.
6279  */
6280 static void
6281 path_refresh (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
6282 {
6283   struct MeshTunnel *t = cls;
6284   struct GNUNET_MESH_TunnelKeepAlive *msg;
6285   size_t size = sizeof (struct GNUNET_MESH_TunnelKeepAlive);
6286   char cbuf[size];
6287
6288   t->path_refresh_task = GNUNET_SCHEDULER_NO_TASK;
6289   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
6290   {
6291     return;
6292   }
6293
6294   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
6295               "sending keepalive for tunnel %d\n", t->id.tid);
6296
6297   msg = (struct GNUNET_MESH_TunnelKeepAlive *) cbuf;
6298   msg->header.size = htons (size);
6299   msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_PATH_KEEPALIVE);
6300   msg->oid = my_full_id;
6301   msg->tid = htonl (t->id.tid);
6302   tunnel_send_multicast (t, &msg->header);
6303
6304   t->path_refresh_task =
6305       GNUNET_SCHEDULER_add_delayed (refresh_path_time, &path_refresh, t);
6306   tunnel_reset_timeout(t);
6307 }
6308
6309
6310 /**
6311  * Function to process paths received for a new peer addition. The recorded
6312  * paths form the initial tunnel, which can be optimized later.
6313  * Called on each result obtained for the DHT search.
6314  *
6315  * @param cls closure
6316  * @param exp when will this value expire
6317  * @param key key of the result
6318  * @param get_path path of the get request
6319  * @param get_path_length lenght of get_path
6320  * @param put_path path of the put request
6321  * @param put_path_length length of the put_path
6322  * @param type type of the result
6323  * @param size number of bytes in data
6324  * @param data pointer to the result data
6325  *
6326  * TODO: re-issue the request after certain time? cancel after X results?
6327  */
6328 static void
6329 dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp,
6330                     const struct GNUNET_HashCode * key,
6331                     const struct GNUNET_PeerIdentity *get_path,
6332                     unsigned int get_path_length,
6333                     const struct GNUNET_PeerIdentity *put_path,
6334                     unsigned int put_path_length, enum GNUNET_BLOCK_Type type,
6335                     size_t size, const void *data)
6336 {
6337   struct MeshPathInfo *path_info = cls;
6338   struct MeshPeerPath *p;
6339   struct GNUNET_PeerIdentity pi;
6340   int i;
6341
6342   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got results from DHT!\n");
6343   GNUNET_PEER_resolve (path_info->peer->id, &pi);
6344   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  for %s\n", GNUNET_i2s (&pi));
6345
6346   p = path_build_from_dht (get_path, get_path_length, put_path,
6347                            put_path_length);
6348   path_add_to_peers (p, GNUNET_NO);
6349   path_destroy(p);
6350   for (i = 0; i < path_info->peer->ntunnels; i++)
6351   {
6352     tunnel_add_peer (path_info->peer->tunnels[i], path_info->peer);
6353     peer_info_connect (path_info->peer, path_info->t);
6354   }
6355
6356   return;
6357 }
6358
6359
6360 /**
6361  * Function to process paths received for a new peer addition. The recorded
6362  * paths form the initial tunnel, which can be optimized later.
6363  * Called on each result obtained for the DHT search.
6364  *
6365  * @param cls closure
6366  * @param exp when will this value expire
6367  * @param key key of the result
6368  * @param get_path path of the get request
6369  * @param get_path_length lenght of get_path
6370  * @param put_path path of the put request
6371  * @param put_path_length length of the put_path
6372  * @param type type of the result
6373  * @param size number of bytes in data
6374  * @param data pointer to the result data
6375  */
6376 static void
6377 dht_get_type_handler (void *cls, struct GNUNET_TIME_Absolute exp,
6378                       const struct GNUNET_HashCode * key,
6379                       const struct GNUNET_PeerIdentity *get_path,
6380                       unsigned int get_path_length,
6381                       const struct GNUNET_PeerIdentity *put_path,
6382                       unsigned int put_path_length, enum GNUNET_BLOCK_Type type,
6383                       size_t size, const void *data)
6384 {
6385   const struct PBlock *pb = data;
6386   const struct GNUNET_PeerIdentity *pi = &pb->id;
6387   struct MeshTunnel *t = cls;
6388   struct MeshPeerInfo *peer_info;
6389   struct MeshPeerPath *p;
6390
6391   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "got type DHT result!\n");
6392   if (size != sizeof (struct PBlock))
6393   {
6394     GNUNET_break_op (0);
6395     return;
6396   }
6397   if (ntohl(pb->type) != t->type)
6398   {
6399     GNUNET_break_op (0);
6400     return;
6401   }
6402   GNUNET_assert (NULL != t->owner);
6403   peer_info = peer_info_get (pi);
6404   (void) GNUNET_CONTAINER_multihashmap_put (t->peers, &pi->hashPubKey,
6405                                             peer_info,
6406                                             GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE);
6407
6408   p = path_build_from_dht (get_path, get_path_length, put_path,
6409                            put_path_length);
6410   path_add_to_peers (p, GNUNET_NO);
6411   path_destroy(p);
6412   tunnel_add_peer (t, peer_info);
6413   peer_info_connect (peer_info, t);
6414 }
6415
6416
6417 /**
6418  * Function to process DHT string to regex matching.
6419  * Called on each result obtained for the DHT search.
6420  *
6421  * @param cls closure (search context)
6422  * @param exp when will this value expire
6423  * @param key key of the result
6424  * @param get_path path of the get request (not used)
6425  * @param get_path_length lenght of get_path (not used)
6426  * @param put_path path of the put request (not used)
6427  * @param put_path_length length of the put_path (not used)
6428  * @param type type of the result
6429  * @param size number of bytes in data
6430  * @param data pointer to the result data
6431  */
6432 static void
6433 dht_get_string_accept_handler (void *cls, struct GNUNET_TIME_Absolute exp,
6434                                const struct GNUNET_HashCode * key,
6435                                const struct GNUNET_PeerIdentity *get_path,
6436                                unsigned int get_path_length,
6437                                const struct GNUNET_PeerIdentity *put_path,
6438                                unsigned int put_path_length,
6439                                enum GNUNET_BLOCK_Type type,
6440                                size_t size, const void *data)
6441 {
6442   const struct MeshRegexAccept *block = data;
6443   struct MeshRegexSearchContext *ctx = cls;
6444   struct MeshRegexSearchInfo *info = ctx->info;
6445   struct MeshPeerPath *p;
6446   struct MeshPeerInfo *peer_info;
6447
6448   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got regex results from DHT!\n");
6449   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  for %s\n", info->description);
6450
6451   peer_info = peer_info_get(&block->id);
6452   p = path_build_from_dht (get_path, get_path_length, put_path,
6453                            put_path_length);
6454   path_add_to_peers (p, GNUNET_NO);
6455   path_destroy(p);
6456
6457   tunnel_add_peer (info->t, peer_info);
6458   peer_info_connect (peer_info, info->t);
6459   if (0 == info->peer)
6460   {
6461     info->peer = peer_info->id;
6462   }
6463   else
6464   {
6465     GNUNET_array_append (info->peers, info->n_peers, peer_info->id);
6466   }
6467
6468   info->timeout = GNUNET_SCHEDULER_add_delayed (connect_timeout,
6469                                                 &regex_connect_timeout,
6470                                                 info);
6471
6472   return;
6473 }
6474
6475
6476 /**
6477  * Function to process DHT string to regex matching.
6478  * Called on each result obtained for the DHT search.
6479  *
6480  * @param cls closure (search context)
6481  * @param exp when will this value expire
6482  * @param key key of the result
6483  * @param get_path path of the get request (not used)
6484  * @param get_path_length lenght of get_path (not used)
6485  * @param put_path path of the put request (not used)
6486  * @param put_path_length length of the put_path (not used)
6487  * @param type type of the result
6488  * @param size number of bytes in data
6489  * @param data pointer to the result data
6490  *
6491  * TODO: re-issue the request after certain time? cancel after X results?
6492  */
6493 static void
6494 dht_get_string_handler (void *cls, struct GNUNET_TIME_Absolute exp,
6495                         const struct GNUNET_HashCode * key,
6496                         const struct GNUNET_PeerIdentity *get_path,
6497                         unsigned int get_path_length,
6498                         const struct GNUNET_PeerIdentity *put_path,
6499                         unsigned int put_path_length,
6500                         enum GNUNET_BLOCK_Type type,
6501                         size_t size, const void *data)
6502 {
6503   const struct MeshRegexBlock *block = data;
6504   struct MeshRegexSearchContext *ctx = cls;
6505   struct MeshRegexSearchInfo *info = ctx->info;
6506   void *copy;
6507   size_t len;
6508
6509   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
6510               "DHT GET STRING RETURNED RESULTS\n");
6511   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
6512               "  key: %s\n", GNUNET_h2s (key));
6513
6514   copy = GNUNET_malloc (size);
6515   memcpy (copy, data, size);
6516   GNUNET_break (GNUNET_OK ==
6517                 GNUNET_CONTAINER_multihashmap_put(info->dht_get_results, key, copy,
6518                                                   GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
6519   len = ntohl (block->n_proof);
6520   {
6521     char proof[len + 1];
6522
6523     memcpy (proof, &block[1], len);
6524     proof[len] = '\0';
6525     if (GNUNET_OK != GNUNET_REGEX_check_proof (proof, key))
6526     {
6527       GNUNET_break_op (0);
6528       return;
6529     }
6530   }
6531   len = strlen (info->description);
6532   if (len == ctx->position) // String processed
6533   {
6534     if (GNUNET_YES == ntohl (block->accepting))
6535     {
6536       regex_find_path(key, ctx);
6537     }
6538     else
6539     {
6540       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  block not accepting!\n");
6541       // FIXME REGEX this block not successful, wait for more? start timeout?
6542     }
6543     return;
6544   }
6545
6546   regex_next_edge (block, size, ctx);
6547
6548   return;
6549 }
6550
6551 /******************************************************************************/
6552 /*********************       MESH LOCAL HANDLES      **************************/
6553 /******************************************************************************/
6554
6555
6556 /**
6557  * Handler for client disconnection
6558  *
6559  * @param cls closure
6560  * @param client identification of the client; NULL
6561  *        for the last call when the server is destroyed
6562  */
6563 static void
6564 handle_local_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
6565 {
6566   struct MeshClient *c;
6567   struct MeshClient *next;
6568   unsigned int i;
6569
6570   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "client disconnected\n");
6571   if (client == NULL)
6572   {
6573     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   (SERVER DOWN)\n");
6574     return;
6575   }
6576   c = clients;
6577   while (NULL != c)
6578   {
6579     if (c->handle != client)
6580     {
6581       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   ... searching\n");
6582       c = c->next;
6583       continue;
6584     }
6585     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "matching client found (%u)\n",
6586                 c->id);
6587     GNUNET_SERVER_client_drop (c->handle);
6588     c->shutting_down = GNUNET_YES;
6589     GNUNET_assert (NULL != c->own_tunnels);
6590     GNUNET_assert (NULL != c->incoming_tunnels);
6591     GNUNET_CONTAINER_multihashmap_iterate (c->own_tunnels,
6592                                            &tunnel_destroy_iterator, c);
6593     GNUNET_CONTAINER_multihashmap_iterate (c->incoming_tunnels,
6594                                            &tunnel_destroy_iterator, c);
6595     GNUNET_CONTAINER_multihashmap_iterate (c->ignore_tunnels,
6596                                            &tunnel_destroy_iterator, c);
6597     GNUNET_CONTAINER_multihashmap_destroy (c->own_tunnels);
6598     GNUNET_CONTAINER_multihashmap_destroy (c->incoming_tunnels);
6599     GNUNET_CONTAINER_multihashmap_destroy (c->ignore_tunnels);
6600
6601     /* deregister clients applications */
6602     if (NULL != c->apps)
6603     {
6604       GNUNET_CONTAINER_multihashmap_iterate (c->apps, &deregister_app, c->apps);
6605       GNUNET_CONTAINER_multihashmap_destroy (c->apps);
6606     }
6607     if (0 == GNUNET_CONTAINER_multihashmap_size (applications) &&
6608         GNUNET_SCHEDULER_NO_TASK != announce_applications_task)
6609     {
6610       GNUNET_SCHEDULER_cancel (announce_applications_task);
6611       announce_applications_task = GNUNET_SCHEDULER_NO_TASK;
6612     }
6613     if (NULL != c->types)
6614       GNUNET_CONTAINER_multihashmap_destroy (c->types);
6615     for (i = 0; i < c->n_regex; i++)
6616     {
6617       GNUNET_free (c->regexes[i].regex);
6618     }
6619     GNUNET_free_non_null (c->regexes);
6620     if (GNUNET_SCHEDULER_NO_TASK != c->regex_announce_task)
6621       GNUNET_SCHEDULER_cancel (c->regex_announce_task);
6622     next = c->next;
6623     GNUNET_CONTAINER_DLL_remove (clients, clients_tail, c);
6624     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  CLIENT FREE at %p\n", c);
6625     GNUNET_free (c);
6626     GNUNET_STATISTICS_update (stats, "# clients", -1, GNUNET_NO);
6627     c = next;
6628   }
6629   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   done!\n");
6630   return;
6631 }
6632
6633
6634 /**
6635  * Handler for new clients
6636  *
6637  * @param cls closure
6638  * @param client identification of the client
6639  * @param message the actual message, which includes messages the client wants
6640  */
6641 static void
6642 handle_local_new_client (void *cls, struct GNUNET_SERVER_Client *client,
6643                          const struct GNUNET_MessageHeader *message)
6644 {
6645   struct GNUNET_MESH_ClientConnect *cc_msg;
6646   struct MeshClient *c;
6647   GNUNET_MESH_ApplicationType *a;
6648   unsigned int size;
6649   uint16_t ntypes;
6650   uint16_t *t;
6651   uint16_t napps;
6652   uint16_t i;
6653
6654   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "new client connected\n");
6655   /* Check data sanity */
6656   size = ntohs (message->size) - sizeof (struct GNUNET_MESH_ClientConnect);
6657   cc_msg = (struct GNUNET_MESH_ClientConnect *) message;
6658   ntypes = ntohs (cc_msg->types);
6659   napps = ntohs (cc_msg->applications);
6660   if (size !=
6661       ntypes * sizeof (uint16_t) + napps * sizeof (GNUNET_MESH_ApplicationType))
6662   {
6663     GNUNET_break (0);
6664     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
6665     return;
6666   }
6667
6668   /* Create new client structure */
6669   c = GNUNET_malloc (sizeof (struct MeshClient));
6670   c->id = next_client_id++;
6671   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  CLIENT NEW %u\n", c->id);
6672   c->handle = client;
6673   GNUNET_SERVER_client_keep (client);
6674   a = (GNUNET_MESH_ApplicationType *) &cc_msg[1];
6675   if (napps > 0)
6676   {
6677     GNUNET_MESH_ApplicationType at;
6678     struct GNUNET_HashCode hc;
6679
6680     c->apps = GNUNET_CONTAINER_multihashmap_create (napps, GNUNET_NO);
6681     for (i = 0; i < napps; i++)
6682     {
6683       at = ntohl (a[i]);
6684       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  app type: %u\n", at);
6685       GNUNET_CRYPTO_hash (&at, sizeof (at), &hc);
6686       /* store in clients hashmap */
6687       GNUNET_CONTAINER_multihashmap_put (c->apps, &hc, (void *) (long) at,
6688                                          GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
6689       /* store in global hashmap, for announcements */
6690       GNUNET_CONTAINER_multihashmap_put (applications, &hc, c,
6691                                          GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
6692     }
6693     if (GNUNET_SCHEDULER_NO_TASK == announce_applications_task)
6694       announce_applications_task =
6695           GNUNET_SCHEDULER_add_now (&announce_applications, NULL);
6696
6697   }
6698   if (ntypes > 0)
6699   {
6700     uint16_t u16;
6701     struct GNUNET_HashCode hc;
6702
6703     t = (uint16_t *) & a[napps];
6704     c->types = GNUNET_CONTAINER_multihashmap_create (ntypes, GNUNET_NO);
6705     for (i = 0; i < ntypes; i++)
6706     {
6707       u16 = ntohs (t[i]);
6708       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  msg type: %u\n", u16);
6709       GNUNET_CRYPTO_hash (&u16, sizeof (u16), &hc);
6710
6711       /* store in clients hashmap */
6712       GNUNET_CONTAINER_multihashmap_put (c->types, &hc, c,
6713                                          GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
6714       /* store in global hashmap */
6715       GNUNET_CONTAINER_multihashmap_put (types, &hc, c,
6716                                          GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
6717     }
6718   }
6719   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
6720               " client has %u+%u subscriptions\n", napps, ntypes);
6721
6722   GNUNET_CONTAINER_DLL_insert (clients, clients_tail, c);
6723   c->own_tunnels = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
6724   c->incoming_tunnels = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
6725   c->ignore_tunnels = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
6726   GNUNET_SERVER_notification_context_add (nc, client);
6727   GNUNET_STATISTICS_update (stats, "# clients", 1, GNUNET_NO);
6728
6729   GNUNET_SERVER_receive_done (client, GNUNET_OK);
6730   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "new client processed\n");
6731 }
6732
6733
6734 /**
6735  * Handler for clients announcing available services by a regular expression.
6736  *
6737  * @param cls closure
6738  * @param client identification of the client
6739  * @param message the actual message, which includes messages the client wants
6740  */
6741 static void
6742 handle_local_announce_regex (void *cls, struct GNUNET_SERVER_Client *client,
6743                              const struct GNUNET_MessageHeader *message)
6744 {
6745   struct GNUNET_MESH_RegexAnnounce *msg;
6746   struct MeshRegexDescriptor rd;
6747   struct MeshClient *c;
6748   char *regex;
6749   size_t len;
6750
6751   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "announce regex started\n");
6752
6753   /* Sanity check for client registration */
6754   if (NULL == (c = client_get (client)))
6755   {
6756     GNUNET_break (0);
6757     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
6758     return;
6759   }
6760   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  by client %u\n", c->id);
6761
6762   msg = (struct GNUNET_MESH_RegexAnnounce *) message;
6763   len = ntohs (message->size) - sizeof(struct GNUNET_MESH_RegexAnnounce);
6764   regex = GNUNET_malloc (len + 1);
6765   memcpy (regex, &msg[1], len);
6766   regex[len] = '\0';
6767   rd.regex = regex;
6768   rd.compression = ntohs (msg->compression_characters);
6769   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  length %u\n", len);
6770   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  regex %s\n", regex);
6771   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  cm %u\n", ntohs(rd.compression));
6772   GNUNET_array_append (c->regexes, c->n_regex, rd);
6773   if (GNUNET_SCHEDULER_NO_TASK == c->regex_announce_task)
6774   {
6775     c->regex_announce_task = GNUNET_SCHEDULER_add_now(&announce_regex, c);
6776   }
6777   else
6778   {
6779     regex_put(&rd);
6780   }
6781   GNUNET_SERVER_receive_done (client, GNUNET_OK);
6782   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "announce regex processed\n");
6783 }
6784
6785
6786 /**
6787  * Handler for requests of new tunnels
6788  *
6789  * @param cls closure
6790  * @param client identification of the client
6791  * @param message the actual message
6792  */
6793 static void
6794 handle_local_tunnel_create (void *cls, struct GNUNET_SERVER_Client *client,
6795                             const struct GNUNET_MessageHeader *message)
6796 {
6797   struct GNUNET_MESH_TunnelMessage *t_msg;
6798   struct MeshTunnel *t;
6799   struct MeshClient *c;
6800   MESH_TunnelNumber tid;
6801
6802   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "new tunnel requested\n");
6803
6804   /* Sanity check for client registration */
6805   if (NULL == (c = client_get (client)))
6806   {
6807     GNUNET_break (0);
6808     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
6809     return;
6810   }
6811   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  by client %u\n", c->id);
6812
6813   /* Message sanity check */
6814   if (sizeof (struct GNUNET_MESH_TunnelMessage) != ntohs (message->size))
6815   {
6816     GNUNET_break (0);
6817     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
6818     return;
6819   }
6820
6821   t_msg = (struct GNUNET_MESH_TunnelMessage *) message;
6822   /* Sanity check for tunnel numbering */
6823   tid = ntohl (t_msg->tunnel_id);
6824   if (0 == (tid & GNUNET_MESH_LOCAL_TUNNEL_ID_CLI))
6825   {
6826     GNUNET_break (0);
6827     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
6828     return;
6829   }
6830   /* Sanity check for duplicate tunnel IDs */
6831   if (NULL != tunnel_get_by_local_id (c, tid))
6832   {
6833     GNUNET_break (0);
6834     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
6835     return;
6836   }
6837
6838   while (NULL != tunnel_get_by_pi (myid, next_tid))
6839     next_tid = (next_tid + 1) & ~GNUNET_MESH_LOCAL_TUNNEL_ID_CLI;
6840   t = tunnel_new (myid, next_tid++, c, tid);
6841   if (NULL == t)
6842   {
6843     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Tunnel creation failed.\n");
6844     GNUNET_break (0);
6845     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
6846     return;
6847   }
6848   next_tid = next_tid & ~GNUNET_MESH_LOCAL_TUNNEL_ID_CLI;
6849   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CREATED TUNNEL %s [%x] (%x)\n",
6850               GNUNET_i2s (&my_full_id), t->id.tid, t->local_tid);
6851   t->peers = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
6852
6853   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "new tunnel created\n");
6854   GNUNET_SERVER_receive_done (client, GNUNET_OK);
6855   return;
6856 }
6857
6858
6859 /**
6860  * Handler for requests of deleting tunnels
6861  *
6862  * @param cls closure
6863  * @param client identification of the client
6864  * @param message the actual message
6865  */
6866 static void
6867 handle_local_tunnel_destroy (void *cls, struct GNUNET_SERVER_Client *client,
6868                              const struct GNUNET_MessageHeader *message)
6869 {
6870   struct GNUNET_MESH_TunnelMessage *tunnel_msg;
6871   struct MeshClient *c;
6872   struct MeshTunnel *t;
6873   MESH_TunnelNumber tid;
6874
6875   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
6876               "Got a DESTROY TUNNEL from client!\n");
6877
6878   /* Sanity check for client registration */
6879   if (NULL == (c = client_get (client)))
6880   {
6881     GNUNET_break (0);
6882     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
6883     return;
6884   }
6885   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  by client %u\n", c->id);
6886
6887   /* Message sanity check */
6888   if (sizeof (struct GNUNET_MESH_TunnelMessage) != ntohs (message->size))
6889   {
6890     GNUNET_break (0);
6891     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
6892     return;
6893   }
6894
6895   tunnel_msg = (struct GNUNET_MESH_TunnelMessage *) message;
6896
6897   /* Retrieve tunnel */
6898   tid = ntohl (tunnel_msg->tunnel_id);
6899   t = tunnel_get_by_local_id(c, tid);
6900   if (NULL == t)
6901   {
6902     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "  tunnel %X not found\n", tid);
6903     GNUNET_break (0);
6904     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
6905     return;
6906   }
6907   if (c != t->owner || tid >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV)
6908   {
6909     client_ignore_tunnel (c, t);
6910 #if 0
6911     // TODO: when to destroy incoming tunnel?
6912     if (t->nclients == 0)
6913     {
6914       GNUNET_assert (GNUNET_YES ==
6915                      GNUNET_CONTAINER_multihashmap_remove (incoming_tunnels,
6916                                                            &hash, t));
6917       GNUNET_assert (GNUNET_YES ==
6918                      GNUNET_CONTAINER_multihashmap_remove (t->peers,
6919                                                            &my_full_id.hashPubKey,
6920                                                            t));
6921     }
6922 #endif
6923     GNUNET_SERVER_receive_done (client, GNUNET_OK);
6924     return;
6925   }
6926   send_client_tunnel_disconnect(t, c);
6927   client_delete_tunnel(c, t);
6928
6929   /* Don't try to ACK the client about the tunnel_destroy multicast packet */
6930   t->owner = NULL;
6931   tunnel_send_destroy (t);
6932   t->destroy = GNUNET_YES;
6933   // The tunnel will be destroyed when the last message is transmitted.
6934   GNUNET_SERVER_receive_done (client, GNUNET_OK);
6935   return;
6936 }
6937
6938
6939 /**
6940  * Handler for requests of seeting tunnel's speed.
6941  *
6942  * @param cls Closure (unused).
6943  * @param client Identification of the client.
6944  * @param message The actual message.
6945  */
6946 static void
6947 handle_local_tunnel_speed (void *cls, struct GNUNET_SERVER_Client *client,
6948                            const struct GNUNET_MessageHeader *message)
6949 {
6950   struct GNUNET_MESH_TunnelMessage *tunnel_msg;
6951   struct MeshClient *c;
6952   struct MeshTunnel *t;
6953   MESH_TunnelNumber tid;
6954
6955   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
6956               "Got a SPEED request from client!\n");
6957
6958   /* Sanity check for client registration */
6959   if (NULL == (c = client_get (client)))
6960   {
6961     GNUNET_break (0);
6962     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
6963     return;
6964   }
6965
6966   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  by client %u\n", c->id);
6967
6968   tunnel_msg = (struct GNUNET_MESH_TunnelMessage *) message;
6969
6970   /* Retrieve tunnel */
6971   tid = ntohl (tunnel_msg->tunnel_id);
6972   t = tunnel_get_by_local_id(c, tid);
6973   if (NULL == t)
6974   {
6975     GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "  tunnel %X not found\n", tid);
6976     GNUNET_break (0);
6977     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
6978     return;
6979   }
6980
6981   switch (ntohs(message->type))
6982   {
6983       case GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_MIN:
6984           t->speed_min = GNUNET_YES;
6985           break;
6986       case GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_MAX:
6987           t->speed_min = GNUNET_NO;
6988           break;
6989       default:
6990           GNUNET_break (0);
6991   }
6992   GNUNET_SERVER_receive_done (client, GNUNET_OK);
6993 }
6994
6995
6996 /**
6997  * Handler for requests of seeting tunnel's buffering policy.
6998  *
6999  * @param cls Closure (unused).
7000  * @param client Identification of the client.
7001  * @param message The actual message.
7002  */
7003 static void
7004 handle_local_tunnel_buffer (void *cls, struct GNUNET_SERVER_Client *client,
7005                             const struct GNUNET_MessageHeader *message)
7006 {
7007   struct GNUNET_MESH_TunnelMessage *tunnel_msg;
7008   struct MeshClient *c;
7009   struct MeshTunnel *t;
7010   MESH_TunnelNumber tid;
7011
7012   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
7013               "Got a BUFFER request from client!\n");
7014
7015   /* Sanity check for client registration */
7016   if (NULL == (c = client_get (client)))
7017   {
7018     GNUNET_break (0);
7019     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
7020     return;
7021   }
7022   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  by client %u\n", c->id);
7023
7024   tunnel_msg = (struct GNUNET_MESH_TunnelMessage *) message;
7025
7026   /* Retrieve tunnel */
7027   tid = ntohl (tunnel_msg->tunnel_id);
7028   t = tunnel_get_by_local_id(c, tid);
7029   if (NULL == t)
7030   {
7031     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "  tunnel %X not found\n", tid);
7032     GNUNET_break (0);
7033     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
7034     return;
7035   }
7036
7037   switch (ntohs(message->type))
7038   {
7039       case GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_BUFFER:
7040           t->nobuffer = GNUNET_NO;
7041           break;
7042       case GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_NOBUFFER:
7043           t->nobuffer = GNUNET_YES;
7044           break;
7045       default:
7046           GNUNET_break (0);
7047   }
7048
7049   GNUNET_SERVER_receive_done (client, GNUNET_OK);
7050 }
7051
7052
7053 /**
7054  * Handler for connection requests to new peers
7055  *
7056  * @param cls closure
7057  * @param client identification of the client
7058  * @param message the actual message (PeerControl)
7059  */
7060 static void
7061 handle_local_connect_add (void *cls, struct GNUNET_SERVER_Client *client,
7062                           const struct GNUNET_MessageHeader *message)
7063 {
7064   struct GNUNET_MESH_PeerControl *peer_msg;
7065   struct MeshPeerInfo *peer_info;
7066   struct MeshClient *c;
7067   struct MeshTunnel *t;
7068   MESH_TunnelNumber tid;
7069
7070   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got connection request\n");
7071   /* Sanity check for client registration */
7072   if (NULL == (c = client_get (client)))
7073   {
7074     GNUNET_break (0);
7075     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
7076     return;
7077   }
7078   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  by client %u\n", c->id);
7079
7080   peer_msg = (struct GNUNET_MESH_PeerControl *) message;
7081
7082   /* Sanity check for message size */
7083   if (sizeof (struct GNUNET_MESH_PeerControl) != ntohs (peer_msg->header.size))
7084   {
7085     GNUNET_break (0);
7086     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
7087     return;
7088   }
7089
7090   /* Tunnel exists? */
7091   tid = ntohl (peer_msg->tunnel_id);
7092   t = tunnel_get_by_local_id (c, tid);
7093   if (NULL == t)
7094   {
7095     GNUNET_break (0);
7096     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
7097     return;
7098   }
7099
7100   /* Does client own tunnel? */
7101   if (t->owner->handle != client)
7102   {
7103     GNUNET_break (0);
7104     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
7105     return;
7106   }
7107   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "     for %s\n",
7108               GNUNET_i2s (&peer_msg->peer));
7109   peer_info = peer_info_get (&peer_msg->peer);
7110
7111   tunnel_add_peer (t, peer_info);
7112   peer_info_connect (peer_info, t);
7113
7114   GNUNET_SERVER_receive_done (client, GNUNET_OK);
7115   return;
7116 }
7117
7118
7119 /**
7120  * Handler for disconnection requests of peers in a tunnel
7121  *
7122  * @param cls closure
7123  * @param client identification of the client
7124  * @param message the actual message (PeerControl)
7125  */
7126 static void
7127 handle_local_connect_del (void *cls, struct GNUNET_SERVER_Client *client,
7128                           const struct GNUNET_MessageHeader *message)
7129 {
7130   struct GNUNET_MESH_PeerControl *peer_msg;
7131   struct MeshPeerInfo *peer_info;
7132   struct MeshClient *c;
7133   struct MeshTunnel *t;
7134   MESH_TunnelNumber tid;
7135
7136   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got a PEER DEL request\n");
7137   /* Sanity check for client registration */
7138   if (NULL == (c = client_get (client)))
7139   {
7140     GNUNET_break (0);
7141     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
7142     return;
7143   }
7144   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  by client %u\n", c->id);
7145
7146   peer_msg = (struct GNUNET_MESH_PeerControl *) message;
7147
7148   /* Sanity check for message size */
7149   if (sizeof (struct GNUNET_MESH_PeerControl) != ntohs (peer_msg->header.size))
7150   {
7151     GNUNET_break (0);
7152     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
7153     return;
7154   }
7155
7156   /* Tunnel exists? */
7157   tid = ntohl (peer_msg->tunnel_id);
7158   t = tunnel_get_by_local_id (c, tid);
7159   if (NULL == t)
7160   {
7161     GNUNET_break (0);
7162     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
7163     return;
7164   }
7165   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  on tunnel %X\n", t->id.tid);
7166
7167   /* Does client own tunnel? */
7168   if (t->owner->handle != client)
7169   {
7170     GNUNET_break (0);
7171     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
7172     return;
7173   }
7174
7175   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  for peer %s\n",
7176               GNUNET_i2s (&peer_msg->peer));
7177   /* Is the peer in the tunnel? */
7178   peer_info =
7179       GNUNET_CONTAINER_multihashmap_get (t->peers, &peer_msg->peer.hashPubKey);
7180   if (NULL == peer_info)
7181   {
7182     GNUNET_break (0);
7183     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
7184     return;
7185   }
7186
7187   /* Ok, delete peer from tunnel */
7188   GNUNET_CONTAINER_multihashmap_remove_all (t->peers,
7189                                             &peer_msg->peer.hashPubKey);
7190
7191   send_destroy_path (t, peer_info->id);
7192   tunnel_delete_peer (t, peer_info->id);
7193   GNUNET_SERVER_receive_done (client, GNUNET_OK);
7194   return;
7195 }
7196
7197 /**
7198  * Handler for blacklist requests of peers in a tunnel
7199  *
7200  * @param cls closure
7201  * @param client identification of the client
7202  * @param message the actual message (PeerControl)
7203  * 
7204  * FIXME implement DHT block bloomfilter
7205  */
7206 static void
7207 handle_local_blacklist (void *cls, struct GNUNET_SERVER_Client *client,
7208                           const struct GNUNET_MessageHeader *message)
7209 {
7210   struct GNUNET_MESH_PeerControl *peer_msg;
7211   struct MeshClient *c;
7212   struct MeshTunnel *t;
7213   MESH_TunnelNumber tid;
7214
7215   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got a PEER BLACKLIST request\n");
7216   /* Sanity check for client registration */
7217   if (NULL == (c = client_get (client)))
7218   {
7219     GNUNET_break (0);
7220     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
7221     return;
7222   }
7223   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  by client %u\n", c->id);
7224
7225   peer_msg = (struct GNUNET_MESH_PeerControl *) message;
7226
7227   /* Sanity check for message size */
7228   if (sizeof (struct GNUNET_MESH_PeerControl) != ntohs (peer_msg->header.size))
7229   {
7230     GNUNET_break (0);
7231     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
7232     return;
7233   }
7234
7235   /* Tunnel exists? */
7236   tid = ntohl (peer_msg->tunnel_id);
7237   t = tunnel_get_by_local_id (c, tid);
7238   if (NULL == t)
7239   {
7240     GNUNET_break (0);
7241     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
7242     return;
7243   }
7244   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  on tunnel %X\n", t->id.tid);
7245
7246   GNUNET_array_append(t->blacklisted, t->nblacklisted,
7247                       GNUNET_PEER_intern(&peer_msg->peer));
7248 }
7249
7250
7251 /**
7252  * Handler for unblacklist requests of peers in a tunnel
7253  *
7254  * @param cls closure
7255  * @param client identification of the client
7256  * @param message the actual message (PeerControl)
7257  */
7258 static void
7259 handle_local_unblacklist (void *cls, struct GNUNET_SERVER_Client *client,
7260                           const struct GNUNET_MessageHeader *message)
7261 {
7262   struct GNUNET_MESH_PeerControl *peer_msg;
7263   struct MeshClient *c;
7264   struct MeshTunnel *t;
7265   MESH_TunnelNumber tid;
7266   GNUNET_PEER_Id pid;
7267   unsigned int i;
7268
7269   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got a PEER UNBLACKLIST request\n");
7270   /* Sanity check for client registration */
7271   if (NULL == (c = client_get (client)))
7272   {
7273     GNUNET_break (0);
7274     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
7275     return;
7276   }
7277   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  by client %u\n", c->id);
7278
7279   peer_msg = (struct GNUNET_MESH_PeerControl *) message;
7280
7281   /* Sanity check for message size */
7282   if (sizeof (struct GNUNET_MESH_PeerControl) != ntohs (peer_msg->header.size))
7283   {
7284     GNUNET_break (0);
7285     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
7286     return;
7287   }
7288
7289   /* Tunnel exists? */
7290   tid = ntohl (peer_msg->tunnel_id);
7291   t = tunnel_get_by_local_id (c, tid);
7292   if (NULL == t)
7293   {
7294     GNUNET_break (0);
7295     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
7296     return;
7297   }
7298   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  on tunnel %X\n", t->id.tid);
7299
7300   /* if peer is not known, complain */
7301   pid = GNUNET_PEER_search (&peer_msg->peer);
7302   if (0 == pid)
7303   {
7304     GNUNET_break (0);
7305     return;
7306   }
7307
7308   /* search and remove from list */
7309   for (i = 0; i < t->nblacklisted; i++)
7310   {
7311     if (t->blacklisted[i] == pid)
7312     {
7313       t->blacklisted[i] = t->blacklisted[t->nblacklisted - 1];
7314       GNUNET_array_grow (t->blacklisted, t->nblacklisted, t->nblacklisted - 1);
7315       return;
7316     }
7317   }
7318
7319   /* if peer hasn't been blacklisted, complain */
7320   GNUNET_break (0);
7321 }
7322
7323
7324 /**
7325  * Handler for connection requests to new peers by type
7326  *
7327  * @param cls closure
7328  * @param client identification of the client
7329  * @param message the actual message (ConnectPeerByType)
7330  */
7331 static void
7332 handle_local_connect_by_type (void *cls, struct GNUNET_SERVER_Client *client,
7333                               const struct GNUNET_MessageHeader *message)
7334 {
7335   struct GNUNET_MESH_ConnectPeerByType *connect_msg;
7336   struct MeshClient *c;
7337   struct MeshTunnel *t;
7338   struct GNUNET_HashCode hash;
7339   MESH_TunnelNumber tid;
7340
7341   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "got connect by type request\n");
7342   /* Sanity check for client registration */
7343   if (NULL == (c = client_get (client)))
7344   {
7345     GNUNET_break (0);
7346     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
7347     return;
7348   }
7349   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  by client %u\n", c->id);
7350
7351   connect_msg = (struct GNUNET_MESH_ConnectPeerByType *) message;
7352
7353   /* Sanity check for message size */
7354   if (sizeof (struct GNUNET_MESH_ConnectPeerByType) !=
7355       ntohs (connect_msg->header.size))
7356   {
7357     GNUNET_break (0);
7358     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
7359     return;
7360   }
7361
7362   /* Tunnel exists? */
7363   tid = ntohl (connect_msg->tunnel_id);
7364   t = tunnel_get_by_local_id (c, tid);
7365   if (NULL == t)
7366   {
7367     GNUNET_break (0);
7368     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
7369     return;
7370   }
7371
7372   /* Does client own tunnel? */
7373   if (t->owner->handle != client)
7374   {
7375     GNUNET_break (0);
7376     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
7377     return;
7378   }
7379
7380   /* Do WE have the service? */
7381   t->type = ntohl (connect_msg->type);
7382   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " type requested: %u\n", t->type);
7383   GNUNET_CRYPTO_hash (&t->type, sizeof (GNUNET_MESH_ApplicationType), &hash);
7384   if (GNUNET_CONTAINER_multihashmap_contains (applications, &hash) ==
7385       GNUNET_YES)
7386   {
7387     /* Yes! Fast forward, add ourselves to the tunnel and send the
7388      * good news to the client, and alert the destination client of
7389      * an incoming tunnel.
7390      *
7391      * FIXME send a path create to self, avoid code duplication
7392      */
7393     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " available locally\n");
7394     GNUNET_CONTAINER_multihashmap_put (t->peers, &my_full_id.hashPubKey,
7395                                        peer_info_get (&my_full_id),
7396                                        GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
7397
7398     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " notifying client\n");
7399     send_client_peer_connected (t, myid);
7400     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " Done\n");
7401     GNUNET_SERVER_receive_done (client, GNUNET_OK);
7402
7403     t->local_tid_dest = next_local_tid++;
7404     GNUNET_CRYPTO_hash (&t->local_tid_dest, sizeof (MESH_TunnelNumber), &hash);
7405     GNUNET_CONTAINER_multihashmap_put (incoming_tunnels, &hash, t,
7406                                        GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
7407
7408     return;
7409   }
7410   /* Ok, lets find a peer offering the service */
7411   if (NULL != t->dht_get_type)
7412   {
7413     GNUNET_DHT_get_stop (t->dht_get_type);
7414   }
7415   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " looking in DHT for %s\n",
7416               GNUNET_h2s (&hash));
7417   t->dht_get_type =
7418       GNUNET_DHT_get_start (dht_handle, 
7419                             GNUNET_BLOCK_TYPE_MESH_PEER_BY_TYPE,
7420                             &hash,
7421                             dht_replication_level,
7422                             GNUNET_DHT_RO_RECORD_ROUTE |
7423                             GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE,
7424                             NULL, 0,
7425                             &dht_get_type_handler, t);
7426
7427   GNUNET_SERVER_receive_done (client, GNUNET_OK);
7428   return;
7429 }
7430
7431
7432 /**
7433  * Handler for connection requests to new peers by a string service description.
7434  *
7435  * @param cls closure
7436  * @param client identification of the client
7437  * @param message the actual message, which includes messages the client wants
7438  */
7439 static void
7440 handle_local_connect_by_string (void *cls, struct GNUNET_SERVER_Client *client,
7441                                 const struct GNUNET_MessageHeader *message)
7442 {
7443   struct GNUNET_MESH_ConnectPeerByString *msg;
7444   struct MeshRegexSearchContext *ctx;
7445   struct MeshRegexSearchInfo *info;
7446   struct GNUNET_DHT_GetHandle *get_h;
7447   struct GNUNET_HashCode key;
7448   struct MeshTunnel *t;
7449   struct MeshClient *c;
7450   MESH_TunnelNumber tid;
7451   const char *string;
7452   size_t size;
7453   size_t len;
7454   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
7455               "Connect by string started\n");
7456   msg = (struct GNUNET_MESH_ConnectPeerByString *) message;
7457   size = htons (message->size);
7458
7459   /* Sanity check for client registration */
7460   if (NULL == (c = client_get (client)))
7461   {
7462     GNUNET_break (0);
7463     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
7464     return;
7465   }
7466   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  by client %u\n", c->id);
7467
7468   /* Message size sanity check */
7469   if (sizeof(struct GNUNET_MESH_ConnectPeerByString) >= size)
7470   {
7471     GNUNET_break (0);
7472     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
7473     return;
7474   }
7475
7476   /* Tunnel exists? */
7477   tid = ntohl (msg->tunnel_id);
7478   t = tunnel_get_by_local_id (c, tid);
7479   if (NULL == t)
7480   {
7481     GNUNET_break (0);
7482     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
7483     return;
7484   }
7485
7486   /* Does client own tunnel? */
7487   if (t->owner->handle != client)
7488   {
7489     GNUNET_break (0);
7490     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
7491     return;
7492   }
7493
7494   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
7495               "  on tunnel %s [%u]\n",
7496               GNUNET_i2s(&my_full_id),
7497               t->id.tid);
7498
7499   /* Only one connect_by_string allowed at the same time! */
7500   /* FIXME: allow more, return handle at api level to cancel, document */
7501   if (NULL != t->regex_ctx)
7502   {
7503     GNUNET_break (0);
7504     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
7505     return;
7506   }
7507
7508   /* Find string itself */
7509   len = size - sizeof(struct GNUNET_MESH_ConnectPeerByString);
7510   string = (const char *) &msg[1];
7511
7512   /* Initialize context */
7513   size = GNUNET_REGEX_get_first_key(string, len, &key);
7514   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
7515               "  consumed %u bits out of %u\n", size, len);
7516   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
7517               "  looking for %s\n", GNUNET_h2s (&key));
7518
7519   info = GNUNET_malloc (sizeof (struct MeshRegexSearchInfo));
7520   info->t = t;
7521   info->description = GNUNET_malloc (len + 1);
7522   memcpy (info->description, string, len);
7523   info->description[len] = '\0';
7524   info->dht_get_handles = GNUNET_CONTAINER_multihashmap_create(32, GNUNET_NO);
7525   info->dht_get_results = GNUNET_CONTAINER_multihashmap_create(32, GNUNET_NO);
7526   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   string: %s\n", info->description);
7527
7528   ctx = GNUNET_malloc (sizeof (struct MeshRegexSearchContext));
7529   ctx->position = size;
7530   ctx->info = info;
7531   t->regex_ctx = ctx;
7532
7533   GNUNET_array_append (info->contexts, info->n_contexts, ctx);
7534
7535   /* Start search in DHT */
7536   get_h = GNUNET_DHT_get_start (dht_handle,    /* handle */
7537                                 GNUNET_BLOCK_TYPE_MESH_REGEX, /* type */
7538                                 &key,     /* key to search */
7539                                 dht_replication_level, /* replication level */
7540                                 GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE,
7541                                 NULL,       /* xquery */ // FIXME BLOOMFILTER
7542                                 0,     /* xquery bits */ // FIXME BLOOMFILTER SIZE
7543                                 &dht_get_string_handler, ctx);
7544
7545   GNUNET_break (GNUNET_OK ==
7546                 GNUNET_CONTAINER_multihashmap_put(info->dht_get_handles,
7547                                                   &key,
7548                                                   get_h,
7549                                                   GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST));
7550
7551   GNUNET_SERVER_receive_done (client, GNUNET_OK);
7552   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "connect by string processed\n");
7553 }
7554
7555
7556 /**
7557  * Handler for client traffic directed to one peer
7558  *
7559  * @param cls closure
7560  * @param client identification of the client
7561  * @param message the actual message
7562  */
7563 static void
7564 handle_local_unicast (void *cls, struct GNUNET_SERVER_Client *client,
7565                       const struct GNUNET_MessageHeader *message)
7566 {
7567   struct MeshClient *c;
7568   struct MeshTunnel *t;
7569   struct MeshPeerInfo *pi;
7570   struct GNUNET_MESH_Unicast *data_msg;
7571   MESH_TunnelNumber tid;
7572   size_t size;
7573
7574   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
7575               "Got a unicast request from a client!\n");
7576
7577   /* Sanity check for client registration */
7578   if (NULL == (c = client_get (client)))
7579   {
7580     GNUNET_break (0);
7581     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
7582     return;
7583   }
7584   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  by client %u\n", c->id);
7585
7586   data_msg = (struct GNUNET_MESH_Unicast *) message;
7587
7588   /* Sanity check for message size */
7589   size = ntohs (message->size);
7590   if (sizeof (struct GNUNET_MESH_Unicast) +
7591       sizeof (struct GNUNET_MessageHeader) > size)
7592   {
7593     GNUNET_break (0);
7594     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
7595     return;
7596   }
7597
7598   /* Tunnel exists? */
7599   tid = ntohl (data_msg->tid);
7600   t = tunnel_get_by_local_id (c, tid);
7601   if (NULL == t)
7602   {
7603     GNUNET_break (0);
7604     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
7605     return;
7606   }
7607
7608   /*  Is it a local tunnel? Then, does client own the tunnel? */
7609   if (t->owner->handle != client)
7610   {
7611     GNUNET_break (0);
7612     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
7613     return;
7614   }
7615
7616   pi = GNUNET_CONTAINER_multihashmap_get (t->peers,
7617                                           &data_msg->destination.hashPubKey);
7618   /* Is the selected peer in the tunnel? */
7619   if (NULL == pi)
7620   {
7621     GNUNET_break (0);
7622     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
7623     return;
7624   }
7625
7626   /* PID should be as expected */
7627   if (ntohl (data_msg->pid) != t->fwd_pid + 1)
7628   {
7629     GNUNET_break (0);
7630     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
7631               "Unicast PID, expected %u, got %u\n",
7632               t->fwd_pid + 1, ntohl (data_msg->pid));
7633     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
7634     return;
7635   }
7636
7637   /* Ok, everything is correct, send the message
7638    * (pretend we got it from a mesh peer)
7639    */
7640   {
7641     /* Work around const limitation */
7642     char buf[ntohs (message->size)] GNUNET_ALIGN;
7643     struct GNUNET_MESH_Unicast *copy;
7644
7645     copy = (struct GNUNET_MESH_Unicast *) buf;
7646     memcpy (buf, data_msg, size);
7647     copy->oid = my_full_id;
7648     copy->tid = htonl (t->id.tid);
7649     copy->ttl = htonl (default_ttl);
7650     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
7651                 "  calling generic handler...\n");
7652     handle_mesh_data_unicast (NULL, &my_full_id, &copy->header, NULL, 0);
7653   }
7654   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "receive done OK\n");
7655   GNUNET_SERVER_receive_done (client, GNUNET_OK);
7656
7657   return;
7658 }
7659
7660
7661 /**
7662  * Handler for client traffic directed to the origin
7663  *
7664  * @param cls closure
7665  * @param client identification of the client
7666  * @param message the actual message
7667  */
7668 static void
7669 handle_local_to_origin (void *cls, struct GNUNET_SERVER_Client *client,
7670                         const struct GNUNET_MessageHeader *message)
7671 {
7672   struct GNUNET_MESH_ToOrigin *data_msg;
7673   struct MeshTunnelFlowControlInfo *fcinfo;
7674   struct MeshClient *c;
7675   struct MeshTunnel *t;
7676   MESH_TunnelNumber tid;
7677   size_t size;
7678
7679   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
7680               "Got a ToOrigin request from a client!\n");
7681   /* Sanity check for client registration */
7682   if (NULL == (c = client_get (client)))
7683   {
7684     GNUNET_break (0);
7685     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
7686     return;
7687   }
7688   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  by client %u\n", c->id);
7689
7690   data_msg = (struct GNUNET_MESH_ToOrigin *) message;
7691
7692   /* Sanity check for message size */
7693   size = ntohs (message->size);
7694   if (sizeof (struct GNUNET_MESH_ToOrigin) +
7695       sizeof (struct GNUNET_MessageHeader) > size)
7696   {
7697     GNUNET_break (0);
7698     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
7699     return;
7700   }
7701
7702   /* Tunnel exists? */
7703   tid = ntohl (data_msg->tid);
7704   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  on tunnel %X\n", tid);
7705   if (tid < GNUNET_MESH_LOCAL_TUNNEL_ID_SERV)
7706   {
7707     GNUNET_break (0);
7708     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
7709     return;
7710   }
7711   t = tunnel_get_by_local_id (c, tid);
7712   if (NULL == t)
7713   {
7714     GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Tunnel %X unknown.\n", tid);
7715     GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "  for client %u.\n", c->id);
7716     GNUNET_break (0);
7717     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
7718     return;
7719   }
7720
7721   /*  It should be sent by someone who has this as incoming tunnel. */
7722   if (GNUNET_NO == client_knows_tunnel (c, t))
7723   {
7724     GNUNET_break (0);
7725     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
7726     return;
7727   }
7728
7729   /* PID should be as expected */
7730   fcinfo = tunnel_get_client_fc (t, c);
7731   if (ntohl (data_msg->pid) != fcinfo->bck_pid + 1)
7732   {
7733     GNUNET_break (0);
7734     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
7735                 "To Origin PID, expected %u, got %u\n",
7736                 fcinfo->bck_pid + 1,
7737                 ntohl (data_msg->pid));
7738     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
7739     return;
7740   }
7741   fcinfo->bck_pid++;
7742
7743   /* Ok, everything is correct, send the message
7744    * (pretend we got it from a mesh peer)
7745    */
7746   {
7747     char buf[ntohs (message->size)] GNUNET_ALIGN;
7748     struct GNUNET_MESH_ToOrigin *copy;
7749
7750     /* Work around const limitation */
7751     copy = (struct GNUNET_MESH_ToOrigin *) buf;
7752     memcpy (buf, data_msg, size);
7753     GNUNET_PEER_resolve (t->id.oid, &copy->oid);
7754     copy->tid = htonl (t->id.tid);
7755     copy->ttl = htonl (default_ttl);
7756     copy->pid = htonl (t->bck_pid + 1);
7757
7758     copy->sender = my_full_id;
7759     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
7760                 "  calling generic handler...\n");
7761     handle_mesh_data_to_orig (NULL, &my_full_id, &copy->header, NULL, 0);
7762   }
7763   GNUNET_SERVER_receive_done (client, GNUNET_OK);
7764
7765   return;
7766 }
7767
7768
7769 /**
7770  * Handler for client traffic directed to all peers in a tunnel
7771  *
7772  * @param cls closure
7773  * @param client identification of the client
7774  * @param message the actual message
7775  */
7776 static void
7777 handle_local_multicast (void *cls, struct GNUNET_SERVER_Client *client,
7778                         const struct GNUNET_MessageHeader *message)
7779 {
7780   struct MeshClient *c;
7781   struct MeshTunnel *t;
7782   struct GNUNET_MESH_Multicast *data_msg;
7783   MESH_TunnelNumber tid;
7784
7785   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
7786               "Got a multicast request from a client!\n");
7787
7788   /* Sanity check for client registration */
7789   if (NULL == (c = client_get (client)))
7790   {
7791     GNUNET_break (0);
7792     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
7793     return;
7794   }
7795   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  by client %u\n", c->id);
7796
7797   data_msg = (struct GNUNET_MESH_Multicast *) message;
7798
7799   /* Sanity check for message size */
7800   if (sizeof (struct GNUNET_MESH_Multicast) +
7801       sizeof (struct GNUNET_MessageHeader) > ntohs (data_msg->header.size))
7802   {
7803     GNUNET_break (0);
7804     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
7805     return;
7806   }
7807
7808   /* Tunnel exists? */
7809   tid = ntohl (data_msg->tid);
7810   t = tunnel_get_by_local_id (c, tid);
7811   if (NULL == t)
7812   {
7813     GNUNET_break (0);
7814     GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Tunnel %X unknown.\n", tid);
7815     GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "  for client %u.\n", c->id);
7816     GNUNET_break (0);
7817     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
7818     return;
7819   }
7820
7821   /* Does client own tunnel? */
7822   if (t->owner->handle != client)
7823   {
7824     GNUNET_break (0);
7825     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
7826     return;
7827   }
7828
7829   /* PID should be as expected */
7830   if (ntohl (data_msg->pid) != t->fwd_pid + 1)
7831   {
7832     GNUNET_break (0);
7833     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
7834               "Multicast PID, expected %u, got %u\n",
7835               t->fwd_pid + 1, ntohl (data_msg->pid));
7836     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
7837     return;
7838   }
7839
7840   {
7841     char buf[ntohs (message->size)] GNUNET_ALIGN;
7842     struct GNUNET_MESH_Multicast *copy;
7843
7844     copy = (struct GNUNET_MESH_Multicast *) buf;
7845     memcpy (buf, message, ntohs (message->size));
7846     copy->oid = my_full_id;
7847     copy->tid = htonl (t->id.tid);
7848     copy->ttl = htonl (default_ttl);
7849     GNUNET_assert (ntohl (copy->pid) == (t->fwd_pid + 1));
7850     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
7851                 "  calling generic handler...\n");
7852     handle_mesh_data_multicast (client, &my_full_id, &copy->header, NULL, 0);
7853   }
7854
7855   GNUNET_SERVER_receive_done (t->owner->handle, GNUNET_OK);
7856   return;
7857 }
7858
7859
7860 /**
7861  * Handler for client's ACKs for payload traffic.
7862  *
7863  * @param cls Closure (unused).
7864  * @param client Identification of the client.
7865  * @param message The actual message.
7866  */
7867 static void
7868 handle_local_ack (void *cls, struct GNUNET_SERVER_Client *client,
7869                   const struct GNUNET_MessageHeader *message)
7870 {
7871   struct GNUNET_MESH_LocalAck *msg;
7872   struct MeshTunnel *t;
7873   struct MeshClient *c;
7874   MESH_TunnelNumber tid;
7875   uint32_t ack;
7876
7877   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got a local ACK\n");
7878   /* Sanity check for client registration */
7879   if (NULL == (c = client_get (client)))
7880   {
7881     GNUNET_break (0);
7882     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
7883     return;
7884   }
7885   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  by client %u\n", c->id);
7886
7887   msg = (struct GNUNET_MESH_LocalAck *) message;
7888
7889   /* Tunnel exists? */
7890   tid = ntohl (msg->tunnel_id);
7891   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  on tunnel %X\n", tid);
7892   t = tunnel_get_by_local_id (c, tid);
7893   if (NULL == t)
7894   {
7895     GNUNET_break (0);
7896     GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Tunnel %X unknown.\n", tid);
7897     GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "  for client %u.\n", c->id);
7898     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
7899     return;
7900   }
7901
7902   ack = ntohl (msg->max_pid);
7903   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  ack %u\n", ack);
7904
7905   /* Does client own tunnel? I.E: Is this and ACK for BCK traffic? */
7906   if (NULL != t->owner && t->owner->handle == client)
7907   {
7908     /* The client owns the tunnel, ACK is for data to_origin, send BCK ACK. */
7909     t->bck_ack = ack;
7910     tunnel_send_bck_ack(t, GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK);
7911   }
7912   else
7913   {
7914     /* The client doesn't own the tunnel, this ACK is for FWD traffic. */
7915     tunnel_set_client_fwd_ack (t, c, ack);
7916     tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK);
7917   }
7918
7919   GNUNET_SERVER_receive_done (client, GNUNET_OK);  
7920
7921   return;
7922 }
7923
7924
7925 /**
7926  * Functions to handle messages from clients
7927  */
7928 static struct GNUNET_SERVER_MessageHandler client_handlers[] = {
7929   {&handle_local_new_client, NULL,
7930    GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT, 0},
7931   {&handle_local_announce_regex, NULL,
7932    GNUNET_MESSAGE_TYPE_MESH_LOCAL_ANNOUNCE_REGEX, 0},
7933   {&handle_local_tunnel_create, NULL,
7934    GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_CREATE,
7935    sizeof (struct GNUNET_MESH_TunnelMessage)},
7936   {&handle_local_tunnel_destroy, NULL,
7937    GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_DESTROY,
7938    sizeof (struct GNUNET_MESH_TunnelMessage)},
7939   {&handle_local_tunnel_speed, NULL,
7940    GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_MIN,
7941    sizeof (struct GNUNET_MESH_TunnelMessage)},
7942   {&handle_local_tunnel_speed, NULL,
7943    GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_MAX,
7944    sizeof (struct GNUNET_MESH_TunnelMessage)},
7945   {&handle_local_tunnel_buffer, NULL,
7946    GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_BUFFER,
7947    sizeof (struct GNUNET_MESH_TunnelMessage)},
7948   {&handle_local_tunnel_buffer, NULL,
7949    GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_NOBUFFER,
7950    sizeof (struct GNUNET_MESH_TunnelMessage)},
7951   {&handle_local_connect_add, NULL,
7952    GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_ADD,
7953    sizeof (struct GNUNET_MESH_PeerControl)},
7954   {&handle_local_connect_del, NULL,
7955    GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_DEL,
7956    sizeof (struct GNUNET_MESH_PeerControl)},
7957   {&handle_local_blacklist, NULL,
7958    GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_BLACKLIST,
7959    sizeof (struct GNUNET_MESH_PeerControl)},
7960   {&handle_local_unblacklist, NULL,
7961    GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_UNBLACKLIST,
7962    sizeof (struct GNUNET_MESH_PeerControl)},
7963   {&handle_local_connect_by_type, NULL,
7964    GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_ADD_BY_TYPE,
7965    sizeof (struct GNUNET_MESH_ConnectPeerByType)},
7966   {&handle_local_connect_by_string, NULL,
7967    GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_ADD_BY_STRING, 0},
7968   {&handle_local_unicast, NULL,
7969    GNUNET_MESSAGE_TYPE_MESH_UNICAST, 0},
7970   {&handle_local_to_origin, NULL,
7971    GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN, 0},
7972   {&handle_local_multicast, NULL,
7973    GNUNET_MESSAGE_TYPE_MESH_MULTICAST, 0},
7974   {&handle_local_ack, NULL,
7975    GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK,
7976    sizeof (struct GNUNET_MESH_LocalAck)},
7977   {NULL, NULL, 0, 0}
7978 };
7979
7980
7981 /**
7982  * To be called on core init/fail.
7983  *
7984  * @param cls service closure
7985  * @param server handle to the server for this service
7986  * @param identity the public identity of this peer
7987  */
7988 static void
7989 core_init (void *cls, struct GNUNET_CORE_Handle *server,
7990            const struct GNUNET_PeerIdentity *identity)
7991 {
7992   static int i = 0;
7993   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Core init\n");
7994   core_handle = server;
7995   if (0 != memcmp (identity, &my_full_id, sizeof (my_full_id)) ||
7996       NULL == server)
7997   {
7998     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Wrong CORE service\n"));
7999     GNUNET_SCHEDULER_shutdown (); // Try gracefully
8000     if (10 < i++)
8001       GNUNET_abort(); // Try harder
8002   }
8003   return;
8004 }
8005
8006
8007 /**
8008  * Method called whenever a given peer connects.
8009  *
8010  * @param cls closure
8011  * @param peer peer identity this notification is about
8012  * @param atsi performance data for the connection
8013  * @param atsi_count number of records in 'atsi'
8014  */
8015 static void
8016 core_connect (void *cls, const struct GNUNET_PeerIdentity *peer,
8017               const struct GNUNET_ATS_Information *atsi,
8018               unsigned int atsi_count)
8019 {
8020   struct MeshPeerInfo *peer_info;
8021   struct MeshPeerPath *path;
8022
8023   DEBUG_CONN ("Peer connected\n");
8024   DEBUG_CONN ("     %s\n", GNUNET_i2s (&my_full_id));
8025   peer_info = peer_info_get (peer);
8026   if (myid == peer_info->id)
8027   {
8028     DEBUG_CONN ("     (self)\n");
8029     return;
8030   }
8031   else
8032   {
8033     DEBUG_CONN ("     %s\n", GNUNET_i2s (peer));
8034   }
8035   path = path_new (2);
8036   path->peers[0] = myid;
8037   path->peers[1] = peer_info->id;
8038   GNUNET_PEER_change_rc (myid, 1);
8039   GNUNET_PEER_change_rc (peer_info->id, 1);
8040   peer_info_add_path (peer_info, path, GNUNET_YES);
8041   GNUNET_STATISTICS_update (stats, "# peers", 1, GNUNET_NO);
8042   return;
8043 }
8044
8045
8046 /**
8047  * Method called whenever a peer disconnects.
8048  *
8049  * @param cls closure
8050  * @param peer peer identity this notification is about
8051  */
8052 static void
8053 core_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer)
8054 {
8055   struct MeshPeerInfo *pi;
8056   struct MeshPeerQueue *q;
8057   struct MeshPeerQueue *n;
8058
8059   DEBUG_CONN ("Peer disconnected\n");
8060   pi = GNUNET_CONTAINER_multihashmap_get (peers, &peer->hashPubKey);
8061   if (NULL == pi)
8062   {
8063     GNUNET_break (0);
8064     return;
8065   }
8066   q = pi->queue_head;
8067   while (NULL != q)
8068   {
8069       n = q->next;
8070       /* TODO try to reroute this traffic instead */
8071       queue_destroy(q, GNUNET_YES);
8072       q = n;
8073   }
8074   if (NULL != pi->core_transmit)
8075   {
8076     GNUNET_CORE_notify_transmit_ready_cancel(pi->core_transmit);
8077     pi->core_transmit = NULL;
8078   }
8079   peer_info_remove_path (pi, pi->id, myid);
8080   if (myid == pi->id)
8081   {
8082     DEBUG_CONN ("     (self)\n");
8083   }
8084   GNUNET_STATISTICS_update (stats, "# peers", -1, GNUNET_NO);
8085   return;
8086 }
8087
8088
8089 /******************************************************************************/
8090 /************************      MAIN FUNCTIONS      ****************************/
8091 /******************************************************************************/
8092
8093 /**
8094  * Iterator over tunnel hash map entries to destroy the tunnel during shutdown.
8095  *
8096  * @param cls closure
8097  * @param key current key code
8098  * @param value value in the hash map
8099  * @return GNUNET_YES if we should continue to iterate,
8100  *         GNUNET_NO if not.
8101  */
8102 static int
8103 shutdown_tunnel (void *cls, const struct GNUNET_HashCode * key, void *value)
8104 {
8105   struct MeshTunnel *t = value;
8106
8107   tunnel_destroy (t);
8108   return GNUNET_YES;
8109 }
8110
8111 /**
8112  * Iterator over peer hash map entries to destroy the tunnel during shutdown.
8113  *
8114  * @param cls closure
8115  * @param key current key code
8116  * @param value value in the hash map
8117  * @return GNUNET_YES if we should continue to iterate,
8118  *         GNUNET_NO if not.
8119  */
8120 static int
8121 shutdown_peer (void *cls, const struct GNUNET_HashCode * key, void *value)
8122 {
8123   struct MeshPeerInfo *p = value;
8124   struct MeshPeerQueue *q;
8125   struct MeshPeerQueue *n;
8126
8127   q = p->queue_head;
8128   while (NULL != q)
8129   {
8130       n = q->next;
8131       if (q->peer == p)
8132       {
8133         queue_destroy(q, GNUNET_YES);
8134       }
8135       q = n;
8136   }
8137   peer_info_destroy (p);
8138   return GNUNET_YES;
8139 }
8140
8141
8142 /**
8143  * Task run during shutdown.
8144  *
8145  * @param cls unused
8146  * @param tc unused
8147  */
8148 static void
8149 shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
8150 {
8151   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "shutting down\n");
8152
8153   if (core_handle != NULL)
8154   {
8155     GNUNET_CORE_disconnect (core_handle);
8156     core_handle = NULL;
8157   }
8158  if (NULL != keygen)
8159   {
8160     GNUNET_CRYPTO_rsa_key_create_stop (keygen);
8161     keygen = NULL;
8162   }
8163   GNUNET_CONTAINER_multihashmap_iterate (tunnels, &shutdown_tunnel, NULL);
8164   GNUNET_CONTAINER_multihashmap_iterate (peers, &shutdown_peer, NULL);
8165   if (dht_handle != NULL)
8166   {
8167     GNUNET_DHT_disconnect (dht_handle);
8168     dht_handle = NULL;
8169   }
8170   if (nc != NULL)
8171   {
8172     GNUNET_SERVER_notification_context_destroy (nc);
8173     nc = NULL;
8174   }
8175   if (GNUNET_SCHEDULER_NO_TASK != announce_id_task)
8176   {
8177     GNUNET_SCHEDULER_cancel (announce_id_task);
8178     announce_id_task = GNUNET_SCHEDULER_NO_TASK;
8179   }
8180   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "shut down\n");
8181 }
8182
8183
8184 /**
8185  * Callback for hostkey read/generation
8186  *
8187  * @param cls NULL
8188  * @param pk the private key
8189  * @param emsg error message
8190  */
8191 static void
8192 key_generation_cb (void *cls,
8193                    struct GNUNET_CRYPTO_RsaPrivateKey *pk,
8194                    const char *emsg)
8195 {
8196   struct MeshPeerInfo *peer;
8197   struct MeshPeerPath *p;
8198
8199   keygen = NULL;  
8200   if (NULL == pk)
8201   {
8202     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
8203                 _("Mesh service could not access hostkey.  Exiting.\n"));
8204     GNUNET_SCHEDULER_shutdown ();
8205     return;
8206   }
8207   my_private_key = pk;
8208   GNUNET_CRYPTO_rsa_key_get_public (my_private_key, &my_public_key);
8209   GNUNET_CRYPTO_hash (&my_public_key, sizeof (my_public_key),
8210                       &my_full_id.hashPubKey);
8211   myid = GNUNET_PEER_intern (&my_full_id);
8212   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
8213               "Mesh for peer [%s] starting\n",
8214               GNUNET_i2s(&my_full_id));
8215
8216 //   transport_handle = GNUNET_TRANSPORT_connect(c,
8217 //                                               &my_full_id,
8218 //                                               NULL,
8219 //                                               NULL,
8220 //                                               NULL,
8221 //                                               NULL);
8222
8223
8224
8225   next_tid = 0;
8226   next_local_tid = GNUNET_MESH_LOCAL_TUNNEL_ID_SERV;
8227
8228
8229   GNUNET_SERVER_add_handlers (server_handle, client_handlers);
8230   nc = GNUNET_SERVER_notification_context_create (server_handle, 1);
8231   GNUNET_SERVER_disconnect_notify (server_handle,
8232                                    &handle_local_client_disconnect, NULL);
8233
8234
8235   clients = NULL;
8236   clients_tail = NULL;
8237   next_client_id = 0;
8238
8239   announce_applications_task = GNUNET_SCHEDULER_NO_TASK;
8240   announce_id_task = GNUNET_SCHEDULER_add_now (&announce_id, cls);
8241
8242   /* Create a peer_info for the local peer */
8243   peer = peer_info_get (&my_full_id);
8244   p = path_new (1);
8245   p->peers[0] = myid;
8246   GNUNET_PEER_change_rc (myid, 1);
8247   peer_info_add_path (peer, p, GNUNET_YES);
8248   GNUNET_SERVER_resume (server_handle);
8249   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Mesh service running\n");
8250 }
8251
8252
8253 /**
8254  * Process mesh requests.
8255  *
8256  * @param cls closure
8257  * @param server the initialized server
8258  * @param c configuration to use
8259  */
8260 static void
8261 run (void *cls, struct GNUNET_SERVER_Handle *server,
8262      const struct GNUNET_CONFIGURATION_Handle *c)
8263 {
8264   char *keyfile;
8265
8266   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "starting to run\n");
8267   server_handle = server;
8268   core_handle = GNUNET_CORE_connect (c, /* Main configuration */
8269                                      NULL,      /* Closure passed to MESH functions */
8270                                      &core_init,        /* Call core_init once connected */
8271                                      &core_connect,     /* Handle connects */
8272                                      &core_disconnect,  /* remove peers on disconnects */
8273                                      NULL,      /* Don't notify about all incoming messages */
8274                                      GNUNET_NO, /* For header only in notification */
8275                                      NULL,      /* Don't notify about all outbound messages */
8276                                      GNUNET_NO, /* For header-only out notification */
8277                                      core_handlers);    /* Register these handlers */
8278
8279   if (core_handle == NULL)
8280   {
8281     GNUNET_break (0);
8282     GNUNET_SCHEDULER_shutdown ();
8283     return;
8284   }
8285
8286   if (GNUNET_OK !=
8287       GNUNET_CONFIGURATION_get_value_filename (c, "GNUNETD", "HOSTKEY",
8288                                                &keyfile))
8289   {
8290     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
8291                 _
8292                 ("%s service is lacking key configuration settings (%s).  Exiting.\n"),
8293                 "mesh", "hostkey");
8294     GNUNET_SCHEDULER_shutdown ();
8295     return;
8296   }
8297
8298   if (GNUNET_OK !=
8299       GNUNET_CONFIGURATION_get_value_time (c, "MESH", "REFRESH_PATH_TIME",
8300                                            &refresh_path_time))
8301   {
8302     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
8303                 _
8304                 ("%s service is lacking key configuration settings (%s).  Exiting.\n"),
8305                 "mesh", "refresh path time");
8306     GNUNET_SCHEDULER_shutdown ();
8307     return;
8308   }
8309
8310   if (GNUNET_OK !=
8311       GNUNET_CONFIGURATION_get_value_time (c, "MESH", "APP_ANNOUNCE_TIME",
8312                                            &app_announce_time))
8313   {
8314     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
8315                 _
8316                 ("%s service is lacking key configuration settings (%s).  Exiting.\n"),
8317                 "mesh", "app announce time");
8318     GNUNET_SCHEDULER_shutdown ();
8319     return;
8320   }
8321   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "APP_ANNOUNCE_TIME %llu ms\n", app_announce_time.rel_value);
8322
8323   if (GNUNET_OK !=
8324       GNUNET_CONFIGURATION_get_value_time (c, "MESH", "ID_ANNOUNCE_TIME",
8325                                            &id_announce_time))
8326   {
8327     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
8328                 _
8329                 ("%s service is lacking key configuration settings (%s).  Exiting.\n"),
8330                 "mesh", "id announce time");
8331     GNUNET_SCHEDULER_shutdown ();
8332     return;
8333   }
8334   else
8335   {
8336   }
8337
8338   if (GNUNET_OK !=
8339       GNUNET_CONFIGURATION_get_value_time (c, "MESH", "CONNECT_TIMEOUT",
8340                                            &connect_timeout))
8341   {
8342     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
8343                 _
8344                 ("%s service is lacking key configuration settings (%s).  Exiting.\n"),
8345                 "mesh", "connect timeout");
8346     GNUNET_SCHEDULER_shutdown ();
8347     return;
8348   }
8349
8350   if (GNUNET_OK !=
8351       GNUNET_CONFIGURATION_get_value_number (c, "MESH", "MAX_MSGS_QUEUE",
8352                                              &max_msgs_queue))
8353   {
8354     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
8355                 _
8356                 ("%s service is lacking key configuration settings (%s).  Exiting.\n"),
8357                 "mesh", "max msgs queue");
8358     GNUNET_SCHEDULER_shutdown ();
8359     return;
8360   }
8361
8362   if (GNUNET_OK !=
8363       GNUNET_CONFIGURATION_get_value_number (c, "MESH", "MAX_TUNNELS",
8364                                              &max_tunnels))
8365   {
8366     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
8367                 _
8368                 ("%s service is lacking key configuration settings (%s).  Exiting.\n"),
8369                 "mesh", "max tunnels");
8370     GNUNET_SCHEDULER_shutdown ();
8371     return;
8372   }
8373
8374   if (GNUNET_OK !=
8375       GNUNET_CONFIGURATION_get_value_number (c, "MESH", "DEFAULT_TTL",
8376                                              &default_ttl))
8377   {
8378     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
8379                 _
8380                 ("%s service is lacking key configuration settings (%s). Using default (%u).\n"),
8381                 "mesh", "default ttl", 64);
8382     default_ttl = 64;
8383   }
8384
8385   if (GNUNET_OK !=
8386       GNUNET_CONFIGURATION_get_value_number (c, "MESH", "DHT_REPLICATION_LEVEL",
8387                                              &dht_replication_level))
8388   {
8389     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
8390                 _
8391                 ("%s service is lacking key configuration settings (%s). Using default (%u).\n"),
8392                 "mesh", "dht replication level", 10);
8393     dht_replication_level = 10;
8394   }
8395
8396   tunnels = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
8397   incoming_tunnels = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
8398   peers = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
8399   applications = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
8400   types = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
8401
8402   dht_handle = GNUNET_DHT_connect (c, 64);
8403   if (NULL == dht_handle)
8404   {
8405     GNUNET_break (0);
8406   }
8407   stats = GNUNET_STATISTICS_create ("mesh", c);
8408
8409   GNUNET_SERVER_suspend (server_handle);
8410   /* Scheduled the task to clean up when shutdown is called */
8411   GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task,
8412                                 NULL);
8413   keygen = GNUNET_CRYPTO_rsa_key_create_start (keyfile, &key_generation_cb, NULL);
8414   GNUNET_free (keyfile);
8415 }
8416
8417
8418 /**
8419  * The main function for the mesh service.
8420  *
8421  * @param argc number of arguments from the command line
8422  * @param argv command line arguments
8423  * @return 0 ok, 1 on error
8424  */
8425 int
8426 main (int argc, char *const *argv)
8427 {
8428   int ret;
8429   int r;
8430
8431   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "main()\n");
8432   r = GNUNET_SERVICE_run (argc, argv, "mesh", GNUNET_SERVICE_OPTION_NONE, &run,
8433                           NULL);
8434   ret = (GNUNET_OK == r) ? 0 : 1;
8435   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "main() END\n");
8436
8437   INTERVAL_SHOW;
8438
8439   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
8440               "Mesh for peer [%s] FWD ACKs %u, BCK ACKs %u\n",
8441               GNUNET_i2s(&my_full_id), debug_fwd_ack, debug_bck_ack);
8442
8443   return ret;
8444 }