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