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