- make mesh2 compile
[oweals/gnunet.git] / src / mesh / gnunet-service-mesh-new.c
1 /*
2      This file is part of GNUnet.
3      (C) 2001-2012 Christian Grothoff (and other contributing authors)
4
5      GNUnet is free software; you can redistribute it and/or modify
6      it under the terms of the GNU General Public License as published
7      by the Free Software Foundation; either version 3, or (at your
8      option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      General Public License for more details.
14
15      You should have received a copy of the GNU General Public License
16      along with GNUnet; see the file COPYING.  If not, write to the
17      Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18      Boston, MA 02111-1307, USA.
19 */
20
21 /**
22  * @file mesh/gnunet-service-mesh.c
23  * @brief GNUnet MESH service
24  * @author Bartlomiej Polot
25  *
26  * STRUCTURE:
27  * - DATA STRUCTURES
28  * - GLOBAL VARIABLES
29  * - GENERAL HELPERS
30  * - PERIODIC FUNCTIONS
31  * - MESH NETWORK HANDLER HELPERS
32  * - MESH NETWORK HANDLES
33  * - MESH LOCAL HANDLER HELPERS
34  * - MESH LOCAL HANDLES
35  * - MAIN FUNCTIONS (main & run)
36  *
37  * TODO:
38  * - 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 "mesh2.h"
50 #include "mesh2_protocol.h"
51 #include "mesh_tunnel_tree.h"
52 #include "block_mesh.h"
53 #include "gnunet_dht_service.h"
54 #include "gnunet_statistics_service.h"
55 #include "gnunet_regex_lib.h"
56
57 #define MESH_BLOOM_SIZE         128
58
59 #define MESH_DEBUG_REGEX        GNUNET_YES
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_REGEX
81 #define DEBUG_REGEX(...) GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__)
82 #else
83 #define DEBUG_REGEX(...)
84 #endif
85
86 #if MESH_DEBUG_TIMING
87 #include <time.h>
88 double __sum;
89 uint64_t __count;
90 struct timespec __mesh_start;
91 struct timespec __mesh_end;
92 #define INTERVAL_START clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &(__mesh_start))
93 #define INTERVAL_END \
94 do {\
95   clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &(__mesh_end));\
96   double __diff = __mesh_end.tv_nsec - __mesh_start.tv_nsec;\
97   if (__diff < 0) __diff += 1000000000;\
98   __sum += __diff;\
99   __count++;\
100 } while (0)
101 #define INTERVAL_SHOW \
102 if (0 < __count)\
103   GNUNET_log (GNUNET_ERROR_TYPE_INFO, "AVG process time: %f ns\n", __sum/__count)
104 #else
105 #define INTERVAL_START
106 #define INTERVAL_END
107 #define INTERVAL_SHOW
108 #endif
109
110 /******************************************************************************/
111 /************************      DATA STRUCTURES     ****************************/
112 /******************************************************************************/
113
114 /** FWD declaration */
115 struct MeshPeerInfo;
116 struct MeshClient;
117
118
119 /**
120  * Struct representing a piece of data being sent to other peers
121  */
122 struct MeshData
123 {
124   /** Tunnel it belongs to. */
125   struct MeshTunnel *t;
126
127   /** How many remaining neighbors still hav't got it. */
128   unsigned int reference_counter;
129
130   /** How many remaining neighbors we need to send this to. */
131   unsigned int total_out;
132
133   /** Size of the data. */
134   size_t data_len;
135
136   /** Data itself */
137   void *data;
138 };
139
140
141 /**
142  * Struct containing info about a queued transmission to this peer
143  */
144 struct MeshPeerQueue
145 {
146     /**
147       * DLL next
148       */
149   struct MeshPeerQueue *next;
150
151     /**
152       * DLL previous
153       */
154   struct MeshPeerQueue *prev;
155
156     /**
157      * Peer this transmission is directed to.
158      */
159   struct MeshPeerInfo *peer;
160
161     /**
162      * Tunnel this message belongs to.
163      */
164   struct MeshTunnel *tunnel;
165
166     /**
167      * Pointer to info stucture used as cls.
168      */
169   void *cls;
170
171     /**
172      * Type of message
173      */
174   uint16_t type;
175
176     /**
177      * Size of the message
178      */
179   size_t size;
180 };
181
182
183 /**
184  * Struct to store regex information announced by clients.
185  */
186 struct MeshRegexDescriptor
187 {
188     /**
189      * Regular expression itself.
190      */
191   char *regex;
192
193     /**
194      * How many characters per edge can we squeeze?
195      */
196   uint16_t compression;
197
198     /**
199      * Handle to announce the regex.
200      */
201   struct GNUNET_REGEX_announce_handle *h;
202 };
203
204
205 /**
206  * Struct to keep information of searches of services described by a regex
207  * using a user-provided string service description.
208  */
209 struct MeshRegexSearchInfo
210 {
211     /**
212      * Which tunnel is this for
213      */
214   struct MeshTunnel *t;
215
216     /**
217      * User provided description of the searched service.
218      */
219   char *description;
220
221     /**
222      * Regex search handle.
223      */
224   struct GNUNET_REGEX_search_handle *search_handle;
225
226     /**
227      * Peer that is connecting via connect_by_string. When connected, free ctx.
228      */
229   GNUNET_PEER_Id peer;
230
231     /**
232      * Other peers that are found but not yet being connected to.
233      */
234   GNUNET_PEER_Id *peers;
235
236     /**
237      * Number of elements in peers.
238      */
239   unsigned int n_peers;
240
241     /**
242      * Next peer to try to connect to.
243      */
244   unsigned int i_peer;
245
246     /**
247      * Timeout for a connect attempt.
248      * When reached, try to connect to a different peer, if any. If not,
249      * try the same peer again.
250      */
251   GNUNET_SCHEDULER_TaskIdentifier timeout;
252
253 };
254
255
256 /**
257  * Struct containing all info possibly needed to build a package when called
258  * back by core.
259  */
260 struct MeshTransmissionDescriptor
261 {
262     /** ID of the tunnel this packet travels in */
263   struct MESH_TunnelID *origin;
264
265     /** Who was this message being sent to */
266   struct MeshPeerInfo *peer;
267
268     /** Ultimate destination of the packet */
269   GNUNET_PEER_Id destination;
270
271     /** Data descriptor */
272   struct MeshData* mesh_data;
273 };
274
275
276 /**
277  * Struct containing all information regarding a given peer
278  */
279 struct MeshPeerInfo
280 {
281     /**
282      * ID of the peer
283      */
284   GNUNET_PEER_Id id;
285
286     /**
287      * Last time we heard from this peer
288      */
289   struct GNUNET_TIME_Absolute last_contact;
290
291     /**
292      * Task handler for delayed connect task;
293      */
294   GNUNET_SCHEDULER_TaskIdentifier connect_task;
295
296     /**
297      * Number of attempts to reconnect so far
298      */
299   int n_reconnect_attempts;
300
301     /**
302      * Paths to reach the peer, ordered by ascending hop count
303      */
304   struct MeshPeerPath *path_head;
305
306     /**
307      * Paths to reach the peer, ordered by ascending hop count
308      */
309   struct MeshPeerPath *path_tail;
310
311     /**
312      * Handle to stop the DHT search for a path to this peer
313      */
314   struct GNUNET_DHT_GetHandle *dhtget;
315
316     /**
317      * Closure given to the DHT GET
318      */
319   struct MeshPathInfo *dhtgetcls;
320
321     /**
322      * Array of tunnels this peer participates in
323      * (most probably a small amount, therefore not a hashmap)
324      * When the path to the peer changes, notify these tunnels to let them
325      * re-adjust their path trees.
326      */
327   struct MeshTunnel **tunnels;
328
329     /**
330      * Number of tunnels this peers participates in
331      */
332   unsigned int ntunnels;
333
334    /**
335     * Transmission queue to core DLL head
336     */
337   struct MeshPeerQueue *queue_head;
338
339    /**
340     * Transmission queue to core DLL tail
341     */
342    struct MeshPeerQueue *queue_tail;
343
344    /**
345     * How many messages are in the queue to this peer.
346     */
347    unsigned int queue_n;
348
349    /**
350     * Handle to for queued transmissions
351     */
352   struct GNUNET_CORE_TransmitHandle *core_transmit;
353 };
354
355
356 /**
357  * Globally unique tunnel identification (owner + number)
358  * DO NOT USE OVER THE NETWORK
359  */
360 struct MESH_TunnelID
361 {
362     /**
363      * Node that owns the tunnel
364      */
365   GNUNET_PEER_Id oid;
366
367     /**
368      * Tunnel number to differentiate all the tunnels owned by the node oid
369      * ( tid < GNUNET_MESH_LOCAL_TUNNEL_ID_CLI )
370      */
371   MESH_TunnelNumber tid;
372 };
373
374
375 /**
376  * Struct containing all information regarding a tunnel
377  * For an intermediate node the improtant info used will be:
378  * - id        Tunnel unique identification
379  * - paths[0]  To know where to send it next
380  * - metainfo: ready, speeds, accounting
381  */
382 struct MeshTunnel
383 {
384     /**
385      * Tunnel ID
386      */
387   struct MESH_TunnelID id;
388
389     /**
390      * Local tunnel number ( >= GNUNET_MESH_LOCAL_TUNNEL_ID_CLI or 0 )
391      */
392   MESH_TunnelNumber local_tid;
393
394     /**
395      * Local tunnel number for local destination clients (incoming number)
396      * ( >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV or 0). All clients share the same
397      * number.
398      */
399   MESH_TunnelNumber local_tid_dest;
400
401     /**
402      * Is the tunnel bufferless (minimum latency)?
403      */
404   int nobuffer;
405
406     /**
407      * Packet ID of the last fwd packet seen (sent/retransmitted/received).
408      */
409   uint32_t fwd_pid;
410
411     /**
412      * Packet ID of the last bck packet sent (unique counter per hop).
413      */
414   uint32_t bck_pid;
415
416     /**
417      * Force sending ACK? Flag to allow duplicate ACK on POLL.
418      */
419   int force_ack;
420
421     /**
422      * Last ACK sent towards the origin (for traffic towards leaf node).
423      */
424   uint32_t last_fwd_ack;
425
426     /**
427      * BCK ACK value received from the hop towards the owner of the tunnel,
428      * (previous node / owner): up to what message PID can we sent back to him.
429      */
430   uint32_t bck_ack;
431
432     /**
433      * How many messages are in the forward queue (towards leaves).
434      */
435   unsigned int fwd_queue_n;
436
437     /**
438      * How many messages do we accept in the forward queue.
439      */
440   unsigned int fwd_queue_max;
441
442     /**
443      * How many messages are in the backward queue (towards origin).
444      */
445   unsigned int bck_queue_n;
446
447     /**
448      * How many messages do we accept in the backward queue.
449     */
450    unsigned int bck_queue_max;
451
452     /**
453      * Task to poll peer in case of a stall.
454      */
455    GNUNET_SCHEDULER_TaskIdentifier fc_poll_bck;
456
457     /**
458      * Last time the tunnel was used
459      */
460   struct GNUNET_TIME_Absolute timestamp;
461
462     /**
463      * Peer of the tunnel.
464      */
465   GNUNET_PEER_Id peer;
466
467     /**
468      * Client owner of the tunnel, if any
469      */
470   struct MeshClient *owner;
471
472     /**
473      * Clients that have been informed about and want to stay in the tunnel.
474      */
475   struct MeshClient **clients;
476
477     /**
478      * Flow control info for each client.
479      */
480   struct MeshTunnelClientInfo *clients_fc;
481
482   /**
483      * Number of elements in clients/clients_fc
484      */
485   unsigned int nclients;
486
487     /**
488      * Clients that have been informed but requested to leave the tunnel.
489      */
490   struct MeshClient **ignore;
491
492     /**
493      * Number of elements in clients
494      */
495   unsigned int nignore;
496
497   /**
498    * Bloomfilter (for peer identities) to stop circular routes
499    */
500   char bloomfilter[MESH_BLOOM_SIZE];
501
502   /**
503    * Tunnel paths
504    * FIXME  just a path
505    */
506   struct MeshTunnelTree *tree;
507
508     /**
509      * Task to keep the used paths alive
510      */
511   GNUNET_SCHEDULER_TaskIdentifier path_refresh_task;
512
513     /**
514      * Task to destroy the tunnel after timeout
515      *
516      * FIXME: merge the two? a tunnel will have either
517      * a path refresh OR a timeout, never both!
518      */
519   GNUNET_SCHEDULER_TaskIdentifier timeout_task;
520
521     /**
522      * Flag to signal the destruction of the tunnel.
523      * If this is set GNUNET_YES the tunnel will be destroyed
524      * when the queue is empty.
525      */
526   int destroy;
527
528     /**
529      * Total messages pending for this tunnels, payload or not.
530      */
531   unsigned int pending_messages;
532
533   /**
534    * If the tunnel is empty, destoy it.
535    */
536   GNUNET_SCHEDULER_TaskIdentifier delayed_destroy;
537 };
538
539
540 /**
541  * Info about a leaf client of a tunnel, needed to perform flow control.
542  */
543 struct MeshTunnelClientInfo
544 {
545   /**
546    * PID of the last packet sent to the client (FWD).
547    */
548   uint32_t fwd_pid;
549
550   /**
551    * PID of the last packet received from the client (BCK).
552    */
553   uint32_t bck_pid;
554
555   /**
556    * Maximum PID allowed (FWD ACK received).
557    */
558   uint32_t fwd_ack;
559   
560   /**
561    * Last ACK sent to that child (BCK ACK).
562    */
563   uint32_t bck_ack;
564 };
565
566
567 /**
568  * Info needed to work with tunnel paths and peers
569  */
570 struct MeshPathInfo
571 {
572   /**
573    * Tunnel
574    */
575   struct MeshTunnel *t;
576
577   /**
578    * Neighbouring peer to whom we send the packet to
579    */
580   struct MeshPeerInfo *peer;
581
582   /**
583    * Path itself
584    */
585   struct MeshPeerPath *path;
586 };
587
588
589 /**
590  * Struct containing information about a client of the service
591  */
592 struct MeshClient
593 {
594     /**
595      * Linked list next
596      */
597   struct MeshClient *next;
598
599     /**
600      * Linked list prev
601      */
602   struct MeshClient *prev;
603
604     /**
605      * Tunnels that belong to this client, indexed by local id
606      */
607   struct GNUNET_CONTAINER_MultiHashMap *own_tunnels;
608
609    /**
610      * Tunnels this client has accepted, indexed by incoming local id
611      */
612   struct GNUNET_CONTAINER_MultiHashMap *incoming_tunnels;
613
614    /**
615      * Tunnels this client has rejected, indexed by incoming local id
616      */
617   struct GNUNET_CONTAINER_MultiHashMap *ignore_tunnels;
618     /**
619      * Handle to communicate with the client
620      */
621   struct GNUNET_SERVER_Client *handle;
622
623     /**
624      * Messages that this client has declared interest in
625      */
626   struct GNUNET_CONTAINER_MultiHashMap *types;
627
628     /**
629      * Whether the client is active or shutting down (don't send confirmations
630      * to a client that is shutting down.
631      */
632   int shutting_down;
633
634     /**
635      * ID of the client, mainly for debug messages
636      */
637   unsigned int id;
638   
639     /**
640      * Regular expressions describing the services offered by this client.
641      */
642   struct MeshRegexDescriptor *regexes; // FIXME regex add timeout? API to remove a regex?
643
644     /**
645      * Number of regular expressions in regexes.
646      */
647   unsigned int n_regex;
648
649     /**
650      * Task to refresh all regular expresions in the DHT.
651      */
652   GNUNET_SCHEDULER_TaskIdentifier regex_announce_task;
653
654     /**
655      * Tmp store for partially retrieved regex.
656      */
657   char *partial_regex;
658
659 };
660
661
662 /******************************************************************************/
663 /************************      DEBUG FUNCTIONS     ****************************/
664 /******************************************************************************/
665
666 #if MESH_DEBUG
667 /**
668  * GNUNET_SCHEDULER_Task for printing a message after some operation is done
669  * @param cls string to print
670  * @param success  GNUNET_OK if the PUT was transmitted,
671  *                GNUNET_NO on timeout,
672  *                GNUNET_SYSERR on disconnect from service
673  *                after the PUT message was transmitted
674  *                (so we don't know if it was received or not)
675  */
676
677 #if 0
678 static void
679 mesh_debug (void *cls, int success)
680 {
681   char *s = cls;
682
683   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%s (%d)\n", s, success);
684 }
685 #endif
686
687 unsigned int debug_fwd_ack;
688 unsigned int debug_bck_ack;
689
690 #endif
691
692 /******************************************************************************/
693 /***********************      GLOBAL VARIABLES     ****************************/
694 /******************************************************************************/
695
696 /************************** Configuration parameters **************************/
697
698 /**
699  * How often to send tunnel keepalives. Tunnels timeout after 4 missed.
700  */
701 static struct GNUNET_TIME_Relative refresh_path_time;
702
703 /**
704  * How often to PUT local application numbers in the DHT.
705  */
706 static struct GNUNET_TIME_Relative app_announce_time;
707
708 /**
709  * How often to PUT own ID in the DHT.
710  */
711 static struct GNUNET_TIME_Relative id_announce_time;
712
713 /**
714  * Maximum time allowed to connect to a peer found by string.
715  */
716 static struct GNUNET_TIME_Relative connect_timeout;
717
718 /**
719  * Default TTL for payload packets.
720  */
721 static unsigned long long default_ttl;
722
723 /**
724  * DHT replication level, see DHT API: GNUNET_DHT_get_start, GNUNET_DHT_put.
725  */
726 static unsigned long long dht_replication_level;
727
728 /**
729  * How many tunnels are we willing to maintain.
730  * Local tunnels are always allowed, even if there are more tunnels than max.
731  */
732 static unsigned long long max_tunnels;
733
734 /**
735  * How many messages *in total* are we willing to queue, divided by number of 
736  * tunnels to get tunnel queue size.
737  */
738 static unsigned long long max_msgs_queue;
739
740 /**
741  * How many peers do we want to remember?
742  */
743 static unsigned long long max_peers;
744
745
746 /*************************** Static global variables **************************/
747
748 /**
749  * Hostkey generation context
750  */
751 static struct GNUNET_CRYPTO_EccKeyGenerationContext *keygen;
752
753 /**
754  * DLL with all the clients, head.
755  */
756 static struct MeshClient *clients;
757
758 /**
759  * DLL with all the clients, tail.
760  */
761 static struct MeshClient *clients_tail;
762
763 /**
764  * Tunnels known, indexed by MESH_TunnelID (MeshTunnel).
765  */
766 static struct GNUNET_CONTAINER_MultiHashMap *tunnels;
767
768 /**
769  * Number of tunnels known.
770  */
771 static unsigned long long n_tunnels;
772
773 /**
774  * Tunnels incoming, indexed by MESH_TunnelNumber
775  * (which is greater than GNUNET_MESH_LOCAL_TUNNEL_ID_SERV).
776  */
777 static struct GNUNET_CONTAINER_MultiHashMap *incoming_tunnels;
778
779 /**
780  * Peers known, indexed by PeerIdentity (MeshPeerInfo).
781  */
782 static struct GNUNET_CONTAINER_MultiHashMap *peers;
783
784 /*
785  * Handle to communicate with transport
786  */
787 // static struct GNUNET_TRANSPORT_Handle *transport_handle;
788
789 /**
790  * Handle to communicate with core.
791  */
792 static struct GNUNET_CORE_Handle *core_handle;
793
794 /**
795  * Handle to use DHT.
796  */
797 static struct GNUNET_DHT_Handle *dht_handle;
798
799 /**
800  * Handle to server.
801  */
802 static struct GNUNET_SERVER_Handle *server_handle;
803
804 /**
805  * Handle to the statistics service.
806  */
807 static struct GNUNET_STATISTICS_Handle *stats;
808
809 /**
810  * Notification context, to send messages to local clients.
811  */
812 static struct GNUNET_SERVER_NotificationContext *nc;
813
814 /**
815  * Local peer own ID (memory efficient handle).
816  */
817 static GNUNET_PEER_Id myid;
818
819 /**
820  * Local peer own ID (full value).
821  */
822 static struct GNUNET_PeerIdentity my_full_id;
823
824 /**
825  * Own private key.
826  */
827 static struct GNUNET_CRYPTO_EccPrivateKey *my_private_key;
828
829 /**
830  * Own public key.
831  */
832 static struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded my_public_key;
833
834 /**
835  * Tunnel ID for the next created tunnel (global tunnel number).
836  */
837 static MESH_TunnelNumber next_tid;
838
839 /**
840  * Tunnel ID for the next incoming tunnel (local tunnel number).
841  */
842 static MESH_TunnelNumber next_local_tid;
843
844 /**
845  * All message types clients of this peer are interested in.
846  */
847 static struct GNUNET_CONTAINER_MultiHashMap *types;
848
849 /**
850  * Task to periodically announce itself in the network.
851  */
852 GNUNET_SCHEDULER_TaskIdentifier announce_id_task;
853
854 /**
855  * Next ID to assign to a client.
856  */
857 unsigned int next_client_id;
858
859
860 /******************************************************************************/
861 /***********************         DECLARATIONS        **************************/
862 /******************************************************************************/
863
864 /**
865  * Function to process paths received for a new peer addition. The recorded
866  * paths form the initial tunnel, which can be optimized later.
867  * Called on each result obtained for the DHT search.
868  *
869  * @param cls closure
870  * @param exp when will this value expire
871  * @param key key of the result
872  * @param type type of the result
873  * @param size number of bytes in data
874  * @param data pointer to the result data
875  */
876 static void
877 dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp,
878                     const struct GNUNET_HashCode * key,
879                     const struct GNUNET_PeerIdentity *get_path,
880                     unsigned int get_path_length,
881                     const struct GNUNET_PeerIdentity *put_path,
882                     unsigned int put_path_length, enum GNUNET_BLOCK_Type type,
883                     size_t size, const void *data);
884
885
886 /**
887  * Retrieve the MeshPeerInfo stucture associated with the peer, create one
888  * and insert it in the appropiate structures if the peer is not known yet.
889  *
890  * @param peer Full identity of the peer.
891  *
892  * @return Existing or newly created peer info.
893  */
894 static struct MeshPeerInfo *
895 peer_info_get (const struct GNUNET_PeerIdentity *peer);
896
897
898 /**
899  * Retrieve the MeshPeerInfo stucture associated with the peer, create one
900  * and insert it in the appropiate structures if the peer is not known yet.
901  *
902  * @param peer Short identity of the peer.
903  *
904  * @return Existing or newly created peer info.
905  */
906 static struct MeshPeerInfo *
907 peer_info_get_short (const GNUNET_PEER_Id peer);
908
909
910 /**
911  * Try to establish a new connection to this peer.
912  * Use the best path for the given tunnel.
913  * If the peer doesn't have any path to it yet, try to get one.
914  * If the peer already has some path, send a CREATE PATH towards it.
915  *
916  * @param peer PeerInfo of the peer.
917  * @param t Tunnel for which to create the path, if possible.
918  */
919 static void
920 peer_info_connect (struct MeshPeerInfo *peer, struct MeshTunnel *t);
921
922
923 /**
924  * Build a PeerPath from the paths returned from the DHT, reversing the paths
925  * to obtain a local peer -> destination path and interning the peer ids.
926  *
927  * @return Newly allocated and created path
928  */
929 static struct MeshPeerPath *
930 path_build_from_dht (const struct GNUNET_PeerIdentity *get_path,
931                      unsigned int get_path_length,
932                      const struct GNUNET_PeerIdentity *put_path,
933                      unsigned int put_path_length);
934
935
936 /**
937  * Adds a path to the peer_infos of all the peers in the path
938  *
939  * @param p Path to process.
940  * @param confirmed Whether we know if the path works or not.
941  */
942 static void
943 path_add_to_peers (struct MeshPeerPath *p, int confirmed);
944
945
946
947 /**
948  * Search for a tunnel by global ID using full PeerIdentities.
949  *
950  * @param oid owner of the tunnel.
951  * @param tid global tunnel number.
952  *
953  * @return tunnel handler, NULL if doesn't exist.
954  */
955 static struct MeshTunnel *
956 tunnel_get (const struct GNUNET_PeerIdentity *oid, MESH_TunnelNumber tid);
957
958
959 /**
960  * Delete an active client from the tunnel.
961  *
962  * @param t Tunnel.
963  * @param c Client.
964  */
965 static void
966 tunnel_delete_active_client (struct MeshTunnel *t, const struct MeshClient *c);
967
968 /**
969  * Notify a tunnel that a connection has broken that affects at least
970  * some of its peers.
971  *
972  * @param t Tunnel affected.
973  * @param p1 Peer that got disconnected from p2.
974  * @param p2 Peer that got disconnected from p1.
975  *
976  * @return Short ID of the peer disconnected (either p1 or p2).
977  *         0 if the tunnel remained unaffected.
978  */
979 static GNUNET_PEER_Id
980 tunnel_notify_connection_broken (struct MeshTunnel *t, GNUNET_PEER_Id p1,
981                                  GNUNET_PEER_Id p2);
982
983
984 /**
985  * Get the current ack value for a tunnel, for data going from root to leaves,
986  * taking in account the tunnel mode and the status of all children and clients.
987  *
988  * @param t Tunnel.
989  *
990  * @return Maximum PID allowed.
991  */
992 static uint32_t
993 tunnel_get_fwd_ack (struct MeshTunnel *t);
994
995
996 /**
997  * Add a client to a tunnel, initializing all needed data structures.
998  * 
999  * @param t Tunnel to which add the client.
1000  * @param c Client which to add to the tunnel.
1001  */
1002 static void
1003 tunnel_add_client (struct MeshTunnel *t, struct MeshClient *c);
1004
1005
1006 /**
1007  * @brief Queue and pass message to core when possible.
1008  * 
1009  * If type is payload (UNICAST, TO_ORIGIN, MULTICAST) checks for queue status
1010  * and accounts for it. In case the queue is full, the message is dropped and
1011  * a break issued.
1012  * 
1013  * Otherwise, message is treated as internal and allowed to go regardless of 
1014  * queue status.
1015  *
1016  * @param cls Closure (@c type dependant). It will be used by queue_send to
1017  *            build the message to be sent if not already prebuilt.
1018  * @param type Type of the message, 0 for a raw message.
1019  * @param size Size of the message.
1020  * @param dst Neighbor to send message to.
1021  * @param t Tunnel this message belongs to.
1022  */
1023 static void
1024 queue_add (void *cls, uint16_t type, size_t size,
1025            struct MeshPeerInfo *dst, struct MeshTunnel *t);
1026
1027
1028 /**
1029  * Free a transmission that was already queued with all resources
1030  * associated to the request.
1031  *
1032  * @param queue Queue handler to cancel.
1033  * @param clear_cls Is it necessary to free associated cls?
1034  */
1035 static void
1036 queue_destroy (struct MeshPeerQueue *queue, int clear_cls);
1037
1038
1039 /**
1040  * @brief Get the next transmittable message from the queue.
1041  *
1042  * This will be the head, except in the case of being a data packet
1043  * not allowed by the destination peer.
1044  *
1045  * @param peer Destination peer.
1046  *
1047  * @return The next viable MeshPeerQueue element to send to that peer.
1048  *         NULL when there are no transmittable messages.
1049  */
1050 struct MeshPeerQueue *
1051 queue_get_next (const struct MeshPeerInfo *peer);
1052
1053
1054 /**
1055  * Core callback to write a queued packet to core buffer
1056  *
1057  * @param cls Closure (peer info).
1058  * @param size Number of bytes available in buf.
1059  * @param buf Where the to write the message.
1060  *
1061  * @return number of bytes written to buf
1062  */
1063 static size_t
1064 queue_send (void *cls, size_t size, void *buf);
1065
1066
1067 /******************************************************************************/
1068 /************************    PERIODIC FUNCTIONS    ****************************/
1069 /******************************************************************************/
1070
1071 /**
1072  * Periodically announce self id in the DHT
1073  *
1074  * @param cls closure
1075  * @param tc task context
1076  */
1077 static void
1078 announce_id (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1079 {
1080   struct PBlock block;
1081
1082   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
1083   {
1084     announce_id_task = GNUNET_SCHEDULER_NO_TASK;
1085     return;
1086   }
1087   /* TODO
1088    * - Set data expiration in function of X
1089    * - Adapt X to churn
1090    */
1091   DEBUG_DHT ("DHT_put for ID %s started.\n", GNUNET_i2s (&my_full_id));
1092
1093   block.id = my_full_id;
1094   block.type = htonl (0);
1095   GNUNET_DHT_put (dht_handle,   /* DHT handle */
1096                   &my_full_id.hashPubKey,       /* Key to use */
1097                   dht_replication_level,     /* Replication level */
1098                   GNUNET_DHT_RO_RECORD_ROUTE | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE,    /* DHT options */
1099                   GNUNET_BLOCK_TYPE_MESH_PEER,       /* Block type */
1100                   sizeof (block),  /* Size of the data */
1101                   (const char *) &block, /* Data itself */
1102                   GNUNET_TIME_UNIT_FOREVER_ABS,  /* Data expiration */
1103                   GNUNET_TIME_UNIT_FOREVER_REL, /* Retry time */
1104                   NULL,         /* Continuation */
1105                   NULL);        /* Continuation closure */
1106   announce_id_task =
1107       GNUNET_SCHEDULER_add_delayed (id_announce_time, &announce_id, cls);
1108 }
1109
1110
1111 /******************************************************************************/
1112 /******************      GENERAL HELPER FUNCTIONS      ************************/
1113 /******************************************************************************/
1114
1115 /**
1116  * Decrements the reference counter and frees all resources if needed
1117  *
1118  * @param mesh_data Data Descriptor used in a multicast message.
1119  *                  Freed no longer needed (last message).
1120  */
1121 static void
1122 data_descriptor_decrement_rc (struct MeshData *mesh_data)
1123 {
1124   if (0 == --(mesh_data->reference_counter))
1125   {
1126     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Last copy!\n");
1127     GNUNET_free (mesh_data->data);
1128     GNUNET_free (mesh_data);
1129   }
1130 }
1131
1132
1133 /**
1134  * Check if client has registered with the service and has not disconnected
1135  *
1136  * @param client the client to check
1137  *
1138  * @return non-NULL if client exists in the global DLL
1139  */
1140 static struct MeshClient *
1141 client_get (struct GNUNET_SERVER_Client *client)
1142 {
1143   struct MeshClient *c;
1144
1145   c = clients;
1146   while (NULL != c)
1147   {
1148     if (c->handle == client)
1149       return c;
1150     c = c->next;
1151   }
1152   return NULL;
1153 }
1154
1155
1156 /**
1157  * Checks if a given client has subscribed to certain message type
1158  *
1159  * @param message_type Type of message to check
1160  * @param c Client to check
1161  *
1162  * @return GNUNET_YES or GNUNET_NO, depending on subscription status
1163  * 
1164  * FIXME: use of crypto_hash slows it down
1165  *  The hash function alone takes 8-10us out of the ~55us for the whole
1166  * process of retransmitting the message from one local client to another.
1167  * Find faster implementation!
1168  */
1169 static int
1170 client_is_subscribed (uint16_t message_type, struct MeshClient *c)
1171 {
1172   struct GNUNET_HashCode hc;
1173
1174   if (NULL == c->types)
1175     return GNUNET_NO;
1176
1177   GNUNET_CRYPTO_hash (&message_type, sizeof (uint16_t), &hc);
1178   return GNUNET_CONTAINER_multihashmap_contains (c->types, &hc);
1179 }
1180
1181
1182 /**
1183  * Check whether client wants traffic from a tunnel.
1184  *
1185  * @param c Client to check.
1186  * @param t Tunnel to be found.
1187  *
1188  * @return GNUNET_YES if client knows tunnel.
1189  * 
1190  * TODO look in client hashmap
1191  */
1192 static int
1193 client_wants_tunnel (struct MeshClient *c, struct MeshTunnel *t)
1194 {
1195   unsigned int i;
1196
1197   for (i = 0; i < t->nclients; i++)
1198     if (t->clients[i] == c)
1199       return GNUNET_YES;
1200   return GNUNET_NO;
1201 }
1202
1203
1204 /**
1205  * Check whether client has been informed about a tunnel.
1206  *
1207  * @param c Client to check.
1208  * @param t Tunnel to be found.
1209  *
1210  * @return GNUNET_YES if client knows tunnel.
1211  * 
1212  * TODO look in client hashmap
1213  */
1214 static int
1215 client_knows_tunnel (struct MeshClient *c, struct MeshTunnel *t)
1216 {
1217   unsigned int i;
1218
1219   for (i = 0; i < t->nignore; i++)
1220     if (t->ignore[i] == c)
1221       return GNUNET_YES;
1222   return client_wants_tunnel(c, t);
1223 }
1224
1225
1226 /**
1227  * Marks a client as uninterested in traffic from the tunnel, updating both
1228  * client and tunnel to reflect this.
1229  *
1230  * @param c Client that doesn't want traffic anymore.
1231  * @param t Tunnel which should be ignored.
1232  *
1233  * FIXME when to delete an incoming tunnel?
1234  */
1235 static void
1236 client_ignore_tunnel (struct MeshClient *c, struct MeshTunnel *t)
1237 {
1238   struct GNUNET_HashCode hash;
1239
1240   GNUNET_CRYPTO_hash (&t->local_tid_dest, sizeof (MESH_TunnelNumber), &hash);
1241   GNUNET_break (GNUNET_YES ==
1242                 GNUNET_CONTAINER_multihashmap_remove (c->incoming_tunnels,
1243                                                       &hash, t));
1244   GNUNET_break (GNUNET_YES ==
1245                 GNUNET_CONTAINER_multihashmap_put (c->ignore_tunnels, &hash, t,
1246                                                    GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST));
1247   tunnel_delete_active_client (t, c);
1248   GNUNET_array_append (t->ignore, t->nignore, c);
1249 }
1250
1251
1252 /**
1253  * Deletes a tunnel from a client (either owner or destination). To be used on
1254  * tunnel destroy, otherwise, use client_ignore_tunnel.
1255  *
1256  * @param c Client whose tunnel to delete.
1257  * @param t Tunnel which should be deleted.
1258  */
1259 static void
1260 client_delete_tunnel (struct MeshClient *c, struct MeshTunnel *t)
1261 {
1262   struct GNUNET_HashCode hash;
1263
1264   if (c == t->owner)
1265   {
1266     GNUNET_CRYPTO_hash(&t->local_tid, sizeof (MESH_TunnelNumber), &hash);
1267     GNUNET_assert (GNUNET_YES ==
1268                    GNUNET_CONTAINER_multihashmap_remove (c->own_tunnels,
1269                                                          &hash,
1270                                                          t));
1271   }
1272   else
1273   {
1274     GNUNET_CRYPTO_hash(&t->local_tid_dest, sizeof (MESH_TunnelNumber), &hash);
1275     // FIXME XOR?
1276     GNUNET_assert (GNUNET_YES ==
1277                    GNUNET_CONTAINER_multihashmap_remove (c->incoming_tunnels,
1278                                                          &hash,
1279                                                          t) ||
1280                    GNUNET_YES ==
1281                    GNUNET_CONTAINER_multihashmap_remove (c->ignore_tunnels,
1282                                                          &hash,
1283                                                          t));
1284   }
1285 }
1286
1287
1288 /**
1289  * Send the message to all clients that have subscribed to its type
1290  *
1291  * @param msg Pointer to the message itself
1292  * @param payload Pointer to the payload of the message.
1293  * @param t The tunnel to whose clients this message goes.
1294  * 
1295  * @return number of clients this message was sent to
1296  */
1297 static unsigned int
1298 send_subscribed_clients (const struct GNUNET_MessageHeader *msg,
1299                          const struct GNUNET_MessageHeader *payload,
1300                          struct MeshTunnel *t)
1301 {
1302   struct MeshClient *c;
1303   MESH_TunnelNumber *tid;
1304   unsigned int count;
1305   uint16_t type;
1306   char cbuf[htons (msg->size)];
1307
1308   type = ntohs (payload->type);
1309   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending to clients...\n");
1310   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "message of type %s\n",
1311               GNUNET_MESH_DEBUG_M2S (type));
1312
1313   memcpy (cbuf, msg, sizeof (cbuf));
1314   switch (htons (msg->type))
1315   {
1316     struct GNUNET_MESH_Unicast *uc;
1317     struct GNUNET_MESH_ToOrigin *to;
1318
1319     case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
1320       uc = (struct GNUNET_MESH_Unicast *) cbuf;
1321       tid = &uc->tid;
1322       break;
1323     case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN:
1324       to = (struct GNUNET_MESH_ToOrigin *) cbuf;
1325       tid = &to->tid;
1326       break;
1327     default:
1328       GNUNET_break (0);
1329       return 0;
1330   }
1331
1332   for (count = 0, c = clients; c != NULL; c = c->next)
1333   {
1334     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   client %u\n", c->id);
1335     if (client_is_subscribed (type, c))
1336     {
1337       if (htons (msg->type) == GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN)
1338       {
1339         if (c != t->owner)
1340           continue;
1341         *tid = htonl (t->local_tid);
1342       }
1343       else
1344       {
1345         if (GNUNET_NO == client_knows_tunnel (c, t))
1346         {
1347           /* This client doesn't know the tunnel */
1348           struct GNUNET_MESH_TunnelNotification tmsg;
1349           struct GNUNET_HashCode hash;
1350
1351           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "     sending tunnel create\n");
1352           tmsg.header.size = htons (sizeof (tmsg));
1353           tmsg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_CREATE);
1354           GNUNET_PEER_resolve (t->id.oid, &tmsg.peer);
1355           tmsg.tunnel_id = htonl (t->local_tid_dest);
1356           tmsg.opt = 0;
1357           if (GNUNET_YES == t->nobuffer)
1358             tmsg.opt |= MESH_TUNNEL_OPT_NOBUFFER;
1359           GNUNET_SERVER_notification_context_unicast (nc, c->handle,
1360                                                       &tmsg.header, GNUNET_NO);
1361           tunnel_add_client (t, c);
1362           GNUNET_CRYPTO_hash (&t->local_tid_dest, sizeof (MESH_TunnelNumber),
1363                               &hash);
1364           GNUNET_break (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (
1365                                        c->incoming_tunnels, &hash, t,
1366                                        GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST));
1367         }
1368         *tid = htonl (t->local_tid_dest);
1369       }
1370
1371       /* Check if the client wants to get traffic from the tunnel */
1372       if (GNUNET_NO == client_wants_tunnel(c, t))
1373         continue;
1374       count++;
1375       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "     sending\n");
1376       GNUNET_SERVER_notification_context_unicast (nc, c->handle,
1377                                                   (struct GNUNET_MessageHeader
1378                                                    *) cbuf, GNUNET_NO);
1379     }
1380   }
1381
1382   return count;
1383 }
1384
1385
1386 /**
1387  * Notify all clients (not depending on registration status) that the incoming
1388  * tunnel is no longer valid.
1389  *
1390  * @param t Tunnel that was destroyed.
1391  */
1392 static void
1393 send_clients_tunnel_destroy (struct MeshTunnel *t)
1394 {
1395   struct GNUNET_MESH_TunnelMessage msg;
1396
1397   msg.header.size = htons (sizeof (msg));
1398   msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_DESTROY);
1399   msg.tunnel_id = htonl (t->local_tid_dest);
1400   GNUNET_SERVER_notification_context_broadcast (nc, &msg.header, GNUNET_NO);
1401 }
1402
1403
1404 /**
1405  * Notify clients of tunnel disconnections, if needed.
1406  * In case the origin disconnects, the destination clients get a tunnel destroy
1407  * notification. If the last destination disconnects (only one remaining client
1408  * in tunnel), the origin gets a (local ID) peer disconnected.
1409  * Note that the function must be called BEFORE removing the client from
1410  * the tunnel.
1411  *
1412  * @param t Tunnel that was destroyed.
1413  * @param c Client that disconnected.
1414  */
1415 static void
1416 send_client_tunnel_disconnect (struct MeshTunnel *t, struct MeshClient *c)
1417 {
1418   unsigned int i;
1419
1420   if (c == t->owner)
1421   {
1422     struct GNUNET_MESH_TunnelMessage msg;
1423
1424     msg.header.size = htons (sizeof (msg));
1425     msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_DESTROY);
1426     msg.tunnel_id = htonl (t->local_tid_dest);
1427     for (i = 0; i < t->nclients; i++)
1428       GNUNET_SERVER_notification_context_unicast (nc, t->clients[i]->handle,
1429                                                   &msg.header, GNUNET_NO);
1430   }
1431   // FIXME when to disconnect an incoming tunnel?
1432 }
1433
1434
1435 /**
1436  * Iterator over all the peers to remove the oldest not-used entry.
1437  *
1438  * @param cls Closure (unsued).
1439  * @param key ID of the peer.
1440  * @param value Peer_Info of the peer.
1441  *
1442  * FIXME implement
1443  */
1444 static int
1445 peer_info_timeout (void *cls,
1446                    const struct GNUNET_HashCode *key,
1447                    void *value)
1448 {
1449   return GNUNET_YES;
1450 }
1451
1452 /**
1453  * Retrieve the MeshPeerInfo stucture associated with the peer, create one
1454  * and insert it in the appropiate structures if the peer is not known yet.
1455  *
1456  * @param peer Full identity of the peer.
1457  *
1458  * @return Existing or newly created peer info.
1459  */
1460 static struct MeshPeerInfo *
1461 peer_info_get (const struct GNUNET_PeerIdentity *peer)
1462 {
1463   struct MeshPeerInfo *peer_info;
1464
1465   peer_info = GNUNET_CONTAINER_multihashmap_get (peers, &peer->hashPubKey);
1466   if (NULL == peer_info)
1467   {
1468     peer_info =
1469         (struct MeshPeerInfo *) GNUNET_malloc (sizeof (struct MeshPeerInfo));
1470     if (GNUNET_CONTAINER_multihashmap_size (peers) > max_peers)
1471     {
1472       GNUNET_CONTAINER_multihashmap_iterate (peers,
1473                                              &peer_info_timeout,
1474                                              NULL);
1475     }
1476     GNUNET_CONTAINER_multihashmap_put (peers, &peer->hashPubKey, peer_info,
1477                                        GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
1478     peer_info->id = GNUNET_PEER_intern (peer);
1479   }
1480   peer_info->last_contact = GNUNET_TIME_absolute_get();
1481
1482   return peer_info;
1483 }
1484
1485
1486 /**
1487  * Retrieve the MeshPeerInfo stucture associated with the peer, create one
1488  * and insert it in the appropiate structures if the peer is not known yet.
1489  *
1490  * @param peer Short identity of the peer.
1491  *
1492  * @return Existing or newly created peer info.
1493  */
1494 static struct MeshPeerInfo *
1495 peer_info_get_short (const GNUNET_PEER_Id peer)
1496 {
1497   struct GNUNET_PeerIdentity id;
1498
1499   GNUNET_PEER_resolve (peer, &id);
1500   return peer_info_get (&id);
1501 }
1502
1503
1504 /**
1505  * Iterator to remove the tunnel from the list of tunnels a peer participates
1506  * in.
1507  *
1508  * @param cls Closure (tunnel info)
1509  * @param key GNUNET_PeerIdentity of the peer (unused)
1510  * @param value PeerInfo of the peer
1511  *
1512  * @return always GNUNET_YES, to keep iterating
1513  */
1514 static int
1515 peer_info_delete_tunnel (void *cls, const struct GNUNET_HashCode * key, void *value)
1516 {
1517   struct MeshTunnel *t = cls;
1518   struct MeshPeerInfo *peer = value;
1519   unsigned int i;
1520
1521   for (i = 0; i < peer->ntunnels; i++)
1522   {
1523     if (0 ==
1524         memcmp (&peer->tunnels[i]->id, &t->id, sizeof (struct MESH_TunnelID)))
1525     {
1526       peer->ntunnels--;
1527       peer->tunnels[i] = peer->tunnels[peer->ntunnels];
1528       peer->tunnels = 
1529         GNUNET_realloc (peer->tunnels, 
1530                         peer->ntunnels * sizeof(struct MeshTunnel *));
1531       return GNUNET_YES;
1532     }
1533   }
1534   return GNUNET_YES;
1535 }
1536
1537
1538 /**
1539   * Core callback to write a pre-constructed data packet to core buffer
1540   *
1541   * @param cls Closure (MeshTransmissionDescriptor with data in "data" member).
1542   * @param size Number of bytes available in buf.
1543   * @param buf Where the to write the message.
1544   *
1545   * @return number of bytes written to buf
1546   */
1547 static size_t
1548 send_core_data_raw (void *cls, size_t size, void *buf)
1549 {
1550   struct MeshTransmissionDescriptor *info = cls;
1551   struct GNUNET_MessageHeader *msg;
1552   size_t total_size;
1553
1554   GNUNET_assert (NULL != info);
1555   GNUNET_assert (NULL != info->mesh_data);
1556   msg = (struct GNUNET_MessageHeader *) info->mesh_data->data;
1557   total_size = ntohs (msg->size);
1558
1559   if (total_size > size)
1560   {
1561     GNUNET_break (0);
1562     return 0;
1563   }
1564   memcpy (buf, msg, total_size);
1565   data_descriptor_decrement_rc (info->mesh_data);
1566   GNUNET_free (info);
1567   return total_size;
1568 }
1569
1570
1571 /**
1572  * Sends an already built non-multicast message to a peer,
1573  * properly registrating all used resources.
1574  *
1575  * @param message Message to send. Function makes a copy of it.
1576  * @param peer Short ID of the neighbor whom to send the message.
1577  * @param t Tunnel on which this message is transmitted.
1578  */
1579 static void
1580 send_prebuilt_message (const struct GNUNET_MessageHeader *message,
1581                        const struct GNUNET_PeerIdentity *peer,
1582                        struct MeshTunnel *t)
1583 {
1584   struct MeshTransmissionDescriptor *info;
1585   struct MeshPeerInfo *neighbor;
1586   struct MeshPeerPath *p;
1587   size_t size;
1588   uint16_t type;
1589
1590 //   GNUNET_TRANSPORT_try_connect(); FIXME use?
1591
1592   size = ntohs (message->size);
1593   info = GNUNET_malloc (sizeof (struct MeshTransmissionDescriptor));
1594   info->mesh_data = GNUNET_malloc (sizeof (struct MeshData));
1595   info->mesh_data->data = GNUNET_malloc (size);
1596   memcpy (info->mesh_data->data, message, size);
1597   type = ntohs(message->type);
1598   switch (type)
1599   {
1600     struct GNUNET_MESH_Unicast *m;
1601     struct GNUNET_MESH_ToOrigin *to;
1602
1603     case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
1604       m = (struct GNUNET_MESH_Unicast *) info->mesh_data->data;
1605       m->ttl = htonl (ntohl (m->ttl) - 1);
1606       break;
1607     case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN:
1608       to = (struct GNUNET_MESH_ToOrigin *) info->mesh_data->data;
1609       t->bck_pid++;
1610       to->pid = htonl(t->bck_pid);
1611   }
1612   info->mesh_data->data_len = size;
1613   info->mesh_data->reference_counter = 1;
1614   info->mesh_data->total_out = 1;
1615   neighbor = peer_info_get (peer);
1616   for (p = neighbor->path_head; NULL != p; p = p->next)
1617   {
1618     if (2 >= p->length)
1619     {
1620       break;
1621     }
1622   }
1623   if (NULL == p)
1624   {
1625 #if MESH_DEBUG
1626     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1627                 "  %s IS NOT DIRECTLY CONNECTED\n",
1628                 GNUNET_i2s(peer));
1629     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1630                 "  PATHS TO %s:\n",
1631                 GNUNET_i2s(peer));
1632     for (p = neighbor->path_head; NULL != p; p = p->next)
1633     {
1634       struct GNUNET_PeerIdentity debug_id;
1635       unsigned int i;
1636
1637       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1638                   "    path with %u hops through:\n",
1639                   p->length);
1640       for (i = 0; i < p->length; i++)
1641       {
1642         GNUNET_PEER_resolve(p->peers[i], &debug_id);
1643         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1644                     "      hop %u: %s\n",
1645                     i, GNUNET_i2s(&debug_id));
1646       }
1647     }
1648 #endif
1649     GNUNET_break (0); // FIXME sometimes fails (testing disconnect?)
1650     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1651                     " no direct connection to %s\n",
1652                     GNUNET_i2s (peer));
1653     GNUNET_free (info->mesh_data->data);
1654     GNUNET_free (info->mesh_data);
1655     GNUNET_free (info);
1656     return;
1657   }
1658   info->peer = neighbor;
1659   if (GNUNET_MESSAGE_TYPE_MESH_PATH_ACK == type)
1660     type = 0;
1661   queue_add (info,
1662              type,
1663              size,
1664              neighbor,
1665              t);
1666 }
1667
1668
1669 /**
1670  * Sends a CREATE PATH message for a path to a peer, properly registrating
1671  * all used resources.
1672  *
1673  * @param peer PeerInfo of the final peer for whom this path is being created.
1674  * @param p Path itself.
1675  * @param t Tunnel for which the path is created.
1676  */
1677 static void
1678 send_create_path (struct MeshPeerInfo *peer, struct MeshPeerPath *p,
1679                   struct MeshTunnel *t)
1680 {
1681   struct GNUNET_PeerIdentity id;
1682   struct MeshPathInfo *path_info;
1683   struct MeshPeerInfo *neighbor;
1684
1685   unsigned int i;
1686
1687   if (NULL == p)
1688   {
1689     p = tree_get_path_to_peer (t->tree, peer->id);
1690     if (NULL == p)
1691     {
1692       GNUNET_break (0);
1693       return;
1694     }
1695   }
1696   for (i = 0; i < p->length; i++)
1697   {
1698     if (p->peers[i] == myid)
1699       break;
1700   }
1701   if (i >= p->length - 1)
1702   {
1703     path_destroy (p);
1704     GNUNET_break (0);
1705     return;
1706   }
1707   GNUNET_PEER_resolve (p->peers[i + 1], &id);
1708
1709   path_info = GNUNET_malloc (sizeof (struct MeshPathInfo));
1710   path_info->path = p;
1711   path_info->t = t;
1712   neighbor = peer_info_get (&id);
1713   path_info->peer = neighbor;
1714   queue_add (path_info,
1715              GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE,
1716              sizeof (struct GNUNET_MESH_ManipulatePath) +
1717                 (p->length * sizeof (struct GNUNET_PeerIdentity)),
1718              neighbor,
1719              t);
1720 }
1721
1722
1723 /**
1724  * Sends a DESTROY PATH message to free resources for a path in a tunnel
1725  *
1726  * @param t Tunnel whose path to destroy.
1727  * @param destination Short ID of the peer to whom the path to destroy.
1728  */
1729 static void
1730 send_destroy_path (struct MeshTunnel *t, GNUNET_PEER_Id destination)
1731 {
1732   struct MeshPeerPath *p;
1733   size_t size;
1734
1735   p = tree_get_path_to_peer (t->tree, destination);
1736   if (NULL == p)
1737   {
1738     GNUNET_break (0);
1739     return;
1740   }
1741   size = sizeof (struct GNUNET_MESH_ManipulatePath);
1742   size += p->length * sizeof (struct GNUNET_PeerIdentity);
1743   {
1744     struct GNUNET_MESH_ManipulatePath *msg;
1745     struct GNUNET_PeerIdentity *pi;
1746     char cbuf[size];
1747     unsigned int i;
1748
1749     msg = (struct GNUNET_MESH_ManipulatePath *) cbuf;
1750     msg->header.size = htons (size);
1751     msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_PATH_DESTROY);
1752     msg->tid = htonl (t->id.tid);
1753     pi = (struct GNUNET_PeerIdentity *) &msg[1];
1754     for (i = 0; i < p->length; i++)
1755     {
1756       GNUNET_PEER_resolve (p->peers[i], &pi[i]);
1757     }
1758     send_prebuilt_message (&msg->header, tree_get_first_hop (t->tree, destination), t);
1759   }
1760   path_destroy (p);
1761 }
1762
1763
1764 /**
1765  * Sends a PATH ACK message in reponse to a received PATH_CREATE directed to us.
1766  *
1767  * @param t Tunnel which to confirm.
1768  */
1769 static void
1770 send_path_ack (struct MeshTunnel *t) 
1771 {
1772   struct MeshTransmissionDescriptor *info;
1773   struct GNUNET_PeerIdentity id;
1774   GNUNET_PEER_Id peer;
1775
1776   peer = tree_get_predecessor (t->tree);
1777   GNUNET_PEER_resolve (peer, &id);
1778   info = GNUNET_malloc (sizeof (struct MeshTransmissionDescriptor));
1779   info->origin = &t->id;
1780   info->peer = GNUNET_CONTAINER_multihashmap_get (peers, &id.hashPubKey);
1781   GNUNET_assert (NULL != info->peer);
1782
1783   queue_add (info,
1784              GNUNET_MESSAGE_TYPE_MESH_PATH_ACK,
1785              sizeof (struct GNUNET_MESH_PathACK),
1786              info->peer,
1787              t);
1788 }
1789
1790
1791 /**
1792  * Try to establish a new connection to this peer.
1793  * Use the best path for the given tunnel.
1794  * If the peer doesn't have any path to it yet, try to get one.
1795  * If the peer already has some path, send a CREATE PATH towards it.
1796  *
1797  * @param peer PeerInfo of the peer.
1798  * @param t Tunnel for which to create the path, if possible.
1799  */
1800 static void
1801 peer_info_connect (struct MeshPeerInfo *peer, struct MeshTunnel *t)
1802 {
1803   struct MeshPeerPath *p;
1804   struct MeshPathInfo *path_info;
1805
1806   if (NULL != peer->path_head)
1807   {
1808     p = tree_get_path_to_peer (t->tree, peer->id);
1809     if (NULL == p)
1810     {
1811       GNUNET_break (0);
1812       return;
1813     }
1814
1815     // FIXME always send create path to self
1816     if (p->length > 1)
1817     {
1818       send_create_path (peer, p, t);
1819     }
1820     else
1821     {
1822       struct GNUNET_HashCode hash;
1823
1824       path_destroy (p);
1825       t->local_tid_dest = next_local_tid++;
1826       GNUNET_CRYPTO_hash (&t->local_tid_dest, sizeof (MESH_TunnelNumber),
1827                           &hash);
1828       if (GNUNET_OK !=
1829           GNUNET_CONTAINER_multihashmap_put (incoming_tunnels, &hash, t,
1830                                              GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
1831       {
1832         GNUNET_break (0);
1833         return;
1834       }
1835     }
1836   }
1837   else if (NULL == peer->dhtget)
1838   {
1839     struct GNUNET_PeerIdentity id;
1840
1841     GNUNET_PEER_resolve (peer->id, &id);
1842     path_info = GNUNET_malloc (sizeof (struct MeshPathInfo));
1843     path_info->peer = peer;
1844     path_info->t = t;
1845     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1846                 "  Starting DHT GET for peer %s\n", GNUNET_i2s (&id));
1847     peer->dhtgetcls = path_info;
1848     peer->dhtget = GNUNET_DHT_get_start (dht_handle,    /* handle */
1849                                          GNUNET_BLOCK_TYPE_MESH_PEER, /* type */
1850                                          &id.hashPubKey,     /* key to search */
1851                                          dht_replication_level, /* replication level */
1852                                          GNUNET_DHT_RO_RECORD_ROUTE |
1853                                          GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE,
1854                                          NULL,       /* xquery */ // FIXME BLOOMFILTER
1855                                          0,     /* xquery bits */ // FIXME BLOOMFILTER SIZE
1856                                          &dht_get_id_handler, path_info);
1857   }
1858   /* Otherwise, there is no path but the DHT get is already started. */
1859 }
1860
1861
1862 /**
1863  * Task to delay the connection of a peer
1864  *
1865  * @param cls Closure (path info with tunnel and peer to connect).
1866  *            Will be free'd on exection.
1867  * @param tc TaskContext
1868  */
1869 static void
1870 peer_info_connect_task (void *cls,
1871                         const struct GNUNET_SCHEDULER_TaskContext *tc)
1872 {
1873   struct MeshPathInfo *path_info = cls;
1874
1875   path_info->peer->connect_task = GNUNET_SCHEDULER_NO_TASK;
1876
1877   if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason))
1878   {
1879     GNUNET_free (cls);
1880     return;
1881   }
1882   peer_info_connect (path_info->peer, path_info->t);
1883   GNUNET_free (cls);
1884 }
1885
1886
1887 /**
1888  * Destroy the peer_info and free any allocated resources linked to it
1889  *
1890  * @param pi The peer_info to destroy.
1891  *
1892  * @return GNUNET_OK on success
1893  */
1894 static int
1895 peer_info_destroy (struct MeshPeerInfo *pi)
1896 {
1897   struct GNUNET_PeerIdentity id;
1898   struct MeshPeerPath *p;
1899   struct MeshPeerPath *nextp;
1900
1901   GNUNET_PEER_resolve (pi->id, &id);
1902   GNUNET_PEER_change_rc (pi->id, -1);
1903
1904   if (GNUNET_YES !=
1905       GNUNET_CONTAINER_multihashmap_remove (peers, &id.hashPubKey, pi))
1906   {
1907     GNUNET_break (0);
1908     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1909                 "removing peer %s, not in hashmap\n", GNUNET_i2s (&id));
1910   }
1911   if (NULL != pi->dhtget)
1912   {
1913     GNUNET_DHT_get_stop (pi->dhtget);
1914     GNUNET_free (pi->dhtgetcls);
1915   }
1916   p = pi->path_head;
1917   while (NULL != p)
1918   {
1919     nextp = p->next;
1920     GNUNET_CONTAINER_DLL_remove (pi->path_head, pi->path_tail, p);
1921     path_destroy (p);
1922     p = nextp;
1923   }
1924   if (GNUNET_SCHEDULER_NO_TASK != pi->connect_task)
1925   {
1926     GNUNET_free (GNUNET_SCHEDULER_cancel (pi->connect_task));
1927   }
1928   GNUNET_free (pi);
1929   return GNUNET_OK;
1930 }
1931
1932
1933 /**
1934  * Remove all paths that rely on a direct connection between p1 and p2
1935  * from the peer itself and notify all tunnels about it.
1936  *
1937  * @param peer PeerInfo of affected peer.
1938  * @param p1 GNUNET_PEER_Id of one peer.
1939  * @param p2 GNUNET_PEER_Id of another peer that was connected to the first and
1940  *           no longer is.
1941  *
1942  * TODO: optimize (see below)
1943  */
1944 static void
1945 peer_info_remove_path (struct MeshPeerInfo *peer, GNUNET_PEER_Id p1,
1946                        GNUNET_PEER_Id p2)
1947 {
1948   struct MeshPeerPath *p;
1949   struct MeshPeerPath *aux;
1950   struct MeshPeerInfo *peer_d;
1951   GNUNET_PEER_Id d;
1952   unsigned int destroyed;
1953   unsigned int best;
1954   unsigned int cost;
1955   unsigned int i;
1956
1957   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "peer_info_remove_path\n");
1958   destroyed = 0;
1959   p = peer->path_head;
1960   while (NULL != p)
1961   {
1962     aux = p->next;
1963     for (i = 0; i < (p->length - 1); i++)
1964     {
1965       if ((p->peers[i] == p1 && p->peers[i + 1] == p2) ||
1966           (p->peers[i] == p2 && p->peers[i + 1] == p1))
1967       {
1968         GNUNET_CONTAINER_DLL_remove (peer->path_head, peer->path_tail, p);
1969         path_destroy (p);
1970         destroyed++;
1971         break;
1972       }
1973     }
1974     p = aux;
1975   }
1976   if (0 == destroyed)
1977     return;
1978
1979   for (i = 0; i < peer->ntunnels; i++)
1980   {
1981     d = tunnel_notify_connection_broken (peer->tunnels[i], p1, p2);
1982     if (0 == d)
1983       continue;
1984     /* TODO
1985      * Problem: one or more peers have been deleted from the tunnel tree.
1986      * We don't know who they are to try to add them again.
1987      * We need to try to find a new path for each of the disconnected peers.
1988      * Some of them might already have a path to reach them that does not
1989      * involve p1 and p2. Adding all anew might render in a better tree than
1990      * the trivial immediate fix.
1991      *
1992      * Trivial immiediate fix: try to reconnect to the disconnected node. All
1993      * its children will be reachable trough him.
1994      */
1995     peer_d = peer_info_get_short (d);
1996     best = UINT_MAX;
1997     aux = NULL;
1998     for (p = peer_d->path_head; NULL != p; p = p->next)
1999     {
2000       if ((cost = tree_get_path_cost (peer->tunnels[i]->tree, p)) < best)
2001       {
2002         best = cost;
2003         aux = p;
2004       }
2005     }
2006     if (NULL != aux)
2007     {
2008       /* No callback, as peer will be already disconnected and a connection
2009        * scheduled by tunnel_notify_connection_broken.
2010        */
2011       tree_add_path (peer->tunnels[i]->tree, aux, NULL, NULL);
2012     }
2013     else
2014     {
2015       peer_info_connect (peer_d, peer->tunnels[i]);
2016     }
2017   }
2018   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "peer_info_remove_path END\n");
2019 }
2020
2021
2022 /**
2023  * Add the path to the peer and update the path used to reach it in case this
2024  * is the shortest.
2025  *
2026  * @param peer_info Destination peer to add the path to.
2027  * @param path New path to add. Last peer must be the peer in arg 1.
2028  *             Path will be either used of freed if already known.
2029  * @param trusted Do we trust that this path is real?
2030  */
2031 void
2032 peer_info_add_path (struct MeshPeerInfo *peer_info, struct MeshPeerPath *path,
2033                     int trusted)
2034 {
2035   struct MeshPeerPath *aux;
2036   unsigned int l;
2037   unsigned int l2;
2038
2039   if ((NULL == peer_info) || (NULL == path))
2040   {
2041     GNUNET_break (0);
2042     path_destroy (path);
2043     return;
2044   }
2045   if (path->peers[path->length - 1] != peer_info->id)
2046   {
2047     GNUNET_break (0);
2048     path_destroy (path);
2049     return;
2050   }
2051   if (path->length <= 2 && GNUNET_NO == trusted)
2052   {
2053     /* Only allow CORE to tell us about direct paths */
2054     path_destroy (path);
2055     return;
2056   }
2057   GNUNET_assert (peer_info->id == path->peers[path->length - 1]);
2058   for (l = 1; l < path->length; l++)
2059   {
2060     if (path->peers[l] == myid)
2061     {
2062       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "shortening path by %u\n", l);
2063       for (l2 = 0; l2 < path->length - l; l2++)
2064       {
2065         path->peers[l2] = path->peers[l + l2];
2066       }
2067       path->length -= l;
2068       l = 1;
2069       path->peers =
2070           GNUNET_realloc (path->peers, path->length * sizeof (GNUNET_PEER_Id));
2071     }
2072   }
2073 #if MESH_DEBUG
2074   {
2075     struct GNUNET_PeerIdentity id;
2076
2077     GNUNET_PEER_resolve (peer_info->id, &id);
2078     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "adding path [%u] to peer %s\n",
2079                 path->length, GNUNET_i2s (&id));
2080   }
2081 #endif
2082   l = path_get_length (path);
2083   if (0 == l)
2084   {
2085     GNUNET_free (path);
2086     return;
2087   }
2088
2089   GNUNET_assert (peer_info->id == path->peers[path->length - 1]);
2090   for (aux = peer_info->path_head; aux != NULL; aux = aux->next)
2091   {
2092     l2 = path_get_length (aux);
2093     if (l2 > l)
2094     {
2095       GNUNET_CONTAINER_DLL_insert_before (peer_info->path_head,
2096                                           peer_info->path_tail, aux, path);
2097       return;
2098     }
2099     else
2100     {
2101       if (l2 == l && memcmp (path->peers, aux->peers, l) == 0)
2102       {
2103         path_destroy (path);
2104         return;
2105       }
2106     }
2107   }
2108   GNUNET_CONTAINER_DLL_insert_tail (peer_info->path_head, peer_info->path_tail,
2109                                     path);
2110   return;
2111 }
2112
2113
2114 /**
2115  * Add the path to the origin peer and update the path used to reach it in case
2116  * this is the shortest.
2117  * The path is given in peer_info -> destination, therefore we turn the path
2118  * upside down first.
2119  *
2120  * @param peer_info Peer to add the path to, being the origin of the path.
2121  * @param path New path to add after being inversed.
2122  * @param trusted Do we trust that this path is real?
2123  */
2124 static void
2125 peer_info_add_path_to_origin (struct MeshPeerInfo *peer_info,
2126                               struct MeshPeerPath *path, int trusted)
2127 {
2128   path_invert (path);
2129   peer_info_add_path (peer_info, path, trusted);
2130 }
2131
2132
2133 /** FIXME
2134  * Function called if the connection to the peer has been stalled for a while,
2135  * possibly due to a missed ACK. Poll the peer about its ACK status.
2136  *
2137  * @param cls Closure (cinfo).
2138  * @param tc TaskContext.
2139  */
2140 static void
2141 tunnel_poll (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
2142 {
2143 //   struct GNUNET_MESH_Poll msg;
2144 //   struct GNUNET_PeerIdentity id;
2145 //   struct MeshTunnel *t;
2146
2147 //   cinfo->fc_poll = GNUNET_SCHEDULER_NO_TASK;
2148   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
2149   {
2150     return;
2151   }
2152
2153 //   t = cinfo->t;
2154 //   msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_POLL);
2155 //   msg.header.size = htons (sizeof (msg));
2156 //   msg.tid = htonl (t->id.tid);
2157 //   GNUNET_PEER_resolve (t->id.oid, &msg.oid);
2158 //   msg.last_ack = htonl (cinfo->fwd_ack);
2159 // 
2160 //   GNUNET_PEER_resolve (cinfo->id, &id);
2161 //   send_prebuilt_message (&msg.header, &id, cinfo->t);
2162 //   cinfo->fc_poll_time = GNUNET_TIME_relative_min (
2163 //     MESH_MAX_POLL_TIME,
2164 //     GNUNET_TIME_relative_multiply (cinfo->fc_poll_time, 2));
2165 //   cinfo->fc_poll = GNUNET_SCHEDULER_add_delayed (cinfo->fc_poll_time,
2166 //                                                  &tunnel_poll, cinfo);
2167 }
2168
2169
2170 /**
2171  * Build a PeerPath from the paths returned from the DHT, reversing the paths
2172  * to obtain a local peer -> destination path and interning the peer ids.
2173  *
2174  * @return Newly allocated and created path
2175  */
2176 static struct MeshPeerPath *
2177 path_build_from_dht (const struct GNUNET_PeerIdentity *get_path,
2178                      unsigned int get_path_length,
2179                      const struct GNUNET_PeerIdentity *put_path,
2180                      unsigned int put_path_length)
2181 {
2182   struct MeshPeerPath *p;
2183   GNUNET_PEER_Id id;
2184   int i;
2185
2186   p = path_new (1);
2187   p->peers[0] = myid;
2188   GNUNET_PEER_change_rc (myid, 1);
2189   i = get_path_length;
2190   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   GET has %d hops.\n", i);
2191   for (i--; i >= 0; i--)
2192   {
2193     id = GNUNET_PEER_intern (&get_path[i]);
2194     if (p->length > 0 && id == p->peers[p->length - 1])
2195     {
2196       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   Optimizing 1 hop out.\n");
2197       GNUNET_PEER_change_rc (id, -1);
2198     }
2199     else
2200     {
2201       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   Adding from GET: %s.\n",
2202                   GNUNET_i2s (&get_path[i]));
2203       p->length++;
2204       p->peers = GNUNET_realloc (p->peers, sizeof (GNUNET_PEER_Id) * p->length);
2205       p->peers[p->length - 1] = id;
2206     }
2207   }
2208   i = put_path_length;
2209   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   PUT has %d hops.\n", i);
2210   for (i--; i >= 0; i--)
2211   {
2212     id = GNUNET_PEER_intern (&put_path[i]);
2213     if (id == myid)
2214     {
2215       /* PUT path went through us, so discard the path up until now and start
2216        * from here to get a much shorter (and loop-free) path.
2217        */
2218       path_destroy (p);
2219       p = path_new (0);
2220     }
2221     if (p->length > 0 && id == p->peers[p->length - 1])
2222     {
2223       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   Optimizing 1 hop out.\n");
2224       GNUNET_PEER_change_rc (id, -1);
2225     }
2226     else
2227     {
2228       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   Adding from PUT: %s.\n",
2229                   GNUNET_i2s (&put_path[i]));
2230       p->length++;
2231       p->peers = GNUNET_realloc (p->peers, sizeof (GNUNET_PEER_Id) * p->length);
2232       p->peers[p->length - 1] = id;
2233     }
2234   }
2235 #if MESH_DEBUG
2236   if (get_path_length > 0)
2237     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   (first of GET: %s)\n",
2238                 GNUNET_i2s (&get_path[0]));
2239   if (put_path_length > 0)
2240     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   (first of PUT: %s)\n",
2241                 GNUNET_i2s (&put_path[0]));
2242   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   In total: %d hops\n",
2243               p->length);
2244   for (i = 0; i < p->length; i++)
2245   {
2246     struct GNUNET_PeerIdentity peer_id;
2247
2248     GNUNET_PEER_resolve (p->peers[i], &peer_id);
2249     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "       %u: %s\n", p->peers[i],
2250                 GNUNET_i2s (&peer_id));
2251   }
2252 #endif
2253   return p;
2254 }
2255
2256
2257 /**
2258  * Adds a path to the peer_infos of all the peers in the path
2259  *
2260  * @param p Path to process.
2261  * @param confirmed Whether we know if the path works or not.
2262  */
2263 static void
2264 path_add_to_peers (struct MeshPeerPath *p, int confirmed)
2265 {
2266   unsigned int i;
2267
2268   /* TODO: invert and add */
2269   for (i = 0; i < p->length && p->peers[i] != myid; i++) /* skip'em */ ;
2270   for (i++; i < p->length; i++)
2271   {
2272     struct MeshPeerInfo *aux;
2273     struct MeshPeerPath *copy;
2274
2275     aux = peer_info_get_short (p->peers[i]);
2276     copy = path_duplicate (p);
2277     copy->length = i + 1;
2278     peer_info_add_path (aux, copy, GNUNET_NO);
2279   }
2280 }
2281
2282
2283 /**
2284  * Send keepalive packets for a peer
2285  *
2286  * @param cls Closure (tunnel for which to send the keepalive).
2287  * @param tc Notification context.
2288  *
2289  * TODO: implement explicit multicast keepalive?
2290  */
2291 static void
2292 path_refresh (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
2293
2294
2295 /**
2296  * Search for a tunnel among the incoming tunnels
2297  *
2298  * @param tid the local id of the tunnel
2299  *
2300  * @return tunnel handler, NULL if doesn't exist
2301  */
2302 static struct MeshTunnel *
2303 tunnel_get_incoming (MESH_TunnelNumber tid)
2304 {
2305   struct GNUNET_HashCode hash;
2306
2307   GNUNET_assert (tid >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV);
2308   GNUNET_CRYPTO_hash (&tid, sizeof (MESH_TunnelNumber), &hash);
2309   return GNUNET_CONTAINER_multihashmap_get (incoming_tunnels, &hash);
2310 }
2311
2312
2313 /**
2314  * Search for a tunnel among the tunnels for a client
2315  *
2316  * @param c the client whose tunnels to search in
2317  * @param tid the local id of the tunnel
2318  *
2319  * @return tunnel handler, NULL if doesn't exist
2320  */
2321 static struct MeshTunnel *
2322 tunnel_get_by_local_id (struct MeshClient *c, MESH_TunnelNumber tid)
2323 {
2324   if (tid >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV)
2325   {
2326     return tunnel_get_incoming (tid);
2327   }
2328   else
2329   {
2330     struct GNUNET_HashCode hash;
2331
2332     GNUNET_CRYPTO_hash (&tid, sizeof (MESH_TunnelNumber), &hash);
2333     return GNUNET_CONTAINER_multihashmap_get (c->own_tunnels, &hash);
2334   }
2335 }
2336
2337
2338 /**
2339  * Search for a tunnel by global ID using PEER_ID
2340  *
2341  * @param pi owner of the tunnel
2342  * @param tid global tunnel number
2343  *
2344  * @return tunnel handler, NULL if doesn't exist
2345  */
2346 static struct MeshTunnel *
2347 tunnel_get_by_pi (GNUNET_PEER_Id pi, MESH_TunnelNumber tid)
2348 {
2349   struct MESH_TunnelID id;
2350   struct GNUNET_HashCode hash;
2351
2352   id.oid = pi;
2353   id.tid = tid;
2354
2355   GNUNET_CRYPTO_hash (&id, sizeof (struct MESH_TunnelID), &hash);
2356   return GNUNET_CONTAINER_multihashmap_get (tunnels, &hash);
2357 }
2358
2359
2360 /**
2361  * Search for a tunnel by global ID using full PeerIdentities
2362  *
2363  * @param oid owner of the tunnel
2364  * @param tid global tunnel number
2365  *
2366  * @return tunnel handler, NULL if doesn't exist
2367  */
2368 static struct MeshTunnel *
2369 tunnel_get (const struct GNUNET_PeerIdentity *oid, MESH_TunnelNumber tid)
2370 {
2371   return tunnel_get_by_pi (GNUNET_PEER_search (oid), tid);
2372 }
2373
2374
2375 /**
2376  * Delete an active client from the tunnel.
2377  * 
2378  * @param t Tunnel.
2379  * @param c Client.
2380  */
2381 static void
2382 tunnel_delete_active_client (struct MeshTunnel *t, const struct MeshClient *c)
2383 {
2384   unsigned int i;
2385
2386   for (i = 0; i < t->nclients; i++)
2387   {
2388     if (t->clients[i] == c)
2389     {
2390       t->clients[i] = t->clients[t->nclients - 1];
2391       t->clients_fc[i] = t->clients_fc[t->nclients - 1];
2392       GNUNET_array_grow (t->clients, t->nclients, t->nclients - 1);
2393       t->nclients++;
2394       GNUNET_array_grow (t->clients_fc, t->nclients, t->nclients - 1);
2395       break;
2396     }
2397   }
2398 }
2399
2400
2401 /**
2402  * Delete an ignored client from the tunnel.
2403  * 
2404  * @param t Tunnel.
2405  * @param c Client.
2406  */
2407 static void
2408 tunnel_delete_ignored_client (struct MeshTunnel *t, const struct MeshClient *c)
2409 {
2410   unsigned int i;
2411
2412   for (i = 0; i < t->nignore; i++)
2413   {
2414     if (t->ignore[i] == c)
2415     {
2416       t->ignore[i] = t->ignore[t->nignore - 1];
2417       GNUNET_array_grow (t->ignore, t->nignore, t->nignore - 1);
2418       break;
2419     }
2420   }
2421 }
2422
2423
2424 /**
2425  * Delete a client from the tunnel. It should be only done on
2426  * client disconnection, otherwise use client_ignore_tunnel.
2427  * 
2428  * @param t Tunnel.
2429  * @param c Client.
2430  */
2431 static void
2432 tunnel_delete_client (struct MeshTunnel *t, const struct MeshClient *c)
2433 {
2434   tunnel_delete_ignored_client (t, c);
2435   tunnel_delete_active_client (t, c);
2436 }
2437
2438
2439 /**
2440  * Add a peer to a tunnel, accomodating paths accordingly and initializing all
2441  * needed rescources.
2442  * If peer already exists, reevaluate shortest path and change if different.
2443  *
2444  * @param t Tunnel we want to add a new peer to
2445  * @param peer PeerInfo of the peer being added
2446  *
2447  */
2448 static void
2449 tunnel_add_peer (struct MeshTunnel *t, struct MeshPeerInfo *peer)
2450 {
2451   struct MeshPeerPath *best_p;
2452   struct MeshPeerPath *p;
2453   unsigned int best_cost;
2454   unsigned int cost;
2455
2456   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tunnel_add_peer\n");
2457   /* FIXME */
2458   if (t->peer != peer->id)
2459   {
2460     GNUNET_array_append (peer->tunnels, peer->ntunnels, t);
2461     t->peer = peer->id;
2462   }
2463
2464   if (NULL != (p = peer->path_head))
2465   {
2466     best_p = p;
2467     best_cost = tree_get_path_cost (t->tree, p);
2468     while (NULL != p)
2469     {
2470       if ((cost = tree_get_path_cost (t->tree, p)) < best_cost)
2471       {
2472         best_cost = cost;
2473         best_p = p;
2474       }
2475       p = p->next;
2476     }
2477     tree_add_path (t->tree, best_p, NULL, NULL); // FIXME
2478     if (GNUNET_SCHEDULER_NO_TASK == t->path_refresh_task)
2479       t->path_refresh_task =
2480           GNUNET_SCHEDULER_add_delayed (refresh_path_time, &path_refresh, t);
2481   }
2482   else
2483   {
2484     /* Start a DHT get */
2485     peer_info_connect (peer, t);
2486   }
2487   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tunnel_add_peer END\n");
2488 }
2489
2490 /**
2491  * Add a path to a tunnel which we don't own, just to remember the next hop.
2492  * If destination node was already in the tunnel, the first hop information
2493  * will be replaced with the new path.
2494  *
2495  * @param t Tunnel we want to add a new peer to
2496  * @param p Path to add
2497  * @param own_pos Position of local node in path.
2498  *
2499  */
2500 static void
2501 tunnel_add_path (struct MeshTunnel *t, struct MeshPeerPath *p,
2502                  unsigned int own_pos)
2503 {
2504   struct GNUNET_PeerIdentity id;
2505
2506   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tunnel_add_path\n");
2507   GNUNET_assert (0 != own_pos);
2508   tree_add_path (t->tree, p, NULL, NULL);
2509   if (own_pos < p->length - 1)
2510   {
2511     GNUNET_PEER_resolve (p->peers[own_pos + 1], &id);
2512     tree_update_first_hops (t->tree, myid, &id);
2513   }
2514   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tunnel_add_path END\n");
2515 }
2516
2517 /**
2518  * Add a client to a tunnel, initializing all needed data structures.
2519  * 
2520  * @param t Tunnel to which add the client.
2521  * @param c Client which to add to the tunnel.
2522  */
2523 static void
2524 tunnel_add_client (struct MeshTunnel *t, struct MeshClient *c)
2525 {
2526   struct MeshTunnelClientInfo clinfo;
2527
2528   GNUNET_array_append (t->clients, t->nclients, c);
2529   clinfo.fwd_ack = t->fwd_pid + 1;
2530   clinfo.bck_ack = t->nobuffer ? 1 : INITIAL_WINDOW_SIZE - 1;
2531   clinfo.fwd_pid = t->fwd_pid;
2532   clinfo.bck_pid = (uint32_t) -1; // Expected next: 0
2533   t->nclients--;
2534   GNUNET_array_append (t->clients_fc, t->nclients, clinfo);
2535 }
2536
2537
2538 /**
2539  * Notifies a tunnel that a connection has broken that affects at least
2540  * some of its peers. Sends a notification towards the root of the tree.
2541  * In case the peer is the owner of the tree, notifies the client that owns
2542  * the tunnel and tries to reconnect.
2543  *
2544  * @param t Tunnel affected.
2545  * @param p1 Peer that got disconnected from p2.
2546  * @param p2 Peer that got disconnected from p1.
2547  *
2548  * @return Short ID of the peer disconnected (either p1 or p2).
2549  *         0 if the tunnel remained unaffected.
2550  */
2551 static GNUNET_PEER_Id
2552 tunnel_notify_connection_broken (struct MeshTunnel *t, GNUNET_PEER_Id p1,
2553                                  GNUNET_PEER_Id p2)
2554 {
2555 //   if (myid != p1 && myid != p2) FIXME
2556 //   {
2557 //     return;
2558 //   }
2559 // 
2560 //   if (tree_get_predecessor (t->tree) != 0)
2561 //   {
2562 //     /* We are the peer still connected, notify owner of the disconnection. */
2563 //     struct GNUNET_MESH_PathBroken msg;
2564 //     struct GNUNET_PeerIdentity neighbor;
2565 // 
2566 //     msg.header.size = htons (sizeof (msg));
2567 //     msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_PATH_BROKEN);
2568 //     GNUNET_PEER_resolve (t->id.oid, &msg.oid);
2569 //     msg.tid = htonl (t->id.tid);
2570 //     msg.peer1 = my_full_id;
2571 //     GNUNET_PEER_resolve (pid, &msg.peer2);
2572 //     GNUNET_PEER_resolve (tree_get_predecessor (t->tree), &neighbor);
2573 //     send_prebuilt_message (&msg.header, &neighbor, t);
2574 //   }
2575   return 0;
2576 }
2577
2578
2579 /**
2580  * Get the Flow Control info of a client.
2581  * 
2582  * @param t Tunnel on which to look.
2583  * @param c Client whose ACK to get.
2584  * 
2585  * @return ACK value.
2586  */
2587 static struct MeshTunnelClientInfo *
2588 tunnel_get_client_fc (struct MeshTunnel *t,
2589                       struct MeshClient *c)
2590 {
2591   unsigned int i;
2592
2593   for (i = 0; i < t->nclients; i++)
2594   {
2595     if (t->clients[i] != c)
2596       continue;
2597     return &t->clients_fc[i];
2598   }
2599   GNUNET_assert (0);
2600   return NULL; // avoid compiler / coverity complaints
2601 }
2602
2603
2604 /**
2605  * Set the FWD ACK value of a client in a particular tunnel.
2606  * 
2607  * @param t Tunnel affected.
2608  * @param c Client whose ACK to set.
2609  * @param ack ACK value.
2610  */
2611 static void
2612 tunnel_set_client_fwd_ack (struct MeshTunnel *t,
2613                            struct MeshClient *c, 
2614                            uint32_t ack)
2615 {
2616   unsigned int i;
2617
2618   for (i = 0; i < t->nclients; i++)
2619   {
2620     if (t->clients[i] != c)
2621       continue;
2622     t->clients_fc[i].fwd_ack = ack;
2623     return;
2624   }
2625   GNUNET_break (0);
2626 }
2627
2628
2629 /**
2630  * Get the highest ACK value of all clients in a particular tunnel,
2631  * according to the buffering/speed settings.
2632  * 
2633  * @param t Tunnel on which to look.
2634  * 
2635  * @return Corresponding ACK value (max uint32_t).
2636  *         If no clients are suscribed, -1LL.
2637  */
2638 static int64_t
2639 tunnel_get_clients_fwd_ack (struct MeshTunnel *t)
2640 {
2641   unsigned int i;
2642   int64_t ack;
2643
2644   if (0 == t->nclients)
2645   {
2646     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2647                 "  tunnel has no clients, no FWD ACK\n");
2648     return -1LL;
2649   }
2650
2651   for (ack = -1LL, i = 0; i < t->nclients; i++)
2652   {
2653     if (-1LL == ack ||
2654         GNUNET_YES == GMC_is_pid_bigger (ack, t->clients_fc[i].fwd_ack))
2655     {
2656       ack = t->clients_fc[i].fwd_ack;
2657     }
2658   }
2659
2660   if (GNUNET_YES == t->nobuffer && GMC_is_pid_bigger(ack, t->fwd_pid))
2661     ack = (uint32_t) t->fwd_pid + 1; // Might overflow, it's ok.
2662
2663   return (uint32_t) ack;
2664 }
2665
2666
2667 /** FIXME
2668  * Get the current fwd ack value for a tunnel, taking in account the tunnel
2669  * mode and the status of all children nodes.
2670  *
2671  * @param t Tunnel.
2672  *
2673  * @return Maximum PID allowed.
2674  */
2675 static uint32_t
2676 tunnel_get_fwd_ack (struct MeshTunnel *t)
2677 {
2678   uint32_t ack;
2679   uint32_t count;
2680   uint32_t buffer_free;
2681   int64_t client_ack;
2682
2683   count = t->fwd_pid;
2684   buffer_free = t->fwd_queue_max - t->fwd_queue_n;
2685   client_ack = tunnel_get_clients_fwd_ack (t);
2686   if (GNUNET_YES == t->nobuffer)
2687   {
2688     ack = count;
2689   }
2690   else
2691   {
2692     ack = count + buffer_free; // Overflow? OK!
2693   }
2694   if (-1LL == client_ack)
2695   {
2696     client_ack = ack;
2697   }
2698   /* FIXME check */
2699   ack = GMC_max_pid ((uint32_t) client_ack, ack);
2700
2701   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2702               "c %u, bf %u, cl %lld, ACK: %u\n",
2703               count, buffer_free, client_ack, ack);
2704   return ack;
2705 }
2706
2707
2708 /**
2709  * Build a local ACK message and send it to a local client.
2710  * 
2711  * @param t Tunnel on which to send the ACK.
2712  * @param c Client to whom send the ACK.
2713  * @param ack Value of the ACK.
2714  */
2715 static void
2716 send_local_ack (struct MeshTunnel *t, struct MeshClient *c, uint32_t ack)
2717 {
2718   struct GNUNET_MESH_LocalAck msg;
2719
2720   msg.header.size = htons (sizeof (msg));
2721   msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK);
2722   msg.tunnel_id = htonl (t->owner == c ? t->local_tid : t->local_tid_dest);
2723   msg.max_pid = htonl (ack); 
2724   GNUNET_SERVER_notification_context_unicast(nc,
2725                                               c->handle,
2726                                               &msg.header,
2727                                               GNUNET_NO);
2728 }
2729
2730 /**
2731  * Build an ACK message and queue it to send to the given peer.
2732  * 
2733  * @param t Tunnel on which to send the ACK.
2734  * @param peer Peer to whom send the ACK.
2735  * @param ack Value of the ACK.
2736  */
2737 static void
2738 send_ack (struct MeshTunnel *t, struct GNUNET_PeerIdentity *peer,  uint32_t ack)
2739 {
2740   struct GNUNET_MESH_ACK msg;
2741
2742   GNUNET_PEER_resolve (t->id.oid, &msg.oid);
2743   msg.header.size = htons (sizeof (msg));
2744   msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_ACK);
2745   msg.pid = htonl (ack);
2746   msg.tid = htonl (t->id.tid);
2747
2748   send_prebuilt_message (&msg.header, peer, t);
2749 }
2750
2751
2752 /**
2753  * Notify a the owner of a tunnel about how many more
2754  * payload packages will we accept on a given tunnel.
2755  *
2756  * @param t Tunnel on which to send the ACK.
2757  */
2758 static void
2759 tunnel_send_client_fwd_ack (struct MeshTunnel *t)
2760 {
2761   uint32_t ack;
2762
2763   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2764               "Sending client FWD ACK on tunnel %X\n",
2765               t->local_tid);
2766
2767   ack = tunnel_get_fwd_ack (t);
2768
2769   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " ack %u\n", ack);
2770   if (t->last_fwd_ack == ack)
2771   {
2772     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " same as last, not sending!\n");
2773     return;
2774   }
2775
2776   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " sending!\n");
2777   t->last_fwd_ack = ack;
2778   send_local_ack (t, t->owner, ack);
2779 }
2780
2781
2782 /**
2783  * Send an ACK informing the predecessor about the available buffer space.
2784  * In case there is no predecessor, inform the owning client.
2785  * If buffering is off, send only on behalf of children or self if endpoint.
2786  * If buffering is on, send when sent to children and buffer space is free.
2787  * Note that although the name is fwd_ack, the FWD mean forward *traffic*,
2788  * the ACK itself goes "back" (towards root).
2789  * 
2790  * @param t Tunnel on which to send the ACK.
2791  * @param type Type of message that triggered the ACK transmission.
2792  */
2793 static void
2794 tunnel_send_fwd_ack (struct MeshTunnel *t, uint16_t type)
2795 {
2796   struct GNUNET_PeerIdentity id;
2797   uint32_t ack;
2798
2799   if (NULL != t->owner)
2800   {
2801     tunnel_send_client_fwd_ack (t);
2802     return;
2803   }
2804   /* Is it after unicast / multicast retransmission? */
2805   switch (type)
2806   {
2807     case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
2808     case GNUNET_MESSAGE_TYPE_MESH_MULTICAST:
2809       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2810                   "ACK due to FWD DATA retransmission\n");
2811       if (GNUNET_YES == t->nobuffer)
2812       {
2813         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Not sending ACK, nobuffer\n");
2814         return;
2815       }
2816       break;
2817     case GNUNET_MESSAGE_TYPE_MESH_ACK:
2818     case GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK:
2819       break;
2820     case GNUNET_MESSAGE_TYPE_MESH_POLL:
2821       t->force_ack = GNUNET_YES;
2822       break;
2823     default:
2824       GNUNET_break (0);
2825   }
2826
2827   /* Check if we need to transmit the ACK */
2828   if (t->fwd_queue_max > t->fwd_queue_n * 4 &&
2829       GMC_is_pid_bigger(t->last_fwd_ack, t->fwd_pid) &&
2830       GNUNET_NO == t->force_ack)
2831   {
2832     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Not sending ACK, buffer free\n");
2833     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2834                 "  t->qmax: %u, t->qn: %u\n",
2835                 t->fwd_queue_max, t->fwd_queue_n);
2836     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2837                 "  t->pid: %u, t->ack: %u\n",
2838                 t->fwd_pid, t->last_fwd_ack);
2839     return;
2840   }
2841
2842   /* Ok, ACK might be necessary, what PID to ACK? */
2843   ack = tunnel_get_fwd_ack (t);
2844
2845   /* If speed_min and not all children have ack'd, dont send yet */
2846   if (ack == t->last_fwd_ack && GNUNET_NO == t->force_ack)
2847   {
2848     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Not sending FWD ACK, not ready\n");
2849     return;
2850   }
2851
2852   t->last_fwd_ack = ack;
2853   GNUNET_PEER_resolve (tree_get_predecessor (t->tree), &id);
2854   send_ack (t, &id, ack);
2855   debug_fwd_ack++;
2856   t->force_ack = GNUNET_NO;
2857 }
2858
2859
2860 /**
2861  * Iterator to send a child node a BCK ACK to allow him to send more
2862  * to_origin data.
2863  *
2864  * @param cls Closure (tunnel).
2865  * @param id Id of the child node.
2866  */
2867 static void
2868 tunnel_send_child_bck_ack (void *cls,
2869                            GNUNET_PEER_Id id)
2870 {
2871   struct MeshTunnel *t = cls;
2872   struct GNUNET_PeerIdentity peer;
2873   uint32_t ack = 0; // FIXME
2874
2875   GNUNET_PEER_resolve (id, &peer);
2876 //   ack = cinfo->bck_pid + t->bck_queue_max - t->bck_queue_n;
2877 // 
2878 //   if (cinfo->bck_ack == ack && GNUNET_NO == t->force_ack)
2879 //   {
2880 //     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2881 //                 "    Not sending ACK, not needed\n");
2882 //     return;
2883 //   }
2884 //   cinfo->bck_ack = ack;
2885 // 
2886 //   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2887 //               "    Sending BCK ACK %u (last sent: %u)\n",
2888 //               ack, cinfo->bck_ack);
2889   send_ack (t, &peer, ack);
2890 }
2891
2892
2893 /**
2894  * @brief Send BCK ACKs to clients to allow them more to_origin traffic
2895  * 
2896  * Iterates over all clients and sends BCK ACKs to the ones that need it.
2897  *
2898  * FIXME fc: what happens if we have 2 clients but q_size is 1?
2899  *           - implement a size 1 buffer in each client_fc AND children_fc
2900  *           to hold at least 1 message per "child".
2901  *             problem: violates no buffer policy
2902  *           - ack 0 and make "children" poll for transmission slots
2903  *             problem: big overhead, extra latency even in low traffic
2904  *                      settings
2905  * 
2906  * @param t Tunnel on which to send the BCK ACKs.
2907  */
2908 static void
2909 tunnel_send_clients_bck_ack (struct MeshTunnel *t)
2910 {
2911   unsigned int i;
2912   unsigned int tunnel_delta;
2913
2914   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  Sending BCK ACK to clients\n");
2915
2916   tunnel_delta = t->bck_queue_max - t->bck_queue_n;
2917   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   tunnel delta: %u\n", tunnel_delta);
2918
2919   /* Find client whom to allow to send to origin (with lowest buffer space) */
2920   for (i = 0; i < t->nclients; i++)
2921   {
2922     struct MeshTunnelClientInfo *clinfo;
2923     unsigned int delta;
2924
2925     clinfo = &t->clients_fc[i];
2926     delta = clinfo->bck_ack - clinfo->bck_pid;
2927     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "    client %u delta: %u\n",
2928          t->clients[i]->id, delta);
2929
2930     if ((GNUNET_NO == t->nobuffer && tunnel_delta > delta) ||
2931         (GNUNET_YES == t->nobuffer && 0 == delta))
2932     {
2933       uint32_t ack;
2934
2935       ack = clinfo->bck_pid;
2936       ack += t->nobuffer ? 1 : tunnel_delta;
2937       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2938                   "    sending ack to client %u: %u\n",
2939                   t->clients[i]->id, ack);
2940       send_local_ack (t, t->clients[i], ack);
2941       clinfo->bck_ack = ack;
2942     }
2943     else
2944     {
2945       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2946                   "    not sending ack to client %u (td %u, d %u)\n",
2947                   t->clients[i]->id, tunnel_delta, delta);
2948     }
2949   }
2950 }
2951
2952
2953 /**
2954  * Send an ACK informing the children nodes and destination clients about
2955  * the available buffer space.
2956  * If buffering is off, send only on behalf of root (can be self).
2957  * If buffering is on, send when sent to predecessor and buffer space is free.
2958  * Note that although the name is bck_ack, the BCK mean backwards *traffic*,
2959  * the ACK itself goes "forward" (towards children/clients).
2960  * 
2961  * @param t Tunnel on which to send the ACK.
2962  * @param type Type of message that triggered the ACK transmission.
2963  */
2964 static void
2965 tunnel_send_bck_ack (struct MeshTunnel *t, uint16_t type)
2966 {
2967   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2968               "Sending BCK ACK on tunnel %u [%u] due to %s\n",
2969               t->id.oid, t->id.tid, GNUNET_MESH_DEBUG_M2S(type));
2970   /* Is it after data to_origin retransmission? */
2971   switch (type)
2972   {
2973     case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN:
2974       if (GNUNET_YES == t->nobuffer)
2975       {
2976         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2977                     "    Not sending ACK, nobuffer\n");
2978         return;
2979       }
2980       break;
2981     case GNUNET_MESSAGE_TYPE_MESH_ACK:
2982     case GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK:
2983       break;
2984     case GNUNET_MESSAGE_TYPE_MESH_POLL:
2985       t->force_ack = GNUNET_YES;
2986       break;
2987     default:
2988       GNUNET_break (0);
2989   }
2990
2991   tunnel_send_clients_bck_ack (t);
2992   tree_iterate_children (t->tree, &tunnel_send_child_bck_ack, t);
2993   t->force_ack = GNUNET_NO;
2994 }
2995
2996
2997 /**
2998  * @brief Re-initiate traffic to this peer if necessary.
2999  *
3000  * Check if there is traffic queued towards this peer
3001  * and the core transmit handle is NULL (traffic was stalled).
3002  * If so, call core tmt rdy.
3003  *
3004  * @param cls Closure (unused)
3005  * @param peer_id Short ID of peer to which initiate traffic.
3006  */
3007 static void
3008 peer_unlock_queue(void *cls, GNUNET_PEER_Id peer_id)
3009 {
3010   struct MeshPeerInfo *peer;
3011   struct GNUNET_PeerIdentity id;
3012   struct MeshPeerQueue *q;
3013   size_t size;
3014
3015   peer = peer_info_get_short(peer_id);
3016   if (NULL != peer->core_transmit)
3017     return;
3018
3019   q = queue_get_next(peer);
3020   if (NULL == q)
3021   {
3022     /* Might br multicast traffic already sent to this particular peer but
3023      * not to other children in this tunnel.
3024      * This way t->queue_n would be > 0 but the queue of this particular peer
3025      * would be empty.
3026      */
3027     return;
3028   }
3029   size = q->size;
3030   GNUNET_PEER_resolve (peer->id, &id);
3031   peer->core_transmit =
3032         GNUNET_CORE_notify_transmit_ready(core_handle,
3033                                           0,
3034                                           0,
3035                                           GNUNET_TIME_UNIT_FOREVER_REL,
3036                                           &id,
3037                                           size,
3038                                           &queue_send,
3039                                           peer);
3040         return;
3041 }
3042
3043
3044 /**
3045  * @brief Allow transmission of FWD traffic on this tunnel
3046  *
3047  * Check if there is traffic queued towards any children
3048  * and the core transmit handle is NULL, and if so, call core tmt rdy.
3049  *
3050  * @param t Tunnel on which to unlock FWD traffic.
3051  */
3052 static void
3053 tunnel_unlock_fwd_queues (struct MeshTunnel *t)
3054 {
3055   if (0 == t->fwd_queue_n)
3056     return;
3057
3058   tree_iterate_children (t->tree, &peer_unlock_queue, NULL);
3059 }
3060
3061
3062 /**
3063  * @brief Allow transmission of BCK traffic on this tunnel
3064  *
3065  * Check if there is traffic queued towards the root of the tree
3066  * and the core transmit handle is NULL, and if so, call core tmt rdy.
3067  *
3068  * @param t Tunnel on which to unlock BCK traffic.
3069  */
3070 static void
3071 tunnel_unlock_bck_queue (struct MeshTunnel *t)
3072 {
3073   if (0 == t->bck_queue_n)
3074     return;
3075
3076   peer_unlock_queue(NULL, tree_get_predecessor(t->tree));
3077 }
3078
3079
3080 /**
3081  * Send a message to all peers in this tunnel that the tunnel is no longer
3082  * valid.
3083  *
3084  * @param t The tunnel whose peers to notify.
3085  * @param parent ID of the parent, in case the tree is already destroyed.
3086  */
3087 static void
3088 tunnel_send_destroy (struct MeshTunnel *t, GNUNET_PEER_Id parent)
3089 {
3090   struct GNUNET_MESH_TunnelDestroy msg;
3091   struct GNUNET_PeerIdentity id;
3092
3093   msg.header.size = htons (sizeof (msg));
3094   msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_TUNNEL_DESTROY);
3095   GNUNET_PEER_resolve (t->id.oid, &msg.oid);
3096   msg.tid = htonl (t->id.tid);
3097   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3098               "  sending tunnel destroy for tunnel: %s [%X]\n",
3099               GNUNET_i2s (&msg.oid), t->id.tid);
3100
3101   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  sending multicast to child\n");
3102   /* FIXME tunnel_send_multicast (t, &msg.header); */
3103
3104   if (0 == parent)
3105     parent = tree_get_predecessor (t->tree);
3106   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  parent: %u\n", parent);
3107   if (0 == parent)
3108     return;
3109
3110   GNUNET_PEER_resolve (parent, &id);
3111   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3112               "  sending back to %s\n",
3113               GNUNET_i2s (&id));
3114   send_prebuilt_message (&msg.header, &id, t);
3115 }
3116
3117
3118 /**
3119  * Cancel all transmissions towards a neighbor that belong to a certain tunnel.
3120  *
3121  * @param cls Closure (Tunnel which to cancel).
3122  * @param neighbor_id Short ID of the neighbor to whom cancel the transmissions.
3123  */
3124 static void
3125 tunnel_cancel_queues (void *cls, GNUNET_PEER_Id neighbor_id)
3126 {
3127   struct MeshTunnel *t = cls;
3128   struct MeshPeerInfo *peer_info;
3129   struct MeshPeerQueue *pq;
3130   struct MeshPeerQueue *next;
3131
3132   peer_info = peer_info_get_short (neighbor_id);
3133   for (pq = peer_info->queue_head; NULL != pq; pq = next)
3134   {
3135     next = pq->next;
3136     if (pq->tunnel == t)
3137     {
3138       if (GNUNET_MESSAGE_TYPE_MESH_MULTICAST == pq->type ||
3139           GNUNET_MESSAGE_TYPE_MESH_UNICAST == pq->type ||
3140           GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN == pq->type)
3141       {
3142         // Should have been removed on destroy children
3143         GNUNET_break (0);
3144       }
3145       queue_destroy (pq, GNUNET_YES);
3146     }
3147   }
3148   if (NULL == peer_info->queue_head && NULL != peer_info->core_transmit)
3149   {
3150     GNUNET_CORE_notify_transmit_ready_cancel(peer_info->core_transmit);
3151     peer_info->core_transmit = NULL;
3152   }
3153 }
3154
3155 /**
3156  * Destroy the tunnel and free any allocated resources linked to it.
3157  *
3158  * @param t the tunnel to destroy
3159  *
3160  * @return GNUNET_OK on success
3161  */
3162 static int
3163 tunnel_destroy (struct MeshTunnel *t)
3164 {
3165   struct MeshClient *c;
3166   struct GNUNET_HashCode hash;
3167   unsigned int i;
3168   int r;
3169
3170   if (NULL == t)
3171     return GNUNET_OK;
3172
3173   r = GNUNET_OK;
3174   c = t->owner;
3175 #if MESH_DEBUG
3176   {
3177     struct GNUNET_PeerIdentity id;
3178
3179     GNUNET_PEER_resolve (t->id.oid, &id);
3180     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "destroying tunnel %s [%x]\n",
3181                 GNUNET_i2s (&id), t->id.tid);
3182     if (NULL != c)
3183       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  by client %u\n", c->id);
3184   }
3185 #endif
3186
3187   GNUNET_CRYPTO_hash (&t->id, sizeof (struct MESH_TunnelID), &hash);
3188   if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_remove (tunnels, &hash, t))
3189   {
3190     GNUNET_break (0);
3191     r = GNUNET_SYSERR;
3192   }
3193
3194   if (NULL != c)
3195   {
3196     GNUNET_CRYPTO_hash (&t->local_tid, sizeof (MESH_TunnelNumber), &hash);
3197     if (GNUNET_YES !=
3198         GNUNET_CONTAINER_multihashmap_remove (c->own_tunnels, &hash, t))
3199     {
3200       GNUNET_break (0);
3201       r = GNUNET_SYSERR;
3202     }
3203   }
3204
3205   GNUNET_CRYPTO_hash (&t->local_tid_dest, sizeof (MESH_TunnelNumber), &hash);
3206   for (i = 0; i < t->nclients; i++)
3207   {
3208     c = t->clients[i];
3209     if (GNUNET_YES !=
3210           GNUNET_CONTAINER_multihashmap_remove (c->incoming_tunnels, &hash, t))
3211     {
3212       GNUNET_break (0);
3213       r = GNUNET_SYSERR;
3214     }
3215   }
3216   for (i = 0; i < t->nignore; i++)
3217   {
3218     c = t->ignore[i];
3219     if (GNUNET_YES !=
3220           GNUNET_CONTAINER_multihashmap_remove (c->ignore_tunnels, &hash, t))
3221     {
3222       GNUNET_break (0);
3223       r = GNUNET_SYSERR;
3224     }
3225   }
3226
3227   (void) GNUNET_CONTAINER_multihashmap_remove (incoming_tunnels, &hash, t);
3228   GNUNET_free_non_null (t->clients);
3229   GNUNET_free_non_null (t->ignore);
3230   GNUNET_free_non_null (t->clients_fc);
3231
3232   tree_iterate_children (t->tree, &tunnel_cancel_queues, t);
3233   tree_destroy (t->tree);
3234
3235   if (GNUNET_SCHEDULER_NO_TASK != t->timeout_task)
3236     GNUNET_SCHEDULER_cancel (t->timeout_task);
3237   if (GNUNET_SCHEDULER_NO_TASK != t->path_refresh_task)
3238     GNUNET_SCHEDULER_cancel (t->path_refresh_task);
3239
3240   n_tunnels--;
3241   GNUNET_STATISTICS_update (stats, "# tunnels", -1, GNUNET_NO);
3242   GNUNET_free (t);
3243   return r;
3244 }
3245
3246 #define TUNNEL_DESTROY_EMPTY_TIME GNUNET_TIME_UNIT_MILLISECONDS
3247
3248 /**
3249  * Tunnel is empty: destroy it.
3250  * 
3251  * @param cls Closure (Tunnel).
3252  * @param tc TaskContext. 
3253  */
3254 static void
3255 tunnel_destroy_empty_delayed (void *cls,
3256                               const struct GNUNET_SCHEDULER_TaskContext *tc)
3257 {
3258   struct MeshTunnel *t = cls;
3259
3260   t->delayed_destroy = GNUNET_SCHEDULER_NO_TASK;
3261   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
3262     return;
3263
3264   if (0 != t->nclients ||
3265       0 != tree_count_children (t->tree))
3266     return;
3267
3268   #if MESH_DEBUG
3269   {
3270     struct GNUNET_PeerIdentity id;
3271
3272     GNUNET_PEER_resolve (t->id.oid, &id);
3273     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3274                 "executing destruction of empty tunnel %s [%X]\n",
3275                 GNUNET_i2s (&id), t->id.tid);
3276   }
3277   #endif
3278
3279   tunnel_send_destroy (t, 0);
3280   if (0 == t->pending_messages)
3281     tunnel_destroy (t);
3282   else
3283     t->destroy = GNUNET_YES;
3284 }
3285
3286
3287 /**
3288  * Schedule tunnel destruction if is empty and no new traffic comes in a time.
3289  * 
3290  * @param t Tunnel to destroy if empty.
3291  */
3292 static void
3293 tunnel_destroy_empty (struct MeshTunnel *t)
3294 {
3295   if (GNUNET_SCHEDULER_NO_TASK != t->delayed_destroy || 
3296       0 != t->nclients ||
3297       0 != tree_count_children (t->tree))
3298   {
3299     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3300                 "%u %u %u\n",
3301                 t->delayed_destroy, t->nclients, tree_count_children(t->tree));
3302     return;
3303   }
3304
3305   #if MESH_DEBUG
3306   {
3307     struct GNUNET_PeerIdentity id;
3308
3309     GNUNET_PEER_resolve (t->id.oid, &id);
3310     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3311                 "scheduling destruction of empty tunnel %s [%X]\n",
3312                 GNUNET_i2s (&id), t->id.tid);
3313   }
3314   #endif
3315
3316   t->delayed_destroy =
3317       GNUNET_SCHEDULER_add_delayed (TUNNEL_DESTROY_EMPTY_TIME,
3318                                     &tunnel_destroy_empty_delayed,
3319                                     t);
3320 }
3321
3322
3323 /**
3324  * Create a new tunnel
3325  * 
3326  * @param owner Who is the owner of the tunnel (short ID).
3327  * @param tid Tunnel Number of the tunnel.
3328  * @param client Clients that owns the tunnel, NULL for foreign tunnels.
3329  * @param local Tunnel Number for the tunnel, for the client point of view.
3330  * 
3331  * @return A new initialized tunnel. NULL on error.
3332  */
3333 static struct MeshTunnel *
3334 tunnel_new (GNUNET_PEER_Id owner,
3335             MESH_TunnelNumber tid,
3336             struct MeshClient *client,
3337             MESH_TunnelNumber local)
3338 {
3339   struct MeshTunnel *t;
3340   struct GNUNET_HashCode hash;
3341
3342   if (n_tunnels >= max_tunnels && NULL == client)
3343     return NULL;
3344
3345   t = GNUNET_malloc (sizeof (struct MeshTunnel));
3346   t->id.oid = owner;
3347   t->id.tid = tid;
3348   t->fwd_queue_max = (max_msgs_queue / max_tunnels) + 1;
3349   t->bck_queue_max = t->fwd_queue_max;
3350   t->tree = tree_new (owner);
3351   t->owner = client;
3352   t->fwd_pid = (uint32_t) -1; // Next (expected) = 0
3353   t->bck_pid = (uint32_t) -1; // Next (expected) = 0
3354   t->bck_ack = INITIAL_WINDOW_SIZE - 1;
3355   t->last_fwd_ack = INITIAL_WINDOW_SIZE - 1;
3356   t->local_tid = local;
3357   n_tunnels++;
3358   GNUNET_STATISTICS_update (stats, "# tunnels", 1, GNUNET_NO);
3359
3360   GNUNET_CRYPTO_hash (&t->id, sizeof (struct MESH_TunnelID), &hash);
3361   if (GNUNET_OK !=
3362       GNUNET_CONTAINER_multihashmap_put (tunnels, &hash, t,
3363                                          GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
3364   {
3365     GNUNET_break (0);
3366     tunnel_destroy (t);
3367     if (NULL != client)
3368     {
3369       GNUNET_break (0);
3370       GNUNET_SERVER_receive_done (client->handle, GNUNET_SYSERR);
3371     }
3372     return NULL;
3373   }
3374
3375   if (NULL != client)
3376   {
3377     GNUNET_CRYPTO_hash (&t->local_tid, sizeof (MESH_TunnelNumber), &hash);
3378     if (GNUNET_OK !=
3379         GNUNET_CONTAINER_multihashmap_put (client->own_tunnels, &hash, t,
3380                                           GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
3381     {
3382       tunnel_destroy (t);
3383       GNUNET_break (0);
3384       GNUNET_SERVER_receive_done (client->handle, GNUNET_SYSERR);
3385       return NULL;
3386     }
3387   }
3388
3389   return t;
3390 }
3391
3392
3393
3394 /**
3395  * tunnel_destroy_iterator: iterator for deleting each tunnel that belongs to a
3396  * client when the client disconnects. If the client is not the owner, the
3397  * owner will get notified if no more clients are in the tunnel and the client
3398  * get removed from the tunnel's list.
3399  *
3400  * @param cls closure (client that is disconnecting)
3401  * @param key the hash of the local tunnel id (used to access the hashmap)
3402  * @param value the value stored at the key (tunnel to destroy)
3403  *
3404  * @return GNUNET_OK, keep iterating.
3405  */
3406 static int
3407 tunnel_destroy_iterator (void *cls,
3408                          const struct GNUNET_HashCode * key,
3409                          void *value)
3410 {
3411   struct MeshTunnel *t = value;
3412   struct MeshClient *c = cls;
3413
3414   send_client_tunnel_disconnect (t, c);
3415   if (c != t->owner)
3416   {
3417     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %u is destination.\n", c->id);
3418     tunnel_delete_client (t, c);
3419     client_delete_tunnel (c, t);
3420     tunnel_destroy_empty (t);
3421     return GNUNET_OK;
3422   }
3423   tunnel_send_destroy (t, 0);
3424   t->owner = NULL;
3425   t->destroy = GNUNET_YES;
3426
3427   return GNUNET_OK;
3428 }
3429
3430
3431 /**
3432  * Timeout function, destroys tunnel if called
3433  *
3434  * @param cls Closure (tunnel to destroy).
3435  * @param tc TaskContext
3436  */
3437 static void
3438 tunnel_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
3439 {
3440   struct MeshTunnel *t = cls;
3441   struct GNUNET_PeerIdentity id;
3442
3443   t->timeout_task = GNUNET_SCHEDULER_NO_TASK;
3444   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
3445     return;
3446   GNUNET_PEER_resolve(t->id.oid, &id);
3447   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
3448               "Tunnel %s [%X] timed out. Destroying.\n",
3449               GNUNET_i2s(&id), t->id.tid);
3450   send_clients_tunnel_destroy (t);
3451   tunnel_destroy (t);
3452 }
3453
3454 /**
3455  * Resets the tunnel timeout. Starts it if no timeout was running.
3456  *
3457  * @param t Tunnel whose timeout to reset.
3458  *
3459  * TODO use heap to improve efficiency of scheduler.
3460  */
3461 static void
3462 tunnel_reset_timeout (struct MeshTunnel *t)
3463 {
3464   if (GNUNET_SCHEDULER_NO_TASK != t->timeout_task)
3465     GNUNET_SCHEDULER_cancel (t->timeout_task);
3466   t->timeout_task =
3467       GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
3468                                     (refresh_path_time, 4), &tunnel_timeout, t);
3469 }
3470
3471
3472 /******************************************************************************/
3473 /****************      MESH NETWORK HANDLER HELPERS     ***********************/
3474 /******************************************************************************/
3475
3476 /**
3477  * Function to send a create path packet to a peer.
3478  *
3479  * @param cls closure
3480  * @param size number of bytes available in buf
3481  * @param buf where the callee should write the message
3482  * @return number of bytes written to buf
3483  */
3484 static size_t
3485 send_core_path_create (void *cls, size_t size, void *buf)
3486 {
3487   struct MeshPathInfo *info = cls;
3488   struct GNUNET_MESH_ManipulatePath *msg;
3489   struct GNUNET_PeerIdentity *peer_ptr;
3490   struct MeshTunnel *t = info->t;
3491   struct MeshPeerPath *p = info->path;
3492   size_t size_needed;
3493   uint32_t opt;
3494   int i;
3495
3496   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CREATE PATH sending...\n");
3497   size_needed =
3498       sizeof (struct GNUNET_MESH_ManipulatePath) +
3499       p->length * sizeof (struct GNUNET_PeerIdentity);
3500
3501   if (size < size_needed || NULL == buf)
3502   {
3503     GNUNET_break (0);
3504     return 0;
3505   }
3506   msg = (struct GNUNET_MESH_ManipulatePath *) buf;
3507   msg->header.size = htons (size_needed);
3508   msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE);
3509   msg->tid = ntohl (t->id.tid);
3510
3511   opt = 0;
3512   if (GNUNET_YES == t->nobuffer)
3513     opt |= MESH_TUNNEL_OPT_NOBUFFER;
3514   msg->opt = htonl(opt);
3515   msg->reserved = 0;
3516
3517   peer_ptr = (struct GNUNET_PeerIdentity *) &msg[1];
3518   for (i = 0; i < p->length; i++)
3519   {
3520     GNUNET_PEER_resolve (p->peers[i], peer_ptr++);
3521   }
3522
3523   path_destroy (p);
3524   GNUNET_free (info);
3525
3526   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3527               "CREATE PATH (%u bytes long) sent!\n", size_needed);
3528   return size_needed;
3529 }
3530
3531
3532 /**
3533  * Fill the core buffer 
3534  *
3535  * @param cls closure (data itself)
3536  * @param size number of bytes available in buf
3537  * @param buf where the callee should write the message
3538  *
3539  * @return number of bytes written to buf
3540  */
3541 static size_t
3542 send_core_data_multicast (void *cls, size_t size, void *buf)
3543 {
3544   struct MeshTransmissionDescriptor *info = cls;
3545   size_t total_size;
3546
3547   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Multicast callback.\n");
3548   GNUNET_assert (NULL != info);
3549   GNUNET_assert (NULL != info->peer);
3550   total_size = info->mesh_data->data_len;
3551   GNUNET_assert (total_size < GNUNET_SERVER_MAX_MESSAGE_SIZE);
3552
3553   if (total_size > size)
3554   {
3555     GNUNET_break (0);
3556     return 0;
3557   }
3558   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " copying data...\n");
3559   memcpy (buf, info->mesh_data->data, total_size);
3560 #if MESH_DEBUG
3561   {
3562     struct GNUNET_MessageHeader *mh;
3563
3564     mh = buf;
3565     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " type %s\n",
3566                 GNUNET_MESH_DEBUG_M2S (ntohs (mh->type)));
3567   }
3568 #endif
3569   data_descriptor_decrement_rc (info->mesh_data);
3570   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "freeing info...\n");
3571   GNUNET_free (info);
3572   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "return %u\n", total_size);
3573   return total_size;
3574 }
3575
3576
3577 /**
3578  * Creates a path ack message in buf and frees all unused resources.
3579  *
3580  * @param cls closure (MeshTransmissionDescriptor)
3581  * @param size number of bytes available in buf
3582  * @param buf where the callee should write the message
3583  * @return number of bytes written to buf
3584  */
3585 static size_t
3586 send_core_path_ack (void *cls, size_t size, void *buf)
3587 {
3588   struct MeshTransmissionDescriptor *info = cls;
3589   struct GNUNET_MESH_PathACK *msg = buf;
3590
3591   GNUNET_assert (NULL != info);
3592   if (sizeof (struct GNUNET_MESH_PathACK) > size)
3593   {
3594     GNUNET_break (0);
3595     return 0;
3596   }
3597   msg->header.size = htons (sizeof (struct GNUNET_MESH_PathACK));
3598   msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_PATH_ACK);
3599   GNUNET_PEER_resolve (info->origin->oid, &msg->oid);
3600   msg->tid = htonl (info->origin->tid);
3601   msg->peer_id = my_full_id;
3602
3603   GNUNET_free (info);
3604   /* TODO add signature */
3605
3606   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "PATH ACK sent!\n");
3607   return sizeof (struct GNUNET_MESH_PathACK);
3608 }
3609
3610
3611 /**
3612  * Free a transmission that was already queued with all resources
3613  * associated to the request.
3614  *
3615  * @param queue Queue handler to cancel.
3616  * @param clear_cls Is it necessary to free associated cls?
3617  */
3618 static void
3619 queue_destroy (struct MeshPeerQueue *queue, int clear_cls)
3620 {
3621   struct MeshTransmissionDescriptor *dd;
3622   struct MeshPathInfo *path_info;
3623 //   unsigned int max;
3624
3625   if (GNUNET_YES == clear_cls)
3626   {
3627     switch (queue->type)
3628     {
3629       case GNUNET_MESSAGE_TYPE_MESH_TUNNEL_DESTROY:
3630         GNUNET_log (GNUNET_ERROR_TYPE_INFO, "   cancelling TUNNEL_DESTROY\n");
3631         GNUNET_break (GNUNET_YES == queue->tunnel->destroy);
3632         /* fall through */
3633       case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
3634       case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN:
3635       case GNUNET_MESSAGE_TYPE_MESH_ACK:
3636       case GNUNET_MESSAGE_TYPE_MESH_POLL:
3637       case GNUNET_MESSAGE_TYPE_MESH_PATH_KEEPALIVE:
3638         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3639                     "   prebuilt message\n");
3640         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3641                     "   type %s\n",
3642                     GNUNET_MESH_DEBUG_M2S(queue->type));
3643         dd = queue->cls;
3644         data_descriptor_decrement_rc (dd->mesh_data);
3645         break;
3646       case GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE:
3647         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   type create path\n");
3648         path_info = queue->cls;
3649         path_destroy (path_info->path);
3650         break;
3651       default:
3652         GNUNET_break (0);
3653         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3654                     "   type %s unknown!\n",
3655                     GNUNET_MESH_DEBUG_M2S(queue->type));
3656     }
3657     GNUNET_free_non_null (queue->cls);
3658   }
3659   GNUNET_CONTAINER_DLL_remove (queue->peer->queue_head,
3660                                queue->peer->queue_tail,
3661                                queue);
3662
3663   /* Delete from child_fc in the appropiate tunnel */
3664 //   max = queue->tunnel->fwd_queue_max;
3665 //   GNUNET_PEER_resolve (queue->peer->id, &id);
3666 //   if (NULL != cinfo)
3667 //   { FIXME
3668 //     for (i = 0; i < cinfo->send_buffer_n; i++)
3669 //     {
3670 //       i2 = (cinfo->send_buffer_start + i) % max;
3671 //       if (cinfo->send_buffer[i2] == queue)
3672 //       {
3673 //         /* Found corresponding entry in the send_buffer. Move all others back. */
3674 //         unsigned int j;
3675 // 
3676 // 
3677 //         for (j = i, j2 = 0, j3 = 0; j < cinfo->send_buffer_n - 1; j++)
3678 //         {
3679 //           j2 = (cinfo->send_buffer_start + j) % max;
3680 //           j3 = (cinfo->send_buffer_start + j + 1) % max;
3681 //           cinfo->send_buffer[j2] = cinfo->send_buffer[j3];
3682 //         }
3683 // 
3684 //         cinfo->send_buffer[j3] = NULL;
3685 //         cinfo->send_buffer_n--;
3686 //       }
3687 //     }
3688 //   }
3689
3690   GNUNET_free (queue);
3691 }
3692
3693
3694 /**
3695  * @brief Get the next transmittable message from the queue.
3696  *
3697  * This will be the head, except in the case of being a data packet
3698  * not allowed by the destination peer.
3699  *
3700  * @param peer Destination peer.
3701  *
3702  * @return The next viable MeshPeerQueue element to send to that peer.
3703  *         NULL when there are no transmittable messages.
3704  */
3705 struct MeshPeerQueue *
3706 queue_get_next (const struct MeshPeerInfo *peer)
3707 {
3708   struct MeshPeerQueue *q;
3709  
3710   struct MeshTransmissionDescriptor *info;
3711 //   struct GNUNET_MESH_Unicast *ucast;
3712 //   struct GNUNET_MESH_ToOrigin *to_orig;
3713   struct GNUNET_PeerIdentity id;
3714 //   uint32_t pid;
3715 //   uint32_t ack; FIXME
3716
3717   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*********   selecting message\n");
3718   for (q = peer->queue_head; NULL != q; q = q->next)
3719   {
3720 //     t = q->tunnel;
3721     info = q->cls;
3722     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3723                 "*********     %s\n",
3724                 GNUNET_MESH_DEBUG_M2S(q->type));
3725     switch (q->type)
3726     {
3727       case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
3728 //         ucast = (struct GNUNET_MESH_Unicast *) info->mesh_data->data;
3729 //         pid = ntohl (ucast->pid);
3730         GNUNET_PEER_resolve (info->peer->id, &id);
3731 //         ack = cinfo->fwd_ack;
3732         break;
3733       case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN:
3734 //         to_orig = (struct GNUNET_MESH_ToOrigin *) info->mesh_data->data;
3735 //         pid = ntohl (to_orig->pid);
3736 //         ack = t->bck_ack;
3737         break;
3738       default:
3739         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3740                     "*********   OK!\n");
3741         return q;
3742     }
3743 //     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3744 //                 "*********     ACK: %u, PID: %u\n",
3745 //                 ack, pid);
3746 //     if (GNUNET_NO == GMC_is_pid_bigger(pid, ack))
3747 //     {
3748 //       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3749 //                   "*********   OK!\n");
3750 //       return q;
3751 //     }
3752 //     else
3753 //     {
3754 //       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3755 //                   "*********     NEXT!\n");
3756 //     }
3757   }
3758   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3759                 "*********   nothing found\n");
3760   return NULL;
3761 }
3762
3763
3764 /**
3765   * Core callback to write a queued packet to core buffer
3766   *
3767   * @param cls Closure (peer info).
3768   * @param size Number of bytes available in buf.
3769   * @param buf Where the to write the message.
3770   *
3771   * @return number of bytes written to buf
3772   */
3773 static size_t
3774 queue_send (void *cls, size_t size, void *buf)
3775 {
3776     struct MeshPeerInfo *peer = cls;
3777     struct GNUNET_MessageHeader *msg;
3778     struct MeshPeerQueue *queue;
3779     struct MeshTunnel *t;
3780     struct GNUNET_PeerIdentity dst_id;
3781     size_t data_size;
3782
3783     peer->core_transmit = NULL;
3784
3785     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "********* Queue send\n");
3786     queue = queue_get_next (peer);
3787
3788     /* Queue has no internal mesh traffic nor sendable payload */
3789     if (NULL == queue)
3790     {
3791       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*********   not ready, return\n");
3792       if (NULL == peer->queue_head)
3793         GNUNET_break (0); // Should've been canceled
3794       return 0;
3795     }
3796     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*********   not empty\n");
3797
3798     GNUNET_PEER_resolve (peer->id, &dst_id);
3799     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3800                 "*********   towards %s\n",
3801                 GNUNET_i2s(&dst_id));
3802     /* Check if buffer size is enough for the message */
3803     if (queue->size > size)
3804     {
3805         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3806                     "*********   not enough room, reissue\n");
3807         peer->core_transmit =
3808             GNUNET_CORE_notify_transmit_ready (core_handle,
3809                                                0,
3810                                                0,
3811                                                GNUNET_TIME_UNIT_FOREVER_REL,
3812                                                &dst_id,
3813                                                queue->size,
3814                                                &queue_send,
3815                                                peer);
3816         return 0;
3817     }
3818     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*********   size ok\n");
3819
3820     t = queue->tunnel;
3821     GNUNET_assert (0 < t->pending_messages);
3822     t->pending_messages--;
3823     if (GNUNET_MESSAGE_TYPE_MESH_UNICAST == queue->type)
3824     {
3825       t->fwd_queue_n--;
3826       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3827                   "*********   unicast: t->q (%u/%u)\n",
3828                   t->fwd_queue_n, t->fwd_queue_max);
3829     }
3830     else if (GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN == queue->type)
3831     {
3832       t->bck_queue_n--;
3833       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*********   to origin\n");
3834     }
3835
3836     /* Fill buf */
3837     switch (queue->type)
3838     {
3839       case 0:
3840       case GNUNET_MESSAGE_TYPE_MESH_ACK:
3841       case GNUNET_MESSAGE_TYPE_MESH_POLL:
3842       case GNUNET_MESSAGE_TYPE_MESH_PATH_BROKEN:
3843       case GNUNET_MESSAGE_TYPE_MESH_PATH_DESTROY:
3844       case GNUNET_MESSAGE_TYPE_MESH_TUNNEL_DESTROY:
3845         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3846                     "*********   raw: %s\n",
3847                     GNUNET_MESH_DEBUG_M2S (queue->type));
3848         /* Fall through */
3849       case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
3850       case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN:
3851         data_size = send_core_data_raw (queue->cls, size, buf);
3852         msg = (struct GNUNET_MessageHeader *) buf;
3853         switch (ntohs (msg->type)) // Type of preconstructed message
3854         {
3855           case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
3856             tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_UNICAST);
3857             break;
3858           case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN:
3859             tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN);
3860             break;
3861           default:
3862               break;
3863         }
3864         break;
3865       case GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE:
3866         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*********   path create\n");
3867         data_size = send_core_path_create (queue->cls, size, buf);
3868         break;
3869       case GNUNET_MESSAGE_TYPE_MESH_PATH_ACK:
3870         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*********   path ack\n");
3871         data_size = send_core_path_ack (queue->cls, size, buf);
3872         break;
3873       case GNUNET_MESSAGE_TYPE_MESH_PATH_KEEPALIVE:
3874         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*********   path keepalive\n");
3875         data_size = send_core_data_multicast (queue->cls, size, buf);
3876         break;
3877       default:
3878         GNUNET_break (0);
3879         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3880                     "*********   type unknown: %u\n",
3881                     queue->type);
3882         data_size = 0;
3883     }
3884     switch (queue->type)
3885     {
3886       case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
3887       case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN:
3888 //         if (cinfo->send_buffer[cinfo->send_buffer_start] != queue)
3889 //         { FIXME
3890 //           GNUNET_break (0);
3891 //           GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3892 //                       "at pos %u (%p) != %p\n",
3893 //                       cinfo->send_buffer_start,
3894 //                       cinfo->send_buffer[cinfo->send_buffer_start],
3895 //                       queue);
3896 //         }
3897 //         if (cinfo->send_buffer_n > 0)
3898 //         {
3899 //           cinfo->send_buffer[cinfo->send_buffer_start] = NULL;
3900 //           cinfo->send_buffer_n--;
3901 //           cinfo->send_buffer_start++;
3902 //           cinfo->send_buffer_start %= t->fwd_queue_max;
3903 //         }
3904 //         else
3905 //         {
3906 //           GNUNET_break (0);
3907 //         }
3908         break;
3909       default:
3910         break;
3911     }
3912
3913     /* Free queue, but cls was freed by send_core_* */
3914     queue_destroy (queue, GNUNET_NO);
3915
3916     if (GNUNET_YES == t->destroy && 0 == t->pending_messages)
3917     {
3918       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*********  destroying tunnel!\n");
3919       tunnel_destroy (t);
3920     }
3921
3922     /* If more data in queue, send next */
3923     queue = queue_get_next(peer);
3924     if (NULL != queue)
3925     {
3926         struct GNUNET_PeerIdentity id;
3927
3928         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*********   more data!\n");
3929         GNUNET_PEER_resolve (peer->id, &id);
3930         peer->core_transmit =
3931             GNUNET_CORE_notify_transmit_ready(core_handle,
3932                                               0,
3933                                               0,
3934                                               GNUNET_TIME_UNIT_FOREVER_REL,
3935                                               &id,
3936                                               queue->size,
3937                                               &queue_send,
3938                                               peer);
3939     }
3940     else
3941     {
3942       if (NULL != peer->queue_head)
3943       {
3944         GNUNET_log (GNUNET_ERROR_TYPE_INFO,
3945                     "*********   %s stalled\n",
3946                     GNUNET_i2s(&my_full_id));
3947 //         if (NULL == cinfo) FIXME
3948 //           cinfo = tunnel_get_neighbor_fc (t, &dst_id);
3949 //         // FIXME unify bck/fwd structures, bck does not have cinfo right now
3950 //         if (NULL != cinfo && GNUNET_SCHEDULER_NO_TASK == cinfo->fc_poll)
3951 //         {
3952 //           cinfo->fc_poll = GNUNET_SCHEDULER_add_delayed (cinfo->fc_poll_time,
3953 //                                                          &tunnel_poll, cinfo);
3954 //         }
3955       }
3956     }
3957     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*********   return %d\n", data_size);
3958     return data_size;
3959 }
3960
3961
3962 /**
3963  * @brief Queue and pass message to core when possible.
3964  * 
3965  * If type is payload (UNICAST, TO_ORIGIN, MULTICAST) checks for queue status
3966  * and accounts for it. In case the queue is full, the message is dropped and
3967  * a break issued.
3968  * 
3969  * Otherwise, message is treated as internal and allowed to go regardless of 
3970  * queue status.
3971  *
3972  * @param cls Closure (@c type dependant). It will be used by queue_send to
3973  *            build the message to be sent if not already prebuilt.
3974  * @param type Type of the message, 0 for a raw message.
3975  * @param size Size of the message.
3976  * @param dst Neighbor to send message to.
3977  * @param t Tunnel this message belongs to.
3978  */
3979 static void
3980 queue_add (void *cls, uint16_t type, size_t size,
3981            struct MeshPeerInfo *dst, struct MeshTunnel *t)
3982 {
3983   struct MeshPeerQueue *queue;
3984   struct GNUNET_PeerIdentity id;
3985   unsigned int *max;
3986   unsigned int *n;
3987
3988   n = NULL;
3989   if (GNUNET_MESSAGE_TYPE_MESH_UNICAST == type ||
3990       GNUNET_MESSAGE_TYPE_MESH_MULTICAST == type)
3991   {
3992     n = &t->fwd_queue_n;
3993     max = &t->fwd_queue_max;
3994   }
3995   else if (GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN == type)
3996   {
3997     n = &t->bck_queue_n;
3998     max = &t->bck_queue_max;
3999   }
4000   if (NULL != n)
4001   {
4002     if (*n >= *max)
4003     {
4004       GNUNET_break(0);
4005       GNUNET_STATISTICS_update(stats,
4006                                "# messages dropped (buffer full)",
4007                                1, GNUNET_NO);
4008       return; // Drop message
4009     }
4010     (*n)++;
4011   }
4012   queue = GNUNET_malloc (sizeof (struct MeshPeerQueue));
4013   queue->cls = cls;
4014   queue->type = type;
4015   queue->size = size;
4016   queue->peer = dst;
4017   queue->tunnel = t;
4018   GNUNET_CONTAINER_DLL_insert_tail (dst->queue_head, dst->queue_tail, queue);
4019   GNUNET_PEER_resolve (dst->id, &id);
4020   if (NULL == dst->core_transmit)
4021   {
4022       dst->core_transmit =
4023           GNUNET_CORE_notify_transmit_ready (core_handle,
4024                                              0,
4025                                              0,
4026                                              GNUNET_TIME_UNIT_FOREVER_REL,
4027                                              &id,
4028                                              size,
4029                                              &queue_send,
4030                                              dst);
4031   }
4032   t->pending_messages++;
4033   if (NULL == n) // Is this internal mesh traffic?
4034     return;
4035
4036   // It's payload, keep track of buffer per peer. FIXME
4037 //   i = (cinfo->send_buffer_start + cinfo->send_buffer_n) % t->fwd_queue_max;
4038 //   if (NULL != cinfo->send_buffer[i])
4039 //   {
4040 //     GNUNET_break (cinfo->send_buffer_n == t->fwd_queue_max); // aka i == start
4041 //     queue_destroy (cinfo->send_buffer[cinfo->send_buffer_start], GNUNET_YES);
4042 //     cinfo->send_buffer_start++;
4043 //     cinfo->send_buffer_start %= t->fwd_queue_max;
4044 //   }
4045 //   else
4046 //   {
4047 //     cinfo->send_buffer_n++;
4048 //   }
4049 //   cinfo->send_buffer[i] = queue;
4050 //   if (cinfo->send_buffer_n > t->fwd_queue_max)
4051 //   {
4052 //     GNUNET_break (0);
4053 //     cinfo->send_buffer_n = t->fwd_queue_max;
4054 //   }
4055 }
4056
4057
4058 /******************************************************************************/
4059 /********************      MESH NETWORK HANDLERS     **************************/
4060 /******************************************************************************/
4061
4062
4063 /**
4064  * Core handler for path creation
4065  *
4066  * @param cls closure
4067  * @param message message
4068  * @param peer peer identity this notification is about
4069  *
4070  * @return GNUNET_OK to keep the connection open,
4071  *         GNUNET_SYSERR to close it (signal serious error)
4072  */
4073 static int
4074 handle_mesh_path_create (void *cls, const struct GNUNET_PeerIdentity *peer,
4075                          const struct GNUNET_MessageHeader *message)
4076 {
4077   unsigned int own_pos;
4078   uint16_t size;
4079   uint16_t i;
4080   MESH_TunnelNumber tid;
4081   struct GNUNET_MESH_ManipulatePath *msg;
4082   struct GNUNET_PeerIdentity *pi;
4083   struct GNUNET_HashCode hash;
4084   struct MeshPeerPath *path;
4085   struct MeshPeerInfo *dest_peer_info;
4086   struct MeshPeerInfo *orig_peer_info;
4087   struct MeshTunnel *t;
4088
4089   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4090               "Received a path create msg [%s]\n",
4091               GNUNET_i2s (&my_full_id));
4092   size = ntohs (message->size);
4093   if (size < sizeof (struct GNUNET_MESH_ManipulatePath))
4094   {
4095     GNUNET_break_op (0);
4096     return GNUNET_OK;
4097   }
4098
4099   size -= sizeof (struct GNUNET_MESH_ManipulatePath);
4100   if (size % sizeof (struct GNUNET_PeerIdentity))
4101   {
4102     GNUNET_break_op (0);
4103     return GNUNET_OK;
4104   }
4105   size /= sizeof (struct GNUNET_PeerIdentity);
4106   if (size < 2)
4107   {
4108     GNUNET_break_op (0);
4109     return GNUNET_OK;
4110   }
4111   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "    path has %u hops.\n", size);
4112   msg = (struct GNUNET_MESH_ManipulatePath *) message;
4113
4114   tid = ntohl (msg->tid);
4115   pi = (struct GNUNET_PeerIdentity *) &msg[1];
4116   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4117               "    path is for tunnel %s [%X].\n", GNUNET_i2s (pi), tid);
4118   t = tunnel_get (pi, tid);
4119   if (NULL == t) // FIXME only for INCOMING tunnels?
4120   {
4121     uint32_t opt;
4122
4123     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  Creating tunnel\n");
4124     t = tunnel_new (GNUNET_PEER_intern (pi), tid, NULL, 0);
4125     if (NULL == t)
4126     {
4127       // FIXME notify failure
4128       return GNUNET_OK;
4129     }
4130     opt = ntohl (msg->opt);
4131     if (0 != (opt & MESH_TUNNEL_OPT_NOBUFFER))
4132     {
4133       t->nobuffer = GNUNET_YES;
4134       t->last_fwd_ack = t->fwd_pid + 1;
4135     }
4136     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  nobuffer:%d\n", t->nobuffer);
4137
4138     if (GNUNET_YES == t->nobuffer)
4139     {
4140       t->bck_queue_max = 1;
4141       t->fwd_queue_max = 1;
4142     }
4143
4144     // FIXME only assign a local tid if a local client is interested (on demand)
4145     while (NULL != tunnel_get_incoming (next_local_tid))
4146       next_local_tid = (next_local_tid + 1) | GNUNET_MESH_LOCAL_TUNNEL_ID_SERV;
4147     t->local_tid_dest = next_local_tid++;
4148     next_local_tid = next_local_tid | GNUNET_MESH_LOCAL_TUNNEL_ID_SERV;
4149     // FIXME end
4150
4151     tunnel_reset_timeout (t);
4152     GNUNET_CRYPTO_hash (&t->local_tid_dest, sizeof (MESH_TunnelNumber), &hash);
4153     if (GNUNET_OK !=
4154         GNUNET_CONTAINER_multihashmap_put (incoming_tunnels, &hash, t,
4155                                            GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
4156     {
4157       tunnel_destroy (t);
4158       GNUNET_break (0);
4159       return GNUNET_OK;
4160     }
4161   }
4162   dest_peer_info =
4163       GNUNET_CONTAINER_multihashmap_get (peers, &pi[size - 1].hashPubKey);
4164   if (NULL == dest_peer_info)
4165   {
4166     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4167                 "  Creating PeerInfo for destination.\n");
4168     dest_peer_info = GNUNET_malloc (sizeof (struct MeshPeerInfo));
4169     dest_peer_info->id = GNUNET_PEER_intern (&pi[size - 1]);
4170     GNUNET_CONTAINER_multihashmap_put (peers, &pi[size - 1].hashPubKey,
4171                                        dest_peer_info,
4172                                        GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
4173   }
4174   orig_peer_info = GNUNET_CONTAINER_multihashmap_get (peers, &pi->hashPubKey);
4175   if (NULL == orig_peer_info)
4176   {
4177     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4178                 "  Creating PeerInfo for origin.\n");
4179     orig_peer_info = GNUNET_malloc (sizeof (struct MeshPeerInfo));
4180     orig_peer_info->id = GNUNET_PEER_intern (pi);
4181     GNUNET_CONTAINER_multihashmap_put (peers, &pi->hashPubKey, orig_peer_info,
4182                                        GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
4183   }
4184   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  Creating path...\n");
4185   path = path_new (size);
4186   own_pos = 0;
4187   for (i = 0; i < size; i++)
4188   {
4189     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  ... adding %s\n",
4190                 GNUNET_i2s (&pi[i]));
4191     path->peers[i] = GNUNET_PEER_intern (&pi[i]);
4192     if (path->peers[i] == myid)
4193       own_pos = i;
4194   }
4195   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  Own position: %u\n", own_pos);
4196   if (own_pos == 0)
4197   {
4198     /* cannot be self, must be 'not found' */
4199     /* create path: self not found in path through self */
4200     GNUNET_break_op (0);
4201     path_destroy (path);
4202     tunnel_destroy (t);
4203     return GNUNET_OK;
4204   }
4205   path_add_to_peers (path, GNUNET_NO);
4206   tunnel_add_path (t, path, own_pos);
4207   if (own_pos == size - 1)
4208   {
4209     /* It is for us! Send ack. */
4210     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  It's for us!\n");
4211     peer_info_add_path_to_origin (orig_peer_info, path, GNUNET_NO);
4212     t->peer = myid;
4213     send_path_ack (t);
4214   }
4215   else
4216   {
4217     struct MeshPeerPath *path2;
4218
4219     /* It's for somebody else! Retransmit. */
4220     path2 = path_duplicate (path);
4221     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  Retransmitting.\n");
4222     peer_info_add_path (dest_peer_info, path2, GNUNET_NO);
4223     path2 = path_duplicate (path);
4224     peer_info_add_path_to_origin (orig_peer_info, path2, GNUNET_NO);
4225     send_create_path (dest_peer_info, path, t);
4226   }
4227   return GNUNET_OK;
4228 }
4229
4230
4231 /**
4232  * Core handler for path destruction
4233  *
4234  * @param cls closure
4235  * @param message message
4236  * @param peer peer identity this notification is about
4237  *
4238  * @return GNUNET_OK to keep the connection open,
4239  *         GNUNET_SYSERR to close it (signal serious error)
4240  */
4241 static int
4242 handle_mesh_path_destroy (void *cls, const struct GNUNET_PeerIdentity *peer,
4243                           const struct GNUNET_MessageHeader *message)
4244 {
4245   struct GNUNET_MESH_ManipulatePath *msg;
4246   struct GNUNET_PeerIdentity *pi;
4247   struct MeshPeerPath *path;
4248   struct MeshTunnel *t;
4249   unsigned int own_pos;
4250   unsigned int i;
4251   size_t size;
4252
4253   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4254               "Received a PATH DESTROY msg from %s\n", GNUNET_i2s (peer));
4255   size = ntohs (message->size);
4256   if (size < sizeof (struct GNUNET_MESH_ManipulatePath))
4257   {
4258     GNUNET_break_op (0);
4259     return GNUNET_OK;
4260   }
4261
4262   size -= sizeof (struct GNUNET_MESH_ManipulatePath);
4263   if (size % sizeof (struct GNUNET_PeerIdentity))
4264   {
4265     GNUNET_break_op (0);
4266     return GNUNET_OK;
4267   }
4268   size /= sizeof (struct GNUNET_PeerIdentity);
4269   if (size < 2)
4270   {
4271     GNUNET_break_op (0);
4272     return GNUNET_OK;
4273   }
4274   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "    path has %u hops.\n", size);
4275
4276   msg = (struct GNUNET_MESH_ManipulatePath *) message;
4277   pi = (struct GNUNET_PeerIdentity *) &msg[1];
4278   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4279               "    path is for tunnel %s [%X].\n", GNUNET_i2s (pi),
4280               msg->tid);
4281   t = tunnel_get (pi, ntohl (msg->tid));
4282   if (NULL == t)
4283   {
4284     /* TODO notify back: we don't know this tunnel */
4285     GNUNET_break_op (0);
4286     return GNUNET_OK;
4287   }
4288   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  Creating path...\n");
4289   path = path_new (size);
4290   own_pos = 0;
4291   for (i = 0; i < size; i++)
4292   {
4293     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  ... adding %s\n",
4294                 GNUNET_i2s (&pi[i]));
4295     path->peers[i] = GNUNET_PEER_intern (&pi[i]);
4296     if (path->peers[i] == myid)
4297       own_pos = i;
4298   }
4299   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  Own position: %u\n", own_pos);
4300   if (own_pos < path->length - 1)
4301     send_prebuilt_message (message, &pi[own_pos + 1], t);
4302   else
4303     send_client_tunnel_disconnect(t, NULL);
4304
4305 //   tunnel_delete_peer (t, path->peers[path->length - 1]); FIXME
4306   path_destroy (path);
4307   return GNUNET_OK;
4308 }
4309
4310
4311 /**
4312  * Core handler for notifications of broken paths
4313  *
4314  * @param cls closure
4315  * @param message message
4316  * @param peer peer identity this notification is about
4317  *
4318  * @return GNUNET_OK to keep the connection open,
4319  *         GNUNET_SYSERR to close it (signal serious error)
4320  */
4321 static int
4322 handle_mesh_path_broken (void *cls, const struct GNUNET_PeerIdentity *peer,
4323                          const struct GNUNET_MessageHeader *message)
4324 {
4325   struct GNUNET_MESH_PathBroken *msg;
4326   struct MeshTunnel *t;
4327
4328   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4329               "Received a PATH BROKEN msg from %s\n", GNUNET_i2s (peer));
4330   msg = (struct GNUNET_MESH_PathBroken *) message;
4331   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  regarding %s\n",
4332               GNUNET_i2s (&msg->peer1));
4333   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  regarding %s\n",
4334               GNUNET_i2s (&msg->peer2));
4335   t = tunnel_get (&msg->oid, ntohl (msg->tid));
4336   if (NULL == t)
4337   {
4338     GNUNET_break_op (0);
4339     return GNUNET_OK;
4340   }
4341   tunnel_notify_connection_broken (t, GNUNET_PEER_search (&msg->peer1),
4342                                    GNUNET_PEER_search (&msg->peer2));
4343   return GNUNET_OK;
4344
4345 }
4346
4347
4348 /**
4349  * Core handler for tunnel destruction
4350  *
4351  * @param cls closure
4352  * @param message message
4353  * @param peer peer identity this notification is about
4354  *
4355  * @return GNUNET_OK to keep the connection open,
4356  *         GNUNET_SYSERR to close it (signal serious error)
4357  */
4358 static int
4359 handle_mesh_tunnel_destroy (void *cls, const struct GNUNET_PeerIdentity *peer,
4360                             const struct GNUNET_MessageHeader *message)
4361 {
4362   struct GNUNET_MESH_TunnelDestroy *msg;
4363   struct MeshTunnel *t;
4364   GNUNET_PEER_Id parent;
4365   GNUNET_PEER_Id pid;
4366
4367   msg = (struct GNUNET_MESH_TunnelDestroy *) message;
4368   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4369               "Got a TUNNEL DESTROY packet from %s\n",
4370               GNUNET_i2s (peer));
4371   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4372               "  for tunnel %s [%u]\n",
4373               GNUNET_i2s (&msg->oid), ntohl (msg->tid));
4374   t = tunnel_get (&msg->oid, ntohl (msg->tid));
4375   /* Check signature */
4376   if (NULL == t)
4377   {
4378     /* Probably already got the message from another path,
4379      * destroyed the tunnel and retransmitted to children.
4380      * Safe to ignore.
4381      */
4382     GNUNET_STATISTICS_update (stats, "# control on unknown tunnel",
4383                               1, GNUNET_NO);
4384     return GNUNET_OK;
4385   }
4386   parent = tree_get_predecessor (t->tree);
4387   pid = GNUNET_PEER_search (peer);
4388   if (pid != parent)
4389   {
4390     unsigned int nc;
4391
4392 //     tree_del_peer (t->tree, pid, &tunnel_child_removed, t);
4393     nc = tree_count_children (t->tree);
4394     if (nc > 0 || NULL != t->owner || t->nclients > 0)
4395     {
4396       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4397                   "still in use: %u cl, %u ch\n",
4398                   t->nclients, nc);
4399       return GNUNET_OK;
4400     }
4401   }
4402   if (t->local_tid_dest >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV)
4403   {
4404     /* Tunnel was incoming, notify clients */
4405     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "INCOMING TUNNEL %X %X\n",
4406                 t->local_tid, t->local_tid_dest);
4407     send_clients_tunnel_destroy (t);
4408   }
4409   tunnel_send_destroy (t, parent);
4410   t->destroy = GNUNET_YES;
4411   // TODO: add timeout to destroy the tunnel anyway
4412   return GNUNET_OK;
4413 }
4414
4415
4416 /**
4417  * Core handler for mesh network traffic going from the origin to a peer
4418  *
4419  * @param cls closure
4420  * @param peer peer identity this notification is about
4421  * @param message message
4422  * @return GNUNET_OK to keep the connection open,
4423  *         GNUNET_SYSERR to close it (signal serious error)
4424  */
4425 static int
4426 handle_mesh_data_unicast (void *cls, const struct GNUNET_PeerIdentity *peer,
4427                           const struct GNUNET_MessageHeader *message)
4428 {
4429   struct GNUNET_MESH_Unicast *msg;
4430   struct GNUNET_PeerIdentity *neighbor;
4431   struct MeshTunnel *t;
4432   GNUNET_PEER_Id dest_id;
4433   uint32_t pid;
4434   uint32_t ttl;
4435   size_t size;
4436
4437   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "got a unicast packet from %s\n",
4438               GNUNET_i2s (peer));
4439   /* Check size */
4440   size = ntohs (message->size);
4441   if (size <
4442       sizeof (struct GNUNET_MESH_Unicast) +
4443       sizeof (struct GNUNET_MessageHeader))
4444   {
4445     GNUNET_break (0);
4446     return GNUNET_OK;
4447   }
4448   msg = (struct GNUNET_MESH_Unicast *) message;
4449   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " of type %s\n",
4450               GNUNET_MESH_DEBUG_M2S (ntohs (msg[1].header.type)));
4451   /* Check tunnel */
4452   t = tunnel_get (&msg->oid, ntohl (msg->tid));
4453   if (NULL == t)
4454   {
4455     /* TODO notify back: we don't know this tunnel */
4456     GNUNET_STATISTICS_update (stats, "# data on unknown tunnel", 1, GNUNET_NO);
4457     GNUNET_break_op (0);
4458     return GNUNET_OK;
4459   }
4460   pid = ntohl (msg->pid);
4461   if (t->fwd_pid == pid)
4462   {
4463     GNUNET_STATISTICS_update (stats, "# duplicate PID drops", 1, GNUNET_NO);
4464     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
4465                 " Already seen pid %u, DROPPING!\n", pid);
4466     return GNUNET_OK;
4467   }
4468   else
4469   {
4470     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4471                 " pid %u not seen yet, forwarding\n", pid);
4472   }
4473
4474   t->fwd_pid = pid;
4475
4476   if (GMC_is_pid_bigger (pid, t->last_fwd_ack))
4477   {
4478     GNUNET_STATISTICS_update (stats, "# unsolicited unicast", 1, GNUNET_NO);
4479     GNUNET_break_op (0);
4480     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4481                 "Received PID %u, ACK %u\n",
4482                 pid, t->last_fwd_ack);
4483     return GNUNET_OK;
4484   }
4485
4486   tunnel_reset_timeout (t);
4487   dest_id = t->peer;
4488   if (dest_id == myid)
4489   {
4490     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4491                 "  it's for us! sending to clients...\n");
4492     GNUNET_STATISTICS_update (stats, "# unicast received", 1, GNUNET_NO);
4493     send_subscribed_clients (message, &msg[1].header, t);
4494     tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_UNICAST);
4495     return GNUNET_OK;
4496   }
4497   ttl = ntohl (msg->ttl);
4498   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   ttl: %u\n", ttl);
4499   if (ttl == 0)
4500   {
4501     GNUNET_STATISTICS_update (stats, "# TTL drops", 1, GNUNET_NO);
4502     GNUNET_log (GNUNET_ERROR_TYPE_WARNING, " TTL is 0, DROPPING!\n");
4503     tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_ACK);
4504     return GNUNET_OK;
4505   }
4506   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4507               "  not for us, retransmitting...\n");
4508
4509   neighbor = tree_get_first_hop (t->tree, dest_id);
4510
4511 /*   cinfo->fwd_pid = pid; FIXME
4512
4513   if (GNUNET_YES == t->nobuffer &&
4514       GNUNET_YES == GMC_is_pid_bigger (pid, cinfo->fwd_ack))
4515   {
4516     GNUNET_STATISTICS_update (stats, "# unsolicited unicast", 1, GNUNET_NO);
4517     GNUNET_log (GNUNET_ERROR_TYPE_INFO, "  %u > %u\n", pid, cinfo->fwd_ack);
4518     GNUNET_break_op (0);
4519     return GNUNET_OK;
4520   }*/
4521   send_prebuilt_message (message, neighbor, t);
4522   GNUNET_STATISTICS_update (stats, "# unicast forwarded", 1, GNUNET_NO);
4523   return GNUNET_OK;
4524 }
4525
4526
4527 /**
4528  * Core handler for mesh network traffic toward the owner of a tunnel
4529  *
4530  * @param cls closure
4531  * @param message message
4532  * @param peer peer identity this notification is about
4533  *
4534  * @return GNUNET_OK to keep the connection open,
4535  *         GNUNET_SYSERR to close it (signal serious error)
4536  */
4537 static int
4538 handle_mesh_data_to_orig (void *cls, const struct GNUNET_PeerIdentity *peer,
4539                           const struct GNUNET_MessageHeader *message)
4540 {
4541   struct GNUNET_MESH_ToOrigin *msg;
4542   struct GNUNET_PeerIdentity id;
4543   struct MeshPeerInfo *peer_info;
4544   struct MeshTunnel *t;
4545   GNUNET_PEER_Id predecessor;
4546   size_t size;
4547   uint32_t pid;
4548
4549   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "got a ToOrigin packet from %s\n",
4550               GNUNET_i2s (peer));
4551   size = ntohs (message->size);
4552   if (size < sizeof (struct GNUNET_MESH_ToOrigin) +     /* Payload must be */
4553       sizeof (struct GNUNET_MessageHeader))     /* at least a header */
4554   {
4555     GNUNET_break_op (0);
4556     return GNUNET_OK;
4557   }
4558   msg = (struct GNUNET_MESH_ToOrigin *) message;
4559   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " of type %s\n",
4560               GNUNET_MESH_DEBUG_M2S (ntohs (msg[1].header.type)));
4561   t = tunnel_get (&msg->oid, ntohl (msg->tid));
4562   pid = ntohl (msg->pid);
4563
4564   if (NULL == t)
4565   {
4566     /* TODO notify that we dont know this tunnel (whom)? */
4567     GNUNET_STATISTICS_update (stats, "# data on unknown tunnel", 1, GNUNET_NO);
4568     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4569                 "Received to_origin with PID %u on unknown tunnel %s [%u]\n",
4570                 pid, GNUNET_i2s (&msg->oid), ntohl (msg->tid));
4571     return GNUNET_OK;
4572   }
4573
4574
4575 //   if (cinfo->bck_pid == pid) FIXME
4576 //   {
4577 //     /* already seen this packet, drop */
4578 //     GNUNET_STATISTICS_update (stats, "# duplicate PID drops BCK", 1, GNUNET_NO);
4579 //     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4580 //                 " Already seen pid %u, DROPPING!\n", pid);
4581 //     tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_ACK);
4582 //     return GNUNET_OK;
4583 //   }
4584
4585   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4586               " pid %u not seen yet, forwarding\n", pid);
4587 //   cinfo->bck_pid = pid; FIXME
4588
4589   if (NULL != t->owner)
4590   {
4591     char cbuf[size];
4592     struct GNUNET_MESH_ToOrigin *copy;
4593
4594     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4595                 "  it's for us! sending to clients...\n");
4596     /* TODO signature verification */
4597     memcpy (cbuf, message, size);
4598     copy = (struct GNUNET_MESH_ToOrigin *) cbuf;
4599     copy->tid = htonl (t->local_tid);
4600     t->bck_pid++;
4601     copy->pid = htonl (t->bck_pid);
4602     GNUNET_STATISTICS_update (stats, "# to origin received", 1, GNUNET_NO);
4603     GNUNET_SERVER_notification_context_unicast (nc, t->owner->handle,
4604                                                 &copy->header, GNUNET_NO);
4605     tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN);
4606     return GNUNET_OK;
4607   }
4608   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4609               "  not for us, retransmitting...\n");
4610
4611   peer_info = peer_info_get (&msg->oid);
4612   if (NULL == peer_info)
4613   {
4614     /* unknown origin of tunnel */
4615     GNUNET_break (0);
4616     return GNUNET_OK;
4617   }
4618   predecessor = tree_get_predecessor (t->tree);
4619   if (0 == predecessor)
4620   {
4621     if (GNUNET_YES == t->destroy)
4622     {
4623       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4624                   "to orig received on a dying tunnel %s [%X]\n",
4625                   GNUNET_i2s (&msg->oid), ntohl(msg->tid));
4626       return GNUNET_OK;
4627     }
4628     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 
4629                 "unknown to origin at %s\n",
4630                 GNUNET_i2s (&my_full_id));
4631     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 
4632                 "from peer %s\n",
4633                 GNUNET_i2s (peer));
4634     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 
4635                 "for tunnel %s [%X]\n",
4636                 GNUNET_i2s (&msg->oid), ntohl(msg->tid));
4637     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 
4638                 "current tree:\n");
4639     tree_debug (t->tree);
4640     return GNUNET_OK;
4641   }
4642   GNUNET_PEER_resolve (predecessor, &id);
4643   send_prebuilt_message (message, &id, t);
4644   GNUNET_STATISTICS_update (stats, "# to origin forwarded", 1, GNUNET_NO);
4645
4646   return GNUNET_OK;
4647 }
4648
4649
4650 /**
4651  * Core handler for mesh network traffic point-to-point acks.
4652  *
4653  * @param cls closure
4654  * @param message message
4655  * @param peer peer identity this notification is about
4656  *
4657  * @return GNUNET_OK to keep the connection open,
4658  *         GNUNET_SYSERR to close it (signal serious error)
4659  */
4660 static int
4661 handle_mesh_ack (void *cls, const struct GNUNET_PeerIdentity *peer,
4662                  const struct GNUNET_MessageHeader *message)
4663 {
4664   struct GNUNET_MESH_ACK *msg;
4665   struct MeshTunnel *t;
4666   uint32_t ack;
4667
4668   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got an ACK packet from %s!\n",
4669               GNUNET_i2s (peer));
4670   msg = (struct GNUNET_MESH_ACK *) message;
4671
4672   t = tunnel_get (&msg->oid, ntohl (msg->tid));
4673
4674   if (NULL == t)
4675   {
4676     /* TODO notify that we dont know this tunnel (whom)? */
4677     GNUNET_STATISTICS_update (stats, "# ack on unknown tunnel", 1, GNUNET_NO);
4678     return GNUNET_OK;
4679   }
4680   ack = ntohl (msg->pid);
4681   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  ACK %u\n", ack);
4682
4683   /* Is this a forward or backward ACK? */
4684   if (tree_get_predecessor(t->tree) != GNUNET_PEER_search(peer))
4685   {
4686
4687     debug_bck_ack++;
4688     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  FWD ACK\n");
4689 //     cinfo->fwd_ack = ack; FIXME
4690     tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_ACK);
4691     tunnel_unlock_fwd_queues (t);
4692 //     if (GNUNET_SCHEDULER_NO_TASK != cinfo->fc_poll) FIXME
4693 //     {
4694 //       GNUNET_SCHEDULER_cancel (cinfo->fc_poll);
4695 //       cinfo->fc_poll = GNUNET_SCHEDULER_NO_TASK;
4696 //       cinfo->fc_poll_time = GNUNET_TIME_UNIT_SECONDS;
4697 //     }
4698   }
4699   else
4700   {
4701     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  BCK ACK\n");
4702     t->bck_ack = ack;
4703     tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_ACK);
4704     tunnel_unlock_bck_queue (t);
4705   }
4706   return GNUNET_OK;
4707 }
4708
4709
4710 /**
4711  * Core handler for mesh network traffic point-to-point ack polls.
4712  *
4713  * @param cls closure
4714  * @param message message
4715  * @param peer peer identity this notification is about
4716  *
4717  * @return GNUNET_OK to keep the connection open,
4718  *         GNUNET_SYSERR to close it (signal serious error)
4719  */
4720 static int
4721 handle_mesh_poll (void *cls, const struct GNUNET_PeerIdentity *peer,
4722                   const struct GNUNET_MessageHeader *message)
4723 {
4724   struct GNUNET_MESH_Poll *msg;
4725   struct MeshTunnel *t;
4726
4727   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got an POLL packet from %s!\n",
4728               GNUNET_i2s (peer));
4729
4730   msg = (struct GNUNET_MESH_Poll *) message;
4731
4732   t = tunnel_get (&msg->oid, ntohl (msg->tid));
4733
4734   if (NULL == t)
4735   {
4736     /* TODO notify that we dont know this tunnel (whom)? */
4737     GNUNET_STATISTICS_update (stats, "# poll on unknown tunnel", 1, GNUNET_NO);
4738     GNUNET_break_op (0);
4739     return GNUNET_OK;
4740   }
4741
4742   /* Is this a forward or backward ACK? */
4743   if (tree_get_predecessor(t->tree) != GNUNET_PEER_search(peer))
4744   {
4745     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  from FWD\n");
4746     /* FIXME cinfo->bck_ack = cinfo->fwd_pid; // mark as ready to send */
4747     tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_POLL);
4748   }
4749   else
4750   {
4751     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  from BCK\n");
4752     tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_POLL);
4753   }
4754
4755   return GNUNET_OK;
4756 }
4757
4758 /**
4759  * Core handler for path ACKs
4760  *
4761  * @param cls closure
4762  * @param message message
4763  * @param peer peer identity this notification is about
4764  *
4765  * @return GNUNET_OK to keep the connection open,
4766  *         GNUNET_SYSERR to close it (signal serious error)
4767  */
4768 static int
4769 handle_mesh_path_ack (void *cls, const struct GNUNET_PeerIdentity *peer,
4770                       const struct GNUNET_MessageHeader *message)
4771 {
4772   struct GNUNET_MESH_PathACK *msg;
4773   struct GNUNET_PeerIdentity id;
4774   struct MeshPeerInfo *peer_info;
4775   struct MeshPeerPath *p;
4776   struct MeshTunnel *t;
4777
4778   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received a path ACK msg [%s]\n",
4779               GNUNET_i2s (&my_full_id));
4780   msg = (struct GNUNET_MESH_PathACK *) message;
4781   t = tunnel_get (&msg->oid, ntohl(msg->tid));
4782   if (NULL == t)
4783   {
4784     /* TODO notify that we don't know the tunnel */
4785     GNUNET_STATISTICS_update (stats, "# control on unknown tunnel", 1, GNUNET_NO);
4786     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  don't know the tunnel %s [%X]!\n",
4787                 GNUNET_i2s (&msg->oid), ntohl(msg->tid));
4788     return GNUNET_OK;
4789   }
4790   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  on tunnel %s [%X]\n",
4791               GNUNET_i2s (&msg->oid), ntohl(msg->tid));
4792
4793   peer_info = peer_info_get (&msg->peer_id);
4794   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  by peer %s\n",
4795               GNUNET_i2s (&msg->peer_id));
4796   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  via peer %s\n",
4797               GNUNET_i2s (peer));
4798
4799   /* Add paths to peers? */
4800   p = tree_get_path_to_peer (t->tree, peer_info->id);
4801   if (NULL != p)
4802   {
4803     path_add_to_peers (p, GNUNET_YES);
4804     path_destroy (p);
4805   }
4806   else
4807   {
4808     GNUNET_break (0);
4809   }
4810
4811   /* Message for us? */
4812   if (0 == memcmp (&msg->oid, &my_full_id, sizeof (struct GNUNET_PeerIdentity)))
4813   {
4814     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  It's for us!\n");
4815     if (NULL == t->owner)
4816     {
4817       GNUNET_break_op (0);
4818       return GNUNET_OK;
4819     }
4820     if (tree_get_status (t->tree, peer_info->id) != MESH_PEER_READY)
4821     {
4822       tree_set_status (t->tree, peer_info->id, MESH_PEER_READY);
4823 //       send_client_peer_connected (t, peer_info->id);
4824     }
4825     if (NULL != peer_info->dhtget)
4826     {
4827       GNUNET_DHT_get_stop (peer_info->dhtget);
4828       peer_info->dhtget = NULL;
4829     }
4830     return GNUNET_OK;
4831   }
4832
4833   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4834               "  not for us, retransmitting...\n");
4835   GNUNET_PEER_resolve (tree_get_predecessor (t->tree), &id);
4836   peer_info = peer_info_get (&msg->oid);
4837   send_prebuilt_message (message, &id, t);
4838   return GNUNET_OK;
4839 }
4840
4841
4842 /**
4843  * Core handler for mesh keepalives.
4844  *
4845  * @param cls closure
4846  * @param message message
4847  * @param peer peer identity this notification is about
4848  * @return GNUNET_OK to keep the connection open,
4849  *         GNUNET_SYSERR to close it (signal serious error)
4850  *
4851  * TODO: Check who we got this from, to validate route.
4852  */
4853 static int
4854 handle_mesh_keepalive (void *cls, const struct GNUNET_PeerIdentity *peer,
4855                        const struct GNUNET_MessageHeader *message)
4856 {
4857   struct GNUNET_MESH_TunnelKeepAlive *msg;
4858   struct MeshTunnel *t;
4859
4860   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "got a keepalive packet from %s\n",
4861               GNUNET_i2s (peer));
4862
4863   msg = (struct GNUNET_MESH_TunnelKeepAlive *) message;
4864   t = tunnel_get (&msg->oid, ntohl (msg->tid));
4865
4866   if (NULL == t)
4867   {
4868     /* TODO notify that we dont know that tunnel */
4869     GNUNET_STATISTICS_update (stats, "# keepalive on unknown tunnel", 1,
4870                               GNUNET_NO);
4871     return GNUNET_OK;
4872   }
4873
4874   tunnel_reset_timeout (t);
4875
4876   GNUNET_STATISTICS_update (stats, "# keepalives forwarded", 1, GNUNET_NO);
4877   /* FIXME tunnel_send_multicast (t, message); */
4878   return GNUNET_OK;
4879   }
4880
4881
4882
4883 /**
4884  * Functions to handle messages from core
4885  */
4886 static struct GNUNET_CORE_MessageHandler core_handlers[] = {
4887   {&handle_mesh_path_create, GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE, 0},
4888   {&handle_mesh_path_destroy, GNUNET_MESSAGE_TYPE_MESH_PATH_DESTROY, 0},
4889   {&handle_mesh_path_broken, GNUNET_MESSAGE_TYPE_MESH_PATH_BROKEN,
4890    sizeof (struct GNUNET_MESH_PathBroken)},
4891   {&handle_mesh_tunnel_destroy, GNUNET_MESSAGE_TYPE_MESH_TUNNEL_DESTROY,
4892    sizeof (struct GNUNET_MESH_TunnelDestroy)},
4893   {&handle_mesh_data_unicast, GNUNET_MESSAGE_TYPE_MESH_UNICAST, 0},
4894   {&handle_mesh_keepalive, GNUNET_MESSAGE_TYPE_MESH_PATH_KEEPALIVE,
4895     sizeof (struct GNUNET_MESH_TunnelKeepAlive)},
4896   {&handle_mesh_data_to_orig, GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN, 0},
4897   {&handle_mesh_ack, GNUNET_MESSAGE_TYPE_MESH_ACK,
4898     sizeof (struct GNUNET_MESH_ACK)},
4899   {&handle_mesh_poll, GNUNET_MESSAGE_TYPE_MESH_POLL,
4900     sizeof (struct GNUNET_MESH_Poll)},
4901   {&handle_mesh_path_ack, GNUNET_MESSAGE_TYPE_MESH_PATH_ACK,
4902    sizeof (struct GNUNET_MESH_PathACK)},
4903   {NULL, 0, 0}
4904 };
4905
4906
4907
4908 /******************************************************************************/
4909 /****************       MESH LOCAL HANDLER HELPERS      ***********************/
4910 /******************************************************************************/
4911
4912
4913 #if LATER
4914 /**
4915  * notify_client_connection_failure: notify a client that the connection to the
4916  * requested remote peer is not possible (for instance, no route found)
4917  * Function called when the socket is ready to queue more data. "buf" will be
4918  * NULL and "size" zero if the socket was closed for writing in the meantime.
4919  *
4920  * @param cls closure
4921  * @param size number of bytes available in buf
4922  * @param buf where the callee should write the message
4923  * @return number of bytes written to buf
4924  */
4925 static size_t
4926 notify_client_connection_failure (void *cls, size_t size, void *buf)
4927 {
4928   int size_needed;
4929   struct MeshPeerInfo *peer_info;
4930   struct GNUNET_MESH_PeerControl *msg;
4931   struct GNUNET_PeerIdentity id;
4932
4933   if (0 == size && NULL == buf)
4934   {
4935     // TODO retry? cancel?
4936     return 0;
4937   }
4938
4939   size_needed = sizeof (struct GNUNET_MESH_PeerControl);
4940   peer_info = (struct MeshPeerInfo *) cls;
4941   msg = (struct GNUNET_MESH_PeerControl *) buf;
4942   msg->header.size = htons (sizeof (struct GNUNET_MESH_PeerControl));
4943   msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_DISCONNECTED);
4944 //     msg->tunnel_id = htonl(peer_info->t->tid);
4945   GNUNET_PEER_resolve (peer_info->id, &id);
4946   memcpy (&msg->peer, &id, sizeof (struct GNUNET_PeerIdentity));
4947
4948   return size_needed;
4949 }
4950 #endif
4951
4952
4953 /**
4954  * Send keepalive packets for a peer
4955  *
4956  * @param cls Closure (tunnel for which to send the keepalive).
4957  * @param tc Notification context.
4958  */
4959 static void
4960 path_refresh (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
4961 {
4962   struct MeshTunnel *t = cls;
4963   struct GNUNET_MESH_TunnelKeepAlive *msg;
4964   size_t size = sizeof (struct GNUNET_MESH_TunnelKeepAlive);
4965   char cbuf[size];
4966
4967   t->path_refresh_task = GNUNET_SCHEDULER_NO_TASK;
4968   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
4969   {
4970     return;
4971   }
4972
4973   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4974               "sending keepalive for tunnel %d\n", t->id.tid);
4975
4976   msg = (struct GNUNET_MESH_TunnelKeepAlive *) cbuf;
4977   msg->header.size = htons (size);
4978   msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_PATH_KEEPALIVE);
4979   msg->oid = my_full_id;
4980   msg->tid = htonl (t->id.tid);
4981   /* FIXME tunnel_send_multicast (t, &msg->header); */
4982
4983   t->path_refresh_task =
4984       GNUNET_SCHEDULER_add_delayed (refresh_path_time, &path_refresh, t);
4985   tunnel_reset_timeout(t);
4986 }
4987
4988
4989 /**
4990  * Function to process paths received for a new peer addition. The recorded
4991  * paths form the initial tunnel, which can be optimized later.
4992  * Called on each result obtained for the DHT search.
4993  *
4994  * @param cls closure
4995  * @param exp when will this value expire
4996  * @param key key of the result
4997  * @param get_path path of the get request
4998  * @param get_path_length lenght of get_path
4999  * @param put_path path of the put request
5000  * @param put_path_length length of the put_path
5001  * @param type type of the result
5002  * @param size number of bytes in data
5003  * @param data pointer to the result data
5004  *
5005  * TODO: re-issue the request after certain time? cancel after X results?
5006  */
5007 static void
5008 dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp,
5009                     const struct GNUNET_HashCode * key,
5010                     const struct GNUNET_PeerIdentity *get_path,
5011                     unsigned int get_path_length,
5012                     const struct GNUNET_PeerIdentity *put_path,
5013                     unsigned int put_path_length, enum GNUNET_BLOCK_Type type,
5014                     size_t size, const void *data)
5015 {
5016   struct MeshPathInfo *path_info = cls;
5017   struct MeshPeerPath *p;
5018   struct GNUNET_PeerIdentity pi;
5019   int i;
5020
5021   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got results from DHT!\n");
5022   GNUNET_PEER_resolve (path_info->peer->id, &pi);
5023   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  for %s\n", GNUNET_i2s (&pi));
5024
5025   p = path_build_from_dht (get_path, get_path_length,
5026                            put_path, put_path_length);
5027   path_add_to_peers (p, GNUNET_NO);
5028   path_destroy (p);
5029   for (i = 0; i < path_info->peer->ntunnels; i++)
5030   {
5031     tunnel_add_peer (path_info->peer->tunnels[i], path_info->peer);
5032     peer_info_connect (path_info->peer, path_info->t);
5033   }
5034
5035   return;
5036 }
5037
5038
5039 /******************************************************************************/
5040 /*********************       MESH LOCAL HANDLES      **************************/
5041 /******************************************************************************/
5042
5043
5044 /**
5045  * Handler for client disconnection
5046  *
5047  * @param cls closure
5048  * @param client identification of the client; NULL
5049  *        for the last call when the server is destroyed
5050  */
5051 static void
5052 handle_local_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
5053 {
5054   struct MeshClient *c;
5055   struct MeshClient *next;
5056   unsigned int i;
5057
5058   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "client disconnected\n");
5059   if (client == NULL)
5060   {
5061     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   (SERVER DOWN)\n");
5062     return;
5063   }
5064
5065   c = clients;
5066   while (NULL != c)
5067   {
5068     if (c->handle != client)
5069     {
5070       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   ... searching\n");
5071       c = c->next;
5072       continue;
5073     }
5074     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "matching client found (%u)\n",
5075                 c->id);
5076     GNUNET_SERVER_client_drop (c->handle);
5077     c->shutting_down = GNUNET_YES;
5078     GNUNET_assert (NULL != c->own_tunnels);
5079     GNUNET_assert (NULL != c->incoming_tunnels);
5080     GNUNET_CONTAINER_multihashmap_iterate (c->own_tunnels,
5081                                            &tunnel_destroy_iterator, c);
5082     GNUNET_CONTAINER_multihashmap_iterate (c->incoming_tunnels,
5083                                            &tunnel_destroy_iterator, c);
5084     GNUNET_CONTAINER_multihashmap_iterate (c->ignore_tunnels,
5085                                            &tunnel_destroy_iterator, c);
5086     GNUNET_CONTAINER_multihashmap_destroy (c->own_tunnels);
5087     GNUNET_CONTAINER_multihashmap_destroy (c->incoming_tunnels);
5088     GNUNET_CONTAINER_multihashmap_destroy (c->ignore_tunnels);
5089
5090     if (NULL != c->types)
5091       GNUNET_CONTAINER_multihashmap_destroy (c->types);
5092     for (i = 0; i < c->n_regex; i++)
5093     {
5094       GNUNET_free (c->regexes[i].regex);
5095       if (NULL != c->regexes[i].h)
5096         GNUNET_REGEX_announce_cancel (c->regexes[i].h);
5097     }
5098     GNUNET_free_non_null (c->regexes);
5099     if (GNUNET_SCHEDULER_NO_TASK != c->regex_announce_task)
5100       GNUNET_SCHEDULER_cancel (c->regex_announce_task);
5101     next = c->next;
5102     GNUNET_CONTAINER_DLL_remove (clients, clients_tail, c);
5103     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  CLIENT FREE at %p\n", c);
5104     GNUNET_free (c);
5105     GNUNET_STATISTICS_update (stats, "# clients", -1, GNUNET_NO);
5106     c = next;
5107   }
5108   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   done!\n");
5109   return;
5110 }
5111
5112
5113 /**
5114  * Handler for new clients
5115  *
5116  * @param cls closure
5117  * @param client identification of the client
5118  * @param message the actual message, which includes messages the client wants
5119  */
5120 static void
5121 handle_local_new_client (void *cls, struct GNUNET_SERVER_Client *client,
5122                          const struct GNUNET_MessageHeader *message)
5123 {
5124   struct GNUNET_MESH_ClientConnect *cc_msg;
5125   struct MeshClient *c;
5126   unsigned int size;
5127   uint16_t ntypes;
5128   uint16_t *t;
5129   uint16_t i;
5130
5131   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "new client connected\n");
5132   /* Check data sanity */
5133   size = ntohs (message->size) - sizeof (struct GNUNET_MESH_ClientConnect);
5134   cc_msg = (struct GNUNET_MESH_ClientConnect *) message;
5135   ntypes = ntohs (cc_msg->types);
5136   if (size != ntypes * sizeof (uint16_t))
5137   {
5138     GNUNET_break (0);
5139     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5140     return;
5141   }
5142
5143   /* Create new client structure */
5144   c = GNUNET_malloc (sizeof (struct MeshClient));
5145   c->id = next_client_id++;
5146   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  CLIENT NEW %u\n", c->id);
5147   c->handle = client;
5148   GNUNET_SERVER_client_keep (client);
5149   if (ntypes > 0)
5150   {
5151     uint16_t u16;
5152     struct GNUNET_HashCode hc;
5153
5154     t = (uint16_t *) &cc_msg[1];
5155     c->types = GNUNET_CONTAINER_multihashmap_create (ntypes, GNUNET_NO);
5156     for (i = 0; i < ntypes; i++)
5157     {
5158       u16 = ntohs (t[i]);
5159       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  msg type: %u\n", u16);
5160       GNUNET_CRYPTO_hash (&u16, sizeof (u16), &hc);
5161
5162       /* store in clients hashmap */
5163       GNUNET_CONTAINER_multihashmap_put (c->types, &hc, c,
5164                                          GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
5165       /* store in global hashmap */
5166       GNUNET_CONTAINER_multihashmap_put (types, &hc, c,
5167                                          GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
5168     }
5169   }
5170   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " client has %u types\n", ntypes);
5171
5172   GNUNET_CONTAINER_DLL_insert (clients, clients_tail, c);
5173   c->own_tunnels = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
5174   c->incoming_tunnels = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
5175   c->ignore_tunnels = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
5176   GNUNET_SERVER_notification_context_add (nc, client);
5177   GNUNET_STATISTICS_update (stats, "# clients", 1, GNUNET_NO);
5178
5179   GNUNET_SERVER_receive_done (client, GNUNET_OK);
5180   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "new client processed\n");
5181 }
5182
5183
5184 /**
5185  * Handler for requests of new tunnels
5186  *
5187  * @param cls closure
5188  * @param client identification of the client
5189  * @param message the actual message
5190  */
5191 static void
5192 handle_local_tunnel_create (void *cls, struct GNUNET_SERVER_Client *client,
5193                             const struct GNUNET_MessageHeader *message)
5194 {
5195   struct GNUNET_MESH_TunnelMessage *t_msg;
5196   struct MeshTunnel *t;
5197   struct MeshClient *c;
5198   MESH_TunnelNumber tid;
5199
5200   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "new tunnel requested\n");
5201
5202   /* Sanity check for client registration */
5203   if (NULL == (c = client_get (client)))
5204   {
5205     GNUNET_break (0);
5206     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5207     return;
5208   }
5209   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  by client %u\n", c->id);
5210
5211   /* Message sanity check */
5212   if (sizeof (struct GNUNET_MESH_TunnelMessage) != ntohs (message->size))
5213   {
5214     GNUNET_break (0);
5215     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5216     return;
5217   }
5218
5219   t_msg = (struct GNUNET_MESH_TunnelMessage *) message;
5220   /* Sanity check for tunnel numbering */
5221   tid = ntohl (t_msg->tunnel_id);
5222   if (0 == (tid & GNUNET_MESH_LOCAL_TUNNEL_ID_CLI))
5223   {
5224     GNUNET_break (0);
5225     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5226     return;
5227   }
5228   /* Sanity check for duplicate tunnel IDs */
5229   if (NULL != tunnel_get_by_local_id (c, tid))
5230   {
5231     GNUNET_break (0);
5232     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5233     return;
5234   }
5235
5236   while (NULL != tunnel_get_by_pi (myid, next_tid))
5237     next_tid = (next_tid + 1) & ~GNUNET_MESH_LOCAL_TUNNEL_ID_CLI;
5238   t = tunnel_new (myid, next_tid++, c, tid);
5239   if (NULL == t)
5240   {
5241     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Tunnel creation failed.\n");
5242     GNUNET_break (0);
5243     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5244     return;
5245   }
5246   next_tid = next_tid & ~GNUNET_MESH_LOCAL_TUNNEL_ID_CLI;
5247   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CREATED TUNNEL %s [%x] (%x)\n",
5248               GNUNET_i2s (&my_full_id), t->id.tid, t->local_tid);
5249
5250   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "new tunnel created\n");
5251   GNUNET_SERVER_receive_done (client, GNUNET_OK);
5252   return;
5253 }
5254
5255
5256 /**
5257  * Handler for requests of deleting tunnels
5258  *
5259  * @param cls closure
5260  * @param client identification of the client
5261  * @param message the actual message
5262  */
5263 static void
5264 handle_local_tunnel_destroy (void *cls, struct GNUNET_SERVER_Client *client,
5265                              const struct GNUNET_MessageHeader *message)
5266 {
5267   struct GNUNET_MESH_TunnelMessage *tunnel_msg;
5268   struct MeshClient *c;
5269   struct MeshTunnel *t;
5270   MESH_TunnelNumber tid;
5271
5272   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5273               "Got a DESTROY TUNNEL from client!\n");
5274
5275   /* Sanity check for client registration */
5276   if (NULL == (c = client_get (client)))
5277   {
5278     GNUNET_break (0);
5279     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5280     return;
5281   }
5282   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  by client %u\n", c->id);
5283
5284   /* Message sanity check */
5285   if (sizeof (struct GNUNET_MESH_TunnelMessage) != ntohs (message->size))
5286   {
5287     GNUNET_break (0);
5288     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5289     return;
5290   }
5291
5292   tunnel_msg = (struct GNUNET_MESH_TunnelMessage *) message;
5293
5294   /* Retrieve tunnel */
5295   tid = ntohl (tunnel_msg->tunnel_id);
5296   t = tunnel_get_by_local_id(c, tid);
5297   if (NULL == t)
5298   {
5299     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "  tunnel %X not found\n", tid);
5300     GNUNET_break (0);
5301     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5302     return;
5303   }
5304   if (c != t->owner || tid >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV)
5305   {
5306     client_ignore_tunnel (c, t);
5307     tunnel_destroy_empty (t);
5308     GNUNET_SERVER_receive_done (client, GNUNET_OK);
5309     return;
5310   }
5311   send_client_tunnel_disconnect (t, c);
5312   client_delete_tunnel (c, t);
5313
5314   /* Don't try to ACK the client about the tunnel_destroy multicast packet */
5315   t->owner = NULL;
5316   tunnel_send_destroy (t, 0);
5317   t->destroy = GNUNET_YES;
5318   /* The tunnel will be destroyed when the last message is transmitted. */
5319   GNUNET_SERVER_receive_done (client, GNUNET_OK);
5320   return;
5321 }
5322
5323
5324 /**
5325  * Handler for requests of seeting tunnel's buffering policy.
5326  *
5327  * @param cls Closure (unused).
5328  * @param client Identification of the client.
5329  * @param message The actual message.
5330  */
5331 static void
5332 handle_local_tunnel_buffer (void *cls, struct GNUNET_SERVER_Client *client,
5333                             const struct GNUNET_MessageHeader *message)
5334 {
5335   struct GNUNET_MESH_TunnelMessage *tunnel_msg;
5336   struct MeshClient *c;
5337   struct MeshTunnel *t;
5338   MESH_TunnelNumber tid;
5339
5340   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5341               "Got a BUFFER request from client!\n");
5342
5343   /* Sanity check for client registration */
5344   if (NULL == (c = client_get (client)))
5345   {
5346     GNUNET_break (0);
5347     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5348     return;
5349   }
5350   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  by client %u\n", c->id);
5351
5352   tunnel_msg = (struct GNUNET_MESH_TunnelMessage *) message;
5353
5354   /* Retrieve tunnel */
5355   tid = ntohl (tunnel_msg->tunnel_id);
5356   t = tunnel_get_by_local_id(c, tid);
5357   if (NULL == t)
5358   {
5359     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "  tunnel %X not found\n", tid);
5360     GNUNET_break (0);
5361     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5362     return;
5363   }
5364
5365   switch (ntohs(message->type))
5366   {
5367       case GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_BUFFER:
5368           t->nobuffer = GNUNET_NO;
5369           break;
5370       case GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_NOBUFFER:
5371           t->nobuffer = GNUNET_YES;
5372           break;
5373       default:
5374           GNUNET_break (0);
5375   }
5376
5377   GNUNET_SERVER_receive_done (client, GNUNET_OK);
5378 }
5379
5380
5381 /**
5382  * Handler for client traffic directed to one peer
5383  *
5384  * @param cls closure
5385  * @param client identification of the client
5386  * @param message the actual message
5387  */
5388 static void
5389 handle_local_unicast (void *cls, struct GNUNET_SERVER_Client *client,
5390                       const struct GNUNET_MessageHeader *message)
5391 {
5392   struct MeshClient *c;
5393   struct MeshTunnel *t;
5394   struct GNUNET_MESH_Unicast *data_msg;
5395   MESH_TunnelNumber tid;
5396   size_t size;
5397
5398   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5399               "Got a unicast request from a client!\n");
5400
5401   /* Sanity check for client registration */
5402   if (NULL == (c = client_get (client)))
5403   {
5404     GNUNET_break (0);
5405     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5406     return;
5407   }
5408   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  by client %u\n", c->id);
5409
5410   data_msg = (struct GNUNET_MESH_Unicast *) message;
5411
5412   /* Sanity check for message size */
5413   size = ntohs (message->size);
5414   if (sizeof (struct GNUNET_MESH_Unicast) +
5415       sizeof (struct GNUNET_MessageHeader) > size)
5416   {
5417     GNUNET_break (0);
5418     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5419     return;
5420   }
5421
5422   /* Tunnel exists? */
5423   tid = ntohl (data_msg->tid);
5424   t = tunnel_get_by_local_id (c, tid);
5425   if (NULL == t)
5426   {
5427     GNUNET_break (0);
5428     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5429     return;
5430   }
5431
5432   /*  Is it a local tunnel? Then, does client own the tunnel? */
5433   if (t->owner->handle != client)
5434   {
5435     GNUNET_break (0);
5436     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5437     return;
5438   }
5439
5440   /* PID should be as expected */
5441   if (ntohl (data_msg->pid) != t->fwd_pid + 1)
5442   {
5443     GNUNET_break (0);
5444     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
5445               "Unicast PID, expected %u, got %u\n",
5446               t->fwd_pid + 1, ntohl (data_msg->pid));
5447     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5448     return;
5449   }
5450
5451   /* Ok, everything is correct, send the message
5452    * (pretend we got it from a mesh peer)
5453    */
5454   {
5455     /* Work around const limitation */
5456     char buf[ntohs (message->size)] GNUNET_ALIGN;
5457     struct GNUNET_MESH_Unicast *copy;
5458
5459     copy = (struct GNUNET_MESH_Unicast *) buf;
5460     memcpy (buf, data_msg, size);
5461     copy->oid = my_full_id;
5462     copy->tid = htonl (t->id.tid);
5463     copy->ttl = htonl (default_ttl);
5464     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5465                 "  calling generic handler...\n");
5466     handle_mesh_data_unicast (NULL, &my_full_id, &copy->header);
5467   }
5468   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "receive done OK\n");
5469   GNUNET_SERVER_receive_done (client, GNUNET_OK);
5470
5471   return;
5472 }
5473
5474
5475 /**
5476  * Handler for client traffic directed to the origin
5477  *
5478  * @param cls closure
5479  * @param client identification of the client
5480  * @param message the actual message
5481  */
5482 static void
5483 handle_local_to_origin (void *cls, struct GNUNET_SERVER_Client *client,
5484                         const struct GNUNET_MessageHeader *message)
5485 {
5486   struct GNUNET_MESH_ToOrigin *data_msg;
5487   struct MeshTunnelClientInfo *clinfo;
5488   struct MeshClient *c;
5489   struct MeshTunnel *t;
5490   MESH_TunnelNumber tid;
5491   size_t size;
5492
5493   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5494               "Got a ToOrigin request from a client!\n");
5495   /* Sanity check for client registration */
5496   if (NULL == (c = client_get (client)))
5497   {
5498     GNUNET_break (0);
5499     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5500     return;
5501   }
5502   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  by client %u\n", c->id);
5503
5504   data_msg = (struct GNUNET_MESH_ToOrigin *) message;
5505
5506   /* Sanity check for message size */
5507   size = ntohs (message->size);
5508   if (sizeof (struct GNUNET_MESH_ToOrigin) +
5509       sizeof (struct GNUNET_MessageHeader) > size)
5510   {
5511     GNUNET_break (0);
5512     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5513     return;
5514   }
5515
5516   /* Tunnel exists? */
5517   tid = ntohl (data_msg->tid);
5518   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  on tunnel %X\n", tid);
5519   if (tid < GNUNET_MESH_LOCAL_TUNNEL_ID_SERV)
5520   {
5521     GNUNET_break (0);
5522     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5523     return;
5524   }
5525   t = tunnel_get_by_local_id (c, tid);
5526   if (NULL == t)
5527   {
5528     GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Tunnel %X unknown.\n", tid);
5529     GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "  for client %u.\n", c->id);
5530     GNUNET_break (0);
5531     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5532     return;
5533   }
5534
5535   /*  It should be sent by someone who has this as incoming tunnel. */
5536   if (GNUNET_NO == client_knows_tunnel (c, t))
5537   {
5538     GNUNET_break (0);
5539     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5540     return;
5541   }
5542
5543   /* PID should be as expected */
5544   clinfo = tunnel_get_client_fc (t, c);
5545   if (ntohl (data_msg->pid) != clinfo->bck_pid + 1)
5546   {
5547     GNUNET_break (0);
5548     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
5549                 "To Origin PID, expected %u, got %u\n",
5550                 clinfo->bck_pid + 1,
5551                 ntohl (data_msg->pid));
5552     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5553     return;
5554   }
5555   clinfo->bck_pid++;
5556
5557   /* Ok, everything is correct, send the message
5558    * (pretend we got it from a mesh peer)
5559    */
5560   {
5561     char buf[ntohs (message->size)] GNUNET_ALIGN;
5562     struct GNUNET_MESH_ToOrigin *copy;
5563
5564     /* Work around const limitation */
5565     copy = (struct GNUNET_MESH_ToOrigin *) buf;
5566     memcpy (buf, data_msg, size);
5567     GNUNET_PEER_resolve (t->id.oid, &copy->oid);
5568     copy->tid = htonl (t->id.tid);
5569     copy->ttl = htonl (default_ttl);
5570     copy->pid = htonl (t->bck_pid + 1);
5571
5572     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5573                 "  calling generic handler...\n");
5574     handle_mesh_data_to_orig (NULL, &my_full_id, &copy->header);
5575   }
5576   GNUNET_SERVER_receive_done (client, GNUNET_OK);
5577
5578   return;
5579 }
5580
5581
5582 /**
5583  * Handler for client's ACKs for payload traffic.
5584  *
5585  * @param cls Closure (unused).
5586  * @param client Identification of the client.
5587  * @param message The actual message.
5588  */
5589 static void
5590 handle_local_ack (void *cls, struct GNUNET_SERVER_Client *client,
5591                   const struct GNUNET_MessageHeader *message)
5592 {
5593   struct GNUNET_MESH_LocalAck *msg;
5594   struct MeshTunnel *t;
5595   struct MeshClient *c;
5596   MESH_TunnelNumber tid;
5597   uint32_t ack;
5598
5599   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got a local ACK\n");
5600   /* Sanity check for client registration */
5601   if (NULL == (c = client_get (client)))
5602   {
5603     GNUNET_break (0);
5604     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5605     return;
5606   }
5607   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  by client %u\n", c->id);
5608
5609   msg = (struct GNUNET_MESH_LocalAck *) message;
5610
5611   /* Tunnel exists? */
5612   tid = ntohl (msg->tunnel_id);
5613   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  on tunnel %X\n", tid);
5614   t = tunnel_get_by_local_id (c, tid);
5615   if (NULL == t)
5616   {
5617     GNUNET_break (0);
5618     GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Tunnel %X unknown.\n", tid);
5619     GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "  for client %u.\n", c->id);
5620     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5621     return;
5622   }
5623
5624   ack = ntohl (msg->max_pid);
5625   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  ack %u\n", ack);
5626
5627   /* Does client own tunnel? I.E: Is this an ACK for BCK traffic? */
5628   if (NULL != t->owner && t->owner->handle == client)
5629   {
5630     /* The client owns the tunnel, ACK is for data to_origin, send BCK ACK. */
5631     t->bck_ack = ack;
5632     tunnel_send_bck_ack(t, GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK);
5633   }
5634   else
5635   {
5636     /* The client doesn't own the tunnel, this ACK is for FWD traffic. */
5637     tunnel_set_client_fwd_ack (t, c, ack);
5638     tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK);
5639   }
5640
5641   GNUNET_SERVER_receive_done (client, GNUNET_OK);
5642
5643   return;
5644 }
5645
5646
5647
5648 /**
5649  * Iterator over all tunnels to send a monitoring client info about each tunnel.
5650  *
5651  * @param cls Closure (client handle).
5652  * @param key Key (hashed tunnel ID, unused).
5653  * @param value Tunnel info.
5654  *
5655  * @return GNUNET_YES, to keep iterating.
5656  */
5657 static int
5658 monitor_all_tunnels_iterator (void *cls,
5659                               const struct GNUNET_HashCode * key,
5660                               void *value)
5661 {
5662   struct GNUNET_SERVER_Client *client = cls;
5663   struct MeshTunnel *t = value;
5664   struct GNUNET_MESH_LocalMonitor *msg;
5665
5666   msg = GNUNET_malloc (sizeof(struct GNUNET_MESH_LocalMonitor));
5667   GNUNET_PEER_resolve(t->id.oid, &msg->owner);
5668   msg->tunnel_id = htonl (t->id.tid);
5669   msg->header.size = htons (sizeof (struct GNUNET_MESH_LocalMonitor));
5670   msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_INFO_TUNNELS);
5671   GNUNET_PEER_resolve (t->peer, &msg->destination);
5672
5673   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
5674               "*  sending info about tunnel %s [%u]\n",
5675               GNUNET_i2s (&msg->owner), t->id.tid);
5676
5677   GNUNET_SERVER_notification_context_unicast (nc, client,
5678                                               &msg->header, GNUNET_NO);
5679   return GNUNET_YES;
5680 }
5681
5682
5683 /**
5684  * Handler for client's MONITOR request.
5685  *
5686  * @param cls Closure (unused).
5687  * @param client Identification of the client.
5688  * @param message The actual message.
5689  */
5690 static void
5691 handle_local_get_tunnels (void *cls, struct GNUNET_SERVER_Client *client,
5692                           const struct GNUNET_MessageHeader *message)
5693 {
5694   struct MeshClient *c;
5695
5696   /* Sanity check for client registration */
5697   if (NULL == (c = client_get (client)))
5698   {
5699     GNUNET_break (0);
5700     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5701     return;
5702   }
5703
5704   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
5705               "Received get tunnels request from client %u\n",
5706               c->id);
5707   GNUNET_CONTAINER_multihashmap_iterate (tunnels,
5708                                          monitor_all_tunnels_iterator,
5709                                          client);
5710   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
5711               "Get tunnels request from client %u completed\n",
5712               c->id);
5713   GNUNET_SERVER_receive_done (client, GNUNET_OK);
5714 }
5715
5716
5717 /**
5718  * Handler for client's MONITOR_TUNNEL request.
5719  *
5720  * @param cls Closure (unused).
5721  * @param client Identification of the client.
5722  * @param message The actual message.
5723  */
5724 static void
5725 handle_local_show_tunnel (void *cls, struct GNUNET_SERVER_Client *client,
5726                           const struct GNUNET_MessageHeader *message)
5727 {
5728   const struct GNUNET_MESH_LocalMonitor *msg;
5729   struct GNUNET_MESH_LocalMonitor *resp;
5730   struct MeshClient *c;
5731   struct MeshTunnel *t;
5732
5733   /* Sanity check for client registration */
5734   if (NULL == (c = client_get (client)))
5735   {
5736     GNUNET_break (0);
5737     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5738     return;
5739   }
5740
5741   msg = (struct GNUNET_MESH_LocalMonitor *) message;
5742   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
5743               "Received tunnel info request from client %u for tunnel %s[%X]\n",
5744               c->id,
5745               &msg->owner,
5746               ntohl (msg->tunnel_id));
5747   t = tunnel_get (&msg->owner, ntohl (msg->tunnel_id));
5748   if (NULL == t)
5749   {
5750     /* We don't know the tunnel FIXME */
5751     struct GNUNET_MESH_LocalMonitor warn;
5752
5753     warn = *msg;
5754     GNUNET_SERVER_notification_context_unicast (nc, client,
5755                                                 &warn.header,
5756                                                 GNUNET_NO);
5757     GNUNET_SERVER_receive_done (client, GNUNET_OK);
5758     return;
5759   }
5760
5761   /* Initialize context */
5762   resp = GNUNET_malloc (sizeof (struct GNUNET_MESH_LocalMonitor));
5763   *resp = *msg;
5764   GNUNET_PEER_resolve (t->peer, &resp->destination);
5765   resp->header.size = htons (sizeof (struct GNUNET_MESH_LocalMonitor));
5766   GNUNET_SERVER_notification_context_unicast (nc, c->handle,
5767                                               &resp->header, GNUNET_NO);
5768   GNUNET_free (resp);
5769
5770   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
5771               "Monitor tunnel request from client %u completed\n",
5772               c->id);
5773   GNUNET_SERVER_receive_done (client, GNUNET_OK);
5774 }
5775
5776
5777 /**
5778  * Functions to handle messages from clients
5779  */
5780 static struct GNUNET_SERVER_MessageHandler client_handlers[] = {
5781   {&handle_local_new_client, NULL,
5782    GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT, 0},
5783   {&handle_local_tunnel_create, NULL,
5784    GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_CREATE,
5785    sizeof (struct GNUNET_MESH_TunnelMessage)},
5786   {&handle_local_tunnel_destroy, NULL,
5787    GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_DESTROY,
5788    sizeof (struct GNUNET_MESH_TunnelMessage)},
5789   {&handle_local_tunnel_buffer, NULL,
5790    GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_BUFFER,
5791    sizeof (struct GNUNET_MESH_TunnelMessage)},
5792   {&handle_local_tunnel_buffer, NULL,
5793    GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_NOBUFFER,
5794    sizeof (struct GNUNET_MESH_TunnelMessage)},
5795   {&handle_local_unicast, NULL,
5796    GNUNET_MESSAGE_TYPE_MESH_UNICAST, 0},
5797   {&handle_local_to_origin, NULL,
5798    GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN, 0},
5799   {&handle_local_ack, NULL,
5800    GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK,
5801    sizeof (struct GNUNET_MESH_LocalAck)},
5802   {&handle_local_get_tunnels, NULL,
5803    GNUNET_MESSAGE_TYPE_MESH_LOCAL_INFO_TUNNELS,
5804    sizeof (struct GNUNET_MessageHeader)},
5805   {&handle_local_show_tunnel, NULL,
5806    GNUNET_MESSAGE_TYPE_MESH_LOCAL_INFO_TUNNEL,
5807      sizeof (struct GNUNET_MESH_LocalMonitor)},
5808   {NULL, NULL, 0, 0}
5809 };
5810
5811
5812 /**
5813  * To be called on core init/fail.
5814  *
5815  * @param cls service closure
5816  * @param server handle to the server for this service
5817  * @param identity the public identity of this peer
5818  */
5819 static void
5820 core_init (void *cls, struct GNUNET_CORE_Handle *server,
5821            const struct GNUNET_PeerIdentity *identity)
5822 {
5823   static int i = 0;
5824   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Core init\n");
5825   core_handle = server;
5826   if (0 != memcmp (identity, &my_full_id, sizeof (my_full_id)) ||
5827       NULL == server)
5828   {
5829     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Wrong CORE service\n"));
5830     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
5831                 " core id %s\n",
5832                 GNUNET_i2s (identity));
5833     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
5834                 " my id %s\n",
5835                 GNUNET_i2s (&my_full_id));
5836     GNUNET_SCHEDULER_shutdown (); // Try gracefully
5837     if (10 < i++)
5838       GNUNET_abort(); // Try harder
5839   }
5840   return;
5841 }
5842
5843
5844 /**
5845  * Method called whenever a given peer connects.
5846  *
5847  * @param cls closure
5848  * @param peer peer identity this notification is about
5849  */
5850 static void
5851 core_connect (void *cls, const struct GNUNET_PeerIdentity *peer)
5852 {
5853   struct MeshPeerInfo *peer_info;
5854   struct MeshPeerPath *path;
5855
5856   DEBUG_CONN ("Peer connected\n");
5857   DEBUG_CONN ("     %s\n", GNUNET_i2s (&my_full_id));
5858   peer_info = peer_info_get (peer);
5859   if (myid == peer_info->id)
5860   {
5861     DEBUG_CONN ("     (self)\n");
5862     return;
5863   }
5864   else
5865   {
5866     DEBUG_CONN ("     %s\n", GNUNET_i2s (peer));
5867   }
5868   path = path_new (2);
5869   path->peers[0] = myid;
5870   path->peers[1] = peer_info->id;
5871   GNUNET_PEER_change_rc (myid, 1);
5872   GNUNET_PEER_change_rc (peer_info->id, 1);
5873   peer_info_add_path (peer_info, path, GNUNET_YES);
5874   GNUNET_STATISTICS_update (stats, "# peers", 1, GNUNET_NO);
5875   return;
5876 }
5877
5878
5879 /**
5880  * Method called whenever a peer disconnects.
5881  *
5882  * @param cls closure
5883  * @param peer peer identity this notification is about
5884  */
5885 static void
5886 core_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer)
5887 {
5888   struct MeshPeerInfo *pi;
5889   struct MeshPeerQueue *q;
5890   struct MeshPeerQueue *n;
5891
5892   DEBUG_CONN ("Peer disconnected\n");
5893   pi = GNUNET_CONTAINER_multihashmap_get (peers, &peer->hashPubKey);
5894   if (NULL == pi)
5895   {
5896     GNUNET_break (0);
5897     return;
5898   }
5899   q = pi->queue_head;
5900   while (NULL != q)
5901   {
5902       n = q->next;
5903       /* TODO try to reroute this traffic instead */
5904       queue_destroy(q, GNUNET_YES);
5905       q = n;
5906   }
5907   if (NULL != pi->core_transmit)
5908   {
5909     GNUNET_CORE_notify_transmit_ready_cancel(pi->core_transmit);
5910     pi->core_transmit = NULL;
5911   }
5912   peer_info_remove_path (pi, pi->id, myid);
5913   if (myid == pi->id)
5914   {
5915     DEBUG_CONN ("     (self)\n");
5916   }
5917   GNUNET_STATISTICS_update (stats, "# peers", -1, GNUNET_NO);
5918   return;
5919 }
5920
5921
5922 /******************************************************************************/
5923 /************************      MAIN FUNCTIONS      ****************************/
5924 /******************************************************************************/
5925
5926 /**
5927  * Iterator over tunnel hash map entries to destroy the tunnel during shutdown.
5928  *
5929  * @param cls closure
5930  * @param key current key code
5931  * @param value value in the hash map
5932  * @return GNUNET_YES if we should continue to iterate,
5933  *         GNUNET_NO if not.
5934  */
5935 static int
5936 shutdown_tunnel (void *cls, const struct GNUNET_HashCode * key, void *value)
5937 {
5938   struct MeshTunnel *t = value;
5939
5940   tunnel_destroy (t);
5941   return GNUNET_YES;
5942 }
5943
5944 /**
5945  * Iterator over peer hash map entries to destroy the tunnel during shutdown.
5946  *
5947  * @param cls closure
5948  * @param key current key code
5949  * @param value value in the hash map
5950  * @return GNUNET_YES if we should continue to iterate,
5951  *         GNUNET_NO if not.
5952  */
5953 static int
5954 shutdown_peer (void *cls, const struct GNUNET_HashCode * key, void *value)
5955 {
5956   struct MeshPeerInfo *p = value;
5957   struct MeshPeerQueue *q;
5958   struct MeshPeerQueue *n;
5959
5960   q = p->queue_head;
5961   while (NULL != q)
5962   {
5963       n = q->next;
5964       if (q->peer == p)
5965       {
5966         queue_destroy(q, GNUNET_YES);
5967       }
5968       q = n;
5969   }
5970   peer_info_destroy (p);
5971   return GNUNET_YES;
5972 }
5973
5974
5975 /**
5976  * Task run during shutdown.
5977  *
5978  * @param cls unused
5979  * @param tc unused
5980  */
5981 static void
5982 shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
5983 {
5984   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "shutting down\n");
5985
5986   if (core_handle != NULL)
5987   {
5988     GNUNET_CORE_disconnect (core_handle);
5989     core_handle = NULL;
5990   }
5991   if (NULL != keygen)
5992   {
5993     GNUNET_CRYPTO_ecc_key_create_stop (keygen);
5994     keygen = NULL;
5995   }
5996   GNUNET_CONTAINER_multihashmap_iterate (tunnels, &shutdown_tunnel, NULL);
5997   GNUNET_CONTAINER_multihashmap_iterate (peers, &shutdown_peer, NULL);
5998   if (dht_handle != NULL)
5999   {
6000     GNUNET_DHT_disconnect (dht_handle);
6001     dht_handle = NULL;
6002   }
6003   if (nc != NULL)
6004   {
6005     GNUNET_SERVER_notification_context_destroy (nc);
6006     nc = NULL;
6007   }
6008   if (GNUNET_SCHEDULER_NO_TASK != announce_id_task)
6009   {
6010     GNUNET_SCHEDULER_cancel (announce_id_task);
6011     announce_id_task = GNUNET_SCHEDULER_NO_TASK;
6012   }
6013   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "shut down\n");
6014 }
6015
6016
6017 /**
6018  * Callback for hostkey read/generation.
6019  *
6020  * @param cls Closure (Configuration handle).
6021  * @param pk The ECC private key.
6022  * @param emsg Error message, if any.
6023  */
6024 static void
6025 key_generation_cb (void *cls,
6026                    struct GNUNET_CRYPTO_EccPrivateKey *pk,
6027                    const char *emsg)
6028 {
6029   const struct GNUNET_CONFIGURATION_Handle *c = cls;
6030   struct MeshPeerInfo *peer;
6031   struct MeshPeerPath *p;
6032
6033   keygen = NULL;  
6034   if (NULL == pk)
6035   {
6036     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
6037                 _("Mesh service could not access hostkey: %s. Exiting.\n"),
6038                 emsg);
6039     GNUNET_SCHEDULER_shutdown ();
6040     return;
6041   }
6042   my_private_key = pk;
6043   GNUNET_CRYPTO_ecc_key_get_public (my_private_key, &my_public_key);
6044   GNUNET_CRYPTO_hash (&my_public_key, sizeof (my_public_key),
6045                       &my_full_id.hashPubKey);
6046   myid = GNUNET_PEER_intern (&my_full_id);
6047   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
6048               "Mesh for peer [%s] starting\n",
6049               GNUNET_i2s(&my_full_id));
6050
6051   core_handle = GNUNET_CORE_connect (c, /* Main configuration */
6052                                      NULL,      /* Closure passed to MESH functions */
6053                                      &core_init,        /* Call core_init once connected */
6054                                      &core_connect,     /* Handle connects */
6055                                      &core_disconnect,  /* remove peers on disconnects */
6056                                      NULL,      /* Don't notify about all incoming messages */
6057                                      GNUNET_NO, /* For header only in notification */
6058                                      NULL,      /* Don't notify about all outbound messages */
6059                                      GNUNET_NO, /* For header-only out notification */
6060                                      core_handlers);    /* Register these handlers */
6061   
6062   if (core_handle == NULL)
6063   {
6064     GNUNET_break (0);
6065     GNUNET_SCHEDULER_shutdown ();
6066     return;
6067   }
6068
6069   next_tid = 0;
6070   next_local_tid = GNUNET_MESH_LOCAL_TUNNEL_ID_SERV;
6071
6072
6073   GNUNET_SERVER_add_handlers (server_handle, client_handlers);
6074   nc = GNUNET_SERVER_notification_context_create (server_handle, 1);
6075   GNUNET_SERVER_disconnect_notify (server_handle,
6076                                    &handle_local_client_disconnect, NULL);
6077
6078
6079   clients = NULL;
6080   clients_tail = NULL;
6081   next_client_id = 0;
6082
6083   announce_id_task = GNUNET_SCHEDULER_add_now (&announce_id, cls);
6084
6085   /* Create a peer_info for the local peer */
6086   peer = peer_info_get (&my_full_id);
6087   p = path_new (1);
6088   p->peers[0] = myid;
6089   GNUNET_PEER_change_rc (myid, 1);
6090   peer_info_add_path (peer, p, GNUNET_YES);
6091   GNUNET_SERVER_resume (server_handle);
6092   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Mesh service running\n");
6093 }
6094
6095
6096 /**
6097  * Process mesh requests.
6098  *
6099  * @param cls closure
6100  * @param server the initialized server
6101  * @param c configuration to use
6102  */
6103 static void
6104 run (void *cls, struct GNUNET_SERVER_Handle *server,
6105      const struct GNUNET_CONFIGURATION_Handle *c)
6106 {
6107   char *keyfile;
6108
6109   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "starting to run\n");
6110   server_handle = server;
6111
6112   if (GNUNET_OK !=
6113       GNUNET_CONFIGURATION_get_value_filename (c, "PEER", "PRIVATE_KEY",
6114                                                &keyfile))
6115   {
6116     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
6117                 _
6118                 ("%s service is lacking key configuration settings (%s).  Exiting.\n"),
6119                 "mesh", "peer/privatekey");
6120     GNUNET_SCHEDULER_shutdown ();
6121     return;
6122   }
6123
6124   if (GNUNET_OK !=
6125       GNUNET_CONFIGURATION_get_value_time (c, "MESH", "REFRESH_PATH_TIME",
6126                                            &refresh_path_time))
6127   {
6128     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
6129                 _
6130                 ("%s service is lacking key configuration settings (%s).  Exiting.\n"),
6131                 "mesh", "refresh path time");
6132     GNUNET_SCHEDULER_shutdown ();
6133     return;
6134   }
6135
6136   if (GNUNET_OK !=
6137       GNUNET_CONFIGURATION_get_value_time (c, "MESH", "APP_ANNOUNCE_TIME",
6138                                            &app_announce_time))
6139   {
6140     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
6141                 _
6142                 ("%s service is lacking key configuration settings (%s).  Exiting.\n"),
6143                 "mesh", "app announce time");
6144     GNUNET_SCHEDULER_shutdown ();
6145     return;
6146   }
6147   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
6148               "APP_ANNOUNCE_TIME %llu ms\n", 
6149               app_announce_time.rel_value);
6150   if (GNUNET_OK !=
6151       GNUNET_CONFIGURATION_get_value_time (c, "MESH", "ID_ANNOUNCE_TIME",
6152                                            &id_announce_time))
6153   {
6154     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
6155                 _
6156                 ("%s service is lacking key configuration settings (%s).  Exiting.\n"),
6157                 "mesh", "id announce time");
6158     GNUNET_SCHEDULER_shutdown ();
6159     return;
6160   }
6161
6162   if (GNUNET_OK !=
6163       GNUNET_CONFIGURATION_get_value_time (c, "MESH", "CONNECT_TIMEOUT",
6164                                            &connect_timeout))
6165   {
6166     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
6167                 _
6168                 ("%s service is lacking key configuration settings (%s).  Exiting.\n"),
6169                 "mesh", "connect timeout");
6170     GNUNET_SCHEDULER_shutdown ();
6171     return;
6172   }
6173
6174   if (GNUNET_OK !=
6175       GNUNET_CONFIGURATION_get_value_number (c, "MESH", "MAX_MSGS_QUEUE",
6176                                              &max_msgs_queue))
6177   {
6178     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
6179                 _
6180                 ("%s service is lacking key configuration settings (%s).  Exiting.\n"),
6181                 "mesh", "max msgs queue");
6182     GNUNET_SCHEDULER_shutdown ();
6183     return;
6184   }
6185
6186   if (GNUNET_OK !=
6187       GNUNET_CONFIGURATION_get_value_number (c, "MESH", "MAX_TUNNELS",
6188                                              &max_tunnels))
6189   {
6190     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
6191                 _
6192                 ("%s service is lacking key configuration settings (%s).  Exiting.\n"),
6193                 "mesh", "max tunnels");
6194     GNUNET_SCHEDULER_shutdown ();
6195     return;
6196   }
6197
6198   if (GNUNET_OK !=
6199       GNUNET_CONFIGURATION_get_value_number (c, "MESH", "DEFAULT_TTL",
6200                                              &default_ttl))
6201   {
6202     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
6203                 _
6204                 ("%s service is lacking key configuration settings (%s). Using default (%u).\n"),
6205                 "mesh", "default ttl", 64);
6206     default_ttl = 64;
6207   }
6208
6209   if (GNUNET_OK !=
6210       GNUNET_CONFIGURATION_get_value_number (c, "MESH", "MAX_PEERS",
6211                                              &max_peers))
6212   {
6213     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
6214                 _("%s service is lacking key configuration settings (%s). Using default (%u).\n"),
6215                 "mesh", "max peers", 1000);
6216     max_peers = 1000;
6217   }
6218
6219   if (GNUNET_OK !=
6220       GNUNET_CONFIGURATION_get_value_number (c, "MESH", "DHT_REPLICATION_LEVEL",
6221                                              &dht_replication_level))
6222   {
6223     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
6224                 _
6225                 ("%s service is lacking key configuration settings (%s). Using default (%u).\n"),
6226                 "mesh", "dht replication level", 3);
6227     dht_replication_level = 3;
6228   }
6229
6230   tunnels = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
6231   incoming_tunnels = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
6232   peers = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
6233   types = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
6234
6235   dht_handle = GNUNET_DHT_connect (c, 64);
6236   if (NULL == dht_handle)
6237   {
6238     GNUNET_break (0);
6239   }
6240   stats = GNUNET_STATISTICS_create ("mesh", c);
6241
6242   GNUNET_SERVER_suspend (server_handle);
6243   /* Scheduled the task to clean up when shutdown is called */
6244   GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task,
6245                                 NULL);
6246   keygen = GNUNET_CRYPTO_ecc_key_create_start (keyfile,
6247                                                &key_generation_cb,
6248                                                (void *) c);
6249   GNUNET_free (keyfile);
6250 }
6251
6252
6253 /**
6254  * The main function for the mesh service.
6255  *
6256  * @param argc number of arguments from the command line
6257  * @param argv command line arguments
6258  * @return 0 ok, 1 on error
6259  */
6260 int
6261 main (int argc, char *const *argv)
6262 {
6263   int ret;
6264   int r;
6265
6266   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "main()\n");
6267   r = GNUNET_SERVICE_run (argc, argv, "mesh", GNUNET_SERVICE_OPTION_NONE, &run,
6268                           NULL);
6269   ret = (GNUNET_OK == r) ? 0 : 1;
6270   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "main() END\n");
6271
6272   INTERVAL_SHOW;
6273
6274   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
6275               "Mesh for peer [%s] FWD ACKs %u, BCK ACKs %u\n",
6276               GNUNET_i2s(&my_full_id), debug_fwd_ack, debug_bck_ack);
6277
6278   return ret;
6279 }