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