- fix encryption/decryption visisbility
[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 /**
261  * FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME
262  * Encrypt data with the tunnel key.
263  * Make static?
264  *
265  * @param t Tunnel whose key to use.
266  * @param dst Destination for the GMT_encrypted data.
267  * @param src Source of the plaintext.
268  * @param size Size of the plaintext.
269  * @param iv Initialization Vector to use.
270  * @param fwd Is this a fwd message?
271  */
272 static void
273 GMT_encrypt (struct MeshTunnel3 *t,
274              void *dst, const void *src,
275              size_t size, uint64_t iv, int fwd)
276 {
277   memcpy (dst, src, size);
278 }
279
280
281 /**
282  * FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME
283  * Decrypt data with the tunnel key.
284  * Make static?
285  *
286  * @param t Tunnel whose key to use.
287  * @param dst Destination for the plaintext.
288  * @param src Source of the GMT_encrypted data.
289  * @param size Size of the GMT_encrypted data.
290  * @param iv Initialization Vector to use.
291  * @param fwd Is this a fwd message?
292  */
293 static void
294 GMT_decrypt (struct MeshTunnel3 *t,
295              void *dst, const void *src,
296              size_t size, uint64_t iv, int fwd)
297 {
298   memcpy (dst, src, size);
299 }
300
301
302 void
303 handle_data (struct MeshTunnel3 *t,
304              const struct GNUNET_MESH_Data *msg,
305              int fwd)
306 {
307   struct MeshChannel *ch;
308   uint16_t type;
309   size_t size;
310
311   /* Check size */
312   size = ntohs (msg->header.size);
313   if (size <
314       sizeof (struct GNUNET_MESH_Data) +
315       sizeof (struct GNUNET_MessageHeader))
316   {
317     GNUNET_break (0);
318     return;
319   }
320   type = ntohs (msg->header.type);
321   LOG (GNUNET_ERROR_TYPE_DEBUG, "got a %s message\n",
322               GNUNET_MESH_DEBUG_M2S (type));
323   LOG (GNUNET_ERROR_TYPE_DEBUG, " payload of type %s\n",
324               GNUNET_MESH_DEBUG_M2S (ntohs (msg[1].header.type)));
325
326   /* Check channel */
327   ch = GMT_get_channel (t, ntohl (msg->chid));
328   if (NULL == ch)
329   {
330     GNUNET_STATISTICS_update (stats, "# data on unknown channel",
331                               1, GNUNET_NO);
332     LOG (GNUNET_ERROR_TYPE_DEBUG, "WARNING channel %u unknown\n",
333          ntohl (msg->chid));
334     return;
335   }
336
337   GMT_change_state (t, MESH_TUNNEL3_READY);
338   GMCH_handle_data (ch, msg, fwd);
339 }
340
341 void
342 handle_data_ack (struct MeshTunnel3 *t,
343                  const struct GNUNET_MESH_DataACK *msg,
344                  int fwd)
345 {
346   struct MeshChannel *ch;
347   size_t size;
348
349   /* Check size */
350   size = ntohs (msg->header.size);
351   if (size != sizeof (struct GNUNET_MESH_DataACK))
352   {
353     GNUNET_break (0);
354     return;
355   }
356
357   /* Check channel */
358   ch = GMT_get_channel (t, ntohl (msg->chid));
359   if (NULL == ch)
360   {
361     GNUNET_STATISTICS_update (stats, "# data ack on unknown channel",
362                               1, GNUNET_NO);
363     LOG (GNUNET_ERROR_TYPE_DEBUG, "WARNING channel %u unknown\n",
364          ntohl (msg->chid));
365     return;
366   }
367
368   GMCH_handle_data_ack (ch, msg, fwd);
369 }
370
371 void
372 handle_ch_create (struct MeshTunnel3 *t,
373                   const struct GNUNET_MESH_ChannelCreate *msg,
374                   int fwd)
375 {
376   struct MeshTChannel *tch;
377   struct MeshChannel *ch;
378   size_t size;
379
380   /* Check size */
381   size = ntohs (msg->header.size);
382   if (size != sizeof (struct GNUNET_MESH_ChannelCreate))
383   {
384     GNUNET_break (0);
385     return;
386   }
387
388   /* Check channel */
389   ch = GMT_get_channel (t, ntohl (msg->chid));
390   if (NULL != ch)
391   {
392     /* Probably a retransmission, safe to ignore */
393     LOG (GNUNET_ERROR_TYPE_DEBUG, "   already exists...\n");
394   }
395   else
396   {
397     ch = GMCH_handle_create (msg, fwd);
398   }
399
400   tch = GNUNET_new (struct MeshTChannel);
401   tch->ch = ch;
402   GNUNET_CONTAINER_DLL_insert (t->channel_head, t->channel_tail, tch);
403 }
404
405 void
406 handle_ch_ack (struct MeshTunnel3 *t,
407                const struct GNUNET_MESH_ChannelManage *msg,
408                int fwd)
409 {
410   struct MeshChannel *ch;
411   size_t size;
412
413   /* Check size */
414   size = ntohs (msg->header.size);
415   if (size != sizeof (struct GNUNET_MESH_ChannelManage))
416   {
417     GNUNET_break (0);
418     return;
419   }
420
421   /* Check channel */
422   ch = GMT_get_channel (t, ntohl (msg->chid));
423   if (NULL == ch)
424   {
425     GNUNET_STATISTICS_update (stats, "# channel ack on unknown channel",
426                               1, GNUNET_NO);
427     LOG (GNUNET_ERROR_TYPE_DEBUG, "WARNING channel %u unknown\n",
428          ntohl (msg->chid));
429     return;
430   }
431
432   GMCH_handle_ack (ch, msg, fwd);
433 }
434
435 void
436 handle_ch_destroy (struct MeshTunnel3 *t,
437                    const struct GNUNET_MESH_ChannelManage *msg,
438                    int fwd)
439 {
440   struct MeshChannel *ch;
441   size_t size;
442
443   /* Check size */
444   size = ntohs (msg->header.size);
445   if (size != sizeof (struct GNUNET_MESH_ChannelManage))
446   {
447     GNUNET_break (0);
448     return;
449   }
450
451   /* Check channel */
452   ch = GMT_get_channel (t, ntohl (msg->chid));
453   if (NULL == ch)
454   {
455     /* Probably a retransmission, safe to ignore */
456     return;
457   }
458
459   GMCH_handle_destroy (ch, msg, fwd);
460 }
461
462
463 /**
464  * Demultiplex by message type and call appropriate handler for a message
465  * towards a channel of a local tunnel.
466  *
467  * @param t Tunnel this message came on.
468  * @param msgh Message header.
469  * @param fwd Is this message fwd?
470  */
471 static void
472 handle_GMT_decrypted (struct MeshTunnel3 *t,
473                   const struct GNUNET_MessageHeader *msgh,
474                   int fwd)
475 {
476   uint16_t type;
477
478   type = ntohs (msgh->type);
479   LOG (GNUNET_ERROR_TYPE_DEBUG,
480        "Got a %s message!\n",
481        GNUNET_MESH_DEBUG_M2S (type));
482
483   switch (type)
484   {
485     case GNUNET_MESSAGE_TYPE_MESH_DATA:
486       /* Don't send hop ACK, wait for client to ACK */
487       handle_data (t, (struct GNUNET_MESH_Data *) msgh, fwd);
488       break;
489
490     case GNUNET_MESSAGE_TYPE_MESH_DATA_ACK:
491       handle_data_ack (t, (struct GNUNET_MESH_DataACK *) msgh, fwd);
492       break;
493
494     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_CREATE:
495       handle_ch_create (t,
496                         (struct GNUNET_MESH_ChannelCreate *) msgh,
497                         fwd);
498       break;
499
500     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_ACK:
501       handle_ch_ack (t,
502                      (struct GNUNET_MESH_ChannelManage *) msgh,
503                      fwd);
504       break;
505
506     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_DESTROY:
507       handle_ch_destroy (t,
508                          (struct GNUNET_MESH_ChannelManage *) msgh,
509                          fwd);
510       break;
511
512     default:
513       GNUNET_break_op (0);
514       LOG (GNUNET_ERROR_TYPE_DEBUG,
515            "end-to-end message not known (%u)\n",
516            ntohs (msgh->type));
517   }
518 }
519
520 /******************************************************************************/
521 /********************************    API    ***********************************/
522 /******************************************************************************/
523
524
525 /**
526  * Decrypt and demultiplex by message type. Call appropriate handler
527  * for every message.
528  *
529  * @param t Tunnel this message came on.
530  * @param msgh Encrypted message.
531  * @param fwd Is this message fwd?
532  */
533 void
534 GMT_handle_GMT_encrypted (struct MeshTunnel3 *t,
535                       const struct GNUNET_MESH_Encrypted *msg,
536                       int fwd)
537 {
538   size_t size = ntohs (msg->header.size);
539   size_t payload_size = size - sizeof (struct GNUNET_MESH_Encrypted);
540   char cbuf[payload_size];
541   struct GNUNET_MessageHeader *msgh;
542   unsigned int off;
543
544   GMT_decrypt (t, cbuf, &msg[1], payload_size, msg->iv, fwd);
545   off = 0;
546   while (off < payload_size)
547   {
548     msgh = (struct GNUNET_MessageHeader *) &cbuf[off];
549     handle_GMT_decrypted (t, msgh, fwd);
550     off += ntohs (msgh->size);
551   }
552 }
553
554
555 /**
556  * Cache a message to be sent once tunnel is online.
557  *
558  * @param t Tunnel to hold the message.
559  * @param ch Channel the message is about.
560  * @param msg Message itself (copy will be made).
561  * @param fwd Is this fwd?
562  */
563 void
564 GMT_queue_data (struct MeshTunnel3 *t,
565                 struct MeshChannel *ch,
566                 struct GNUNET_MessageHeader *msg,
567                 int fwd)
568 {
569   struct MeshTunnelQueue *tq;
570   uint16_t size = ntohs (msg->size);
571
572   tq = GNUNET_malloc (sizeof (struct MeshTunnelQueue) + size);
573
574   tq->ch = ch;
575   memcpy (&tq[1], msg, size);
576   GNUNET_CONTAINER_DLL_insert_tail (t->tq_head, t->tq_tail, tq);
577
578   if (MESH_TUNNEL3_READY == t->state)
579     GMT_send_queued_data (t, fwd);
580 }
581
582
583 /**
584  * Send all cached messages that we can, tunnel is online.
585  *
586  * @param t Tunnel that holds the messages.
587  * @param fwd Is this fwd?
588  */
589 void
590 GMT_send_queued_data (struct MeshTunnel3 *t, int fwd)
591 {
592   struct MeshTunnelQueue *tq;
593   struct MeshTunnelQueue *next;
594   unsigned int room;
595
596   LOG (GNUNET_ERROR_TYPE_DEBUG,
597               "GMT_send_queued_data on tunnel %s\n",
598               GMP_2s (t->peer));
599   room = GMT_get_buffer (t, fwd);
600   LOG (GNUNET_ERROR_TYPE_DEBUG, "  buffer space: %u\n", room);
601   for (tq = t->tq_head; NULL != tq && room > 0; tq = next)
602   {
603     next = tq->next;
604     room--;
605     GNUNET_CONTAINER_DLL_remove (t->tq_head, t->tq_tail, tq);
606     GMCH_send_prebuilt_message ((struct GNUNET_MessageHeader *) &tq[1],
607                                 tq->ch, fwd);
608
609     GNUNET_free (tq);
610   }
611 }
612
613
614 /**
615  * Initialize the tunnel subsystem.
616  *
617  * @param c Configuration handle.
618  * @param id Peer identity.
619  * @param key ECC private key, to derive all other keys and do crypto.
620  */
621 void
622 GMT_init (const struct GNUNET_CONFIGURATION_Handle *c,
623           const struct GNUNET_CRYPTO_EddsaPrivateKey *key)
624 {
625   if (GNUNET_OK !=
626       GNUNET_CONFIGURATION_get_value_number (c, "MESH", "DEFAULT_TTL",
627                                              &default_ttl))
628   {
629     GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING,
630                                "MESH", "DEFAULT_TTL", "USING DEFAULT");
631     default_ttl = 64;
632   }
633   my_private_key = key;
634 }
635
636
637 /**
638  * Shut down the tunnel subsystem.
639  */
640 void
641 GMT_shutdown (void)
642 {
643   GNUNET_PEER_change_rc (myid, -1);
644 }
645
646
647 /**
648  * Create a tunnel.
649  *
650  * @param destination Peer this tunnel is towards.
651  */
652 struct MeshTunnel3 *
653 GMT_new (struct MeshPeer *destination)
654 {
655   struct MeshTunnel3 *t;
656
657   t = GNUNET_new (struct MeshTunnel3);
658   t->next_chid = 0;
659   t->peer = destination;
660 //   if (GNUNET_OK !=
661 //       GNUNET_CONTAINER_multihashmap_put (tunnels, tid, t,
662 //                                          GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
663 //   {
664 //     GNUNET_break (0);
665 //     tunnel_destroy (t);
666 //     return NULL;
667 //   }
668
669 //   char salt[] = "salt";
670 //   GNUNET_CRYPTO_kdf (&t->e_key, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
671 //                      salt, sizeof (salt),
672 //                      &t->e_key, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
673 //                      &my_full_id, sizeof (struct GNUNET_PeerIdentity),
674 //                      GNUNET_PEER_resolve2 (t->peer->id), sizeof (struct GNUNET_PeerIdentity),
675 //                      NULL);
676 //   GNUNET_CRYPTO_kdf (&t->d_key, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
677 //                      salt, sizeof (salt),
678 //                      &t->d_key, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
679 //                      GNUNET_PEER_resolve2 (t->peer->id), sizeof (struct GNUNET_PeerIdentity),
680 //                      &my_full_id, sizeof (struct GNUNET_PeerIdentity),
681 //                      NULL);
682
683   return t;
684 }
685
686
687 /**
688  * Change the tunnel state.
689  *
690  * @param t Tunnel whose state to change.
691  * @param state New state.
692  */
693 void
694 GMT_change_state (struct MeshTunnel3* t, enum MeshTunnel3State state)
695 {
696   if (NULL == t)
697     return;
698   LOG (GNUNET_ERROR_TYPE_DEBUG,
699               "Tunnel %s state was %s\n",
700               GMP_2s (t->peer),
701               GMT_state2s (t->state));
702   LOG (GNUNET_ERROR_TYPE_DEBUG,
703               "Tunnel %s state is now %s\n",
704               GMP_2s (t->peer),
705               GMT_state2s (state));
706   t->state = state;
707   if (MESH_TUNNEL3_READY == state && 3 <= GMT_count_connections (t))
708   {
709     GMP_stop_search (t->peer);
710   }
711 }
712
713
714 /**
715  * Add a connection to a tunnel.
716  *
717  * @param t Tunnel.
718  * @param c Connection.
719  */
720 void
721 GMT_add_connection (struct MeshTunnel3 *t, struct MeshConnection *c)
722 {
723   struct MeshTConnection *aux;
724
725   for (aux = t->connection_head; aux != NULL; aux = aux->next)
726     if (aux->c == c)
727       return;
728
729   aux = GNUNET_new (struct MeshTConnection);
730   aux->c = c;
731   GNUNET_CONTAINER_DLL_insert_tail (t->connection_head, t->connection_tail, aux);
732 }
733
734
735 /**
736  * Remove a connection from a tunnel.
737  *
738  * @param t Tunnel.
739  * @param c Connection.
740  */
741 void
742 GMT_remove_connection (struct MeshTunnel3 *t, struct MeshConnection *c)
743 {
744   struct MeshTConnection *aux;
745
746   for (aux = t->connection_head; aux != NULL; aux = aux->next)
747     if (aux->c == c)
748     {
749       GNUNET_CONTAINER_DLL_remove (t->connection_head, t->connection_tail, aux);
750       GNUNET_free (aux);
751       return;
752     }
753 }
754
755
756 /**
757  * Add a channel to a tunnel.
758  *
759  * @param t Tunnel.
760  * @param ch Channel.
761  */
762 void
763 GMT_add_channel (struct MeshTunnel3 *t, struct MeshChannel *ch)
764 {
765   struct MeshTChannel *aux;
766
767   for (aux = t->channel_head; aux != NULL; aux = aux->next)
768     if (aux->ch == ch)
769       return;
770
771   aux = GNUNET_new (struct MeshTChannel);
772   aux->ch = ch;
773   GNUNET_CONTAINER_DLL_insert_tail (t->channel_head, t->channel_tail, aux);
774 }
775
776
777 /**
778  * Remove a channel from a tunnel.
779  *
780  * @param t Tunnel.
781  * @param ch Channel.
782  */
783 void
784 GMT_remove_channel (struct MeshTunnel3 *t, struct MeshChannel *ch)
785 {
786   struct MeshTChannel *aux;
787
788   for (aux = t->channel_head; aux != NULL; aux = aux->next)
789     if (aux->ch == ch)
790     {
791       GNUNET_CONTAINER_DLL_remove (t->channel_head, t->channel_tail, aux);
792       GNUNET_free (aux);
793       return;
794     }
795 }
796
797
798 /**
799  * Search for a channel by global ID.
800  *
801  * @param t Tunnel containing the channel.
802  * @param chid Public channel number.
803  *
804  * @return channel handler, NULL if doesn't exist
805  */
806 struct MeshChannel *
807 GMT_get_channel (struct MeshTunnel3 *t, MESH_ChannelNumber chid)
808 {
809   struct MeshTChannel *iter;
810
811   if (NULL == t)
812     return NULL;
813
814   for (iter = t->channel_head; NULL != iter; iter = iter->next)
815   {
816     if (GMCH_get_id (iter->ch) == chid)
817       break;
818   }
819
820   return NULL == iter ? NULL : iter->ch;
821 }
822
823
824 /**
825  * Tunnel is empty: destroy it.
826  *
827  * Notifies all connections about the destruction.
828  *
829  * @param t Tunnel to destroy.
830  */
831 void
832 GMT_destroy_empty (struct MeshTunnel3 *t)
833 {
834   struct MeshTConnection *iter;
835
836   for (iter = t->connection_head; NULL != iter; iter = iter->next)
837   {
838     GMC_send_destroy (iter->c);
839   }
840
841   if (0 == t->pending_messages)
842     GMT_destroy (t);
843   else
844     t->destroy = GNUNET_YES;
845 }
846
847
848 /**
849  * Destroy tunnel if empty (no more channels).
850  *
851  * @param t Tunnel to destroy if empty.
852  */
853 void
854 GMT_destroy_if_empty (struct MeshTunnel3 *t)
855 {
856   if (1 < GMT_count_channels (t))
857     return;
858
859   GMT_destroy_empty (t);
860 }
861
862
863 /**
864  * Destroy the tunnel.
865  *
866  * This function does not generate any warning traffic to clients or peers.
867  *
868  * Tasks:
869  * Cancel messages belonging to this tunnel queued to neighbors.
870  * Free any allocated resources linked to the tunnel.
871  *
872  * @param t The tunnel to destroy.
873  */
874 void
875 GMT_destroy (struct MeshTunnel3 *t)
876 {
877   struct MeshTConnection *iter;
878   struct MeshTConnection *next;
879
880   if (NULL == t)
881     return;
882
883   LOG (GNUNET_ERROR_TYPE_DEBUG, "destroying tunnel %s\n", GMP_2s (t->peer));
884
885 //   if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_remove (tunnels, &t->id, t))
886 //     GNUNET_break (0);
887
888   for (iter = t->connection_head; NULL != iter; iter = next)
889   {
890     next = iter->next;
891     GMC_destroy (iter->c);
892     GNUNET_free (iter);
893   }
894
895   GNUNET_STATISTICS_update (stats, "# tunnels", -1, GNUNET_NO);
896   GMP_set_tunnel (t->peer, NULL);
897
898   GNUNET_free (t);
899 }
900
901
902 /**
903  * @brief Use the given path for the tunnel.
904  * Update the next and prev hops (and RCs).
905  * (Re)start the path refresh in case the tunnel is locally owned.
906  *
907  * @param t Tunnel to update.
908  * @param p Path to use.
909  *
910  * @return Connection created.
911  */
912 struct MeshConnection *
913 GMT_use_path (struct MeshTunnel3 *t, struct MeshPeerPath *p)
914 {
915   struct MeshConnection *c;
916   struct GNUNET_HashCode cid;
917   unsigned int own_pos;
918
919   if (NULL == t || NULL == p)
920   {
921     GNUNET_break (0);
922     return NULL;
923   }
924
925   for (own_pos = 0; own_pos < p->length; own_pos++)
926   {
927     if (p->peers[own_pos] == myid)
928       break;
929   }
930   if (own_pos > p->length - 1)
931   {
932     GNUNET_break (0);
933     return NULL;
934   }
935
936   GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_NONCE, &cid);
937   c = GMC_new (&cid, t, p, own_pos);
938   GMT_add_connection (t, c);
939   return c;
940 }
941
942
943 /**
944  * Count established (ready) connections of a tunnel.
945  *
946  * @param t Tunnel on which to count.
947  *
948  * @return Number of connections.
949  */
950 unsigned int
951 GMT_count_connections (struct MeshTunnel3 *t)
952 {
953   struct MeshTConnection *iter;
954   unsigned int count;
955
956   for (count = 0, iter = t->connection_head;
957        NULL != iter;
958        iter = iter->next, count++);
959
960   return count;
961 }
962
963 /**
964  * Count channels of a tunnel.
965  *
966  * @param t Tunnel on which to count.
967  *
968  * @return Number of channels.
969  */
970 unsigned int
971 GMT_count_channels (struct MeshTunnel3 *t)
972 {
973   struct MeshTChannel *iter;
974   unsigned int count;
975
976   for (count = 0, iter = t->channel_head;
977        NULL != iter;
978   iter = iter->next, count++);
979
980   return count;
981 }
982
983
984 /**
985  * Get the state of a tunnel.
986  *
987  * @param t Tunnel.
988  *
989  * @return Tunnel's state.
990  */
991 enum MeshTunnel3State
992 GMT_get_state (struct MeshTunnel3 *t)
993 {
994   if (NULL == t)
995     return (enum MeshTunnel3State) -1;
996   return t->state;
997 }
998
999 /**
1000  * Get the total buffer space for a tunnel.
1001  *
1002  * @param t Tunnel.
1003  * @param fwd Is this for FWD traffic?
1004  *
1005  * @return Buffer space offered by all connections in the tunnel.
1006  */
1007 unsigned int
1008 GMT_get_buffer (struct MeshTunnel3 *t, int fwd)
1009 {
1010   struct MeshTConnection *iter;
1011   unsigned int buffer;
1012
1013   iter = t->connection_head;
1014   buffer = 0;
1015
1016   /* If terminal, return biggest channel buffer */
1017   if (NULL == iter || GMC_is_terminal (iter->c, fwd))
1018   {
1019     struct MeshTChannel *iter_ch;
1020     unsigned int ch_buf;
1021
1022     if (NULL == t->channel_head)
1023       return 64;
1024
1025     for (iter_ch = t->channel_head; NULL != iter_ch; iter_ch = iter_ch->next)
1026     {
1027       ch_buf = GMCH_get_buffer (iter_ch->ch, fwd);
1028       if (ch_buf > buffer)
1029         buffer = ch_buf;
1030     }
1031     return buffer;
1032   }
1033
1034   /* If not terminal, return sum of connection buffers */
1035   while (NULL != iter)
1036   {
1037     if (GMC_get_state (iter->c) != MESH_CONNECTION_READY)
1038     {
1039       iter = iter->next;
1040       continue;
1041     }
1042
1043     buffer += GMC_get_buffer (iter->c, fwd);
1044     iter = iter->next;
1045   }
1046
1047   return buffer;
1048 }
1049
1050
1051 /**
1052  * Get the tunnel's destination.
1053  *
1054  * @param t Tunnel.
1055  *
1056  * @return ID of the destination peer.
1057  */
1058 const struct GNUNET_PeerIdentity *
1059 GMT_get_destination (struct MeshTunnel3 *t)
1060 {
1061   return GMP_get_id (t->peer);
1062 }
1063
1064
1065 /**
1066  * Get the tunnel's next free global channel ID.
1067  *
1068  * @param t Tunnel.
1069  *
1070  * @return GID of a channel free to use.
1071  */
1072 MESH_ChannelNumber
1073 GMT_get_next_chid (struct MeshTunnel3 *t)
1074 {
1075   MESH_ChannelNumber chid;
1076
1077   while (NULL != GMT_get_channel (t, t->next_chid))
1078   {
1079     LOG (GNUNET_ERROR_TYPE_DEBUG, "Channel %u exists...\n", t->next_chid);
1080     t->next_chid = (t->next_chid + 1) & ~GNUNET_MESH_LOCAL_CHANNEL_ID_CLI;
1081   }
1082   chid = t->next_chid;
1083   t->next_chid = (t->next_chid + 1) & ~GNUNET_MESH_LOCAL_CHANNEL_ID_CLI;
1084
1085   return chid;
1086 }
1087
1088
1089 /**
1090  * Sends an already built message on a tunnel, GMT_encrypting it and
1091  * choosing the best connection.
1092  *
1093  * @param message Message to send. Function modifies it.
1094  * @param t Tunnel on which this message is transmitted.
1095  * @param ch Channel on which this message is transmitted.
1096  * @param fwd Is this a fwd message?
1097  */
1098 void
1099 GMT_send_prebuilt_message (const struct GNUNET_MessageHeader *message,
1100                            struct MeshTunnel3 *t,
1101                            struct MeshChannel *ch,
1102                            int fwd)
1103 {
1104   struct MeshConnection *c;
1105   struct GNUNET_MESH_Encrypted *msg;
1106   size_t size = ntohs (message->size);
1107   char *cbuf[sizeof (struct GNUNET_MESH_Encrypted) + size];
1108   uint64_t iv;
1109   uint16_t type;
1110
1111   LOG (GNUNET_ERROR_TYPE_DEBUG, "Send on Tunnel %s\n", GMP_2s (t->peer));
1112
1113   iv = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_NONCE, UINT64_MAX);
1114   msg = (struct GNUNET_MESH_Encrypted *) cbuf;
1115   msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_ENCRYPTED);
1116   msg->header.size = htons (sizeof (struct GNUNET_MESH_Encrypted) + size);
1117   msg->iv = GNUNET_htonll (iv);
1118   GMT_encrypt (t, &msg[1], message, size, iv, fwd);
1119   c = tunnel_get_connection (t, fwd);
1120   if (NULL == c)
1121   {
1122     GNUNET_break (GNUNET_YES == t->destroy);
1123     return;
1124   }
1125   type = ntohs (message->type);
1126   switch (type)
1127   {
1128     case GNUNET_MESSAGE_TYPE_MESH_FWD:
1129     case GNUNET_MESSAGE_TYPE_MESH_BCK:
1130     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_CREATE:
1131     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_DESTROY:
1132       msg->cid = *GMC_get_id (c);
1133       msg->ttl = htonl (default_ttl);
1134       break;
1135     default:
1136       LOG (GNUNET_ERROR_TYPE_DEBUG, "unkown type %s\n",
1137            GNUNET_MESH_DEBUG_M2S (type));
1138       GNUNET_break (0);
1139   }
1140   msg->reserved = 0;
1141
1142   t->pending_messages++;
1143   GMC_send_prebuilt_message (&msg->header, c, ch, fwd);
1144 }
1145
1146 /**
1147  * Is the tunnel directed towards the local peer?
1148  *
1149  * @param t Tunnel.
1150  *
1151  * @return GNUNET_YES if it is loopback.
1152  */
1153 int
1154 GMT_is_loopback (const struct MeshTunnel3 *t)
1155 {
1156   return (myid == GMP_get_short_id(t->peer));
1157 }
1158
1159
1160 /**
1161  * Is the tunnel using this path already?
1162  *
1163  * @param t Tunnel.
1164  * @param p Path.
1165  *
1166  * @return GNUNET_YES a connection uses this path.
1167  */
1168 int
1169 GMT_is_path_used (const struct MeshTunnel3 *t, const struct MeshPeerPath *p)
1170 {
1171   struct MeshTConnection *iter;
1172
1173   for (iter = t->connection_head; NULL != iter; iter = iter->next)
1174     if (GMC_get_path (iter->c) == p)
1175       return GNUNET_YES;
1176
1177   return GNUNET_NO;
1178 }
1179
1180
1181 /**
1182  * Get a cost of a path for a tunnel considering existing connections.
1183  *
1184  * @param t Tunnel.
1185  * @param path Candidate path.
1186  *
1187  * @return Cost of the path (path length + number of overlapping nodes)
1188  */
1189 unsigned int
1190 GMT_get_path_cost (const struct MeshTunnel3 *t,
1191                    const struct MeshPeerPath *path)
1192 {
1193   struct MeshTConnection *iter;
1194   unsigned int overlap;
1195   unsigned int i;
1196   unsigned int j;
1197
1198   if (NULL == path)
1199     return 0;
1200
1201   overlap = 0;
1202   GNUNET_assert (NULL != t);
1203
1204   for (i = 0; i < path->length; i++)
1205   {
1206     for (iter = t->connection_head; NULL != iter; iter = iter->next)
1207     {
1208       for (j = 0; j < GMC_get_path (iter->c)->length; j++)
1209       {
1210         if (path->peers[i] == GMC_get_path (iter->c)->peers[j])
1211         {
1212           overlap++;
1213           break;
1214         }
1215       }
1216     }
1217   }
1218   return (path->length + overlap) * (path->score * -1);
1219 }
1220
1221
1222 /**
1223  * Get the static string for the peer this tunnel is directed.
1224  *
1225  * @param t Tunnel.
1226  *
1227  * @return Static string the destination peer's ID.
1228  */
1229 const char *
1230 GMT_2s (const struct MeshTunnel3 *t)
1231 {
1232   return GMP_2s (t->peer);
1233 }