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