bada66388842408661d17d1f17d1c91e149d0824
[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   struct MeshTunnelReliability *rel = t->fwd_rel;
2181   uint64_t delta_mid;
2182   uint32_t ack;
2183   int delta;
2184
2185   /* Is it after unicast retransmission? */
2186   switch (type)
2187   {
2188     case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
2189       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2190                   "ACK due to FWD DATA retransmission\n");
2191       if (GNUNET_YES == t->nobuffer)
2192       {
2193         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Not sending ACK, nobuffer\n");
2194         return;
2195       }
2196       if (GNUNET_YES == t->reliable && NULL != t->client)
2197         tunnel_send_fwd_data_ack (t);
2198       break;
2199     case GNUNET_MESSAGE_TYPE_MESH_ACK:
2200     case GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK:
2201     case GNUNET_MESSAGE_TYPE_MESH_UNICAST_ACK:
2202       break;
2203     case GNUNET_MESSAGE_TYPE_MESH_POLL:
2204     case GNUNET_MESSAGE_TYPE_MESH_PATH_ACK:
2205       t->force_ack = GNUNET_YES;
2206       break;
2207     default:
2208       GNUNET_break (0);
2209   }
2210
2211   /* Check if we need to transmit the ACK */
2212   if (0 && NULL == t->owner && 
2213       t->queue_max > t->next_fc.queue_n * 4 &&
2214       GMC_is_pid_bigger(t->prev_fc.last_ack_sent, t->prev_fc.last_pid_recv) &&
2215       GNUNET_NO == t->force_ack)
2216   {
2217     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Not sending FWD ACK, buffer free\n");
2218     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2219                 "  t->qmax: %u, t->qn: %u\n",
2220                 t->queue_max, t->next_fc.queue_n);
2221     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2222                 "  t->pid: %u, t->ack: %u\n",
2223                 t->prev_fc.last_pid_recv, t->prev_fc.last_ack_sent);
2224     return;
2225   }
2226
2227   /* Ok, ACK might be necessary, what PID to ACK? */
2228   delta = t->queue_max - t->next_fc.queue_n;
2229   if (NULL != t->owner && GNUNET_YES == t->reliable && NULL != rel->head_sent)
2230     delta_mid = rel->mid_sent - rel->head_sent->mid;
2231   else
2232     delta_mid = 0;
2233   if (0 > delta || (GNUNET_YES == t->reliable && 
2234                     NULL != t->owner &&
2235                     (rel->n_sent > 10 || delta_mid > 64)))
2236     delta = 0;
2237   if (NULL != t->owner && delta > 1)
2238     delta = 1;
2239   ack = t->prev_fc.last_pid_recv + delta;
2240   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " FWD ACK %u\n", ack);
2241   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2242               " last pid %u, last ack %u, qmax %u, q %u\n",
2243               t->prev_fc.last_pid_recv, t->prev_fc.last_ack_sent,
2244               t->queue_max, t->next_fc.queue_n);
2245   if (ack == t->prev_fc.last_ack_sent && GNUNET_NO == t->force_ack)
2246   {
2247     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Not sending FWD ACK, not needed\n");
2248     return;
2249   }
2250
2251   t->prev_fc.last_ack_sent = ack;
2252   if (NULL != t->owner)
2253     send_local_ack (t, t->owner, GNUNET_YES);
2254   else if (0 != t->prev_hop)
2255     send_ack (t, t->prev_hop, ack);
2256   else
2257     GNUNET_break (0);
2258   debug_fwd_ack++;
2259   t->force_ack = GNUNET_NO;
2260 }
2261
2262
2263 /**
2264  * Send an ACK informing the children node/client about the available
2265  * buffer space.
2266  * If buffering is off, send only on behalf of root (can be self).
2267  * If buffering is on, send when sent to predecessor and buffer space is free.
2268  * Note that although the name is bck_ack, the BCK mean backwards *traffic*,
2269  * the ACK itself goes "forward" (towards children/clients).
2270  * 
2271  * @param t Tunnel on which to send the ACK.
2272  * @param type Type of message that triggered the ACK transmission.
2273  */
2274 static void
2275 tunnel_send_bck_ack (struct MeshTunnel *t, uint16_t type)
2276 {
2277   uint32_t ack;
2278   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2279               "Sending BCK ACK on tunnel %u [%u] due to %s\n",
2280               t->id.oid, t->id.tid, GNUNET_MESH_DEBUG_M2S(type));
2281   /* Is it after data to_origin retransmission? */
2282   switch (type)
2283   {
2284     case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN:
2285       if (GNUNET_YES == t->nobuffer)
2286       {
2287         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2288                     "    Not sending ACK, nobuffer + traffic\n");
2289         return;
2290       }
2291       if (GNUNET_YES == t->reliable && NULL != t->owner)
2292         tunnel_send_bck_data_ack (t);
2293       break;
2294     case GNUNET_MESSAGE_TYPE_MESH_ACK:
2295     case GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK:
2296       break;
2297     case GNUNET_MESSAGE_TYPE_MESH_PATH_ACK:
2298     case GNUNET_MESSAGE_TYPE_MESH_POLL:
2299       t->force_ack = GNUNET_YES;
2300       break;
2301     default:
2302       GNUNET_break (0);
2303   }
2304
2305   /* TODO: Check if we need to transmit the ACK (as in fwd) */
2306
2307   ack = t->next_fc.last_pid_recv + t->queue_max - t->prev_fc.queue_n;
2308
2309   if (t->next_fc.last_ack_sent == ack && GNUNET_NO == t->force_ack)
2310   {
2311     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2312                 "    Not sending ACK, not needed, last ack sent was %u\n",
2313                 t->next_fc.last_ack_sent);
2314     return;
2315   }
2316   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2317               "    Sending BCK ACK %u (last sent: %u)\n",
2318               ack, t->next_fc.last_ack_sent);
2319   t->next_fc.last_ack_sent = ack;
2320
2321   if (NULL != t->client)
2322     send_local_ack (t, t->client, GNUNET_NO);
2323   else if (0 != t->next_hop)
2324     send_ack (t, t->next_hop, ack);
2325   else
2326     GNUNET_break (0);
2327   t->force_ack = GNUNET_NO;
2328 }
2329
2330
2331 /**
2332  * Modify the mesh message TID from global to local and send to client.
2333  * 
2334  * @param t Tunnel on which to send the message.
2335  * @param msg Message to modify and send.
2336  * @param c Client to send to.
2337  * @param tid Tunnel ID to use (c can be both owner and client).
2338  */
2339 static void
2340 tunnel_send_client_data (struct MeshTunnel *t,
2341                          const struct GNUNET_MESH_Data *msg,
2342                          struct MeshClient *c, MESH_TunnelNumber tid)
2343 {
2344   struct GNUNET_MESH_LocalData *copy;
2345   uint16_t size = ntohs (msg->header.size) - sizeof (struct GNUNET_MESH_Data);
2346   char cbuf[size + sizeof (struct GNUNET_MESH_LocalData)];
2347
2348   if (size < sizeof (struct GNUNET_MessageHeader))
2349   {
2350     GNUNET_break_op (0);
2351     return;
2352   }
2353   if (NULL == c)
2354   {
2355     GNUNET_break (0);
2356     return;
2357   }
2358   copy = (struct GNUNET_MESH_LocalData *) cbuf;
2359   memcpy (&copy[1], &msg[1], size);
2360   copy->header.size = htons (sizeof (struct GNUNET_MESH_LocalData) + size);
2361   copy->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_DATA);
2362   copy->tid = htonl (tid);
2363   GNUNET_SERVER_notification_context_unicast (nc, c->handle,
2364                                               &copy->header, GNUNET_NO);
2365 }
2366
2367 /**
2368  * Modify the unicast message TID from global to local and send to client.
2369  * 
2370  * @param t Tunnel on which to send the message.
2371  * @param msg Message to modify and send.
2372  */
2373 static void
2374 tunnel_send_client_ucast (struct MeshTunnel *t,
2375                           const struct GNUNET_MESH_Data *msg)
2376 {
2377   tunnel_send_client_data (t, msg, t->client, t->local_tid_dest);
2378 }
2379
2380
2381 /**
2382  * Send up to 64 buffered messages to the client for in order delivery.
2383  * 
2384  * @param t Tunnel on which to empty the message buffer.
2385  */
2386 static void
2387 tunnel_send_client_buffered_ucast (struct MeshTunnel *t)
2388 {
2389   struct MeshTunnelReliability *rel;
2390   struct MeshReliableMessage *copy;
2391   struct MeshReliableMessage *next;
2392
2393   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "send_buffered_unicast\n");
2394   rel = t->bck_rel;
2395   for (copy = rel->head_recv; NULL != copy; copy = next)
2396   {
2397     next = copy->next;
2398     if (copy->mid == rel->mid_recv)
2399     {
2400       struct GNUNET_MESH_Data *msg = (struct GNUNET_MESH_Data *) &copy[1];
2401
2402       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2403                   " have %llu! now expecting %llu\n",
2404                   copy->mid, rel->mid_recv + 1LL);
2405       tunnel_send_client_ucast (t, msg);
2406       rel->mid_recv++;
2407       GNUNET_CONTAINER_DLL_remove (rel->head_recv, rel->tail_recv, copy);
2408       GNUNET_free (copy);
2409     }
2410     else
2411     {
2412       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2413                   " don't have %llu, (%llu)\n",
2414                   rel->mid_recv,
2415                   copy->mid);
2416       return;
2417     }
2418   }
2419   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "send_buffered_unicast END\n");
2420 }
2421
2422
2423 /**
2424  * We have received a message out of order, buffer it until we receive
2425  * the missing one and we can feed the rest to the client.
2426  */
2427 static void
2428 tunnel_add_buffer_ucast (struct MeshTunnel *t,
2429                          const struct GNUNET_MESH_Data *msg)
2430 {
2431   struct MeshTunnelReliability *rel;
2432   struct MeshReliableMessage *copy;
2433   struct MeshReliableMessage *prev;
2434   uint64_t mid;
2435   uint16_t size;
2436
2437   rel = t->bck_rel;
2438   size = ntohs (msg->header.size);
2439   mid = GNUNET_ntohll (msg->mid);
2440   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "add_buffer_ucast %llu\n", mid);
2441
2442   copy = GNUNET_malloc (sizeof (*copy) + size);
2443   copy->mid = mid;
2444   copy->rel = rel;
2445   memcpy (&copy[1], msg, size);
2446
2447   // FIXME do something better than O(n), although n < 64...
2448   for (prev = rel->head_recv; NULL != prev; prev = prev->next)
2449   {
2450     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " prev %llu\n", prev->mid);
2451     if (mid < prev->mid)
2452     {
2453       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " bingo!\n");
2454       GNUNET_CONTAINER_DLL_insert_before (rel->head_recv, rel->tail_recv,
2455                                           prev, copy);
2456       return;
2457     }
2458   }
2459   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " insert at tail!\n");
2460   GNUNET_CONTAINER_DLL_insert_tail (rel->head_recv, rel->tail_recv, copy);
2461   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "add_buffer_ucast END\n");
2462 }
2463
2464
2465 /**
2466  * Destroy a reliable message after it has been acknowledged, either by
2467  * direct mid ACK or bitfield. Updates the appropriate data structures and
2468  * timers and frees all memory.
2469  * 
2470  * @param copy Message that is no longer needed: remote peer got it.
2471  */
2472 static void
2473 tunnel_free_reliable_message (struct MeshReliableMessage *copy)
2474 {
2475   struct MeshTunnelReliability *rel;
2476   struct GNUNET_TIME_Relative time;
2477
2478   rel = copy->rel;
2479   time = GNUNET_TIME_absolute_get_duration (copy->timestamp);
2480   rel->expected_delay.rel_value *= 7;
2481   rel->expected_delay.rel_value += time.rel_value;
2482   rel->expected_delay.rel_value /= 8;
2483   rel->n_sent--;
2484   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!! Freeing %llu\n", copy->mid);
2485   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "    n_sent %u\n", rel->n_sent);
2486   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!!  took %s\n",
2487               GNUNET_STRINGS_relative_time_to_string (time, GNUNET_NO));
2488   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!!  new expected delay %s\n",
2489               GNUNET_STRINGS_relative_time_to_string (rel->expected_delay,
2490                                                       GNUNET_NO));
2491   rel->retry_timer = rel->expected_delay;
2492   GNUNET_CONTAINER_DLL_remove (rel->head_sent, rel->tail_sent, copy);
2493   GNUNET_free (copy);
2494 }
2495
2496
2497 /**
2498  * Mark future messages as ACK'd.
2499  *
2500  * @param t Tunnel whose sent buffer to clean.
2501  * @param msg DataACK message with a bitfield of future ACK'd messages.
2502  */
2503 static void
2504 tunnel_free_buffer_ucast (struct MeshTunnel *t,
2505                           const struct GNUNET_MESH_DataACK *msg)
2506 {
2507   struct MeshTunnelReliability *rel;
2508   struct MeshReliableMessage *copy;
2509   struct MeshReliableMessage *next;
2510   uint64_t bitfield;
2511   uint64_t mask;
2512   uint64_t mid;
2513   uint64_t target;
2514   unsigned int i;
2515
2516   bitfield = msg->futures;
2517   mid = GNUNET_ntohll (msg->mid);
2518   rel = t->fwd_rel;
2519   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2520               "free_sent_buffer %llu %llX\n",
2521               mid, bitfield);
2522   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2523               " rel %p, head %p\n",
2524               rel, rel->head_sent);
2525   for (i = 0, copy = rel->head_sent;
2526        i < 64 && NULL != copy && 0 != bitfield;
2527        i++)
2528   {
2529     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2530                 " trying bit %u (mid %llu)\n",
2531                 i, mid + i + 1);
2532     mask = 0x1LL << i;
2533     if (0 == (bitfield & mask))
2534      continue;
2535
2536     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " set!\n");
2537     /* Bit was set, clear the bit from the bitfield */
2538     bitfield &= ~mask;
2539
2540     /* The i-th bit was set. Do we have that copy? */
2541     /* Skip copies with mid < target */
2542     target = mid + i + 1;
2543     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " target %llu\n", target);
2544     while (NULL != copy && copy->mid < target)
2545      copy = copy->next;
2546
2547     /* Did we run out of copies? (previously freed, it's ok) */
2548     if (NULL == copy)
2549     {
2550      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "run out of copies...\n");
2551      return;
2552     }
2553
2554     /* Did we overshoot the target? (previously freed, it's ok) */
2555     if (copy->mid > target)
2556     {
2557      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " next copy %llu\n", copy->mid);
2558      continue;
2559     }
2560
2561     /* Now copy->mid == target, free it */
2562     next = copy->next;
2563     tunnel_free_reliable_message (copy);
2564     copy = next;
2565   }
2566   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "free_sent_buffer END\n");
2567 }
2568
2569
2570 /**
2571  * Modify the to_origin  message TID from global to local and send to client.
2572  * 
2573  * @param t Tunnel on which to send the message.
2574  * @param msg Message to modify and send.
2575  */
2576 static void
2577 tunnel_send_client_to_orig (struct MeshTunnel *t,
2578                             const struct GNUNET_MESH_Data *msg)
2579 {
2580   tunnel_send_client_data (t, msg, t->owner, t->local_tid);
2581 }
2582
2583
2584 /**
2585  * We haven't received an ACK after a certain time: restransmit the message.
2586  *
2587  * @param cls Closure (MeshReliableMessage with the message to restransmit)
2588  * @param tc TaskContext.
2589  */
2590 static void
2591 tunnel_retransmit_message (void *cls,
2592                            const struct GNUNET_SCHEDULER_TaskContext *tc)
2593 {
2594   struct MeshTunnelReliability *rel = cls;
2595   struct MeshReliableMessage *copy;
2596   struct MeshFlowControl *fc;
2597   struct MeshPeerQueue *q;
2598   struct MeshPeerInfo *pi;
2599   struct MeshTunnel *t;
2600   struct GNUNET_MESH_Data *payload;
2601   GNUNET_PEER_Id hop;
2602
2603   rel->retry_task = GNUNET_SCHEDULER_NO_TASK;
2604   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
2605     return;
2606
2607   t = rel->t;
2608   copy = rel->head_sent;
2609   if (NULL == copy)
2610   {
2611     GNUNET_break (0);
2612     return;
2613   }
2614
2615   /* Search the message to be retransmitted in the outgoing queue */
2616   payload = (struct GNUNET_MESH_Data *) &copy[1];
2617   hop = rel == t->fwd_rel ? t->next_hop : t->prev_hop;
2618   fc = rel == t->fwd_rel ? &t->prev_fc : &t->next_fc;
2619   pi = peer_get_short (hop);
2620   for (q = pi->queue_head; NULL != q; q = q->next)
2621   {
2622     if (ntohs (payload->header.type) == q->type)
2623     {
2624       struct GNUNET_MESH_Data *queued_data = q->cls;
2625
2626       if (queued_data->mid == payload->mid)
2627         break;
2628     }
2629   }
2630
2631   /* Message not found in the queue */
2632   if (NULL == q)
2633   {
2634     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!! RETRANSMIT %llu\n", copy->mid);
2635
2636     fc->last_ack_sent++;
2637     fc->last_pid_recv++;
2638     payload->pid = htonl (fc->last_pid_recv);
2639     send_prebuilt_message (&payload->header, hop, t);
2640     GNUNET_STATISTICS_update (stats, "# data retransmitted", 1, GNUNET_NO);
2641   }
2642   else
2643   {
2644     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!! STILL IN QUEUE %llu\n", copy->mid);
2645   }
2646
2647   rel->retry_timer = GNUNET_TIME_STD_BACKOFF (rel->retry_timer);
2648   rel->retry_task = GNUNET_SCHEDULER_add_delayed (rel->retry_timer,
2649                                                   &tunnel_retransmit_message,
2650                                                   cls);
2651 }
2652
2653
2654 /**
2655  * @brief Re-initiate traffic to this peer if necessary.
2656  *
2657  * Check if there is traffic queued towards this peer
2658  * and the core transmit handle is NULL (traffic was stalled).
2659  * If so, call core tmt rdy.
2660  *
2661  * @param peer_id Short ID of peer to which initiate traffic.
2662  */
2663 static void
2664 peer_unlock_queue(GNUNET_PEER_Id peer_id)
2665 {
2666   struct MeshPeerInfo *peer;
2667   struct GNUNET_PeerIdentity id;
2668   struct MeshPeerQueue *q;
2669   size_t size;
2670
2671   peer = peer_get_short (peer_id);
2672   if (NULL != peer->core_transmit)
2673     return;
2674
2675   q = queue_get_next (peer);
2676   if (NULL == q)
2677   {
2678     /* Might br multicast traffic already sent to this particular peer but
2679      * not to other children in this tunnel.
2680      * This way t->queue_n would be > 0 but the queue of this particular peer
2681      * would be empty.
2682      */
2683     return;
2684   }
2685   size = q->size;
2686   GNUNET_PEER_resolve (peer->id, &id);
2687   peer->core_transmit =
2688         GNUNET_CORE_notify_transmit_ready(core_handle,
2689                                           0,
2690                                           0,
2691                                           GNUNET_TIME_UNIT_FOREVER_REL,
2692                                           &id,
2693                                           size,
2694                                           &queue_send,
2695                                           peer);
2696         return;
2697 }
2698
2699
2700 /**
2701  * Send a message to all peers and clients in this tunnel that the tunnel
2702  * is no longer valid. If some peer or client should not receive the message,
2703  * should be zero'ed out before calling this function.
2704  *
2705  * @param t The tunnel whose peers and clients to notify.
2706  */
2707 static void
2708 tunnel_send_destroy (struct MeshTunnel *t)
2709 {
2710   struct GNUNET_MESH_TunnelDestroy msg;
2711   struct GNUNET_PeerIdentity id;
2712
2713   msg.header.size = htons (sizeof (msg));
2714   msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_TUNNEL_DESTROY);
2715   GNUNET_PEER_resolve (t->id.oid, &msg.oid);
2716   msg.tid = htonl (t->id.tid);
2717   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2718               "  sending tunnel destroy for tunnel: %s [%X]\n",
2719               GNUNET_i2s (&msg.oid), t->id.tid);
2720
2721   if (NULL == t->client && 0 != t->next_hop)
2722   {
2723     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  child: %u\n", t->next_hop);
2724     GNUNET_PEER_resolve (t->next_hop, &id);
2725     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2726                 "  sending forward to %s\n",
2727                 GNUNET_i2s (&id));
2728     send_prebuilt_message (&msg.header, t->next_hop, t);
2729   }
2730   if (NULL == t->owner && 0 != t->prev_hop)
2731   {
2732     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  parent: %u\n", t->prev_hop);
2733     GNUNET_PEER_resolve (t->prev_hop, &id);
2734     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2735                 "  sending back to %s\n",
2736                 GNUNET_i2s (&id));
2737     send_prebuilt_message (&msg.header, t->prev_hop, t);
2738   }
2739   if (NULL != t->owner)
2740   {
2741     send_client_tunnel_destroy (t->owner, t);
2742   }
2743   if (NULL != t->client)
2744   {
2745     send_client_tunnel_destroy (t->client, t);
2746   }
2747 }
2748
2749
2750 /**
2751  * Cancel all transmissions towards a neighbor that belongs to a certain tunnel.
2752  *
2753  * @param t Tunnel which to cancel.
2754  * @param neighbor Short ID of the neighbor to whom cancel the transmissions.
2755  */
2756 static void
2757 peer_cancel_queues (GNUNET_PEER_Id neighbor, struct MeshTunnel *t)
2758 {
2759   struct MeshPeerInfo *peer_info;
2760   struct MeshPeerQueue *pq;
2761   struct MeshPeerQueue *next;
2762
2763   if (0 == neighbor)
2764     return; /* Was local peer, 0'ed in tunnel_destroy_iterator */
2765   peer_info = peer_get_short (neighbor);
2766   for (pq = peer_info->queue_head; NULL != pq; pq = next)
2767   {
2768     next = pq->next;
2769     if (pq->tunnel == t)
2770     {
2771       if (GNUNET_MESSAGE_TYPE_MESH_UNICAST == pq->type ||
2772           GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN == pq->type)
2773       {
2774         /* Should have been removed on destroy children */
2775         GNUNET_break (0);
2776       }
2777       queue_destroy (pq, GNUNET_YES);
2778     }
2779   }
2780   if (NULL == peer_info->queue_head && NULL != peer_info->core_transmit)
2781   {
2782     GNUNET_CORE_notify_transmit_ready_cancel(peer_info->core_transmit);
2783     peer_info->core_transmit = NULL;
2784   }
2785 }
2786
2787
2788 /**
2789  * Destroy the tunnel.
2790  * 
2791  * This function does not generate any warning traffic to clients or peers.
2792  * 
2793  * Tasks:
2794  * Remove the tunnel from peer_info's and clients' hashmaps.
2795  * Cancel messages belonging to this tunnel queued to neighbors.
2796  * Free any allocated resources linked to the tunnel.
2797  *
2798  * @param t the tunnel to destroy
2799  *
2800  * @return GNUNET_OK on success
2801  */
2802 static int
2803 tunnel_destroy (struct MeshTunnel *t)
2804 {
2805   struct MeshClient *c;
2806   struct GNUNET_HashCode hash;
2807   int r;
2808
2809   if (NULL == t)
2810     return GNUNET_OK;
2811
2812   r = GNUNET_OK;
2813   c = t->owner;
2814 #if MESH_DEBUG
2815   {
2816     struct GNUNET_PeerIdentity id;
2817
2818     GNUNET_PEER_resolve (t->id.oid, &id);
2819     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "destroying tunnel %s [%x]\n",
2820                 GNUNET_i2s (&id), t->id.tid);
2821     if (NULL != c)
2822       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  by client %u\n", c->id);
2823   }
2824 #endif
2825
2826   GNUNET_CRYPTO_hash (&t->id, sizeof (struct MESH_TunnelID), &hash);
2827   if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_remove (tunnels, &hash, t))
2828   {
2829     GNUNET_break (0);
2830     r = GNUNET_SYSERR;
2831   }
2832
2833   if (NULL != c)
2834   {
2835     if (GNUNET_YES !=
2836       GNUNET_CONTAINER_multihashmap32_remove (c->own_tunnels, t->local_tid, t))
2837     {
2838       GNUNET_break (0);
2839       r = GNUNET_SYSERR;
2840     }
2841   }
2842
2843   if (NULL != t->client)
2844   {
2845     c = t->client;
2846     if (GNUNET_YES !=
2847         GNUNET_CONTAINER_multihashmap32_remove (c->incoming_tunnels,
2848                                                 t->local_tid_dest, t))
2849     {
2850       GNUNET_break (0);
2851       r = GNUNET_SYSERR;
2852     }
2853     if (GNUNET_YES != 
2854         GNUNET_CONTAINER_multihashmap32_remove (incoming_tunnels,
2855                                                 t->local_tid_dest, t))
2856     {
2857       GNUNET_break (0);
2858       r = GNUNET_SYSERR;
2859     }
2860   }
2861
2862   if (0 != t->prev_hop)
2863   {
2864     peer_cancel_queues (t->prev_hop, t);
2865     GNUNET_PEER_change_rc (t->prev_hop, -1);
2866   }
2867   if (0 != t->next_hop)
2868   {
2869     peer_cancel_queues (t->next_hop, t);
2870     GNUNET_PEER_change_rc (t->next_hop, -1);
2871   }
2872   if (0 != t->dest) {
2873       peer_info_remove_tunnel (peer_get_short (t->dest), t);
2874   }
2875
2876   if (GNUNET_SCHEDULER_NO_TASK != t->maintenance_task)
2877     GNUNET_SCHEDULER_cancel (t->maintenance_task);
2878
2879   n_tunnels--;
2880   GNUNET_STATISTICS_update (stats, "# tunnels", -1, GNUNET_NO);
2881   path_destroy (t->path);
2882   GNUNET_free (t);
2883   return r;
2884 }
2885
2886 /**
2887  * Tunnel is empty: destroy it.
2888  * 
2889  * Notifies all participants (peers, cleints) about the destruction.
2890  * 
2891  * @param t Tunnel to destroy. 
2892  */
2893 static void
2894 tunnel_destroy_empty (struct MeshTunnel *t)
2895 {
2896   #if MESH_DEBUG
2897   {
2898     struct GNUNET_PeerIdentity id;
2899
2900     GNUNET_PEER_resolve (t->id.oid, &id);
2901     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2902                 "executing destruction of empty tunnel %s [%X]\n",
2903                 GNUNET_i2s (&id), t->id.tid);
2904   }
2905   #endif
2906
2907   if (GNUNET_NO == t->destroy)
2908     tunnel_send_destroy (t);
2909   if (0 == t->pending_messages)
2910     tunnel_destroy (t);
2911   else
2912     t->destroy = GNUNET_YES;
2913 }
2914
2915 /**
2916  * Initialize a Flow Control structure to the initial state.
2917  * 
2918  * @param fc Flow Control structure to initialize.
2919  */
2920 static void
2921 fc_init (struct MeshFlowControl *fc)
2922 {
2923   fc->last_pid_sent = (uint32_t) -1; /* Next (expected) = 0 */
2924   fc->last_pid_recv = (uint32_t) -1;
2925   fc->last_ack_sent = (uint32_t) -1; /* No traffic allowed yet */
2926   fc->last_ack_recv = (uint32_t) -1;
2927   fc->poll_task = GNUNET_SCHEDULER_NO_TASK;
2928   fc->poll_time = GNUNET_TIME_UNIT_SECONDS;
2929   fc->queue_n = 0;
2930 }
2931
2932 /**
2933  * Create a new tunnel
2934  * 
2935  * @param owner Who is the owner of the tunnel (short ID).
2936  * @param tid Tunnel Number of the tunnel.
2937  * @param client Clients that owns the tunnel, NULL for foreign tunnels.
2938  * @param local Tunnel Number for the tunnel, for the client point of view.
2939  * 
2940  * @return A new initialized tunnel. NULL on error.
2941  */
2942 static struct MeshTunnel *
2943 tunnel_new (GNUNET_PEER_Id owner,
2944             MESH_TunnelNumber tid,
2945             struct MeshClient *client,
2946             MESH_TunnelNumber local)
2947 {
2948   struct MeshTunnel *t;
2949   struct GNUNET_HashCode hash;
2950
2951   if (n_tunnels >= max_tunnels && NULL == client)
2952     return NULL;
2953
2954   t = GNUNET_malloc (sizeof (struct MeshTunnel));
2955   t->id.oid = owner;
2956   t->id.tid = tid;
2957   t->queue_max = (max_msgs_queue / max_tunnels) + 1;
2958   t->owner = client;
2959   fc_init (&t->next_fc);
2960   fc_init (&t->prev_fc);
2961   t->local_tid = local;
2962   n_tunnels++;
2963   GNUNET_STATISTICS_update (stats, "# tunnels", 1, GNUNET_NO);
2964
2965   GNUNET_CRYPTO_hash (&t->id, sizeof (struct MESH_TunnelID), &hash);
2966   if (GNUNET_OK !=
2967       GNUNET_CONTAINER_multihashmap_put (tunnels, &hash, t,
2968                                          GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
2969   {
2970     GNUNET_break (0);
2971     tunnel_destroy (t);
2972     if (NULL != client)
2973     {
2974       GNUNET_break (0);
2975       GNUNET_SERVER_receive_done (client->handle, GNUNET_SYSERR);
2976     }
2977     return NULL;
2978   }
2979
2980   if (NULL != client)
2981   {
2982     if (GNUNET_OK !=
2983         GNUNET_CONTAINER_multihashmap32_put (client->own_tunnels,
2984                                              t->local_tid, t,
2985                                              GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
2986     {
2987       tunnel_destroy (t);
2988       GNUNET_break (0);
2989       GNUNET_SERVER_receive_done (client->handle, GNUNET_SYSERR);
2990       return NULL;
2991     }
2992   }
2993
2994   return t;
2995 }
2996
2997
2998 /**
2999  * Set options in a tunnel, extracted from a bit flag field
3000  * 
3001  * @param t Tunnel to set options to.
3002  * @param options Bit array in host byte order.
3003  */
3004 static void
3005 tunnel_set_options (struct MeshTunnel *t, uint32_t options)
3006 {
3007   t->nobuffer = (options & GNUNET_MESH_OPTION_NOBUFFER) != 0 ?
3008                  GNUNET_YES : GNUNET_NO;
3009   t->reliable = (options & GNUNET_MESH_OPTION_RELIABLE) != 0 ?
3010                  GNUNET_YES : GNUNET_NO;
3011 }
3012
3013
3014 /**
3015  * Iterator for deleting each tunnel whose client endpoint disconnected.
3016  *
3017  * @param cls Closure (client that has disconnected).
3018  * @param key The local tunnel id (used to access the hashmap).
3019  * @param value The value stored at the key (tunnel to destroy).
3020  *
3021  * @return GNUNET_OK, keep iterating.
3022  */
3023 static int
3024 tunnel_destroy_iterator (void *cls,
3025                          uint32_t key,
3026                          void *value)
3027 {
3028   struct MeshTunnel *t = value;
3029   struct MeshClient *c = cls;
3030
3031   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3032               " Tunnel %X / %X destroy, due to client %u shutdown.\n",
3033               t->local_tid, t->local_tid_dest, c->id);
3034   client_delete_tunnel (c, t);
3035   if (c == t->client)
3036   {
3037     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " Client %u is destination.\n", c->id);
3038     t->client = NULL;
3039     if (0 != t->next_hop) { /* destroy could come before a path is used */
3040         GNUNET_PEER_change_rc (t->next_hop, -1);
3041         t->next_hop = 0;
3042     }
3043   }
3044   if (c == t->owner)
3045   {
3046     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " Client %u is owner.\n", c->id);
3047     t->owner = NULL;
3048     if (0 != t->prev_hop) { /* destroy could come before a path is used */
3049         GNUNET_PEER_change_rc (t->prev_hop, -1);
3050         t->prev_hop = 0;
3051     }
3052   }
3053
3054   tunnel_destroy_empty (t);
3055
3056   return GNUNET_OK;
3057 }
3058
3059
3060 /**
3061  * Timeout function, destroys tunnel if called
3062  *
3063  * @param cls Closure (tunnel to destroy).
3064  * @param tc TaskContext
3065  */
3066 static void
3067 tunnel_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
3068 {
3069   struct MeshTunnel *t = cls;
3070   struct GNUNET_PeerIdentity id;
3071
3072   t->maintenance_task = GNUNET_SCHEDULER_NO_TASK;
3073   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
3074     return;
3075   GNUNET_PEER_resolve(t->id.oid, &id);
3076   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
3077               "Tunnel %s [%X] timed out. Destroying.\n",
3078               GNUNET_i2s(&id), t->id.tid);
3079   if (NULL != t->client)
3080     send_client_tunnel_destroy (t->client, t);
3081   tunnel_destroy (t); /* Do not notify other */
3082 }
3083
3084
3085 /**
3086  * Resets the tunnel timeout. Starts it if no timeout was running.
3087  *
3088  * @param t Tunnel whose timeout to reset.
3089  *
3090  * TODO use heap to improve efficiency of scheduler.
3091  */
3092 static void
3093 tunnel_reset_timeout (struct MeshTunnel *t)
3094 {
3095   if (NULL != t->owner || 0 != t->local_tid || 0 == t->prev_hop)
3096     return;
3097   if (GNUNET_SCHEDULER_NO_TASK != t->maintenance_task)
3098     GNUNET_SCHEDULER_cancel (t->maintenance_task);
3099   t->maintenance_task =
3100       GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
3101                                     (refresh_path_time, 4), &tunnel_timeout, t);
3102 }
3103
3104
3105 /******************************************************************************/
3106 /****************      MESH NETWORK HANDLER HELPERS     ***********************/
3107 /******************************************************************************/
3108
3109 /**
3110  * Function to send a create path packet to a peer.
3111  *
3112  * @param cls closure
3113  * @param size number of bytes available in buf
3114  * @param buf where the callee should write the message
3115  * @return number of bytes written to buf
3116  */
3117 static size_t
3118 send_core_path_create (void *cls, size_t size, void *buf)
3119 {
3120   struct MeshTunnel *t = cls;
3121   struct GNUNET_MESH_CreateTunnel *msg;
3122   struct GNUNET_PeerIdentity *peer_ptr;
3123   struct MeshPeerPath *p = t->path;
3124   size_t size_needed;
3125   uint32_t opt;
3126   int i;
3127
3128   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CREATE PATH sending...\n");
3129   size_needed =
3130       sizeof (struct GNUNET_MESH_CreateTunnel) +
3131       p->length * sizeof (struct GNUNET_PeerIdentity);
3132
3133   if (size < size_needed || NULL == buf)
3134   {
3135     GNUNET_break (0);
3136     return 0;
3137   }
3138   msg = (struct GNUNET_MESH_CreateTunnel *) buf;
3139   msg->header.size = htons (size_needed);
3140   msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE);
3141   msg->tid = ntohl (t->id.tid);
3142
3143   opt = 0;
3144   if (GNUNET_YES == t->nobuffer)
3145     opt |= GNUNET_MESH_OPTION_NOBUFFER;
3146   if (GNUNET_YES == t->reliable)
3147     opt |= GNUNET_MESH_OPTION_RELIABLE;
3148   msg->opt = htonl (opt);
3149   msg->port = htonl (t->port);
3150
3151   peer_ptr = (struct GNUNET_PeerIdentity *) &msg[1];
3152   for (i = 0; i < p->length; i++)
3153   {
3154     GNUNET_PEER_resolve (p->peers[i], peer_ptr++);
3155   }
3156
3157   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3158               "CREATE PATH (%u bytes long) sent!\n", size_needed);
3159   return size_needed;
3160 }
3161
3162
3163 /**
3164  * Creates a path ack message in buf and frees all unused resources.
3165  *
3166  * @param cls closure (MeshTransmissionDescriptor)
3167  * @param size number of bytes available in buf
3168  * @param buf where the callee should write the message
3169  * @return number of bytes written to buf
3170  */
3171 static size_t
3172 send_core_path_ack (void *cls, size_t size, void *buf)
3173 {
3174   struct MeshTunnel *t = cls;
3175   struct GNUNET_MESH_PathACK *msg = buf;
3176
3177   GNUNET_assert (NULL != t);
3178   if (sizeof (struct GNUNET_MESH_PathACK) > size)
3179   {
3180     GNUNET_break (0);
3181     return 0;
3182   }
3183   t->prev_fc.last_ack_sent = t->nobuffer ? 0 : t->queue_max - 1;
3184   msg->header.size = htons (sizeof (struct GNUNET_MESH_PathACK));
3185   msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_PATH_ACK);
3186   GNUNET_PEER_resolve (t->id.oid, &msg->oid);
3187   msg->tid = htonl (t->id.tid);
3188   msg->peer_id = my_full_id;
3189   msg->ack = htonl (t->prev_fc.last_ack_sent);
3190
3191   /* TODO add signature */
3192
3193   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "PATH ACK sent!\n");
3194   return sizeof (struct GNUNET_MESH_PathACK);
3195 }
3196
3197
3198 /**
3199  * Free a transmission that was already queued with all resources
3200  * associated to the request.
3201  *
3202  * @param queue Queue handler to cancel.
3203  * @param clear_cls Is it necessary to free associated cls?
3204  */
3205 static void
3206 queue_destroy (struct MeshPeerQueue *queue, int clear_cls)
3207 {
3208   struct MeshFlowControl *fc;
3209
3210   if (GNUNET_YES == clear_cls)
3211   {
3212     switch (queue->type)
3213     {
3214       case GNUNET_MESSAGE_TYPE_MESH_TUNNEL_DESTROY:
3215         GNUNET_log (GNUNET_ERROR_TYPE_INFO, "   cancelling TUNNEL_DESTROY\n");
3216         GNUNET_break (GNUNET_YES == queue->tunnel->destroy);
3217         /* fall through */
3218       case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
3219       case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN:
3220       case GNUNET_MESSAGE_TYPE_MESH_ACK:
3221       case GNUNET_MESSAGE_TYPE_MESH_POLL:
3222       case GNUNET_MESSAGE_TYPE_MESH_PATH_KEEPALIVE:
3223         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3224                     "   prebuilt message\n");
3225         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3226                     "   type %s\n",
3227                     GNUNET_MESH_DEBUG_M2S (queue->type));
3228         break;
3229       case GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE:
3230         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   type create path\n");
3231         break;
3232       default:
3233         GNUNET_break (0);
3234         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3235                     "   type %s unknown!\n",
3236                     GNUNET_MESH_DEBUG_M2S (queue->type));
3237     }
3238     GNUNET_free_non_null (queue->cls);
3239   }
3240   GNUNET_CONTAINER_DLL_remove (queue->peer->queue_head,
3241                                queue->peer->queue_tail,
3242                                queue);
3243
3244   /* Delete from appropriate fc in the tunnel */
3245   if (GNUNET_MESSAGE_TYPE_MESH_UNICAST == queue->type ||
3246       GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN == queue->type )
3247   {
3248     if (queue->peer->id == queue->tunnel->prev_hop)
3249       fc = &queue->tunnel->prev_fc;
3250     else if (queue->peer->id == queue->tunnel->next_hop)
3251       fc = &queue->tunnel->next_fc;
3252     else
3253     {
3254       GNUNET_break (0);
3255       GNUNET_free (queue);
3256       return;
3257     }
3258     fc->queue_n--;
3259   }
3260   GNUNET_free (queue);
3261 }
3262
3263
3264 /**
3265  * @brief Get the next transmittable message from the queue.
3266  *
3267  * This will be the head, except in the case of being a data packet
3268  * not allowed by the destination peer.
3269  *
3270  * @param peer Destination peer.
3271  *
3272  * @return The next viable MeshPeerQueue element to send to that peer.
3273  *         NULL when there are no transmittable messages.
3274  */
3275 struct MeshPeerQueue *
3276 queue_get_next (const struct MeshPeerInfo *peer)
3277 {
3278   struct MeshPeerQueue *q;
3279
3280   struct GNUNET_MESH_Data *dmsg;
3281   struct MeshTunnel* t;
3282   uint32_t pid;
3283   uint32_t ack;
3284
3285   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*   selecting message\n");
3286   for (q = peer->queue_head; NULL != q; q = q->next)
3287   {
3288     t = q->tunnel;
3289     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3290                 "*     %s\n",
3291                 GNUNET_MESH_DEBUG_M2S (q->type));
3292     dmsg = (struct GNUNET_MESH_Data *) q->cls;
3293     pid = ntohl (dmsg->pid);
3294     switch (q->type)
3295     {
3296       case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
3297         ack = t->next_fc.last_ack_recv;
3298         break;
3299       case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN:
3300         ack = t->prev_fc.last_ack_recv;
3301         break;
3302       default:
3303         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3304                     "*   OK!\n");
3305         return q;
3306     }
3307     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3308                 "*     ACK: %u, PID: %u, MID: %llu\n",
3309                 ack, pid, GNUNET_ntohll (dmsg->mid));
3310     if (GNUNET_NO == GMC_is_pid_bigger (pid, ack))
3311     {
3312       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3313                   "*   OK!\n");
3314       return q;
3315     }
3316     else
3317     {
3318       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3319                   "*     NEXT!\n");
3320     }
3321   }
3322   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3323                 "*   nothing found\n");
3324   return NULL;
3325 }
3326
3327
3328 static size_t
3329 queue_send (void *cls, size_t size, void *buf)
3330 {
3331   struct MeshPeerInfo *peer = cls;
3332   struct GNUNET_MessageHeader *msg;
3333   struct MeshPeerQueue *queue;
3334   struct MeshTunnel *t;
3335   struct GNUNET_PeerIdentity dst_id;
3336   struct MeshFlowControl *fc;
3337   size_t data_size;
3338   uint32_t pid;
3339   uint16_t type;
3340
3341   peer->core_transmit = NULL;
3342
3343   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "* Queue send\n");
3344   queue = queue_get_next (peer);
3345
3346   /* Queue has no internal mesh traffic nor sendable payload */
3347   if (NULL == queue)
3348   {
3349     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*   not ready, return\n");
3350     if (NULL == peer->queue_head)
3351       GNUNET_break (0); /* Core tmt_rdy should've been canceled */
3352     return 0;
3353   }
3354   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*   not empty\n");
3355
3356   GNUNET_PEER_resolve (peer->id, &dst_id);
3357   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3358               "*   towards %s\n",
3359               GNUNET_i2s (&dst_id));
3360   /* Check if buffer size is enough for the message */
3361   if (queue->size > size)
3362   {
3363       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3364                   "*   not enough room, reissue\n");
3365       peer->core_transmit =
3366           GNUNET_CORE_notify_transmit_ready (core_handle,
3367                                              GNUNET_NO,
3368                                              0,
3369                                              GNUNET_TIME_UNIT_FOREVER_REL,
3370                                              &dst_id,
3371                                              queue->size,
3372                                              &queue_send,
3373                                              peer);
3374       return 0;
3375   }
3376   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*   size ok\n");
3377
3378   t = queue->tunnel;
3379   GNUNET_assert (0 < t->pending_messages);
3380   t->pending_messages--;
3381   type = 0;
3382
3383   /* Fill buf */
3384   switch (queue->type)
3385   {
3386     case 0:
3387     case GNUNET_MESSAGE_TYPE_MESH_ACK:
3388     case GNUNET_MESSAGE_TYPE_MESH_UNICAST_ACK:
3389     case GNUNET_MESSAGE_TYPE_MESH_TO_ORIG_ACK:
3390     case GNUNET_MESSAGE_TYPE_MESH_POLL:
3391     case GNUNET_MESSAGE_TYPE_MESH_PATH_BROKEN:
3392     case GNUNET_MESSAGE_TYPE_MESH_PATH_DESTROY:
3393     case GNUNET_MESSAGE_TYPE_MESH_TUNNEL_DESTROY:
3394     case GNUNET_MESSAGE_TYPE_MESH_PATH_KEEPALIVE:
3395       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3396                   "*   raw: %s\n",
3397                   GNUNET_MESH_DEBUG_M2S (queue->type));
3398       /* Fall through */
3399     case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
3400     case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN:
3401       data_size = send_core_data_raw (queue->cls, size, buf);
3402       msg = (struct GNUNET_MessageHeader *) buf;
3403       type = ntohs (msg->type);
3404       break;
3405     case GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE:
3406       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*   path create\n");
3407       data_size = send_core_path_create (queue->cls, size, buf);
3408       break;
3409     case GNUNET_MESSAGE_TYPE_MESH_PATH_ACK:
3410       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*   path ack\n");
3411       data_size = send_core_path_ack (queue->cls, size, buf);
3412       break;
3413     default:
3414       GNUNET_break (0);
3415       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3416                   "*   type unknown: %u\n",
3417                   queue->type);
3418       data_size = 0;
3419   }
3420
3421   if (0 < drop_percent &&
3422       GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, 101) < drop_percent)
3423   {
3424     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3425                 "Dropping message of type %s\n",
3426                 GNUNET_MESH_DEBUG_M2S(queue->type));
3427     data_size = 0;
3428   }
3429   /* Free queue, but cls was freed by send_core_* */
3430   queue_destroy (queue, GNUNET_NO);
3431
3432   /* Send ACK if needed, after accounting for sent ID in fc->queue_n */
3433   pid = ((struct GNUNET_MESH_Data *) buf)->pid;
3434   pid = ntohl (pid);
3435   switch (type)
3436   {
3437     case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
3438       t->next_fc.last_pid_sent = pid;
3439       tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_UNICAST);
3440       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3441                   "!!! SEND %llu\n",
3442                   GNUNET_ntohll ( ((struct GNUNET_MESH_Data *) buf)->mid ));
3443       break;
3444     case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN:
3445       t->prev_fc.last_pid_sent = pid;
3446       tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN);
3447       break;
3448     default:
3449       break;
3450   }
3451
3452   if (GNUNET_YES == t->destroy && 0 == t->pending_messages)
3453   {
3454     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*  destroying tunnel!\n");
3455     tunnel_destroy (t);
3456   }
3457
3458   /* If more data in queue, send next */
3459   queue = queue_get_next (peer);
3460   if (NULL != queue)
3461   {
3462       struct GNUNET_PeerIdentity id;
3463
3464       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*   more data!\n");
3465       GNUNET_PEER_resolve (peer->id, &id);
3466       peer->core_transmit =
3467           GNUNET_CORE_notify_transmit_ready(core_handle,
3468                                             0,
3469                                             0,
3470                                             GNUNET_TIME_UNIT_FOREVER_REL,
3471                                             &id,
3472                                             queue->size,
3473                                             &queue_send,
3474                                             peer);
3475   }
3476   else if (NULL != peer->queue_head)
3477   {
3478     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
3479                 "*   %s stalled\n",
3480                 GNUNET_i2s (&my_full_id));
3481     if (peer->id == t->next_hop)
3482       fc = &t->next_fc;
3483     else if (peer->id == t->prev_hop)
3484       fc = &t->prev_fc;
3485     else
3486     {
3487       GNUNET_break (0);
3488       return data_size;
3489     }
3490     if (NULL != fc && GNUNET_SCHEDULER_NO_TASK == fc->poll_task)
3491     {
3492       fc->t = t;
3493       fc->poll_task = GNUNET_SCHEDULER_add_delayed (fc->poll_time,
3494                                                     &tunnel_poll, fc);
3495     }
3496   }
3497   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "*  Return %d\n", data_size);
3498   return data_size;
3499 }
3500
3501
3502 /**
3503  * @brief Queue and pass message to core when possible.
3504  * 
3505  * If type is payload (UNICAST, TO_ORIGIN) checks for queue status and
3506  * accounts for it. In case the queue is full, the message is dropped and
3507  * a break issued.
3508  * 
3509  * Otherwise, message is treated as internal and allowed to go regardless of 
3510  * queue status.
3511  *
3512  * @param cls Closure (@c type dependant). It will be used by queue_send to
3513  *            build the message to be sent if not already prebuilt.
3514  * @param type Type of the message, 0 for a raw message.
3515  * @param size Size of the message.
3516  * @param dst Neighbor to send message to.
3517  * @param t Tunnel this message belongs to.
3518  */
3519 static void
3520 queue_add (void *cls, uint16_t type, size_t size,
3521            struct MeshPeerInfo *dst, struct MeshTunnel *t)
3522 {
3523   struct MeshPeerQueue *queue;
3524   struct GNUNET_PeerIdentity id;
3525   struct MeshFlowControl *fc;
3526   int priority;
3527
3528   fc = NULL;
3529   priority = GNUNET_NO;
3530   if (GNUNET_MESSAGE_TYPE_MESH_UNICAST == type)
3531   {
3532     fc = &t->next_fc;
3533   }
3534   else if (GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN == type)
3535   {
3536     fc = &t->prev_fc;
3537   }
3538   if (NULL != fc)
3539   {
3540     if (fc->queue_n >= t->queue_max)
3541     {
3542       /* If this isn't a retransmission, drop the message */
3543       if (GNUNET_NO == t->reliable ||
3544           (NULL == t->owner && GNUNET_MESSAGE_TYPE_MESH_UNICAST == type) ||
3545           (NULL == t->client && GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN == type))
3546       {
3547         GNUNET_STATISTICS_update (stats, "# messages dropped (buffer full)",
3548                                   1, GNUNET_NO);
3549         GNUNET_break (0);
3550         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3551                     "queue full: %u/%u\n",
3552                     fc->queue_n, t->queue_max);
3553         return; /* Drop this message */
3554       }
3555       priority = GNUNET_YES;
3556     }
3557     fc->queue_n++;
3558   }
3559   queue = GNUNET_malloc (sizeof (struct MeshPeerQueue));
3560   queue->cls = cls;
3561   queue->type = type;
3562   queue->size = size;
3563   queue->peer = dst;
3564   queue->tunnel = t;
3565   if (GNUNET_YES == priority)
3566   {
3567     struct GNUNET_MESH_Data *d;
3568     uint32_t prev;
3569     uint32_t next;
3570
3571     GNUNET_CONTAINER_DLL_insert (dst->queue_head, dst->queue_tail, queue);
3572     d = (struct GNUNET_MESH_Data *) queue->cls;
3573     prev = d->pid;
3574     for (queue = dst->queue_tail; NULL != queue; queue = queue->prev)
3575     {
3576       if (queue->type != type)
3577         continue;
3578       d = (struct GNUNET_MESH_Data *) queue->cls;
3579       next = d->pid;
3580       d->pid = prev;
3581       prev = next;
3582     }
3583   }
3584   else
3585     GNUNET_CONTAINER_DLL_insert_tail (dst->queue_head, dst->queue_tail, queue);
3586   if (NULL == dst->core_transmit)
3587   {
3588     GNUNET_PEER_resolve (dst->id, &id);
3589     dst->core_transmit =
3590         GNUNET_CORE_notify_transmit_ready (core_handle,
3591                                            0,
3592                                            0,
3593                                            GNUNET_TIME_UNIT_FOREVER_REL,
3594                                            &id,
3595                                            size,
3596                                            &queue_send,
3597                                            dst);
3598   }
3599   t->pending_messages++;
3600 }
3601
3602
3603 /******************************************************************************/
3604 /********************      MESH NETWORK HANDLERS     **************************/
3605 /******************************************************************************/
3606
3607
3608 /**
3609  * Core handler for path creation
3610  *
3611  * @param cls closure
3612  * @param message message
3613  * @param peer peer identity this notification is about
3614  *
3615  * @return GNUNET_OK to keep the connection open,
3616  *         GNUNET_SYSERR to close it (signal serious error)
3617  */
3618 static int
3619 handle_mesh_path_create (void *cls, const struct GNUNET_PeerIdentity *peer,
3620                          const struct GNUNET_MessageHeader *message)
3621 {
3622   unsigned int own_pos;
3623   uint16_t size;
3624   uint16_t i;
3625   MESH_TunnelNumber tid;
3626   struct GNUNET_MESH_CreateTunnel *msg;
3627   struct GNUNET_PeerIdentity *pi;
3628   struct MeshPeerPath *path;
3629   struct MeshPeerInfo *dest_peer_info;
3630   struct MeshPeerInfo *orig_peer_info;
3631   struct MeshTunnel *t;
3632
3633   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3634               "Received a path create msg [%s]\n",
3635               GNUNET_i2s (&my_full_id));
3636   size = ntohs (message->size);
3637   if (size < sizeof (struct GNUNET_MESH_CreateTunnel))
3638   {
3639     GNUNET_break_op (0);
3640     return GNUNET_OK;
3641   }
3642
3643   size -= sizeof (struct GNUNET_MESH_CreateTunnel);
3644   if (size % sizeof (struct GNUNET_PeerIdentity))
3645   {
3646     GNUNET_break_op (0);
3647     return GNUNET_OK;
3648   }
3649   size /= sizeof (struct GNUNET_PeerIdentity);
3650   if (size < 1)
3651   {
3652     GNUNET_break_op (0);
3653     return GNUNET_OK;
3654   }
3655   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "    path has %u hops.\n", size);
3656   msg = (struct GNUNET_MESH_CreateTunnel *) message;
3657
3658   tid = ntohl (msg->tid);
3659   pi = (struct GNUNET_PeerIdentity *) &msg[1];
3660   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3661               "    path is for tunnel %s[%X].\n", GNUNET_i2s (pi), tid);
3662   t = tunnel_get (pi, tid);
3663   if (NULL == t) /* might be a local tunnel */
3664   {
3665     uint32_t opt;
3666
3667     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  Creating tunnel\n");
3668     t = tunnel_new (GNUNET_PEER_intern (pi), tid, NULL, 0);
3669     if (NULL == t)
3670     {
3671       GNUNET_break (0);
3672       return GNUNET_OK;
3673     }
3674     t->port = ntohl (msg->port);
3675     opt = ntohl (msg->opt);
3676     if (0 != (opt & GNUNET_MESH_OPTION_NOBUFFER))
3677     {
3678       t->nobuffer = GNUNET_YES;
3679       t->queue_max = 1;
3680     }
3681     if (0 != (opt & GNUNET_MESH_OPTION_RELIABLE))
3682     {
3683       t->reliable = GNUNET_YES;
3684     }
3685     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  nobuffer:%d\n", t->nobuffer);
3686
3687     tunnel_reset_timeout (t);
3688   }
3689   t->state = MESH_TUNNEL_WAITING;
3690   dest_peer_info =
3691       GNUNET_CONTAINER_multihashmap_get (peers, &pi[size - 1].hashPubKey);
3692   if (NULL == dest_peer_info)
3693   {
3694     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3695                 "  Creating PeerInfo for destination.\n");
3696     dest_peer_info = GNUNET_malloc (sizeof (struct MeshPeerInfo));
3697     dest_peer_info->id = GNUNET_PEER_intern (&pi[size - 1]);
3698     GNUNET_CONTAINER_multihashmap_put (peers, &pi[size - 1].hashPubKey,
3699                                        dest_peer_info,
3700                                        GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
3701   }
3702   orig_peer_info = GNUNET_CONTAINER_multihashmap_get (peers, &pi->hashPubKey);
3703   if (NULL == orig_peer_info)
3704   {
3705     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3706                 "  Creating PeerInfo for origin.\n");
3707     orig_peer_info = GNUNET_malloc (sizeof (struct MeshPeerInfo));
3708     orig_peer_info->id = GNUNET_PEER_intern (pi);
3709     GNUNET_CONTAINER_multihashmap_put (peers, &pi->hashPubKey, orig_peer_info,
3710                                        GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
3711   }
3712   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  Creating path...\n");
3713   path = path_new (size);
3714   own_pos = 0;
3715   for (i = 0; i < size; i++)
3716   {
3717     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  ... adding %s\n",
3718                 GNUNET_i2s (&pi[i]));
3719     path->peers[i] = GNUNET_PEER_intern (&pi[i]);
3720     if (path->peers[i] == myid)
3721       own_pos = i;
3722   }
3723   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  Own position: %u\n", own_pos);
3724   if (own_pos == 0 && path->peers[own_pos] != myid)
3725   {
3726     /* create path: self not found in path through self */
3727     GNUNET_break_op (0);
3728     path_destroy (path);
3729     tunnel_destroy (t);
3730     return GNUNET_OK;
3731   }
3732   path_add_to_peers (path, GNUNET_NO);
3733   tunnel_use_path (t, path);
3734
3735   peer_info_add_tunnel (dest_peer_info, t);
3736
3737   if (own_pos == size - 1)
3738   {
3739     struct MeshClient *c;
3740
3741     /* Find target client */
3742     c = GNUNET_CONTAINER_multihashmap32_get (ports, t->port);
3743     if (NULL == c)
3744     {
3745       /* TODO send reject */
3746       return GNUNET_OK;
3747     }
3748
3749     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  It's for us!\n");
3750     peer_info_add_path_to_origin (orig_peer_info, path, GNUNET_YES);
3751
3752     /* Assign local tid */
3753     while (NULL != tunnel_get_incoming (next_local_tid))
3754       next_local_tid = (next_local_tid + 1) | GNUNET_MESH_LOCAL_TUNNEL_ID_SERV;
3755     t->local_tid_dest = next_local_tid++;
3756     next_local_tid = next_local_tid | GNUNET_MESH_LOCAL_TUNNEL_ID_SERV;
3757
3758     if (GNUNET_YES == t->reliable)
3759     {
3760       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!! Reliable\n");
3761       t->bck_rel = GNUNET_malloc (sizeof (struct MeshTunnelReliability));
3762       t->bck_rel->t = t;
3763       t->bck_rel->expected_delay = MESH_RETRANSMIT_TIME;
3764     }
3765
3766     tunnel_add_client (t, c);
3767     send_client_tunnel_create (t);
3768     send_path_ack (t);
3769   }
3770   else
3771   {
3772     struct MeshPeerPath *path2;
3773
3774     t->next_hop = path->peers[own_pos + 1];
3775     GNUNET_PEER_change_rc(t->next_hop, 1);
3776
3777     /* It's for somebody else! Retransmit. */
3778     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  Retransmitting.\n");
3779     path2 = path_duplicate (path);
3780     peer_info_add_path (dest_peer_info, path2, GNUNET_NO);
3781     peer_info_add_path_to_origin (orig_peer_info, path, GNUNET_NO);
3782     send_create_path (t);
3783   }
3784   return GNUNET_OK;
3785 }
3786
3787
3788
3789 /**
3790  * Core handler for path ACKs
3791  *
3792  * @param cls closure
3793  * @param message message
3794  * @param peer peer identity this notification is about
3795  *
3796  * @return GNUNET_OK to keep the connection open,
3797  *         GNUNET_SYSERR to close it (signal serious error)
3798  */
3799 static int
3800 handle_mesh_path_ack (void *cls, const struct GNUNET_PeerIdentity *peer,
3801                       const struct GNUNET_MessageHeader *message)
3802 {
3803   struct GNUNET_MESH_PathACK *msg;
3804   struct MeshPeerInfo *peer_info;
3805   struct MeshPeerPath *p;
3806   struct MeshTunnel *t;
3807
3808   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received a path ACK msg [%s]\n",
3809               GNUNET_i2s (&my_full_id));
3810   msg = (struct GNUNET_MESH_PathACK *) message;
3811   t = tunnel_get (&msg->oid, ntohl(msg->tid));
3812   if (NULL == t)
3813   {
3814     /* TODO notify that we don't know the tunnel */
3815     GNUNET_STATISTICS_update (stats, "# control on unknown tunnel", 1, GNUNET_NO);
3816     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  don't know the tunnel %s [%X]!\n",
3817                 GNUNET_i2s (&msg->oid), ntohl(msg->tid));
3818     return GNUNET_OK;
3819   }
3820   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  on tunnel %s [%X]\n",
3821               GNUNET_i2s (&msg->oid), ntohl(msg->tid));
3822
3823   peer_info = peer_get (&msg->peer_id);
3824   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  by peer %s\n",
3825               GNUNET_i2s (&msg->peer_id));
3826   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  via peer %s\n",
3827               GNUNET_i2s (peer));
3828
3829   /* Add path to peers? */
3830   p = t->path;
3831   if (NULL != p)
3832   {
3833     path_add_to_peers (p, GNUNET_YES);
3834   }
3835   else
3836   {
3837     GNUNET_break (0);
3838   }
3839   t->state = MESH_TUNNEL_READY;
3840   t->next_fc.last_ack_recv = (NULL == t->client) ? ntohl (msg->ack) : 0;
3841   t->prev_fc.last_ack_sent = ntohl (msg->ack);
3842
3843   /* Message for us? */
3844   if (0 == memcmp (&msg->oid, &my_full_id, sizeof (struct GNUNET_PeerIdentity)))
3845   {
3846     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  It's for us!\n");
3847     if (NULL == t->owner)
3848     {
3849       GNUNET_break_op (0);
3850       return GNUNET_OK;
3851     }
3852     if (NULL != peer_info->dhtget)
3853     {
3854       GNUNET_DHT_get_stop (peer_info->dhtget);
3855       peer_info->dhtget = NULL;
3856     }
3857     tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_PATH_ACK);
3858     tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_PATH_ACK);
3859     return GNUNET_OK;
3860   }
3861
3862   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3863               "  not for us, retransmitting...\n");
3864   peer_info = peer_get (&msg->oid);
3865   send_prebuilt_message (message, t->prev_hop, t);
3866   return GNUNET_OK;
3867 }
3868
3869
3870 /**
3871  * Core handler for notifications of broken paths
3872  *
3873  * @param cls closure
3874  * @param message message
3875  * @param peer peer identity this notification is about
3876  *
3877  * @return GNUNET_OK to keep the connection open,
3878  *         GNUNET_SYSERR to close it (signal serious error)
3879  */
3880 static int
3881 handle_mesh_path_broken (void *cls, const struct GNUNET_PeerIdentity *peer,
3882                          const struct GNUNET_MessageHeader *message)
3883 {
3884   struct GNUNET_MESH_PathBroken *msg;
3885   struct MeshTunnel *t;
3886
3887   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3888               "Received a PATH BROKEN msg from %s\n", GNUNET_i2s (peer));
3889   msg = (struct GNUNET_MESH_PathBroken *) message;
3890   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  regarding %s\n",
3891               GNUNET_i2s (&msg->peer1));
3892   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  regarding %s\n",
3893               GNUNET_i2s (&msg->peer2));
3894   t = tunnel_get (&msg->oid, ntohl (msg->tid));
3895   if (NULL == t)
3896   {
3897     GNUNET_break_op (0);
3898     return GNUNET_OK;
3899   }
3900   tunnel_notify_connection_broken (t, GNUNET_PEER_search (&msg->peer1),
3901                                    GNUNET_PEER_search (&msg->peer2));
3902   return GNUNET_OK;
3903
3904 }
3905
3906
3907 /**
3908  * Core handler for tunnel destruction
3909  *
3910  * @param cls closure
3911  * @param message message
3912  * @param peer peer identity this notification is about
3913  *
3914  * @return GNUNET_OK to keep the connection open,
3915  *         GNUNET_SYSERR to close it (signal serious error)
3916  */
3917 static int
3918 handle_mesh_tunnel_destroy (void *cls, const struct GNUNET_PeerIdentity *peer,
3919                             const struct GNUNET_MessageHeader *message)
3920 {
3921   struct GNUNET_MESH_TunnelDestroy *msg;
3922   struct MeshTunnel *t;
3923
3924   msg = (struct GNUNET_MESH_TunnelDestroy *) message;
3925   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3926               "Got a TUNNEL DESTROY packet from %s\n",
3927               GNUNET_i2s (peer));
3928   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3929               "  for tunnel %s [%u]\n",
3930               GNUNET_i2s (&msg->oid), ntohl (msg->tid));
3931   t = tunnel_get (&msg->oid, ntohl (msg->tid));
3932   if (NULL == t)
3933   {
3934     /* Probably already got the message from another path,
3935      * destroyed the tunnel and retransmitted to children.
3936      * Safe to ignore.
3937      */
3938     GNUNET_STATISTICS_update (stats, "# control on unknown tunnel",
3939                               1, GNUNET_NO);
3940     return GNUNET_OK;
3941   }
3942   if (t->local_tid_dest >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV)
3943   {
3944     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "INCOMING TUNNEL %X %X\n",
3945                 t->local_tid, t->local_tid_dest);
3946   }
3947   if (GNUNET_PEER_search (peer) == t->prev_hop)
3948   {
3949     // TODO check owner's signature
3950     // TODO add owner's signatue to tunnel for retransmission
3951     peer_cancel_queues (t->prev_hop, t);
3952     GNUNET_PEER_change_rc (t->prev_hop, -1);
3953     t->prev_hop = 0;
3954   }
3955   else if (GNUNET_PEER_search (peer) == t->next_hop)
3956   {
3957     // TODO check dest's signature
3958     // TODO add dest's signatue to tunnel for retransmission
3959     peer_cancel_queues (t->next_hop, t);
3960     GNUNET_PEER_change_rc (t->next_hop, -1);
3961     t->next_hop = 0;
3962   }
3963   else
3964   {
3965     GNUNET_break_op (0);
3966     // TODO check both owner AND destination's signature to see which matches
3967     // TODO restransmit in appropriate direction
3968     return GNUNET_OK;
3969   }
3970   tunnel_destroy_empty (t);
3971
3972   // TODO: add timeout to destroy the tunnel anyway
3973   return GNUNET_OK;
3974 }
3975
3976
3977 /**
3978  * Core handler for mesh network traffic going from the origin to a peer
3979  *
3980  * @param cls closure
3981  * @param peer peer identity this notification is about
3982  * @param message message
3983  * @return GNUNET_OK to keep the connection open,
3984  *         GNUNET_SYSERR to close it (signal serious error)
3985  */
3986 static int
3987 handle_mesh_unicast (void *cls, const struct GNUNET_PeerIdentity *peer,
3988                           const struct GNUNET_MessageHeader *message)
3989 {
3990   struct GNUNET_MESH_Data *msg;
3991   struct MeshTunnel *t;
3992   uint32_t pid;
3993   uint32_t ttl;
3994   size_t size;
3995
3996   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "got a unicast packet from %s\n",
3997               GNUNET_i2s (peer));
3998   /* Check size */
3999   size = ntohs (message->size);
4000   if (size <
4001       sizeof (struct GNUNET_MESH_Data) +
4002       sizeof (struct GNUNET_MessageHeader))
4003   {
4004     GNUNET_break (0);
4005     return GNUNET_OK;
4006   }
4007   msg = (struct GNUNET_MESH_Data *) message;
4008   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " of type %s\n",
4009               GNUNET_MESH_DEBUG_M2S (ntohs (msg[1].header.type)));
4010   /* Check tunnel */
4011   t = tunnel_get (&msg->oid, ntohl (msg->tid));
4012   if (NULL == t)
4013   {
4014     /* TODO notify back: we don't know this tunnel */
4015     GNUNET_STATISTICS_update (stats, "# data on unknown tunnel", 1, GNUNET_NO);
4016     GNUNET_break_op (0);
4017     return GNUNET_OK;
4018   }
4019   pid = ntohl (msg->pid);
4020   if (GMC_is_pid_bigger (pid, t->prev_fc.last_ack_sent))
4021   {
4022     GNUNET_STATISTICS_update (stats, "# unsolicited unicast", 1, GNUNET_NO);
4023     GNUNET_break_op (0);
4024     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4025                 "Received PID %u, (prev %u), ACK %u\n",
4026                 pid, t->prev_fc.last_pid_recv, t->prev_fc.last_ack_sent);
4027     return GNUNET_OK;
4028   }
4029
4030   tunnel_reset_timeout (t);
4031   if (t->dest == myid)
4032   {
4033     /* TODO signature verification */
4034     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4035                 "  it's for us! sending to clients...\n");
4036     GNUNET_STATISTICS_update (stats, "# unicast received", 1, GNUNET_NO);
4037 //     if (GMC_is_pid_bigger(pid, t->prev_fc.last_pid_recv)) FIXME use
4038     if (GMC_is_pid_bigger (pid, t->prev_fc.last_pid_recv))
4039     {
4040       uint64_t mid;
4041
4042       mid = GNUNET_ntohll (msg->mid);
4043       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4044                   " pid %u (%llu) not seen yet\n", pid, mid);
4045       t->prev_fc.last_pid_recv = pid;
4046
4047       if (GNUNET_NO == t->reliable ||
4048           (mid >= t->bck_rel->mid_recv && mid <= t->bck_rel->mid_recv + 64))
4049       {
4050         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4051                     "!!! RECV %llu\n", GNUNET_ntohll(msg->mid));
4052         if (GNUNET_YES == t->reliable)
4053         {
4054           /* Is this the exact next expected messasge? */
4055           if (mid == t->bck_rel->mid_recv)
4056           {
4057             GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "as expected\n");
4058             t->bck_rel->mid_recv++;
4059             tunnel_send_client_ucast (t, msg);
4060             tunnel_send_client_buffered_ucast (t);
4061           }
4062           else
4063           {
4064             GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "save for later\n");
4065             tunnel_add_buffer_ucast (t, msg);
4066           }
4067         }
4068       }
4069       else
4070       {
4071         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4072                     " MID %llu not expected (%llu - %llu), dropping!\n",
4073                     GNUNET_ntohll (msg->mid),
4074                     t->bck_rel->mid_recv, t->bck_rel->mid_recv + 64LL);
4075       }
4076     }
4077     else
4078     {
4079 //       GNUNET_STATISTICS_update (stats, "# duplicate PID", 1, GNUNET_NO);
4080       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4081                   " Pid %u not expected (%u), dropping!\n",
4082                   pid, t->prev_fc.last_pid_recv + 1);
4083     }
4084     tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_UNICAST);
4085     return GNUNET_OK;
4086   }
4087   t->prev_fc.last_pid_recv = pid;
4088   if (0 == t->next_hop)
4089   {
4090     GNUNET_break (0);
4091     return GNUNET_OK;
4092   }
4093   ttl = ntohl (msg->ttl);
4094   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   ttl: %u\n", ttl);
4095   if (ttl == 0)
4096   {
4097     GNUNET_STATISTICS_update (stats, "# TTL drops", 1, GNUNET_NO);
4098     GNUNET_log (GNUNET_ERROR_TYPE_WARNING, " TTL is 0, DROPPING!\n");
4099     tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_ACK);
4100     return GNUNET_OK;
4101   }
4102   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4103               "  not for us, retransmitting...\n");
4104
4105   send_prebuilt_message (message, t->next_hop, t);
4106   GNUNET_STATISTICS_update (stats, "# unicast forwarded", 1, GNUNET_NO);
4107   return GNUNET_OK;
4108 }
4109
4110
4111 /**
4112  * Core handler for mesh network traffic toward the owner of a tunnel
4113  *
4114  * @param cls closure
4115  * @param message message
4116  * @param peer peer identity this notification is about
4117  *
4118  * @return GNUNET_OK to keep the connection open,
4119  *         GNUNET_SYSERR to close it (signal serious error)
4120  */
4121 static int
4122 handle_mesh_to_orig (void *cls, const struct GNUNET_PeerIdentity *peer,
4123                           const struct GNUNET_MessageHeader *message)
4124 {
4125   struct GNUNET_MESH_Data *msg;
4126   struct MeshTunnel *t;
4127   size_t size;
4128   uint32_t pid;
4129   uint32_t ttl;
4130
4131   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "got a ToOrigin packet from %s\n",
4132               GNUNET_i2s (peer));
4133   size = ntohs (message->size);
4134   if (size < sizeof (struct GNUNET_MESH_Data) +     /* Payload must be */
4135       sizeof (struct GNUNET_MessageHeader))     /* at least a header */
4136   {
4137     GNUNET_break_op (0);
4138     return GNUNET_OK;
4139   }
4140   msg = (struct GNUNET_MESH_Data *) message;
4141   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " of type %s\n",
4142               GNUNET_MESH_DEBUG_M2S (ntohs (msg[1].header.type)));
4143   t = tunnel_get (&msg->oid, ntohl (msg->tid));
4144   pid = ntohl (msg->pid);
4145   if (NULL == t)
4146   {
4147     /* TODO notify that we dont know this tunnel (whom)? */
4148     GNUNET_STATISTICS_update (stats, "# data on unknown tunnel", 1, GNUNET_NO);
4149     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4150                 "Received to_origin with PID %u on unknown tunnel %s [%u]\n",
4151                 pid, GNUNET_i2s (&msg->oid), ntohl (msg->tid));
4152     return GNUNET_OK;
4153   }
4154
4155   if (GMC_is_pid_bigger (pid, t->next_fc.last_ack_sent))
4156   {
4157     GNUNET_STATISTICS_update (stats, "# unsolicited to_orig", 1, GNUNET_NO);
4158     GNUNET_break_op (0);
4159     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4160                 "Received PID %u, ACK %u\n",
4161                 pid, t->next_fc.last_ack_sent);
4162     tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_POLL);
4163     return GNUNET_OK;
4164   }
4165
4166   if (myid == t->id.oid)
4167   {
4168     /* TODO signature verification */
4169     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4170                 "  it's for us! sending to clients...\n");
4171     GNUNET_STATISTICS_update (stats, "# to origin received", 1, GNUNET_NO);
4172     if ( (GNUNET_NO == t->reliable &&
4173           GMC_is_pid_bigger(pid, t->next_fc.last_pid_recv))
4174         ||
4175           (GNUNET_YES == t->reliable &&
4176            pid == t->next_fc.last_pid_recv + 1) ) // FIXME use "futures" as accepting
4177     {
4178       t->next_fc.last_pid_recv = pid;
4179       tunnel_send_client_to_orig (t, msg);
4180     }
4181     else
4182     {
4183 //       GNUNET_STATISTICS_update (stats, "# duplicate PID drops BCK", 1, GNUNET_NO);
4184       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
4185                   " Pid %u not expected, sending FWD ACK!\n", pid);
4186     }
4187     tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN);
4188     return GNUNET_OK;
4189   }
4190   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4191               "  not for us, retransmitting...\n");
4192   t->next_fc.last_pid_recv = pid;
4193   if (0 == t->prev_hop) /* No owner AND no prev hop */
4194   {
4195     if (GNUNET_YES == t->destroy)
4196     {
4197       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4198                   "to orig received on a dying tunnel %s [%X]\n",
4199                   GNUNET_i2s (&msg->oid), ntohl(msg->tid));
4200       return GNUNET_OK;
4201     }
4202     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 
4203                 "unknown to origin at %s\n",
4204                 GNUNET_i2s (&my_full_id));
4205     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 
4206                 "from peer %s\n",
4207                 GNUNET_i2s (peer));
4208     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 
4209                 "on tunnel %s [%X]\n",
4210                 GNUNET_i2s (&msg->oid), ntohl(msg->tid));
4211     return GNUNET_OK;
4212   }
4213   ttl = ntohl (msg->ttl);
4214   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   ttl: %u\n", ttl);
4215   if (ttl == 0)
4216   {
4217     GNUNET_STATISTICS_update (stats, "# TTL drops", 1, GNUNET_NO);
4218     GNUNET_log (GNUNET_ERROR_TYPE_WARNING, " TTL is 0, DROPPING!\n");
4219     tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_ACK);
4220     return GNUNET_OK;
4221   }
4222   send_prebuilt_message (message, t->prev_hop, t);
4223   GNUNET_STATISTICS_update (stats, "# to origin forwarded", 1, GNUNET_NO);
4224
4225   return GNUNET_OK;
4226 }
4227
4228
4229 /**
4230  * Core handler for mesh network traffic end-to-end ACKs.
4231  *
4232  * @param cls Closure.
4233  * @param message Message.
4234  * @param peer Peer identity this notification is about.
4235  *
4236  * @return GNUNET_OK to keep the connection open,
4237  *         GNUNET_SYSERR to close it (signal serious error)
4238  */
4239 static int
4240 handle_mesh_data_ack (void *cls, const struct GNUNET_PeerIdentity *peer,
4241                       const struct GNUNET_MessageHeader *message)
4242 {
4243   struct GNUNET_MESH_DataACK *msg;
4244   struct MeshTunnelReliability *rel;
4245   struct MeshReliableMessage *copy;
4246   struct MeshReliableMessage *next;
4247   struct MeshTunnel *t;
4248   GNUNET_PEER_Id id;
4249   uint64_t ack;
4250   uint16_t type;
4251   int work;
4252
4253   type = ntohs (message->type);
4254   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got a %s message from %s!\n",
4255               GNUNET_MESH_DEBUG_M2S (type), GNUNET_i2s (peer));
4256   msg = (struct GNUNET_MESH_DataACK *) message;
4257
4258   t = tunnel_get (&msg->oid, ntohl (msg->tid));
4259   if (NULL == t)
4260   {
4261     /* TODO notify that we dont know this tunnel (whom)? */
4262     GNUNET_STATISTICS_update (stats, "# ack on unknown tunnel", 1, GNUNET_NO);
4263     return GNUNET_OK;
4264   }
4265   ack = GNUNET_ntohll (msg->mid);
4266   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  ACK %llu\n", ack);
4267
4268   /* Is this a forward or backward ACK? */
4269   id = GNUNET_PEER_search (peer);
4270   if (t->next_hop == id && GNUNET_MESSAGE_TYPE_MESH_UNICAST_ACK == type)
4271   {
4272     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  FWD ACK\n");
4273     if (NULL == t->owner)
4274     {
4275       send_prebuilt_message (message, t->prev_hop, t);
4276       return GNUNET_OK;
4277     }
4278     rel = t->fwd_rel;
4279     tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_UNICAST);
4280   }
4281   else if (t->prev_hop == id && GNUNET_MESSAGE_TYPE_MESH_TO_ORIG_ACK == type)
4282   {
4283     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  BCK ACK\n");
4284     if (NULL == t->client)
4285     {
4286       send_prebuilt_message (message, t->next_hop, t);
4287       return GNUNET_OK;
4288     }
4289     rel = t->bck_rel;
4290     tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN);
4291   }
4292   else
4293   {
4294     GNUNET_break_op (0);
4295     return GNUNET_OK;
4296   }
4297
4298   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!! ACK %llu\n", ack);
4299   for (work = GNUNET_NO, copy = rel->head_sent; copy != NULL; copy = next)
4300   {
4301    if (copy->mid > ack)
4302     {
4303       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!!  head %llu, out!\n", copy->mid);
4304       tunnel_free_buffer_ucast (t, msg);
4305       break;
4306     }
4307     work = GNUNET_YES;
4308     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!!  id %llu\n", copy->mid);
4309     next = copy->next;
4310     tunnel_free_reliable_message (copy);
4311   }
4312
4313   if (GNUNET_YES == work)
4314   {
4315     if (GNUNET_SCHEDULER_NO_TASK != rel->retry_task)
4316     {
4317       GNUNET_SCHEDULER_cancel (rel->retry_task);
4318       if (NULL == rel->head_sent)
4319       {
4320         rel->retry_task = GNUNET_SCHEDULER_NO_TASK;
4321       }
4322       else
4323       {
4324         struct GNUNET_TIME_Absolute new_target;
4325         struct GNUNET_TIME_Relative delay;
4326
4327         delay = GNUNET_TIME_relative_multiply (rel->retry_timer,
4328                                                MESH_RETRANSMIT_MARGIN);
4329         new_target = GNUNET_TIME_absolute_add (rel->head_sent->timestamp,
4330                                                delay);
4331         delay = GNUNET_TIME_absolute_get_remaining (new_target);
4332         rel->retry_task =
4333             GNUNET_SCHEDULER_add_delayed (delay,
4334                                           &tunnel_retransmit_message,
4335                                           rel);
4336       }
4337     }
4338     else
4339       GNUNET_break (0);
4340     tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_UNICAST_ACK);
4341   }
4342   return GNUNET_OK;
4343 }
4344
4345 /**
4346  * Core handler for mesh network traffic point-to-point acks.
4347  *
4348  * @param cls closure
4349  * @param message message
4350  * @param peer peer identity this notification is about
4351  *
4352  * @return GNUNET_OK to keep the connection open,
4353  *         GNUNET_SYSERR to close it (signal serious error)
4354  */
4355 static int
4356 handle_mesh_ack (void *cls, const struct GNUNET_PeerIdentity *peer,
4357                  const struct GNUNET_MessageHeader *message)
4358 {
4359   struct GNUNET_MESH_ACK *msg;
4360   struct MeshTunnel *t;
4361   struct MeshFlowControl *fc;
4362   GNUNET_PEER_Id id;
4363   uint32_t ack;
4364
4365   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got an ACK packet from %s!\n",
4366               GNUNET_i2s (peer));
4367   msg = (struct GNUNET_MESH_ACK *) message;
4368
4369   t = tunnel_get (&msg->oid, ntohl (msg->tid));
4370
4371   if (NULL == t)
4372   {
4373     /* TODO notify that we dont know this tunnel (whom)? */
4374     GNUNET_STATISTICS_update (stats, "# ack on unknown tunnel", 1, GNUNET_NO);
4375     return GNUNET_OK;
4376   }
4377   ack = ntohl (msg->pid);
4378   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  ACK %u\n", ack);
4379
4380   /* Is this a forward or backward ACK? */
4381   id = GNUNET_PEER_search (peer);
4382   if (t->next_hop == id)
4383   {
4384     debug_fwd_ack++;
4385     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  FWD ACK\n");
4386     fc = &t->next_fc;
4387   }
4388   else if (t->prev_hop == id)
4389   {
4390     debug_bck_ack++;
4391     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  BCK ACK\n");
4392     fc = &t->prev_fc;
4393   }
4394   else
4395   {
4396     GNUNET_break_op (0);
4397     return GNUNET_OK;
4398   }
4399
4400   if (GNUNET_SCHEDULER_NO_TASK != fc->poll_task &&
4401       GMC_is_pid_bigger (ack, fc->last_ack_recv))
4402   {
4403     GNUNET_SCHEDULER_cancel (fc->poll_task);
4404     fc->poll_task = GNUNET_SCHEDULER_NO_TASK;
4405     fc->poll_time = GNUNET_TIME_UNIT_SECONDS;
4406   }
4407   fc->last_ack_recv = ack;
4408   peer_unlock_queue (id);
4409
4410   if (t->next_hop == id)
4411     tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_ACK);
4412   else
4413     tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_ACK);
4414
4415   return GNUNET_OK;
4416 }
4417
4418
4419 /**
4420  * Core handler for mesh network traffic point-to-point ack polls.
4421  *
4422  * @param cls closure
4423  * @param message message
4424  * @param peer peer identity this notification is about
4425  *
4426  * @return GNUNET_OK to keep the connection open,
4427  *         GNUNET_SYSERR to close it (signal serious error)
4428  */
4429 static int
4430 handle_mesh_poll (void *cls, const struct GNUNET_PeerIdentity *peer,
4431                   const struct GNUNET_MessageHeader *message)
4432 {
4433   struct GNUNET_MESH_Poll *msg;
4434   struct MeshTunnel *t;
4435   struct MeshFlowControl *fc;
4436   GNUNET_PEER_Id id;
4437   uint32_t pid;
4438   uint32_t old;
4439
4440   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got an POLL packet from %s!\n",
4441               GNUNET_i2s (peer));
4442
4443   msg = (struct GNUNET_MESH_Poll *) message;
4444
4445   t = tunnel_get (&msg->oid, ntohl (msg->tid));
4446
4447   if (NULL == t)
4448   {
4449     /* TODO notify that we dont know this tunnel (whom)? */
4450     GNUNET_STATISTICS_update (stats, "# poll on unknown tunnel", 1, GNUNET_NO);
4451     GNUNET_break_op (0);
4452     return GNUNET_OK;
4453   }
4454
4455   /* Is this a forward or backward ACK? */
4456   id = GNUNET_PEER_search(peer);
4457   pid = ntohl (msg->pid);
4458   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  PID %u\n", pid);
4459   if (t->next_hop == id)
4460   {
4461     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  from FWD\n");
4462     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  was %u\n", t->next_fc.last_pid_recv);
4463     fc = &t->next_fc;
4464     old = fc->last_pid_recv;
4465     fc->last_pid_recv = pid;
4466     tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_POLL);
4467   }
4468   else if (t->prev_hop == id)
4469   {
4470     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  from BCK\n");
4471     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  was %u\n", t->prev_fc.last_pid_recv);
4472     fc = &t->prev_fc;
4473     old = fc->last_pid_recv;
4474     fc->last_pid_recv = pid;
4475     tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_POLL);
4476   }
4477   else
4478     GNUNET_break (0);
4479   
4480   if (GNUNET_YES == t->reliable)
4481     fc->last_pid_recv = old;
4482
4483   return GNUNET_OK;
4484 }
4485
4486
4487 /**
4488  * Core handler for mesh keepalives.
4489  *
4490  * @param cls closure
4491  * @param message message
4492  * @param peer peer identity this notification is about
4493  * @return GNUNET_OK to keep the connection open,
4494  *         GNUNET_SYSERR to close it (signal serious error)
4495  *
4496  * TODO: Check who we got this from, to validate route.
4497  */
4498 static int
4499 handle_mesh_keepalive (void *cls, const struct GNUNET_PeerIdentity *peer,
4500                        const struct GNUNET_MessageHeader *message)
4501 {
4502   struct GNUNET_MESH_TunnelKeepAlive *msg;
4503   struct MeshTunnel *t;
4504
4505   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "got a keepalive packet from %s\n",
4506               GNUNET_i2s (peer));
4507
4508   msg = (struct GNUNET_MESH_TunnelKeepAlive *) message;
4509   t = tunnel_get (&msg->oid, ntohl (msg->tid));
4510
4511   if (NULL == t)
4512   {
4513     /* TODO notify that we dont know that tunnel */
4514     GNUNET_STATISTICS_update (stats, "# keepalive on unknown tunnel", 1,
4515                               GNUNET_NO);
4516     return GNUNET_OK;
4517   }
4518
4519   tunnel_reset_timeout (t);
4520   if (NULL != t->client || 0 == t->next_hop || myid == t->next_hop)
4521     return GNUNET_OK;
4522
4523   GNUNET_STATISTICS_update (stats, "# keepalives forwarded", 1, GNUNET_NO);
4524   send_prebuilt_message (message, t->next_hop, t);
4525   return GNUNET_OK;
4526   }
4527
4528
4529
4530 /**
4531  * Functions to handle messages from core
4532  */
4533 static struct GNUNET_CORE_MessageHandler core_handlers[] = {
4534   {&handle_mesh_path_create, GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE, 0},
4535   {&handle_mesh_path_broken, GNUNET_MESSAGE_TYPE_MESH_PATH_BROKEN,
4536    sizeof (struct GNUNET_MESH_PathBroken)},
4537   {&handle_mesh_tunnel_destroy, GNUNET_MESSAGE_TYPE_MESH_TUNNEL_DESTROY,
4538    sizeof (struct GNUNET_MESH_TunnelDestroy)},
4539   {&handle_mesh_unicast, GNUNET_MESSAGE_TYPE_MESH_UNICAST, 0},
4540   {&handle_mesh_to_orig, GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN, 0},
4541   {&handle_mesh_data_ack, GNUNET_MESSAGE_TYPE_MESH_UNICAST_ACK,
4542     sizeof (struct GNUNET_MESH_DataACK)},
4543   {&handle_mesh_data_ack, GNUNET_MESSAGE_TYPE_MESH_TO_ORIG_ACK,
4544     sizeof (struct GNUNET_MESH_DataACK)},
4545   {&handle_mesh_keepalive, GNUNET_MESSAGE_TYPE_MESH_PATH_KEEPALIVE,
4546     sizeof (struct GNUNET_MESH_TunnelKeepAlive)},
4547   {&handle_mesh_ack, GNUNET_MESSAGE_TYPE_MESH_ACK,
4548     sizeof (struct GNUNET_MESH_ACK)},
4549   {&handle_mesh_poll, GNUNET_MESSAGE_TYPE_MESH_POLL,
4550     sizeof (struct GNUNET_MESH_Poll)},
4551   {&handle_mesh_path_ack, GNUNET_MESSAGE_TYPE_MESH_PATH_ACK,
4552    sizeof (struct GNUNET_MESH_PathACK)},
4553   {NULL, 0, 0}
4554 };
4555
4556
4557
4558 /******************************************************************************/
4559 /****************       MESH LOCAL HANDLER HELPERS      ***********************/
4560 /******************************************************************************/
4561
4562
4563 #if LATER
4564 /**
4565  * notify_client_connection_failure: notify a client that the connection to the
4566  * requested remote peer is not possible (for instance, no route found)
4567  * Function called when the socket is ready to queue more data. "buf" will be
4568  * NULL and "size" zero if the socket was closed for writing in the meantime.
4569  *
4570  * @param cls closure
4571  * @param size number of bytes available in buf
4572  * @param buf where the callee should write the message
4573  * @return number of bytes written to buf
4574  */
4575 static size_t
4576 notify_client_connection_failure (void *cls, size_t size, void *buf)
4577 {
4578   int size_needed;
4579   struct MeshPeerInfo *peer_info;
4580   struct GNUNET_MESH_PeerControl *msg;
4581   struct GNUNET_PeerIdentity id;
4582
4583   if (0 == size && NULL == buf)
4584   {
4585     // TODO retry? cancel?
4586     return 0;
4587   }
4588
4589   size_needed = sizeof (struct GNUNET_MESH_PeerControl);
4590   peer_info = (struct MeshPeerInfo *) cls;
4591   msg = (struct GNUNET_MESH_PeerControl *) buf;
4592   msg->header.size = htons (sizeof (struct GNUNET_MESH_PeerControl));
4593   msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_DISCONNECTED);
4594 //     msg->tunnel_id = htonl(peer_info->t->tid);
4595   GNUNET_PEER_resolve (peer_info->id, &id);
4596   memcpy (&msg->peer, &id, sizeof (struct GNUNET_PeerIdentity));
4597
4598   return size_needed;
4599 }
4600 #endif
4601
4602
4603 /**
4604  * Send keepalive packets for a tunnel.
4605  *
4606  * @param cls Closure (tunnel for which to send the keepalive).
4607  * @param tc Notification context.
4608  * 
4609  * FIXME: add a refresh reset in case of normal unicast traffic is doing the job
4610  */
4611 static void
4612 path_refresh (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
4613 {
4614   struct MeshTunnel *t = cls;
4615   struct GNUNET_MESH_TunnelKeepAlive *msg;
4616   size_t size = sizeof (struct GNUNET_MESH_TunnelKeepAlive);
4617   char cbuf[size];
4618
4619   t->maintenance_task = GNUNET_SCHEDULER_NO_TASK;
4620   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) ||
4621       NULL == t->owner || 0 == t->local_tid)
4622   {
4623     return;
4624   }
4625
4626   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4627               "sending keepalive for tunnel %d\n", t->id.tid);
4628
4629   msg = (struct GNUNET_MESH_TunnelKeepAlive *) cbuf;
4630   msg->header.size = htons (size);
4631   msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_PATH_KEEPALIVE);
4632   msg->oid = my_full_id;
4633   msg->tid = htonl (t->id.tid);
4634   send_prebuilt_message (&msg->header, t->next_hop, t);
4635
4636   t->maintenance_task =
4637       GNUNET_SCHEDULER_add_delayed (refresh_path_time, &path_refresh, t);
4638 }
4639
4640
4641 /**
4642  * Function to process paths received for a new peer addition. The recorded
4643  * paths form the initial tunnel, which can be optimized later.
4644  * Called on each result obtained for the DHT search.
4645  *
4646  * @param cls closure
4647  * @param exp when will this value expire
4648  * @param key key of the result
4649  * @param get_path path of the get request
4650  * @param get_path_length lenght of get_path
4651  * @param put_path path of the put request
4652  * @param put_path_length length of the put_path
4653  * @param type type of the result
4654  * @param size number of bytes in data
4655  * @param data pointer to the result data
4656  */
4657 static void
4658 dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp,
4659                     const struct GNUNET_HashCode * key,
4660                     const struct GNUNET_PeerIdentity *get_path,
4661                     unsigned int get_path_length,
4662                     const struct GNUNET_PeerIdentity *put_path,
4663                     unsigned int put_path_length, enum GNUNET_BLOCK_Type type,
4664                     size_t size, const void *data)
4665 {
4666   struct MeshPeerInfo *peer = cls;
4667   struct MeshPeerPath *p;
4668   struct GNUNET_PeerIdentity pi;
4669   int i;
4670
4671   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got results from DHT!\n");
4672   GNUNET_PEER_resolve (peer->id, &pi);
4673   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  for %s\n", GNUNET_i2s (&pi));
4674
4675   p = path_build_from_dht (get_path, get_path_length,
4676                            put_path, put_path_length);
4677   path_add_to_peers (p, GNUNET_NO);
4678   path_destroy (p);
4679   for (i = 0; i < peer->ntunnels; i++)
4680   {
4681     struct GNUNET_PeerIdentity id;
4682
4683     GNUNET_PEER_resolve (peer->tunnels[i]->id.oid, &id);
4684     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " ... tunnel %s:%X (%X / %X)\n",
4685                 GNUNET_i2s (&id), peer->tunnels[i]->id.tid,
4686                 peer->tunnels[i]->local_tid, 
4687                 peer->tunnels[i]->local_tid_dest);
4688     if (peer->tunnels[i]->state == MESH_TUNNEL_SEARCHING)
4689     {
4690       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " ... connect!\n");
4691       peer_connect (peer, peer->tunnels[i]);
4692     }
4693   }
4694
4695   return;
4696 }
4697
4698
4699 /******************************************************************************/
4700 /*********************       MESH LOCAL HANDLES      **************************/
4701 /******************************************************************************/
4702
4703
4704 /**
4705  * Handler for client connection.
4706  *
4707  * @param cls Closure (unused).
4708  * @param client Client handler.
4709  */
4710 static void
4711 handle_local_client_connect (void *cls, struct GNUNET_SERVER_Client *client)
4712 {
4713   struct MeshClient *c;
4714
4715   if (NULL == client)
4716     return;
4717   c = GNUNET_malloc (sizeof (struct MeshClient));
4718   c->handle = client;
4719   GNUNET_SERVER_client_keep (client);
4720   GNUNET_SERVER_client_set_user_context (client, c);
4721   GNUNET_CONTAINER_DLL_insert (clients_head, clients_tail, c);
4722 }
4723
4724
4725 /**
4726  * Handler for client disconnection
4727  *
4728  * @param cls closure
4729  * @param client identification of the client; NULL
4730  *        for the last call when the server is destroyed
4731  */
4732 static void
4733 handle_local_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
4734 {
4735   struct MeshClient *c;
4736   struct MeshClient *next;
4737
4738   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "client disconnected: %p\n", client);
4739   if (client == NULL)
4740   {
4741     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "   (SERVER DOWN)\n");
4742     return;
4743   }
4744
4745   c = client_get (client);
4746   if (NULL != c)
4747   {
4748     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "matching client found (%u)\n",
4749                 c->id);
4750     GNUNET_SERVER_client_drop (c->handle);
4751     c->shutting_down = GNUNET_YES;
4752     if (NULL != c->own_tunnels)
4753     {
4754       GNUNET_CONTAINER_multihashmap32_iterate (c->own_tunnels,
4755                                                &tunnel_destroy_iterator, c);
4756       GNUNET_CONTAINER_multihashmap32_destroy (c->own_tunnels);
4757     }
4758
4759     if (NULL != c->incoming_tunnels)
4760     {
4761       GNUNET_CONTAINER_multihashmap32_iterate (c->incoming_tunnels,
4762                                              &tunnel_destroy_iterator, c);
4763       GNUNET_CONTAINER_multihashmap32_destroy (c->incoming_tunnels);
4764     }
4765
4766     if (NULL != c->ports)
4767       GNUNET_CONTAINER_multihashmap32_destroy (c->ports);
4768     next = c->next;
4769     GNUNET_CONTAINER_DLL_remove (clients_head, clients_tail, c);
4770     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  CLIENT FREE at %p\n", c);
4771     GNUNET_free (c);
4772     GNUNET_STATISTICS_update (stats, "# clients", -1, GNUNET_NO);
4773     c = next;
4774   }
4775   else
4776   {
4777     GNUNET_log (GNUNET_ERROR_TYPE_WARNING, " context NULL!\n");
4778   }
4779   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "done!\n");
4780   return;
4781 }
4782
4783
4784 /**
4785  * Handler for new clients
4786  *
4787  * @param cls closure
4788  * @param client identification of the client
4789  * @param message the actual message, which includes messages the client wants
4790  */
4791 static void
4792 handle_local_new_client (void *cls, struct GNUNET_SERVER_Client *client,
4793                          const struct GNUNET_MessageHeader *message)
4794 {
4795   struct GNUNET_MESH_ClientConnect *cc_msg;
4796   struct MeshClient *c;
4797   unsigned int size;
4798   uint32_t *p;
4799   unsigned int i;
4800
4801   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "new client connected %p\n", client);
4802
4803   /* Check data sanity */
4804   size = ntohs (message->size) - sizeof (struct GNUNET_MESH_ClientConnect);
4805   cc_msg = (struct GNUNET_MESH_ClientConnect *) message;
4806   if (0 != (size % sizeof (uint32_t)))
4807   {
4808     GNUNET_break (0);
4809     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
4810     return;
4811   }
4812   size /= sizeof (uint32_t);
4813
4814   /* Initialize new client structure */
4815   c = GNUNET_SERVER_client_get_user_context (client, struct MeshClient);
4816   c->id = next_client_id++; /* overflow not important: just for debug */
4817   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  client id %u\n", c->id);
4818   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  client has %u ports\n", size);
4819   if (size > 0)
4820   {
4821     uint32_t u32;
4822
4823     p = (uint32_t *) &cc_msg[1];
4824     c->ports = GNUNET_CONTAINER_multihashmap32_create (size);
4825     for (i = 0; i < size; i++)
4826     {
4827       u32 = ntohl (p[i]);
4828       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "    port: %u\n", u32);
4829
4830       /* store in client's hashmap */
4831       GNUNET_CONTAINER_multihashmap32_put (c->ports, u32, c,
4832                                            GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
4833       /* store in global hashmap */
4834       /* FIXME only allow one client to have the port open,
4835        *       have a backup hashmap with waiting clients */
4836       GNUNET_CONTAINER_multihashmap32_put (ports, u32, c,
4837                                            GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
4838     }
4839   }
4840
4841   c->own_tunnels = GNUNET_CONTAINER_multihashmap32_create (32);
4842   c->incoming_tunnels = GNUNET_CONTAINER_multihashmap32_create (32);
4843   GNUNET_SERVER_notification_context_add (nc, client);
4844   GNUNET_STATISTICS_update (stats, "# clients", 1, GNUNET_NO);
4845
4846   GNUNET_SERVER_receive_done (client, GNUNET_OK);
4847   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "new client processed\n");
4848 }
4849
4850
4851 /**
4852  * Handler for requests of new tunnels
4853  *
4854  * @param cls Closure.
4855  * @param client Identification of the client.
4856  * @param message The actual message.
4857  */
4858 static void
4859 handle_local_tunnel_create (void *cls, struct GNUNET_SERVER_Client *client,
4860                             const struct GNUNET_MessageHeader *message)
4861 {
4862   struct GNUNET_MESH_TunnelMessage *t_msg;
4863   struct MeshPeerInfo *peer_info;
4864   struct MeshTunnel *t;
4865   struct MeshClient *c;
4866   MESH_TunnelNumber tid;
4867
4868   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "new tunnel requested\n");
4869
4870   /* Sanity check for client registration */
4871   if (NULL == (c = client_get (client)))
4872   {
4873     GNUNET_break (0);
4874     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
4875     return;
4876   }
4877   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  by client %u\n", c->id);
4878
4879   /* Message size sanity check */
4880   if (sizeof (struct GNUNET_MESH_TunnelMessage) != ntohs (message->size))
4881   {
4882     GNUNET_break (0);
4883     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
4884     return;
4885   }
4886
4887   t_msg = (struct GNUNET_MESH_TunnelMessage *) message;
4888   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  towards %s\n",
4889               GNUNET_i2s (&t_msg->peer));
4890   /* Sanity check for tunnel numbering */
4891   tid = ntohl (t_msg->tunnel_id);
4892   if (0 == (tid & GNUNET_MESH_LOCAL_TUNNEL_ID_CLI))
4893   {
4894     GNUNET_break (0);
4895     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
4896     return;
4897   }
4898   /* Sanity check for duplicate tunnel IDs */
4899   if (NULL != tunnel_get_by_local_id (c, tid))
4900   {
4901     GNUNET_break (0);
4902     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
4903     return;
4904   }
4905
4906   /* Create tunnel */
4907   while (NULL != tunnel_get_by_pi (myid, next_tid))
4908     next_tid = (next_tid + 1) & ~GNUNET_MESH_LOCAL_TUNNEL_ID_CLI;
4909   t = tunnel_new (myid, next_tid, c, tid);
4910   next_tid = (next_tid + 1) & ~GNUNET_MESH_LOCAL_TUNNEL_ID_CLI;
4911   if (NULL == t)
4912   {
4913     GNUNET_break (0);
4914     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
4915     return;
4916   }
4917   t->port = ntohl (t_msg->port);
4918   tunnel_set_options (t, ntohl (t_msg->opt));
4919   if (GNUNET_YES == t->reliable)
4920   {
4921     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!! Reliable\n");
4922     t->fwd_rel = GNUNET_malloc (sizeof (struct MeshTunnelReliability));
4923     t->fwd_rel->t = t;
4924     t->fwd_rel->expected_delay = MESH_RETRANSMIT_TIME;
4925   }
4926
4927   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CREATED TUNNEL %s[%x]:%u (%x)\n",
4928               GNUNET_i2s (&my_full_id), t->id.tid, t->port, t->local_tid);
4929
4930   peer_info = peer_get (&t_msg->peer);
4931   peer_info_add_tunnel (peer_info, t);
4932   peer_connect (peer_info, t);
4933   GNUNET_SERVER_receive_done (client, GNUNET_OK);
4934   return;
4935 }
4936
4937
4938 /**
4939  * Handler for requests of deleting tunnels
4940  *
4941  * @param cls closure
4942  * @param client identification of the client
4943  * @param message the actual message
4944  */
4945 static void
4946 handle_local_tunnel_destroy (void *cls, struct GNUNET_SERVER_Client *client,
4947                              const struct GNUNET_MessageHeader *message)
4948 {
4949   struct GNUNET_MESH_TunnelMessage *tunnel_msg;
4950   struct MeshClient *c;
4951   struct MeshTunnel *t;
4952   MESH_TunnelNumber tid;
4953
4954   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4955               "Got a DESTROY TUNNEL from client!\n");
4956
4957   /* Sanity check for client registration */
4958   if (NULL == (c = client_get (client)))
4959   {
4960     GNUNET_break (0);
4961     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
4962     return;
4963   }
4964   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  by client %u\n", c->id);
4965
4966   /* Message sanity check */
4967   if (sizeof (struct GNUNET_MESH_TunnelMessage) != ntohs (message->size))
4968   {
4969     GNUNET_break (0);
4970     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
4971     return;
4972   }
4973
4974   tunnel_msg = (struct GNUNET_MESH_TunnelMessage *) message;
4975
4976   /* Retrieve tunnel */
4977   tid = ntohl (tunnel_msg->tunnel_id);
4978   t = tunnel_get_by_local_id(c, tid);
4979   if (NULL == t)
4980   {
4981     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "  tunnel %X not found\n", tid);
4982     GNUNET_break (0);
4983     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
4984     return;
4985   }
4986
4987   /* Cleanup after the tunnel */
4988   client_delete_tunnel (c, t);
4989   if (c == t->client)
4990   {
4991     t->client = NULL;
4992   }
4993   if (c == t->owner)
4994   {
4995     peer_info_remove_tunnel (peer_get_short (t->dest), t);
4996     t->owner = NULL;
4997   }
4998
4999   /* The tunnel will be destroyed when the last message is transmitted. */
5000   tunnel_destroy_empty (t);
5001
5002   GNUNET_SERVER_receive_done (client, GNUNET_OK);
5003   return;
5004 }
5005
5006
5007 /**
5008  * Handler for client traffic
5009  *
5010  * @param cls closure
5011  * @param client identification of the client
5012  * @param message the actual message
5013  */
5014 static void
5015 handle_local_data (void *cls, struct GNUNET_SERVER_Client *client,
5016                    const struct GNUNET_MessageHeader *message)
5017 {
5018   struct GNUNET_MESH_LocalData *data_msg;
5019   struct MeshClient *c;
5020   struct MeshTunnel *t;
5021   struct MeshFlowControl *fc;
5022   MESH_TunnelNumber tid;
5023   size_t size;
5024
5025   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5026               "Got data from a client!\n");
5027
5028   /* Sanity check for client registration */
5029   if (NULL == (c = client_get (client)))
5030   {
5031     GNUNET_break (0);
5032     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5033     return;
5034   }
5035   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  by client %u\n", c->id);
5036
5037   data_msg = (struct GNUNET_MESH_LocalData *) message;
5038
5039   /* Sanity check for message size */
5040   size = ntohs (message->size) - sizeof (struct GNUNET_MESH_LocalData);
5041   if (size < sizeof (struct GNUNET_MessageHeader))
5042   {
5043     GNUNET_break (0);
5044     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5045     return;
5046   }
5047
5048   /* Tunnel exists? */
5049   tid = ntohl (data_msg->tid);
5050   if (tid < GNUNET_MESH_LOCAL_TUNNEL_ID_CLI)
5051   {
5052     GNUNET_break (0);
5053     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5054     return;
5055   }
5056   t = tunnel_get_by_local_id (c, tid);
5057   if (NULL == t)
5058   {
5059     GNUNET_break (0);
5060     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5061     return;
5062   }
5063
5064   /* Is the client in the tunnel? */
5065   if ( !( (tid < GNUNET_MESH_LOCAL_TUNNEL_ID_SERV &&
5066            t->owner &&
5067            t->owner->handle == client)
5068          ||
5069           (tid >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV &&
5070            t->client && 
5071            t->client->handle == client) ) )
5072   {
5073     GNUNET_break (0);
5074     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5075     return;
5076   }
5077
5078   /* Ok, everything is correct, send the message
5079    * (pretend we got it from a mesh peer)
5080    */
5081   {
5082     struct GNUNET_MESH_Data *payload;
5083     char cbuf[sizeof(struct GNUNET_MESH_Data) + size];
5084
5085     fc = tid < GNUNET_MESH_LOCAL_TUNNEL_ID_SERV ? &t->prev_fc : &t->next_fc;
5086     if (GNUNET_YES == t->reliable)
5087     {
5088       struct MeshTunnelReliability *rel;
5089       struct MeshReliableMessage *copy;
5090
5091       rel = (tid < GNUNET_MESH_LOCAL_TUNNEL_ID_SERV) ? t->fwd_rel : t->bck_rel;
5092       copy = GNUNET_malloc (sizeof (struct MeshReliableMessage)
5093                             + sizeof(struct GNUNET_MESH_Data)
5094                             + size);
5095       copy->mid = rel->mid_sent++;
5096       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!! DATA %llu\n", copy->mid);
5097       copy->timestamp = GNUNET_TIME_absolute_get ();
5098       copy->rel = rel;
5099       rel->n_sent++;
5100       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " n_sent %u\n", rel->n_sent);
5101       GNUNET_CONTAINER_DLL_insert_tail (rel->head_sent, rel->tail_sent, copy);
5102       if (GNUNET_SCHEDULER_NO_TASK == rel->retry_task)
5103       {
5104         rel->retry_timer =
5105             GNUNET_TIME_relative_multiply (rel->expected_delay,
5106                                            MESH_RETRANSMIT_MARGIN);
5107         rel->retry_task =
5108             GNUNET_SCHEDULER_add_delayed (rel->retry_timer,
5109                                           &tunnel_retransmit_message,
5110                                           rel);
5111       }
5112       payload = (struct GNUNET_MESH_Data *) &copy[1];
5113       payload->mid = GNUNET_htonll (copy->mid);
5114     }
5115     else
5116     {
5117       payload = (struct GNUNET_MESH_Data *) cbuf;
5118       payload->mid = 0;
5119       // FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME 
5120       // use different struct for unreliable traffic, save 8 bytes
5121     }
5122     memcpy (&payload[1], &data_msg[1], size);
5123     payload->header.size = htons (sizeof (struct GNUNET_MESH_Data) + size);
5124     payload->header.type = htons (tid < GNUNET_MESH_LOCAL_TUNNEL_ID_SERV ?
5125                                   GNUNET_MESSAGE_TYPE_MESH_UNICAST :
5126                                   GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN);
5127     GNUNET_PEER_resolve(t->id.oid, &payload->oid);;
5128     payload->tid = htonl (t->id.tid);
5129     payload->ttl = htonl (default_ttl);
5130     payload->pid = htonl (fc->last_pid_recv + 1);
5131     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5132                 "  calling generic handler...\n");
5133     if (tid < GNUNET_MESH_LOCAL_TUNNEL_ID_SERV)
5134       handle_mesh_unicast (NULL, &my_full_id, &payload->header);
5135     else
5136       handle_mesh_to_orig (NULL, &my_full_id, &payload->header);
5137   }
5138   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "receive done OK\n");
5139   GNUNET_SERVER_receive_done (client, GNUNET_OK);
5140
5141   return;
5142 }
5143
5144
5145 /**
5146  * Handler for client's ACKs for payload traffic.
5147  *
5148  * @param cls Closure (unused).
5149  * @param client Identification of the client.
5150  * @param message The actual message.
5151  */
5152 static void
5153 handle_local_ack (void *cls, struct GNUNET_SERVER_Client *client,
5154                   const struct GNUNET_MessageHeader *message)
5155 {
5156   struct GNUNET_MESH_LocalAck *msg;
5157   struct MeshTunnel *t;
5158   struct MeshClient *c;
5159   MESH_TunnelNumber tid;
5160
5161   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got a local ACK\n");
5162   /* Sanity check for client registration */
5163   if (NULL == (c = client_get (client)))
5164   {
5165     GNUNET_break (0);
5166     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5167     return;
5168   }
5169   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  by client %u\n", c->id);
5170
5171   msg = (struct GNUNET_MESH_LocalAck *) message;
5172
5173   /* Tunnel exists? */
5174   tid = ntohl (msg->tunnel_id);
5175   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  on tunnel %X\n", tid);
5176   t = tunnel_get_by_local_id (c, tid);
5177   if (NULL == t)
5178   {
5179     GNUNET_break (0);
5180     GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Tunnel %X unknown.\n", tid);
5181     GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "  for client %u.\n", c->id);
5182     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5183     return;
5184   }
5185
5186   /* Does client own tunnel? I.E: Is this an ACK for BCK traffic? */
5187   if (t->owner == c)
5188   {
5189     /* The client owns the tunnel, ACK is for data to_origin, send BCK ACK. */
5190     t->prev_fc.last_ack_recv++;
5191     tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK);
5192   }
5193   else
5194   {
5195     /* The client doesn't own the tunnel, this ACK is for FWD traffic. */
5196     t->next_fc.last_ack_recv++;
5197     tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK);
5198   }
5199
5200   GNUNET_SERVER_receive_done (client, GNUNET_OK);
5201
5202   return;
5203 }
5204
5205
5206
5207 /**
5208  * Iterator over all tunnels to send a monitoring client info about each tunnel.
5209  *
5210  * @param cls Closure (client handle).
5211  * @param key Key (hashed tunnel ID, unused).
5212  * @param value Tunnel info.
5213  *
5214  * @return GNUNET_YES, to keep iterating.
5215  */
5216 static int
5217 monitor_all_tunnels_iterator (void *cls,
5218                               const struct GNUNET_HashCode * key,
5219                               void *value)
5220 {
5221   struct GNUNET_SERVER_Client *client = cls;
5222   struct MeshTunnel *t = value;
5223   struct GNUNET_MESH_LocalMonitor *msg;
5224
5225   msg = GNUNET_malloc (sizeof(struct GNUNET_MESH_LocalMonitor));
5226   GNUNET_PEER_resolve(t->id.oid, &msg->owner);
5227   msg->tunnel_id = htonl (t->id.tid);
5228   msg->header.size = htons (sizeof (struct GNUNET_MESH_LocalMonitor));
5229   msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_INFO_TUNNELS);
5230   GNUNET_PEER_resolve (t->dest, &msg->destination);
5231
5232   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
5233               "*  sending info about tunnel %s [%u]\n",
5234               GNUNET_i2s (&msg->owner), t->id.tid);
5235
5236   GNUNET_SERVER_notification_context_unicast (nc, client,
5237                                               &msg->header, GNUNET_NO);
5238   return GNUNET_YES;
5239 }
5240
5241
5242 /**
5243  * Handler for client's MONITOR request.
5244  *
5245  * @param cls Closure (unused).
5246  * @param client Identification of the client.
5247  * @param message The actual message.
5248  */
5249 static void
5250 handle_local_get_tunnels (void *cls, struct GNUNET_SERVER_Client *client,
5251                           const struct GNUNET_MessageHeader *message)
5252 {
5253   struct MeshClient *c;
5254
5255   /* Sanity check for client registration */
5256   if (NULL == (c = client_get (client)))
5257   {
5258     GNUNET_break (0);
5259     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5260     return;
5261   }
5262
5263   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
5264               "Received get tunnels request from client %u\n",
5265               c->id);
5266   GNUNET_CONTAINER_multihashmap_iterate (tunnels,
5267                                          monitor_all_tunnels_iterator,
5268                                          client);
5269   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
5270               "Get tunnels request from client %u completed\n",
5271               c->id);
5272   GNUNET_SERVER_receive_done (client, GNUNET_OK);
5273 }
5274
5275
5276 /**
5277  * Handler for client's MONITOR_TUNNEL request.
5278  *
5279  * @param cls Closure (unused).
5280  * @param client Identification of the client.
5281  * @param message The actual message.
5282  */
5283 static void
5284 handle_local_show_tunnel (void *cls, struct GNUNET_SERVER_Client *client,
5285                           const struct GNUNET_MessageHeader *message)
5286 {
5287   const struct GNUNET_MESH_LocalMonitor *msg;
5288   struct GNUNET_MESH_LocalMonitor *resp;
5289   struct MeshClient *c;
5290   struct MeshTunnel *t;
5291
5292   /* Sanity check for client registration */
5293   if (NULL == (c = client_get (client)))
5294   {
5295     GNUNET_break (0);
5296     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5297     return;
5298   }
5299
5300   msg = (struct GNUNET_MESH_LocalMonitor *) message;
5301   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
5302               "Received tunnel info request from client %u for tunnel %s[%X]\n",
5303               c->id,
5304               &msg->owner,
5305               ntohl (msg->tunnel_id));
5306   t = tunnel_get (&msg->owner, ntohl (msg->tunnel_id));
5307   if (NULL == t)
5308   {
5309     /* We don't know the tunnel FIXME */
5310     struct GNUNET_MESH_LocalMonitor warn;
5311
5312     warn = *msg;
5313     GNUNET_SERVER_notification_context_unicast (nc, client,
5314                                                 &warn.header,
5315                                                 GNUNET_NO);
5316     GNUNET_SERVER_receive_done (client, GNUNET_OK);
5317     return;
5318   }
5319
5320   /* Initialize context */
5321   resp = GNUNET_malloc (sizeof (struct GNUNET_MESH_LocalMonitor));
5322   *resp = *msg;
5323   GNUNET_PEER_resolve (t->dest, &resp->destination);
5324   resp->header.size = htons (sizeof (struct GNUNET_MESH_LocalMonitor));
5325   GNUNET_SERVER_notification_context_unicast (nc, c->handle,
5326                                               &resp->header, GNUNET_NO);
5327   GNUNET_free (resp);
5328
5329   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
5330               "Monitor tunnel request from client %u completed\n",
5331               c->id);
5332   GNUNET_SERVER_receive_done (client, GNUNET_OK);
5333 }
5334
5335
5336 /**
5337  * Functions to handle messages from clients
5338  */
5339 static struct GNUNET_SERVER_MessageHandler client_handlers[] = {
5340   {&handle_local_new_client, NULL,
5341    GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT, 0},
5342   {&handle_local_tunnel_create, NULL,
5343    GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_CREATE,
5344    sizeof (struct GNUNET_MESH_TunnelMessage)},
5345   {&handle_local_tunnel_destroy, NULL,
5346    GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_DESTROY,
5347    sizeof (struct GNUNET_MESH_TunnelMessage)},
5348   {&handle_local_data, NULL,
5349    GNUNET_MESSAGE_TYPE_MESH_LOCAL_DATA, 0},
5350   {&handle_local_ack, NULL,
5351    GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK,
5352    sizeof (struct GNUNET_MESH_LocalAck)},
5353   {&handle_local_get_tunnels, NULL,
5354    GNUNET_MESSAGE_TYPE_MESH_LOCAL_INFO_TUNNELS,
5355    sizeof (struct GNUNET_MessageHeader)},
5356   {&handle_local_show_tunnel, NULL,
5357    GNUNET_MESSAGE_TYPE_MESH_LOCAL_INFO_TUNNEL,
5358      sizeof (struct GNUNET_MESH_LocalMonitor)},
5359   {NULL, NULL, 0, 0}
5360 };
5361
5362
5363 /**
5364  * Method called whenever a given peer connects.
5365  *
5366  * @param cls closure
5367  * @param peer peer identity this notification is about
5368  */
5369 static void
5370 core_connect (void *cls, const struct GNUNET_PeerIdentity *peer)
5371 {
5372   struct MeshPeerInfo *peer_info;
5373   struct MeshPeerPath *path;
5374
5375   DEBUG_CONN ("Peer connected\n");
5376   DEBUG_CONN ("     %s\n", GNUNET_i2s (&my_full_id));
5377   peer_info = peer_get (peer);
5378   if (myid == peer_info->id)
5379   {
5380     DEBUG_CONN ("     (self)\n");
5381     path = path_new (1);
5382   }
5383   else
5384   {
5385     DEBUG_CONN ("     %s\n", GNUNET_i2s (peer));
5386     path = path_new (2);
5387     path->peers[1] = peer_info->id;
5388     GNUNET_PEER_change_rc (peer_info->id, 1);
5389     GNUNET_STATISTICS_update (stats, "# peers", 1, GNUNET_NO);
5390   }
5391   path->peers[0] = myid;
5392   GNUNET_PEER_change_rc (myid, 1);
5393   peer_info_add_path (peer_info, path, GNUNET_YES);
5394   return;
5395 }
5396
5397
5398 /**
5399  * Method called whenever a peer disconnects.
5400  *
5401  * @param cls closure
5402  * @param peer peer identity this notification is about
5403  */
5404 static void
5405 core_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer)
5406 {
5407   struct MeshPeerInfo *pi;
5408   struct MeshPeerQueue *q;
5409   struct MeshPeerQueue *n;
5410
5411   DEBUG_CONN ("Peer disconnected\n");
5412   pi = GNUNET_CONTAINER_multihashmap_get (peers, &peer->hashPubKey);
5413   if (NULL == pi)
5414   {
5415     GNUNET_break (0);
5416     return;
5417   }
5418   q = pi->queue_head;
5419   while (NULL != q)
5420   {
5421       n = q->next;
5422       /* TODO try to reroute this traffic instead */
5423       queue_destroy(q, GNUNET_YES);
5424       q = n;
5425   }
5426   if (NULL != pi->core_transmit)
5427   {
5428     GNUNET_CORE_notify_transmit_ready_cancel(pi->core_transmit);
5429     pi->core_transmit = NULL;
5430   }
5431     peer_remove_path (pi, pi->id, myid);
5432   if (myid == pi->id)
5433   {
5434     DEBUG_CONN ("     (self)\n");
5435   }
5436   GNUNET_STATISTICS_update (stats, "# peers", -1, GNUNET_NO);
5437   return;
5438 }
5439
5440
5441 /**
5442  * Install server (service) handlers and start listening to clients.
5443  */
5444 static void
5445 server_init (void)
5446 {
5447   GNUNET_SERVER_add_handlers (server_handle, client_handlers);
5448   GNUNET_SERVER_connect_notify (server_handle,
5449                                 &handle_local_client_connect, NULL);
5450   GNUNET_SERVER_disconnect_notify (server_handle,
5451                                    &handle_local_client_disconnect, NULL);
5452   nc = GNUNET_SERVER_notification_context_create (server_handle, 1);
5453
5454   clients_head = NULL;
5455   clients_tail = NULL;
5456   next_client_id = 0;
5457   GNUNET_SERVER_resume (server_handle);
5458 }
5459
5460
5461 /**
5462  * To be called on core init/fail.
5463  *
5464  * @param cls Closure (config)
5465  * @param server handle to the server for this service
5466  * @param identity the public identity of this peer
5467  */
5468 static void
5469 core_init (void *cls, struct GNUNET_CORE_Handle *server,
5470            const struct GNUNET_PeerIdentity *identity)
5471 {
5472   const struct GNUNET_CONFIGURATION_Handle *c = cls;
5473   static int i = 0;
5474
5475   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Core init\n");
5476   GNUNET_break (core_handle == server);
5477   if (0 != memcmp (identity, &my_full_id, sizeof (my_full_id)) ||
5478     NULL == server)
5479   {
5480     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Wrong CORE service\n"));
5481     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
5482                 " core id %s\n",
5483                 GNUNET_i2s (identity));
5484     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
5485                 " my id %s\n",
5486                 GNUNET_i2s (&my_full_id));
5487     GNUNET_CORE_disconnect (core_handle);
5488     core_handle = GNUNET_CORE_connect (c, /* Main configuration */
5489                                        NULL,      /* Closure passed to MESH functions */
5490                                        &core_init,        /* Call core_init once connected */
5491                                        &core_connect,     /* Handle connects */
5492                                        &core_disconnect,  /* remove peers on disconnects */
5493                                        NULL,      /* Don't notify about all incoming messages */
5494                                        GNUNET_NO, /* For header only in notification */
5495                                        NULL,      /* Don't notify about all outbound messages */
5496                                        GNUNET_NO, /* For header-only out notification */
5497                                        core_handlers);    /* Register these handlers */
5498     if (10 < i++)
5499       GNUNET_abort();
5500   }
5501   server_init ();
5502   return;
5503 }
5504
5505
5506 /******************************************************************************/
5507 /************************      MAIN FUNCTIONS      ****************************/
5508 /******************************************************************************/
5509
5510 /**
5511  * Iterator over tunnel hash map entries to destroy the tunnel during shutdown.
5512  *
5513  * @param cls closure
5514  * @param key current key code
5515  * @param value value in the hash map
5516  * @return GNUNET_YES if we should continue to iterate,
5517  *         GNUNET_NO if not.
5518  */
5519 static int
5520 shutdown_tunnel (void *cls, const struct GNUNET_HashCode * key, void *value)
5521 {
5522   struct MeshTunnel *t = value;
5523
5524   tunnel_destroy (t);
5525   return GNUNET_YES;
5526 }
5527
5528 /**
5529  * Iterator over peer hash map entries to destroy the tunnel during shutdown.
5530  *
5531  * @param cls closure
5532  * @param key current key code
5533  * @param value value in the hash map
5534  * @return GNUNET_YES if we should continue to iterate,
5535  *         GNUNET_NO if not.
5536  */
5537 static int
5538 shutdown_peer (void *cls, const struct GNUNET_HashCode * key, void *value)
5539 {
5540   struct MeshPeerInfo *p = value;
5541   struct MeshPeerQueue *q;
5542   struct MeshPeerQueue *n;
5543
5544   q = p->queue_head;
5545   while (NULL != q)
5546   {
5547       n = q->next;
5548       if (q->peer == p)
5549       {
5550         queue_destroy(q, GNUNET_YES);
5551       }
5552       q = n;
5553   }
5554   peer_info_destroy (p);
5555   return GNUNET_YES;
5556 }
5557
5558
5559 /**
5560  * Task run during shutdown.
5561  *
5562  * @param cls unused
5563  * @param tc unused
5564  */
5565 static void
5566 shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
5567 {
5568   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "shutting down\n");
5569
5570   if (core_handle != NULL)
5571   {
5572     GNUNET_CORE_disconnect (core_handle);
5573     core_handle = NULL;
5574   }
5575   GNUNET_CONTAINER_multihashmap_iterate (tunnels, &shutdown_tunnel, NULL);
5576   GNUNET_CONTAINER_multihashmap_iterate (peers, &shutdown_peer, NULL);
5577   if (dht_handle != NULL)
5578   {
5579     GNUNET_DHT_disconnect (dht_handle);
5580     dht_handle = NULL;
5581   }
5582   if (nc != NULL)
5583   {
5584     GNUNET_SERVER_notification_context_destroy (nc);
5585     nc = NULL;
5586   }
5587   if (GNUNET_SCHEDULER_NO_TASK != announce_id_task)
5588   {
5589     GNUNET_SCHEDULER_cancel (announce_id_task);
5590     announce_id_task = GNUNET_SCHEDULER_NO_TASK;
5591   }
5592   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "shut down\n");
5593 }
5594
5595
5596 /**
5597  * Process mesh requests.
5598  *
5599  * @param cls closure
5600  * @param server the initialized server
5601  * @param c configuration to use
5602  */
5603 static void
5604 run (void *cls, struct GNUNET_SERVER_Handle *server,
5605      const struct GNUNET_CONFIGURATION_Handle *c)
5606 {
5607   char *keyfile;
5608   struct GNUNET_CRYPTO_EccPrivateKey *pk;
5609
5610   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "starting to run\n");
5611   server_handle = server;
5612   GNUNET_SERVER_suspend (server_handle);
5613
5614   if (GNUNET_OK !=
5615       GNUNET_CONFIGURATION_get_value_filename (c, "PEER", "PRIVATE_KEY",
5616                                                &keyfile))
5617   {
5618     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
5619                 _
5620                 ("%s service is lacking key configuration settings (%s).  Exiting.\n"),
5621                 "mesh", "peer/privatekey");
5622     GNUNET_SCHEDULER_shutdown ();
5623     return;
5624   }
5625
5626   if (GNUNET_OK !=
5627       GNUNET_CONFIGURATION_get_value_time (c, "MESH", "REFRESH_PATH_TIME",
5628                                            &refresh_path_time))
5629   {
5630     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
5631                 _
5632                 ("%s service is lacking key configuration settings (%s).  Exiting.\n"),
5633                 "mesh", "refresh path time");
5634     GNUNET_SCHEDULER_shutdown ();
5635     return;
5636   }
5637
5638   if (GNUNET_OK !=
5639       GNUNET_CONFIGURATION_get_value_time (c, "MESH", "ID_ANNOUNCE_TIME",
5640                                            &id_announce_time))
5641   {
5642     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
5643                 _
5644                 ("%s service is lacking key configuration settings (%s).  Exiting.\n"),
5645                 "mesh", "id announce time");
5646     GNUNET_SCHEDULER_shutdown ();
5647     return;
5648   }
5649
5650   if (GNUNET_OK !=
5651       GNUNET_CONFIGURATION_get_value_time (c, "MESH", "CONNECT_TIMEOUT",
5652                                            &connect_timeout))
5653   {
5654     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
5655                 _
5656                 ("%s service is lacking key configuration settings (%s).  Exiting.\n"),
5657                 "mesh", "connect timeout");
5658     GNUNET_SCHEDULER_shutdown ();
5659     return;
5660   }
5661
5662   if (GNUNET_OK !=
5663       GNUNET_CONFIGURATION_get_value_number (c, "MESH", "MAX_MSGS_QUEUE",
5664                                              &max_msgs_queue))
5665   {
5666     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
5667                 _
5668                 ("%s service is lacking key configuration settings (%s).  Exiting.\n"),
5669                 "mesh", "max msgs queue");
5670     GNUNET_SCHEDULER_shutdown ();
5671     return;
5672   }
5673
5674   if (GNUNET_OK !=
5675       GNUNET_CONFIGURATION_get_value_number (c, "MESH", "MAX_TUNNELS",
5676                                              &max_tunnels))
5677   {
5678     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
5679                 _
5680                 ("%s service is lacking key configuration settings (%s).  Exiting.\n"),
5681                 "mesh", "max tunnels");
5682     GNUNET_SCHEDULER_shutdown ();
5683     return;
5684   }
5685
5686   if (GNUNET_OK !=
5687       GNUNET_CONFIGURATION_get_value_number (c, "MESH", "DEFAULT_TTL",
5688                                              &default_ttl))
5689   {
5690     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
5691                 _
5692                 ("%s service is lacking key configuration settings (%s). Using default (%u).\n"),
5693                 "mesh", "default ttl", 64);
5694     default_ttl = 64;
5695   }
5696
5697   if (GNUNET_OK !=
5698       GNUNET_CONFIGURATION_get_value_number (c, "MESH", "MAX_PEERS",
5699                                              &max_peers))
5700   {
5701     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
5702                 _("%s service is lacking key configuration settings (%s). Using default (%u).\n"),
5703                 "mesh", "max peers", 1000);
5704     max_peers = 1000;
5705   }
5706
5707   if (GNUNET_OK !=
5708       GNUNET_CONFIGURATION_get_value_number (c, "MESH", "DROP_PERCENT",
5709                                              &drop_percent))
5710   {
5711     drop_percent = 0;
5712   }
5713   else
5714   {
5715     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
5716                 "Mesh is running with drop mode enabled. "
5717                 "This is NOT a good idea! "
5718                 "Remove the DROP_PERCENT option from your configuration.\n");
5719   }
5720
5721   if (GNUNET_OK !=
5722       GNUNET_CONFIGURATION_get_value_number (c, "MESH", "DHT_REPLICATION_LEVEL",
5723                                              &dht_replication_level))
5724   {
5725     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
5726                 _
5727                 ("%s service is lacking key configuration settings (%s). Using default (%u).\n"),
5728                 "mesh", "dht replication level", 3);
5729     dht_replication_level = 3;
5730   }
5731
5732   tunnels = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
5733   incoming_tunnels = GNUNET_CONTAINER_multihashmap32_create (32);
5734   peers = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
5735   ports = GNUNET_CONTAINER_multihashmap32_create (32);
5736
5737   dht_handle = GNUNET_DHT_connect (c, 64);
5738   if (NULL == dht_handle)
5739   {
5740     GNUNET_break (0);
5741   }
5742   stats = GNUNET_STATISTICS_create ("mesh", c);
5743
5744   /* Scheduled the task to clean up when shutdown is called */
5745   GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task,
5746                                 NULL);
5747   pk = GNUNET_CRYPTO_ecc_key_create_from_file (keyfile);
5748   GNUNET_free (keyfile);
5749   GNUNET_assert (NULL != pk);
5750   my_private_key = pk;
5751   GNUNET_CRYPTO_ecc_key_get_public (my_private_key, &my_public_key);
5752   GNUNET_CRYPTO_hash (&my_public_key, sizeof (my_public_key),
5753                       &my_full_id.hashPubKey);
5754   myid = GNUNET_PEER_intern (&my_full_id);
5755   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
5756               "Mesh for peer [%s] starting\n",
5757               GNUNET_i2s(&my_full_id));
5758
5759   core_handle = GNUNET_CORE_connect (c, /* Main configuration */
5760                                      NULL,      /* Closure passed to MESH functions */
5761                                      &core_init,        /* Call core_init once connected */
5762                                      &core_connect,     /* Handle connects */
5763                                      &core_disconnect,  /* remove peers on disconnects */
5764                                      NULL,      /* Don't notify about all incoming messages */
5765                                      GNUNET_NO, /* For header only in notification */
5766                                      NULL,      /* Don't notify about all outbound messages */
5767                                      GNUNET_NO, /* For header-only out notification */
5768                                      core_handlers);    /* Register these handlers */
5769   if (NULL == core_handle)
5770   {
5771     GNUNET_break (0);
5772     GNUNET_SCHEDULER_shutdown ();
5773     return;
5774   }
5775   next_tid = 0;
5776   next_local_tid = GNUNET_MESH_LOCAL_TUNNEL_ID_SERV;
5777   announce_id_task = GNUNET_SCHEDULER_add_now (&announce_id, cls);
5778   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Mesh service running\n");
5779 }
5780
5781
5782 /**
5783  * The main function for the mesh service.
5784  *
5785  * @param argc number of arguments from the command line
5786  * @param argv command line arguments
5787  * @return 0 ok, 1 on error
5788  */
5789 int
5790 main (int argc, char *const *argv)
5791 {
5792   int ret;
5793   int r;
5794
5795   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "main()\n");
5796   r = GNUNET_SERVICE_run (argc, argv, "mesh", GNUNET_SERVICE_OPTION_NONE, &run,
5797                           NULL);
5798   ret = (GNUNET_OK == r) ? 0 : 1;
5799   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "main() END\n");
5800
5801   INTERVAL_SHOW;
5802
5803   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
5804               "Mesh for peer [%s] FWD ACKs %u, BCK ACKs %u\n",
5805               GNUNET_i2s(&my_full_id), debug_fwd_ack, debug_bck_ack);
5806
5807   return ret;
5808 }