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