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