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