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