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