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