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