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