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