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