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