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