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