- MOve peer2s to peer section
[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-service-mesh_tunnel.h"
25 #include "gnunet-service-mesh_connection.h"
26 #include "gnunet-service-mesh_channel.h"
27 #include "mesh_path.h"
28
29
30 /**
31  * All the states a tunnel can be in.
32  */
33 enum MeshTunnelState
34 {
35     /**
36      * Uninitialized status, should never appear in operation.
37      */
38   MESH_TUNNEL_NEW,
39
40     /**
41      * Path to the peer not known yet
42      */
43   MESH_TUNNEL_SEARCHING,
44
45     /**
46      * Request sent, not yet answered.
47      */
48   MESH_TUNNEL_WAITING,
49
50     /**
51      * Peer connected and ready to accept data
52      */
53   MESH_TUNNEL_READY,
54
55     /**
56      * Peer connected previosly but not responding
57      */
58   MESH_TUNNEL_RECONNECTING
59 };
60
61
62
63 /******************************************************************************/
64 /********************************   STRUCTS  **********************************/
65 /******************************************************************************/
66
67 /**
68  * Struct containing all information regarding a tunnel to a peer.
69  */
70 struct MeshTunnel2
71 {
72     /**
73      * Endpoint of the tunnel.
74      */
75   struct MeshPeer *peer;
76
77     /**
78      * State of the tunnel.
79      */
80   enum MeshTunnelState state;
81
82   /**
83    * Local peer ephemeral private key
84    */
85   struct GNUNET_CRYPTO_EccPrivateKey *my_eph_key;
86
87   /**
88    * Local peer ephemeral public key
89    */
90   struct GNUNET_CRYPTO_EccPublicSignKey *my_eph;
91
92   /**
93    * Remote peer's public key.
94    */
95   struct GNUNET_CRYPTO_EccPublicSignKey *peers_eph;
96
97   /**
98    * Encryption ("our") key.
99    */
100   struct GNUNET_CRYPTO_SymmetricSessionKey e_key;
101
102   /**
103    * Decryption ("their") key.
104    */
105   struct GNUNET_CRYPTO_SymmetricSessionKey d_key;
106
107   /**
108    * Paths that are actively used to reach the destination peer.
109    */
110   struct MeshConnection *connection_head;
111   struct MeshConnection *connection_tail;
112
113   /**
114    * Next connection number.
115    */
116   uint32_t next_cid;
117
118   /**
119    * Channels inside this tunnel.
120    */
121   struct MeshChannel *channel_head;
122   struct MeshChannel *channel_tail;
123
124   /**
125    * Channel ID for the next created channel.
126    */
127   MESH_ChannelNumber next_chid;
128
129   /**
130    * Channel ID for the next incoming channel.
131    */
132   MESH_ChannelNumber next_local_chid;
133
134   /**
135    * Pending message count.
136    */
137   int pending_messages;
138
139   /**
140    * Destroy flag: if true, destroy on last message.
141    */
142   int destroy;
143
144   /**
145    * Queued messages, to transmit once tunnel gets connected.
146    */
147   struct MeshTunnelQueue *tq_head;
148   struct MeshTunnelQueue *tq_tail;
149 };
150
151
152 /**
153  * Struct used to queue messages in a tunnel.
154  */
155 struct MeshTunnelQueue
156 {
157   /**
158    * DLL
159    */
160   struct MeshTunnelQueue *next;
161   struct MeshTunnelQueue *prev;
162
163   /**
164    * Channel.
165    */
166   struct MeshChannel *ch;
167
168   /**
169    * Message to send.
170    */
171   /* struct GNUNET_MessageHeader *msg; */
172 };
173
174 /******************************************************************************/
175 /*******************************   GLOBALS  ***********************************/
176 /******************************************************************************/
177
178 /**
179  * Default TTL for payload packets.
180  */
181 static unsigned long long default_ttl;
182
183 /**
184  * Local peer own ID (memory efficient handle).
185  */
186 static GNUNET_PEER_Id my_short_id;
187
188 /**
189  * Local peer own ID (full value).
190  */
191 const static struct GNUNET_PeerIdentity *my_full_id;
192
193 /**
194  * Own private key.
195  */
196 const static struct GNUNET_CRYPTO_EccPrivateKey *my_private_key;
197
198
199 /******************************************************************************/
200 /********************************   STATIC  ***********************************/
201 /******************************************************************************/
202
203
204 /**
205  * Get string description for tunnel state.
206  *
207  * @param s Tunnel state.
208  *
209  * @return String representation.
210  */
211 static const char *
212 GNUNET_MESH_DEBUG_TS2S (enum MeshTunnelState s)
213 {
214   static char buf[128];
215
216   switch (s)
217   {
218     case MESH_TUNNEL_NEW:
219       return "MESH_TUNNEL_NEW";
220     case MESH_TUNNEL_SEARCHING:
221       return "MESH_TUNNEL_SEARCHING";
222     case MESH_TUNNEL_WAITING:
223       return "MESH_TUNNEL_WAITING";
224     case MESH_TUNNEL_READY:
225       return "MESH_TUNNEL_READY";
226     case MESH_TUNNEL_RECONNECTING:
227       return "MESH_TUNNEL_RECONNECTING";
228
229     default:
230       sprintf (buf, "%u (UNKNOWN STATE)", s);
231       return buf;
232   }
233 }
234
235
236 /**
237  * Pick a connection on which send the next data message.
238  *
239  * @param t Tunnel on which to send the message.
240  * @param fwd Is this a fwd message?
241  *
242  * @return The connection on which to send the next message.
243  */
244 static struct MeshConnection *
245 tunnel_get_connection (struct MeshTunnel2 *t, int fwd)
246 {
247   struct MeshConnection *c;
248   struct MeshConnection *best;
249   struct MeshFlowControl *fc;
250   unsigned int lowest_q;
251
252   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tunnel_get_connection %s\n",
253               peer2s (t->peer));
254   best = NULL;
255   lowest_q = UINT_MAX;
256   for (c = t->connection_head; NULL != c; c = c->next)
257   {
258     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  connection %s: %u\n",
259                 GNUNET_h2s (&c->id), c->state);
260     if (MESH_CONNECTION_READY == c->state)
261     {
262       fc = fwd ? &c->fwd_fc : &c->bck_fc;
263       if (NULL == fc)
264       {
265         GNUNET_break (0);
266         continue;
267       }
268       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "    q_n %u, \n", fc->queue_n);
269       if (fc->queue_n < lowest_q)
270       {
271         best = c;
272         lowest_q = fc->queue_n;
273       }
274     }
275   }
276   return best;
277 }
278
279
280 /**
281  * Get the total buffer space for a tunnel.
282  *
283  * @param t Tunnel.
284  * @param fwd Is this for FWD traffic?
285  *
286  * @return Buffer space offered by all connections in the tunnel.
287  */
288 static unsigned int
289 tunnel_get_buffer (struct MeshTunnel2 *t, int fwd)
290 {
291   struct MeshConnection *c;
292   struct MeshFlowControl *fc;
293   unsigned int buffer;
294
295   c = t->connection_head;
296   buffer = 0;
297
298   /* If terminal, return biggest channel buffer */
299   if (NULL == c || GMC_is_terminal (c, fwd))
300   {
301     struct MeshChannel *ch;
302     unsigned int ch_buf;
303
304     if (NULL == t->channel_head)
305       return 64;
306
307     for (ch = t->channel_head; NULL != ch; ch = ch->next)
308     {
309       ch_buf = GMCH_get_buffer (ch, fwd);
310       if (ch_buf > buffer)
311         buffer = ch_buf;
312     }
313     return buffer;
314   }
315
316   /* If not terminal, return sum of connection buffers */
317   while (NULL != c)
318   {
319     if (c->state != MESH_CONNECTION_READY)
320     {
321       c = c->next;
322       continue;
323     }
324
325     fc = fwd ? &c->fwd_fc : &c->bck_fc;
326     buffer += fc->queue_max - fc->queue_n;
327     c = c->next;
328   }
329
330   return buffer;
331 }
332
333
334 /**
335  * Send all cached messages that we can, tunnel is online.
336  *
337  * @param t Tunnel that holds the messages.
338  * @param fwd Is this fwd?
339  */
340 static void
341 tunnel_send_queued_data (struct MeshTunnel2 *t, int fwd)
342 {
343   struct MeshTunnelQueue *tq;
344   struct MeshTunnelQueue *next;
345   unsigned int room;
346
347   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
348               "tunnel_send_queued_data on tunnel %s\n",
349               peer2s (t->peer));
350   room = tunnel_get_buffer (t, fwd);
351   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  buffer space: %u\n", room);
352   for (tq = t->tq_head; NULL != tq && room > 0; tq = next)
353   {
354     next = tq->next;
355     room--;
356     GNUNET_CONTAINER_DLL_remove (t->tq_head, t->tq_tail, tq);
357     GMCH_send_prebuilt_message ((struct GNUNET_MessageHeader *) &tq[1],
358                                 tq->ch, fwd);
359
360     GNUNET_free (tq);
361   }
362 }
363
364
365 /**
366  * Cache a message to be sent once tunnel is online.
367  *
368  * @param t Tunnel to hold the message.
369  * @param ch Channel the message is about.
370  * @param msg Message itself (copy will be made).
371  * @param fwd Is this fwd?
372  */
373 static void
374 tunnel_queue_data (struct MeshTunnel2 *t,
375                    struct MeshChannel *ch,
376                    struct GNUNET_MessageHeader *msg,
377                    int fwd)
378 {
379   struct MeshTunnelQueue *tq;
380   uint16_t size = ntohs (msg->size);
381
382   tq = GNUNET_malloc (sizeof (struct MeshTunnelQueue) + size);
383
384   tq->ch = ch;
385   memcpy (&tq[1], msg, size);
386   GNUNET_CONTAINER_DLL_insert_tail (t->tq_head, t->tq_tail, tq);
387
388   if (MESH_TUNNEL_READY == t->state)
389     tunnel_send_queued_data (t, fwd);
390 }
391
392
393
394 /******************************************************************************/
395 /********************************    API    ***********************************/
396 /******************************************************************************/
397
398 /**
399  * Initialize the tunnel subsystem.
400  *
401  * @param c Configuration handle.
402  * @param id Peer identity.
403  * @param key ECC private key, to derive all other keys and do crypto.
404  */
405 void
406 GMT_init (const struct GNUNET_CONFIGURATION_Handle *c,
407           const struct GNUNET_PeerIdentity *id,
408           const struct GNUNET_CRYPTO_EccPrivateKey *key)
409 {
410   if (GNUNET_OK !=
411       GNUNET_CONFIGURATION_get_value_number (c, "MESH", "DEFAULT_TTL",
412                                              &default_ttl))
413   {
414     GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING,
415                                "MESH", "DEFAULT_TTL", "USING DEFAULT");
416     default_ttl = 64;
417   }
418   my_full_id = id;
419   my_private_key = key;
420   my_short_id = GNUNET_PEER_intern (my_full_id);
421 }
422
423
424 /**
425  * Shut down the tunnel subsystem.
426  */
427 void
428 GMT_shutdown (void)
429 {
430   GNUNET_PEER_change_rc (my_short_id, -1);
431 }
432
433
434 /**
435  * Create a tunnel.
436  */
437 struct MeshTunnel2 *
438 GMT_new (void)
439 {
440   struct MeshTunnel2 *t;
441
442   t = GNUNET_new (struct MeshTunnel2);
443   t->next_chid = 0;
444   t->next_local_chid = GNUNET_MESH_LOCAL_CHANNEL_ID_SERV;
445 //   if (GNUNET_OK !=
446 //       GNUNET_CONTAINER_multihashmap_put (tunnels, tid, t,
447 //                                          GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
448 //   {
449 //     GNUNET_break (0);
450 //     tunnel_destroy (t);
451 //     return NULL;
452 //   }
453
454 //   char salt[] = "salt";
455 //   GNUNET_CRYPTO_kdf (&t->e_key, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
456 //                      salt, sizeof (salt),
457 //                      &t->e_key, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
458 //                      &my_full_id, sizeof (struct GNUNET_PeerIdentity),
459 //                      GNUNET_PEER_resolve2 (t->peer->id), sizeof (struct GNUNET_PeerIdentity),
460 //                      NULL);
461 //   GNUNET_CRYPTO_kdf (&t->d_key, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
462 //                      salt, sizeof (salt),
463 //                      &t->d_key, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
464 //                      GNUNET_PEER_resolve2 (t->peer->id), sizeof (struct GNUNET_PeerIdentity),
465 //                      &my_full_id, sizeof (struct GNUNET_PeerIdentity),
466 //                      NULL);
467
468   return t;
469 }
470
471
472
473 /**
474  * Change the tunnel state.
475  *
476  * @param t Tunnel whose state to change.
477  * @param state New state.
478  */
479 static void
480 tunnel_change_state (struct MeshTunnel2* t, enum MeshTunnelState state)
481 {
482   if (NULL == t)
483     return;
484   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
485               "Tunnel %s state was %s\n",
486               peer2s (t->peer),
487               GNUNET_MESH_DEBUG_TS2S (t->state));
488   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
489               "Tunnel %s state is now %s\n",
490               peer2s (t->peer),
491               GNUNET_MESH_DEBUG_TS2S (state));
492   t->state = state;
493 }
494
495
496 /**
497  * Add a connection to a tunnel.
498  *
499  * @param t Tunnel.
500  * @param c Connection.
501  */
502 void
503 GMT_add_connection (struct MeshTunnel2 *t, struct MeshConnection *c)
504 {
505   struct MeshConnection *aux;
506   c->t = t;
507   for (aux = t->connection_head; aux != NULL; aux = aux->next)
508     if (aux == c)
509       return;
510     GNUNET_CONTAINER_DLL_insert_tail (t->connection_head, t->connection_tail, c);
511 }
512
513
514
515
516 /**
517  * Tunnel is empty: destroy it.
518  *
519  * Notifies all connections about the destruction.
520  *
521  * @param t Tunnel to destroy.
522  */
523 void
524 GMT_destroy_empty (struct MeshTunnel2 *t)
525 {
526   struct MeshConnection *c;
527
528   for (c = t->connection_head; NULL != c; c = c->next)
529   {
530     if (GNUNET_NO == c->destroy)
531       GMC_send_destroy (c);
532   }
533
534   if (0 == t->pending_messages)
535     GMT_destroy (t);
536   else
537     t->destroy = GNUNET_YES;
538 }
539
540
541 /**
542  * Destroy tunnel if empty (no more channels).
543  *
544  * @param t Tunnel to destroy if empty.
545  */
546 void
547 GMT_destroy_if_empty (struct MeshTunnel2 *t)
548 {
549   if (1 <= GMCH_count (t->channel_head))
550     return;
551
552   GMT_destroy_empty (t);
553 }
554
555
556
557 /**
558  * Destroy the tunnel.
559  *
560  * This function does not generate any warning traffic to clients or peers.
561  *
562  * Tasks:
563  * Cancel messages belonging to this tunnel queued to neighbors.
564  * Free any allocated resources linked to the tunnel.
565  *
566  * @param t The tunnel to destroy.
567  */
568 void
569 GMT_destroy (struct MeshTunnel2 *t)
570 {
571   struct MeshConnection *c;
572   struct MeshConnection *next;
573
574   if (NULL == t)
575     return;
576
577   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "destroying tunnel %s\n",
578               peer2s (t->peer));
579
580 //   if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_remove (tunnels, &t->id, t))
581 //     GNUNET_break (0);
582
583   for (c = t->connection_head; NULL != c; c = next)
584   {
585     next = c->next;
586     GMC_destroy (c);
587   }
588
589   GNUNET_STATISTICS_update (stats, "# tunnels", -1, GNUNET_NO);
590   t->peer->tunnel = NULL;
591
592   GNUNET_free (t);
593 }
594
595 /**
596  * Demultiplex by message type and call appropriate handler for a message
597  * towards a channel of a local tunnel.
598  *
599  * @param t Tunnel this message came on.
600  * @param msgh Message header.
601  * @param fwd Is this message fwd?
602  */
603 void
604 GMT_handle_decrypted (struct MeshTunnel2 *t,
605                       const struct GNUNET_MessageHeader *msgh,
606                       int fwd)
607 {
608   switch (ntohs (msgh->type))
609   {
610     case GNUNET_MESSAGE_TYPE_MESH_DATA:
611       /* Don't send hop ACK, wait for client to ACK */
612       handle_data (t, (struct GNUNET_MESH_Data *) msgh, fwd);
613       break;
614
615     case GNUNET_MESSAGE_TYPE_MESH_DATA_ACK:
616       handle_data_ack (t, (struct GNUNET_MESH_DataACK *) msgh, fwd);
617       break;
618
619     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_CREATE:
620       handle_channel_create (t,
621                              (struct GNUNET_MESH_ChannelCreate *) msgh,
622                              fwd);
623       break;
624
625     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_ACK:
626       handle_channel_ack (t,
627                           (struct GNUNET_MESH_ChannelManage *) msgh,
628                           fwd);
629       break;
630
631     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_DESTROY:
632       handle_channel_destroy (t,
633                               (struct GNUNET_MESH_ChannelManage *) msgh,
634                               fwd);
635       break;
636
637     default:
638       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
639                   "end-to-end message not known (%u)\n",
640                   ntohs (msgh->type));
641   }
642 }
643
644
645 /**
646  * Notifies a tunnel that a connection has broken that affects at least
647  * some of its peers. Sends a notification towards the root of the tree.
648  * In case the peer is the owner of the tree, notifies the client that owns
649  * the tunnel and tries to reconnect.
650  *
651  * FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME
652  *
653  * @param t Tunnel affected.
654  * @param p1 Peer that got disconnected from p2.
655  * @param p2 Peer that got disconnected from p1.
656  *
657  * @return Short ID of the peer disconnected (either p1 or p2).
658  *         0 if the tunnel remained unaffected.
659  */
660 static GNUNET_PEER_Id
661 GMT_notify_connection_broken (struct MeshTunnel2* t,
662                               GNUNET_PEER_Id p1, GNUNET_PEER_Id p2)
663 {
664 //   if (myid != p1 && myid != p2) FIXME
665 //   {
666 //     return;
667 //   }
668 //
669 //   if (tree_get_predecessor (t->tree) != 0)
670 //   {
671 //     /* We are the peer still connected, notify owner of the disconnection. */
672 //     struct GNUNET_MESH_PathBroken msg;
673 //     struct GNUNET_PeerIdentity neighbor;
674 //
675 //     msg.header.size = htons (sizeof (msg));
676 //     msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_PATH_BROKEN);
677 //     GNUNET_PEER_resolve (t->id.oid, &msg.oid);
678 //     msg.tid = htonl (t->id.tid);
679 //     msg.peer1 = my_full_id;
680 //     GNUNET_PEER_resolve (pid, &msg.peer2);
681 //     GNUNET_PEER_resolve (tree_get_predecessor (t->tree), &neighbor);
682 //     send_prebuilt_message (&msg.header, &neighbor, t);
683 //   }
684   return 0;
685 }
686
687 /**
688  * @brief Use the given path for the tunnel.
689  * Update the next and prev hops (and RCs).
690  * (Re)start the path refresh in case the tunnel is locally owned.
691  *
692  * @param t Tunnel to update.
693  * @param p Path to use.
694  *
695  * @return Connection created.
696  */
697 struct MeshConnection *
698 GMT_use_path (struct MeshTunnel2 *t, struct MeshPeerPath *p)
699 {
700   struct MeshConnection *c;
701   struct GNUNET_HashCode cid;
702   struct MeshPeer *peer;
703   unsigned int own_pos;
704
705   if (NULL == t || NULL == p)
706   {
707     GNUNET_break (0);
708     return NULL;
709   }
710
711   GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_NONCE, &cid);
712
713   c = GMC_new (&cid);
714   c->t = t;
715   GNUNET_CONTAINER_DLL_insert (t->connection_head, t->connection_tail, c);
716   for (own_pos = 0; own_pos < p->length; own_pos++)
717   {
718     if (p->peers[own_pos] == myid)
719       break;
720   }
721   if (own_pos > p->length - 1)
722   {
723     GNUNET_break (0);
724     connection_destroy (c);
725     return NULL;
726   }
727   c->own_pos = own_pos;
728   c->path = p;
729
730   if (0 == own_pos)
731   {
732     c->fwd_maintenance_task =
733         GNUNET_SCHEDULER_add_delayed (refresh_connection_time,
734                                       &connection_fwd_keepalive, c);
735   }
736
737   peer = connection_get_next_hop (c);
738   if (NULL == peer->connections)
739   {
740     connection_destroy (c);
741     return NULL;
742   }
743   GNUNET_CONTAINER_multihashmap_put (peer->connections, &c->id, c,
744                                      GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
745   peer = connection_get_prev_hop (c);
746   if (NULL == peer->connections)
747   {
748     connection_destroy (c);
749     return NULL;
750   }
751   GNUNET_CONTAINER_multihashmap_put (peer->connections, &c->id, c,
752                                      GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
753   return c;
754 }
755
756
757 /**
758  * FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME
759  * Encrypt data with the tunnel key.
760  *
761  * @param t Tunnel whose key to use.
762  * @param dst Destination for the encrypted data.
763  * @param src Source of the plaintext.
764  * @param size Size of the plaintext.
765  * @param iv Initialization Vector to use.
766  * @param fwd Is this a fwd message?
767  */
768 void
769 GMT_encrypt (struct MeshTunnel2 *t,
770              void *dst, const void *src,
771              size_t size, uint64_t iv, int fwd)
772 {
773   memcpy (dst, src, size);
774 }
775
776
777 /**
778  * FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME
779  * Decrypt data with the tunnel key.
780  *
781  * @param t Tunnel whose key to use.
782  * @param dst Destination for the plaintext.
783  * @param src Source of the encrypted data.
784  * @param size Size of the encrypted data.
785  * @param iv Initialization Vector to use.
786  * @param fwd Is this a fwd message?
787  */
788 void
789 GMT_decrypt (struct MeshTunnel2 *t,
790              void *dst, const void *src,
791              size_t size, uint64_t iv, int fwd)
792 {
793   memcpy (dst, src, size);
794 }
795
796
797 /**
798  * Count established (ready) connections of a tunnel.
799  *
800  * @param t Tunnel on which to send the message.
801  *
802  * @return Number of connections.
803  */
804 unsigned int
805 GMT_count_connections (struct MeshTunnel2 *t)
806 {
807   return GMC_count (t->connection_head);
808 }
809
810
811 /**
812  * Sends an already built message on a tunnel, choosing the best connection.
813  *
814  * @param message Message to send. Function modifies it.
815  * @param t Tunnel on which this message is transmitted.
816  * @param ch Channel on which this message is transmitted.
817  * @param fwd Is this a fwd message?
818  */
819 void
820 GMT_send_prebuilt_message (struct GNUNET_MESH_Encrypted *msg,
821                            struct MeshTunnel2 *t,
822                            struct MeshChannel *ch,
823                            int fwd)
824 {
825   struct MeshConnection *c;
826   uint16_t type;
827
828   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Send on Tunnel %s\n",
829               peer2s (t->peer));
830   c = tunnel_get_connection (t, fwd);
831   if (NULL == c)
832   {
833     GNUNET_break (GNUNET_YES == t->destroy);
834     return;
835   }
836   type = ntohs (msg->header.type);
837   switch (type)
838   {
839     case GNUNET_MESSAGE_TYPE_MESH_FWD:
840     case GNUNET_MESSAGE_TYPE_MESH_BCK:
841     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_CREATE:
842     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_DESTROY:
843       msg->cid = c->id;
844       msg->ttl = htonl (default_ttl);
845       break;
846     default:
847       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "unkown type %s\n",
848                   GNUNET_MESH_DEBUG_M2S (type));
849       GNUNET_break (0);
850   }
851   msg->reserved = 0;
852
853   send_prebuilt_message_connection (&msg->header, c, ch, fwd);
854 }