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