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