e117a9481f562e5318b036b996b439803c2c287f
[oweals/gnunet.git] / src / mesh / gnunet-service-mesh_tunnel.c
1 /*
2      This file is part of GNUnet.
3      (C) 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 #include "platform.h"
22 #include "gnunet_util_lib.h"
23
24 #include "gnunet_statistics_service.h"
25
26 #include "mesh_protocol_enc.h"
27
28 #include "gnunet-service-mesh_tunnel.h"
29 #include "gnunet-service-mesh_connection.h"
30 #include "gnunet-service-mesh_channel.h"
31 #include "gnunet-service-mesh_peer.h"
32 #include "mesh_path.h"
33
34 #define LOG(level, ...) GNUNET_log_from(level,"mesh-tun",__VA_ARGS__)
35
36
37 /******************************************************************************/
38 /********************************   STRUCTS  **********************************/
39 /******************************************************************************/
40
41 struct MeshTChannel
42 {
43   struct MeshTChannel *next;
44   struct MeshTChannel *prev;
45   struct MeshChannel *ch;
46 };
47
48 struct MeshTConnection
49 {
50   struct MeshTConnection *next;
51   struct MeshTConnection *prev;
52   struct MeshConnection *c;
53 };
54
55 /**
56  * Struct containing all information regarding a tunnel to a peer.
57  */
58 struct MeshTunnel3
59 {
60     /**
61      * Endpoint of the tunnel.
62      */
63   struct MeshPeer *peer;
64
65     /**
66      * State of the tunnel.
67      */
68   enum MeshTunnel3State state;
69
70   /**
71    * Local peer ephemeral private key
72    */
73   struct GNUNET_CRYPTO_EddsaPrivateKey *my_eph_key;
74
75   /**
76    * Local peer ephemeral public key
77    */
78   struct GNUNET_CRYPTO_EddsaPublicKey *my_eph;
79
80   /**
81    * Remote peer's public key.
82    */
83   struct GNUNET_CRYPTO_EddsaPublicKey *peers_eph;
84
85   /**
86    * Encryption ("our") key.
87    */
88   struct GNUNET_CRYPTO_SymmetricSessionKey e_key;
89
90   /**
91    * Decryption ("their") key.
92    */
93   struct GNUNET_CRYPTO_SymmetricSessionKey d_key;
94
95   /**
96    * Paths that are actively used to reach the destination peer.
97    */
98   struct MeshTConnection *connection_head;
99   struct MeshTConnection *connection_tail;
100
101   /**
102    * Next connection number.
103    */
104   uint32_t next_cid;
105
106   /**
107    * Channels inside this tunnel.
108    */
109   struct MeshTChannel *channel_head;
110   struct MeshTChannel *channel_tail;
111
112   /**
113    * Channel ID for the next created channel.
114    */
115   MESH_ChannelNumber next_chid;
116
117   /**
118    * Pending message count.
119    */
120   int pending_messages;
121
122   /**
123    * Destroy flag: if true, destroy on last message.
124    */
125   int destroy;
126
127   /**
128    * Queued messages, to transmit once tunnel gets connected.
129    */
130   struct MeshTunnelQueue *tq_head;
131   struct MeshTunnelQueue *tq_tail;
132 };
133
134
135 /**
136  * Struct used to queue messages in a tunnel.
137  */
138 struct MeshTunnelQueue
139 {
140   /**
141    * DLL
142    */
143   struct MeshTunnelQueue *next;
144   struct MeshTunnelQueue *prev;
145
146   /**
147    * Channel.
148    */
149   struct MeshChannel *ch;
150
151   /**
152    * Message to send.
153    */
154   /* struct GNUNET_MessageHeader *msg; */
155 };
156
157 /******************************************************************************/
158 /*******************************   GLOBALS  ***********************************/
159 /******************************************************************************/
160
161 /**
162  * Global handle to the statistics service.
163  */
164 extern struct GNUNET_STATISTICS_Handle *stats;
165
166 /**
167  * Local peer own ID (memory efficient handle).
168  */
169 extern GNUNET_PEER_Id myid;
170
171 /**
172  * Local peer own ID (full value).
173  */
174 extern struct GNUNET_PeerIdentity my_full_id;
175
176 /**
177  * Default TTL for payload packets.
178  */
179 static unsigned long long default_ttl;
180
181 /**
182  * Own private key.
183  */
184 const static struct GNUNET_CRYPTO_EddsaPrivateKey *my_private_key;
185
186
187 /******************************************************************************/
188 /********************************   STATIC  ***********************************/
189 /******************************************************************************/
190
191 /**
192  * Get string description for tunnel state.
193  *
194  * @param s Tunnel state.
195  *
196  * @return String representation.
197  */
198 static const char *
199 GMT_state2s (enum MeshTunnel3State s)
200 {
201   static char buf[128];
202
203   switch (s)
204   {
205     case MESH_TUNNEL3_NEW:
206       return "MESH_TUNNEL3_NEW";
207     case MESH_TUNNEL3_SEARCHING:
208       return "MESH_TUNNEL3_SEARCHING";
209     case MESH_TUNNEL3_WAITING:
210       return "MESH_TUNNEL3_WAITING";
211     case MESH_TUNNEL3_READY:
212       return "MESH_TUNNEL3_READY";
213     case MESH_TUNNEL3_RECONNECTING:
214       return "MESH_TUNNEL3_RECONNECTING";
215
216     default:
217       sprintf (buf, "%u (UNKNOWN STATE)", s);
218       return buf;
219   }
220 }
221
222 /**
223  * Pick a connection on which send the next data message.
224  *
225  * @param t Tunnel on which to send the message.
226  * @param fwd Is this a fwd message?
227  *
228  * @return The connection on which to send the next message.
229  */
230 static struct MeshConnection *
231 tunnel_get_connection (struct MeshTunnel3 *t, int fwd)
232 {
233   struct MeshTConnection *iter;
234   struct MeshConnection *best;
235   unsigned int qn;
236   unsigned int lowest_q;
237
238   LOG (GNUNET_ERROR_TYPE_DEBUG, "tunnel_get_connection %s\n", GMP_2s (t->peer));
239   best = NULL;
240   lowest_q = UINT_MAX;
241   for (iter = t->connection_head; NULL != iter; iter = iter->next)
242   {
243     LOG (GNUNET_ERROR_TYPE_DEBUG, "  connection %s: %u\n",
244          GNUNET_h2s (GMC_get_id (iter->c)), GMC_get_state (iter->c));
245     if (MESH_CONNECTION_READY == GMC_get_state (iter->c))
246     {
247       qn = GMC_get_qn (iter->c, fwd);
248       LOG (GNUNET_ERROR_TYPE_DEBUG, "    q_n %u, \n", qn);
249       if (qn < lowest_q)
250       {
251         best = iter->c;
252         lowest_q = qn;
253       }
254     }
255   }
256   return best;
257 }
258
259
260 void
261 handle_data (struct MeshTunnel3 *t,
262              const struct GNUNET_MESH_Data *msg,
263              int fwd)
264 {
265   struct MeshChannel *ch;
266   uint16_t type;
267   size_t size;
268
269   /* Check size */
270   size = ntohs (msg->header.size);
271   if (size <
272       sizeof (struct GNUNET_MESH_Data) +
273       sizeof (struct GNUNET_MessageHeader))
274   {
275     GNUNET_break (0);
276     return;
277   }
278   type = ntohs (msg->header.type);
279   LOG (GNUNET_ERROR_TYPE_DEBUG, "got a %s message\n",
280               GNUNET_MESH_DEBUG_M2S (type));
281   LOG (GNUNET_ERROR_TYPE_DEBUG, " payload of type %s\n",
282               GNUNET_MESH_DEBUG_M2S (ntohs (msg[1].header.type)));
283
284   /* Check channel */
285   ch = GMT_get_channel (t, ntohl (msg->chid));
286   if (NULL == ch)
287   {
288     GNUNET_STATISTICS_update (stats, "# data on unknown channel",
289                               1, GNUNET_NO);
290     LOG (GNUNET_ERROR_TYPE_DEBUG, "WARNING channel %u unknown\n",
291          ntohl (msg->chid));
292     return;
293   }
294
295   GMT_change_state (t, MESH_TUNNEL3_READY);
296   GMCH_handle_data (ch, msg, fwd);
297 }
298
299 void
300 handle_data_ack (struct MeshTunnel3 *t,
301                  const struct GNUNET_MESH_DataACK *msg,
302                  int fwd)
303 {
304   struct MeshChannel *ch;
305   size_t size;
306
307   /* Check size */
308   size = ntohs (msg->header.size);
309   if (size != sizeof (struct GNUNET_MESH_DataACK))
310   {
311     GNUNET_break (0);
312     return;
313   }
314
315   /* Check channel */
316   ch = GMT_get_channel (t, ntohl (msg->chid));
317   if (NULL == ch)
318   {
319     GNUNET_STATISTICS_update (stats, "# data ack on unknown channel",
320                               1, GNUNET_NO);
321     LOG (GNUNET_ERROR_TYPE_DEBUG, "WARNING channel %u unknown\n",
322          ntohl (msg->chid));
323     return;
324   }
325
326   GMCH_handle_data_ack (ch, msg, fwd);
327 }
328
329 void
330 handle_ch_create (struct MeshTunnel3 *t,
331                   const struct GNUNET_MESH_ChannelCreate *msg,
332                   int fwd)
333 {
334   struct MeshTChannel *tch;
335   struct MeshChannel *ch;
336   size_t size;
337
338   /* Check size */
339   size = ntohs (msg->header.size);
340   if (size != sizeof (struct GNUNET_MESH_ChannelCreate))
341   {
342     GNUNET_break (0);
343     return;
344   }
345
346   /* Check channel */
347   ch = GMT_get_channel (t, ntohl (msg->chid));
348   if (NULL != ch)
349   {
350     /* Probably a retransmission, safe to ignore */
351     LOG (GNUNET_ERROR_TYPE_DEBUG, "   already exists...\n");
352   }
353   else
354   {
355     ch = GMCH_handle_create (msg, fwd);
356   }
357
358   tch = GNUNET_new (struct MeshTChannel);
359   tch->ch = ch;
360   GNUNET_CONTAINER_DLL_insert (t->channel_head, t->channel_tail, tch);
361 }
362
363 void
364 handle_ch_ack (struct MeshTunnel3 *t,
365                const struct GNUNET_MESH_ChannelManage *msg,
366                int fwd)
367 {
368   struct MeshChannel *ch;
369   size_t size;
370
371   /* Check size */
372   size = ntohs (msg->header.size);
373   if (size != sizeof (struct GNUNET_MESH_ChannelManage))
374   {
375     GNUNET_break (0);
376     return;
377   }
378
379   /* Check channel */
380   ch = GMT_get_channel (t, ntohl (msg->chid));
381   if (NULL == ch)
382   {
383     GNUNET_STATISTICS_update (stats, "# channel ack on unknown channel",
384                               1, GNUNET_NO);
385     LOG (GNUNET_ERROR_TYPE_DEBUG, "WARNING channel %u unknown\n",
386          ntohl (msg->chid));
387     return;
388   }
389
390   GMCH_handle_ack (ch, msg, fwd);
391 }
392
393 void
394 handle_ch_destroy (struct MeshTunnel3 *t,
395                    const struct GNUNET_MESH_ChannelManage *msg,
396                    int fwd)
397 {
398   struct MeshChannel *ch;
399   size_t size;
400
401   /* Check size */
402   size = ntohs (msg->header.size);
403   if (size != sizeof (struct GNUNET_MESH_ChannelManage))
404   {
405     GNUNET_break (0);
406     return;
407   }
408
409   /* Check channel */
410   ch = GMT_get_channel (t, ntohl (msg->chid));
411   if (NULL == ch)
412   {
413     /* Probably a retransmission, safe to ignore */
414     return;
415   }
416
417   GMCH_handle_destroy (ch, msg, fwd);
418 }
419
420 /******************************************************************************/
421 /********************************    API    ***********************************/
422 /******************************************************************************/
423
424 /**
425  * Demultiplex by message type and call appropriate handler for a message
426  * towards a channel of a local tunnel.
427  *
428  * @param t Tunnel this message came on.
429  * @param msgh Message header.
430  * @param fwd Is this message fwd?
431  */
432 void
433 GMT_handle_decrypted (struct MeshTunnel3 *t,
434                       const struct GNUNET_MessageHeader *msgh,
435                       int fwd)
436 {
437   uint16_t type;
438
439   type = ntohs (msgh->type);
440   LOG (GNUNET_ERROR_TYPE_DEBUG,
441        "Got a %s message!\n",
442        GNUNET_MESH_DEBUG_M2S (type));
443
444   switch (type)
445   {
446     case GNUNET_MESSAGE_TYPE_MESH_DATA:
447       /* Don't send hop ACK, wait for client to ACK */
448       handle_data (t, (struct GNUNET_MESH_Data *) msgh, fwd);
449       break;
450
451     case GNUNET_MESSAGE_TYPE_MESH_DATA_ACK:
452       handle_data_ack (t, (struct GNUNET_MESH_DataACK *) msgh, fwd);
453       break;
454
455     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_CREATE:
456       handle_ch_create (t,
457                         (struct GNUNET_MESH_ChannelCreate *) msgh,
458                         fwd);
459       break;
460
461     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_ACK:
462       handle_ch_ack (t,
463                      (struct GNUNET_MESH_ChannelManage *) msgh,
464                      fwd);
465       break;
466
467     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_DESTROY:
468       handle_ch_destroy (t,
469                          (struct GNUNET_MESH_ChannelManage *) msgh,
470                          fwd);
471       break;
472
473     default:
474       GNUNET_break_op (0);
475       LOG (GNUNET_ERROR_TYPE_DEBUG,
476            "end-to-end message not known (%u)\n",
477            ntohs (msgh->type));
478   }
479 }
480
481
482 /**
483  * Cache a message to be sent once tunnel is online.
484  *
485  * @param t Tunnel to hold the message.
486  * @param ch Channel the message is about.
487  * @param msg Message itself (copy will be made).
488  * @param fwd Is this fwd?
489  */
490 void
491 GMT_queue_data (struct MeshTunnel3 *t,
492                 struct MeshChannel *ch,
493                 struct GNUNET_MessageHeader *msg,
494                 int fwd)
495 {
496   struct MeshTunnelQueue *tq;
497   uint16_t size = ntohs (msg->size);
498
499   tq = GNUNET_malloc (sizeof (struct MeshTunnelQueue) + size);
500
501   tq->ch = ch;
502   memcpy (&tq[1], msg, size);
503   GNUNET_CONTAINER_DLL_insert_tail (t->tq_head, t->tq_tail, tq);
504
505   if (MESH_TUNNEL3_READY == t->state)
506     GMT_send_queued_data (t, fwd);
507 }
508
509
510 /**
511  * Send all cached messages that we can, tunnel is online.
512  *
513  * @param t Tunnel that holds the messages.
514  * @param fwd Is this fwd?
515  */
516 void
517 GMT_send_queued_data (struct MeshTunnel3 *t, int fwd)
518 {
519   struct MeshTunnelQueue *tq;
520   struct MeshTunnelQueue *next;
521   unsigned int room;
522
523   LOG (GNUNET_ERROR_TYPE_DEBUG,
524               "GMT_send_queued_data on tunnel %s\n",
525               GMP_2s (t->peer));
526   room = GMT_get_buffer (t, fwd);
527   LOG (GNUNET_ERROR_TYPE_DEBUG, "  buffer space: %u\n", room);
528   for (tq = t->tq_head; NULL != tq && room > 0; tq = next)
529   {
530     next = tq->next;
531     room--;
532     GNUNET_CONTAINER_DLL_remove (t->tq_head, t->tq_tail, tq);
533     GMCH_send_prebuilt_message ((struct GNUNET_MessageHeader *) &tq[1],
534                                 tq->ch, fwd);
535
536     GNUNET_free (tq);
537   }
538 }
539
540
541 /**
542  * Initialize the tunnel subsystem.
543  *
544  * @param c Configuration handle.
545  * @param id Peer identity.
546  * @param key ECC private key, to derive all other keys and do crypto.
547  */
548 void
549 GMT_init (const struct GNUNET_CONFIGURATION_Handle *c,
550           const struct GNUNET_CRYPTO_EddsaPrivateKey *key)
551 {
552   if (GNUNET_OK !=
553       GNUNET_CONFIGURATION_get_value_number (c, "MESH", "DEFAULT_TTL",
554                                              &default_ttl))
555   {
556     GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING,
557                                "MESH", "DEFAULT_TTL", "USING DEFAULT");
558     default_ttl = 64;
559   }
560   my_private_key = key;
561 }
562
563
564 /**
565  * Shut down the tunnel subsystem.
566  */
567 void
568 GMT_shutdown (void)
569 {
570   GNUNET_PEER_change_rc (myid, -1);
571 }
572
573
574 /**
575  * Create a tunnel.
576  *
577  * @param destination Peer this tunnel is towards.
578  */
579 struct MeshTunnel3 *
580 GMT_new (struct MeshPeer *destination)
581 {
582   struct MeshTunnel3 *t;
583
584   t = GNUNET_new (struct MeshTunnel3);
585   t->next_chid = 0;
586   t->peer = destination;
587 //   if (GNUNET_OK !=
588 //       GNUNET_CONTAINER_multihashmap_put (tunnels, tid, t,
589 //                                          GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
590 //   {
591 //     GNUNET_break (0);
592 //     tunnel_destroy (t);
593 //     return NULL;
594 //   }
595
596 //   char salt[] = "salt";
597 //   GNUNET_CRYPTO_kdf (&t->e_key, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
598 //                      salt, sizeof (salt),
599 //                      &t->e_key, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
600 //                      &my_full_id, sizeof (struct GNUNET_PeerIdentity),
601 //                      GNUNET_PEER_resolve2 (t->peer->id), sizeof (struct GNUNET_PeerIdentity),
602 //                      NULL);
603 //   GNUNET_CRYPTO_kdf (&t->d_key, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
604 //                      salt, sizeof (salt),
605 //                      &t->d_key, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
606 //                      GNUNET_PEER_resolve2 (t->peer->id), sizeof (struct GNUNET_PeerIdentity),
607 //                      &my_full_id, sizeof (struct GNUNET_PeerIdentity),
608 //                      NULL);
609
610   return t;
611 }
612
613
614 /**
615  * Change the tunnel state.
616  *
617  * @param t Tunnel whose state to change.
618  * @param state New state.
619  */
620 void
621 GMT_change_state (struct MeshTunnel3* t, enum MeshTunnel3State state)
622 {
623   if (NULL == t)
624     return;
625   LOG (GNUNET_ERROR_TYPE_DEBUG,
626               "Tunnel %s state was %s\n",
627               GMP_2s (t->peer),
628               GMT_state2s (t->state));
629   LOG (GNUNET_ERROR_TYPE_DEBUG,
630               "Tunnel %s state is now %s\n",
631               GMP_2s (t->peer),
632               GMT_state2s (state));
633   t->state = state;
634   if (MESH_TUNNEL3_READY == state && 3 <= GMT_count_connections (t))
635   {
636     GMP_stop_search (t->peer);
637   }
638 }
639
640
641 /**
642  * Add a connection to a tunnel.
643  *
644  * @param t Tunnel.
645  * @param c Connection.
646  */
647 void
648 GMT_add_connection (struct MeshTunnel3 *t, struct MeshConnection *c)
649 {
650   struct MeshTConnection *aux;
651
652   for (aux = t->connection_head; aux != NULL; aux = aux->next)
653     if (aux->c == c)
654       return;
655
656   aux = GNUNET_new (struct MeshTConnection);
657   aux->c = c;
658   GNUNET_CONTAINER_DLL_insert_tail (t->connection_head, t->connection_tail, aux);
659 }
660
661
662 /**
663  * Remove a connection from a tunnel.
664  *
665  * @param t Tunnel.
666  * @param c Connection.
667  */
668 void
669 GMT_remove_connection (struct MeshTunnel3 *t, struct MeshConnection *c)
670 {
671   struct MeshTConnection *aux;
672
673   for (aux = t->connection_head; aux != NULL; aux = aux->next)
674     if (aux->c == c)
675     {
676       GNUNET_CONTAINER_DLL_remove (t->connection_head, t->connection_tail, aux);
677       GNUNET_free (aux);
678       return;
679     }
680 }
681
682
683 /**
684  * Add a channel to a tunnel.
685  *
686  * @param t Tunnel.
687  * @param ch Channel.
688  */
689 void
690 GMT_add_channel (struct MeshTunnel3 *t, struct MeshChannel *ch)
691 {
692   struct MeshTChannel *aux;
693
694   for (aux = t->channel_head; aux != NULL; aux = aux->next)
695     if (aux->ch == ch)
696       return;
697
698   aux = GNUNET_new (struct MeshTChannel);
699   aux->ch = ch;
700   GNUNET_CONTAINER_DLL_insert_tail (t->channel_head, t->channel_tail, aux);
701 }
702
703
704 /**
705  * Remove a channel from a tunnel.
706  *
707  * @param t Tunnel.
708  * @param ch Channel.
709  */
710 void
711 GMT_remove_channel (struct MeshTunnel3 *t, struct MeshChannel *ch)
712 {
713   struct MeshTChannel *aux;
714
715   for (aux = t->channel_head; aux != NULL; aux = aux->next)
716     if (aux->ch == ch)
717     {
718       GNUNET_CONTAINER_DLL_remove (t->channel_head, t->channel_tail, aux);
719       GNUNET_free (aux);
720       return;
721     }
722 }
723
724
725 /**
726  * Search for a channel by global ID.
727  *
728  * @param t Tunnel containing the channel.
729  * @param chid Public channel number.
730  *
731  * @return channel handler, NULL if doesn't exist
732  */
733 struct MeshChannel *
734 GMT_get_channel (struct MeshTunnel3 *t, MESH_ChannelNumber chid)
735 {
736   struct MeshTChannel *iter;
737
738   if (NULL == t)
739     return NULL;
740
741   for (iter = t->channel_head; NULL != iter; iter = iter->next)
742   {
743     if (GMCH_get_id (iter->ch) == chid)
744       break;
745   }
746
747   return NULL == iter ? NULL : iter->ch;
748 }
749
750
751 /**
752  * Tunnel is empty: destroy it.
753  *
754  * Notifies all connections about the destruction.
755  *
756  * @param t Tunnel to destroy.
757  */
758 void
759 GMT_destroy_empty (struct MeshTunnel3 *t)
760 {
761   struct MeshTConnection *iter;
762
763   for (iter = t->connection_head; NULL != iter; iter = iter->next)
764   {
765     GMC_send_destroy (iter->c);
766   }
767
768   if (0 == t->pending_messages)
769     GMT_destroy (t);
770   else
771     t->destroy = GNUNET_YES;
772 }
773
774
775 /**
776  * Destroy tunnel if empty (no more channels).
777  *
778  * @param t Tunnel to destroy if empty.
779  */
780 void
781 GMT_destroy_if_empty (struct MeshTunnel3 *t)
782 {
783   if (1 < GMT_count_channels (t))
784     return;
785
786   GMT_destroy_empty (t);
787 }
788
789
790 /**
791  * Destroy the tunnel.
792  *
793  * This function does not generate any warning traffic to clients or peers.
794  *
795  * Tasks:
796  * Cancel messages belonging to this tunnel queued to neighbors.
797  * Free any allocated resources linked to the tunnel.
798  *
799  * @param t The tunnel to destroy.
800  */
801 void
802 GMT_destroy (struct MeshTunnel3 *t)
803 {
804   struct MeshTConnection *iter;
805   struct MeshTConnection *next;
806
807   if (NULL == t)
808     return;
809
810   LOG (GNUNET_ERROR_TYPE_DEBUG, "destroying tunnel %s\n", GMP_2s (t->peer));
811
812 //   if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_remove (tunnels, &t->id, t))
813 //     GNUNET_break (0);
814
815   for (iter = t->connection_head; NULL != iter; iter = next)
816   {
817     next = iter->next;
818     GMC_destroy (iter->c);
819     GNUNET_free (iter);
820   }
821
822   GNUNET_STATISTICS_update (stats, "# tunnels", -1, GNUNET_NO);
823   GMP_set_tunnel (t->peer, NULL);
824
825   GNUNET_free (t);
826 }
827
828
829 /**
830  * Notifies a tunnel that a connection has broken that affects at least
831  * some of its peers. Sends a notification towards the root of the tree.
832  * In case the peer is the owner of the tree, notifies the client that owns
833  * the tunnel and tries to reconnect.
834  *
835  * FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME
836  *
837  * @param t Tunnel affected.
838  * @param p1 Peer that got disconnected from p2.
839  * @param p2 Peer that got disconnected from p1.
840  *
841  * @return Short ID of the peer disconnected (either p1 or p2).
842  *         0 if the tunnel remained unaffected.
843  */
844 GNUNET_PEER_Id
845 GMT_notify_connection_broken (struct MeshTunnel3* t,
846                               GNUNET_PEER_Id p1, GNUNET_PEER_Id p2)
847 {
848 //   if (myid != p1 && myid != p2) FIXME
849 //   {
850 //     return;
851 //   }
852 //
853 //   if (tree_get_predecessor (t->tree) != 0)
854 //   {
855 //     /* We are the peer still connected, notify owner of the disconnection. */
856 //     struct GNUNET_MESH_PathBroken msg;
857 //     struct GNUNET_PeerIdentity neighbor;
858 //
859 //     msg.header.size = htons (sizeof (msg));
860 //     msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_PATH_BROKEN);
861 //     GNUNET_PEER_resolve (t->id.oid, &msg.oid);
862 //     msg.tid = htonl (t->id.tid);
863 //     msg.peer1 = my_full_id;
864 //     GNUNET_PEER_resolve (pid, &msg.peer2);
865 //     GNUNET_PEER_resolve (tree_get_predecessor (t->tree), &neighbor);
866 //     send_prebuilt_message (&msg.header, &neighbor, t);
867 //   }
868   return 0;
869 }
870
871 /**
872  * @brief Use the given path for the tunnel.
873  * Update the next and prev hops (and RCs).
874  * (Re)start the path refresh in case the tunnel is locally owned.
875  *
876  * @param t Tunnel to update.
877  * @param p Path to use.
878  *
879  * @return Connection created.
880  */
881 struct MeshConnection *
882 GMT_use_path (struct MeshTunnel3 *t, struct MeshPeerPath *p)
883 {
884   struct MeshConnection *c;
885   struct GNUNET_HashCode cid;
886   unsigned int own_pos;
887
888   if (NULL == t || NULL == p)
889   {
890     GNUNET_break (0);
891     return NULL;
892   }
893
894   for (own_pos = 0; own_pos < p->length; own_pos++)
895   {
896     if (p->peers[own_pos] == myid)
897       break;
898   }
899   if (own_pos > p->length - 1)
900   {
901     GNUNET_break (0);
902     return NULL;
903   }
904
905   GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_NONCE, &cid);
906   c = GMC_new (&cid, t, p, own_pos);
907   GMT_add_connection (t, c);
908   return c;
909 }
910
911
912 /**
913  * FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME
914  * Encrypt data with the tunnel key.
915  * Make static?
916  *
917  * @param t Tunnel whose key to use.
918  * @param dst Destination for the encrypted data.
919  * @param src Source of the plaintext.
920  * @param size Size of the plaintext.
921  * @param iv Initialization Vector to use.
922  * @param fwd Is this a fwd message?
923  */
924 void
925 GMT_encrypt (struct MeshTunnel3 *t,
926              void *dst, const void *src,
927              size_t size, uint64_t iv, int fwd)
928 {
929   memcpy (dst, src, size);
930 }
931
932
933 /**
934  * FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME
935  * Decrypt data with the tunnel key.
936  * Make static?
937  *
938  * @param t Tunnel whose key to use.
939  * @param dst Destination for the plaintext.
940  * @param src Source of the encrypted data.
941  * @param size Size of the encrypted data.
942  * @param iv Initialization Vector to use.
943  * @param fwd Is this a fwd message?
944  */
945 void
946 GMT_decrypt (struct MeshTunnel3 *t,
947              void *dst, const void *src,
948              size_t size, uint64_t iv, int fwd)
949 {
950   memcpy (dst, src, size);
951 }
952
953
954 /**
955  * Count established (ready) connections of a tunnel.
956  *
957  * @param t Tunnel on which to count.
958  *
959  * @return Number of connections.
960  */
961 unsigned int
962 GMT_count_connections (struct MeshTunnel3 *t)
963 {
964   struct MeshTConnection *iter;
965   unsigned int count;
966
967   for (count = 0, iter = t->connection_head;
968        NULL != iter;
969        iter = iter->next, count++);
970
971   return count;
972 }
973
974 /**
975  * Count channels of a tunnel.
976  *
977  * @param t Tunnel on which to count.
978  *
979  * @return Number of channels.
980  */
981 unsigned int
982 GMT_count_channels (struct MeshTunnel3 *t)
983 {
984   struct MeshTChannel *iter;
985   unsigned int count;
986
987   for (count = 0, iter = t->channel_head;
988        NULL != iter;
989   iter = iter->next, count++);
990
991   return count;
992 }
993
994
995 /**
996  * Get the state of a tunnel.
997  *
998  * @param t Tunnel.
999  *
1000  * @return Tunnel's state.
1001  */
1002 enum MeshTunnel3State
1003 GMT_get_state (struct MeshTunnel3 *t)
1004 {
1005   if (NULL == t)
1006     return (enum MeshTunnel3State) -1;
1007   return t->state;
1008 }
1009
1010 /**
1011  * Get the total buffer space for a tunnel.
1012  *
1013  * @param t Tunnel.
1014  * @param fwd Is this for FWD traffic?
1015  *
1016  * @return Buffer space offered by all connections in the tunnel.
1017  */
1018 unsigned int
1019 GMT_get_buffer (struct MeshTunnel3 *t, int fwd)
1020 {
1021   struct MeshTConnection *iter;
1022   unsigned int buffer;
1023
1024   iter = t->connection_head;
1025   buffer = 0;
1026
1027   /* If terminal, return biggest channel buffer */
1028   if (NULL == iter || GMC_is_terminal (iter->c, fwd))
1029   {
1030     struct MeshTChannel *iter_ch;
1031     unsigned int ch_buf;
1032
1033     if (NULL == t->channel_head)
1034       return 64;
1035
1036     for (iter_ch = t->channel_head; NULL != iter_ch; iter_ch = iter_ch->next)
1037     {
1038       ch_buf = GMCH_get_buffer (iter_ch->ch, fwd);
1039       if (ch_buf > buffer)
1040         buffer = ch_buf;
1041     }
1042     return buffer;
1043   }
1044
1045   /* If not terminal, return sum of connection buffers */
1046   while (NULL != iter)
1047   {
1048     if (GMC_get_state (iter->c) != MESH_CONNECTION_READY)
1049     {
1050       iter = iter->next;
1051       continue;
1052     }
1053
1054     buffer += GMC_get_buffer (iter->c, fwd);
1055     iter = iter->next;
1056   }
1057
1058   return buffer;
1059 }
1060
1061
1062 /**
1063  * Get the tunnel's destination.
1064  *
1065  * @param t Tunnel.
1066  *
1067  * @return ID of the destination peer.
1068  */
1069 const struct GNUNET_PeerIdentity *
1070 GMT_get_destination (struct MeshTunnel3 *t)
1071 {
1072   return GMP_get_id (t->peer);
1073 }
1074
1075
1076 /**
1077  * Get the tunnel's next free global channel ID.
1078  *
1079  * @param t Tunnel.
1080  *
1081  * @return GID of a channel free to use.
1082  */
1083 MESH_ChannelNumber
1084 GMT_get_next_chid (struct MeshTunnel3 *t)
1085 {
1086   MESH_ChannelNumber chid;
1087
1088   while (NULL != GMT_get_channel (t, t->next_chid))
1089   {
1090     LOG (GNUNET_ERROR_TYPE_DEBUG, "Channel %u exists...\n", t->next_chid);
1091     t->next_chid = (t->next_chid + 1) & ~GNUNET_MESH_LOCAL_CHANNEL_ID_CLI;
1092   }
1093   chid = t->next_chid;
1094   t->next_chid = (t->next_chid + 1) & ~GNUNET_MESH_LOCAL_CHANNEL_ID_CLI;
1095
1096   return chid;
1097 }
1098
1099
1100 /**
1101  * Sends an already built message on a tunnel, encrypting it and
1102  * choosing the best connection.
1103  *
1104  * @param message Message to send. Function modifies it.
1105  * @param t Tunnel on which this message is transmitted.
1106  * @param ch Channel on which this message is transmitted.
1107  * @param fwd Is this a fwd message?
1108  */
1109 void
1110 GMT_send_prebuilt_message (const struct GNUNET_MessageHeader *message,
1111                            struct MeshTunnel3 *t,
1112                            struct MeshChannel *ch,
1113                            int fwd)
1114 {
1115   struct MeshConnection *c;
1116   struct GNUNET_MESH_Encrypted *msg;
1117   size_t size = ntohs (message->size);
1118   char *cbuf[sizeof (struct GNUNET_MESH_Encrypted) + size];
1119   uint64_t iv;
1120   uint16_t type;
1121
1122   LOG (GNUNET_ERROR_TYPE_DEBUG, "Send on Tunnel %s\n", GMP_2s (t->peer));
1123
1124   iv = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_NONCE, UINT64_MAX);
1125   msg = (struct GNUNET_MESH_Encrypted *) cbuf;
1126   msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_ENCRYPTED);
1127   msg->header.size = htons (sizeof (struct GNUNET_MESH_Encrypted) + size);
1128   msg->iv = GNUNET_htonll (iv);
1129   GMT_encrypt (t, &msg[1], message, size, iv, fwd);
1130   c = tunnel_get_connection (t, fwd);
1131   if (NULL == c)
1132   {
1133     GNUNET_break (GNUNET_YES == t->destroy);
1134     return;
1135   }
1136   type = ntohs (message->type);
1137   switch (type)
1138   {
1139     case GNUNET_MESSAGE_TYPE_MESH_FWD:
1140     case GNUNET_MESSAGE_TYPE_MESH_BCK:
1141     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_CREATE:
1142     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_DESTROY:
1143       msg->cid = *GMC_get_id (c);
1144       msg->ttl = htonl (default_ttl);
1145       break;
1146     default:
1147       LOG (GNUNET_ERROR_TYPE_DEBUG, "unkown type %s\n",
1148            GNUNET_MESH_DEBUG_M2S (type));
1149       GNUNET_break (0);
1150   }
1151   msg->reserved = 0;
1152
1153   t->pending_messages++;
1154   GMC_send_prebuilt_message (&msg->header, c, ch, fwd);
1155 }
1156
1157 /**
1158  * Is the tunnel directed towards the local peer?
1159  *
1160  * @param t Tunnel.
1161  *
1162  * @return GNUNET_YES if it is loopback.
1163  */
1164 int
1165 GMT_is_loopback (const struct MeshTunnel3 *t)
1166 {
1167   return (myid == GMP_get_short_id(t->peer));
1168 }
1169
1170
1171 /**
1172  * Is the tunnel using this path already?
1173  *
1174  * @param t Tunnel.
1175  * @param p Path.
1176  *
1177  * @return GNUNET_YES a connection uses this path.
1178  */
1179 int
1180 GMT_is_path_used (const struct MeshTunnel3 *t, const struct MeshPeerPath *p)
1181 {
1182   struct MeshTConnection *iter;
1183
1184   for (iter = t->connection_head; NULL != iter; iter = iter->next)
1185     if (GMC_get_path (iter->c) == p)
1186       return GNUNET_YES;
1187
1188   return GNUNET_NO;
1189 }
1190
1191
1192 /**
1193  * Get a cost of a path for a tunnel considering existing connections.
1194  *
1195  * @param t Tunnel.
1196  * @param path Candidate path.
1197  *
1198  * @return Cost of the path (path length + number of overlapping nodes)
1199  */
1200 unsigned int
1201 GMT_get_path_cost (const struct MeshTunnel3 *t,
1202                    const struct MeshPeerPath *path)
1203 {
1204   struct MeshTConnection *iter;
1205   unsigned int overlap;
1206   unsigned int i;
1207   unsigned int j;
1208
1209   if (NULL == path)
1210     return 0;
1211
1212   overlap = 0;
1213   GNUNET_assert (NULL != t);
1214
1215   for (i = 0; i < path->length; i++)
1216   {
1217     for (iter = t->connection_head; NULL != iter; iter = iter->next)
1218     {
1219       for (j = 0; j < GMC_get_path (iter->c)->length; j++)
1220       {
1221         if (path->peers[i] == GMC_get_path (iter->c)->peers[j])
1222         {
1223           overlap++;
1224           break;
1225         }
1226       }
1227     }
1228   }
1229   return (path->length + overlap) * (path->score * -1);
1230 }
1231
1232
1233 /**
1234  * Get the static string for the peer this tunnel is directed.
1235  *
1236  * @param t Tunnel.
1237  *
1238  * @return Static string the destination peer's ID.
1239  */
1240 const char *
1241 GMT_2s (const struct MeshTunnel3 *t)
1242 {
1243   return GMP_2s (t->peer);
1244 }