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