- fixing channel functions
[oweals/gnunet.git] / src / mesh / gnunet-service-mesh_channel.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
22 #include "platform.h"
23 #include "gnunet_util_lib.h"
24
25 #include "gnunet_statistics_service.h"
26
27 #include "mesh_enc.h"
28 #include "mesh_protocol_enc.h"
29
30 #include "gnunet-service-mesh_channel.h"
31 #include "gnunet-service-mesh_local.h"
32 #include "gnunet-service-mesh_tunnel.h"
33
34 #define LOG(level, ...) GNUNET_log_from(level,"mesh-chn",__VA_ARGS__)
35
36 #define MESH_RETRANSMIT_MARGIN  4
37
38 /**
39  * All the states a connection can be in.
40  */
41 enum MeshChannelState
42 {
43   /**
44    * Uninitialized status, should never appear in operation.
45    */
46   MESH_CHANNEL_NEW,
47
48   /**
49    * Connection create message sent, waiting for ACK.
50    */
51   MESH_CHANNEL_SENT,
52
53   /**
54    * Connection confirmed, ready to carry traffic..
55    */
56   MESH_CHANNEL_READY,
57 };
58
59
60
61 /**
62  * Info needed to retry a message in case it gets lost.
63  */
64 struct MeshReliableMessage
65 {
66     /**
67      * Double linked list, FIFO style
68      */
69   struct MeshReliableMessage    *next;
70   struct MeshReliableMessage    *prev;
71
72     /**
73      * Type of message (payload, channel management).
74      */
75   int16_t type;
76
77     /**
78      * Tunnel Reliability queue this message is in.
79      */
80   struct MeshChannelReliability  *rel;
81
82     /**
83      * ID of the message (ACK needed to free)
84      */
85   uint32_t                      mid;
86
87     /**
88      * When was this message issued (to calculate ACK delay)
89      */
90   struct GNUNET_TIME_Absolute   timestamp;
91
92   /* struct GNUNET_MESH_Data with payload */
93 };
94
95
96 /**
97  * Info about the traffic state for a client in a channel.
98  */
99 struct MeshChannelReliability
100 {
101     /**
102      * Channel this is about.
103      */
104   struct MeshChannel *ch;
105
106     /**
107      * DLL of messages sent and not yet ACK'd.
108      */
109   struct MeshReliableMessage        *head_sent;
110   struct MeshReliableMessage        *tail_sent;
111
112     /**
113      * Messages pending to send.
114      */
115   unsigned int                      n_sent;
116
117     /**
118      * DLL of messages received out of order.
119      */
120   struct MeshReliableMessage        *head_recv;
121   struct MeshReliableMessage        *tail_recv;
122
123     /**
124      * Messages received.
125      */
126   unsigned int                      n_recv;
127
128     /**
129      * Next MID to use for outgoing traffic.
130      */
131   uint32_t                          mid_send;
132
133     /**
134      * Next MID expected for incoming traffic.
135      */
136   uint32_t                          mid_recv;
137
138     /**
139      * Can we send data to the client?
140      */
141   int                               client_ready;
142
143     /**
144      * Task to resend/poll in case no ACK is received.
145      */
146   GNUNET_SCHEDULER_TaskIdentifier   retry_task;
147
148     /**
149      * Counter for exponential backoff.
150      */
151   struct GNUNET_TIME_Relative       retry_timer;
152
153     /**
154      * How long does it usually take to get an ACK.
155      */
156   struct GNUNET_TIME_Relative       expected_delay;
157 };
158
159
160 /**
161  * Struct containing all information regarding a channel to a remote client.
162  */
163 struct MeshChannel
164 {
165     /**
166      * Tunnel this channel is in.
167      */
168   struct MeshTunnel3 *t;
169
170     /**
171      * Destination port of the channel.
172      */
173   uint32_t port;
174
175     /**
176      * Global channel number ( < GNUNET_MESH_LOCAL_CHANNEL_ID_CLI)
177      */
178   MESH_ChannelNumber gid;
179
180     /**
181      * Local tunnel number for root (owner) client.
182      * ( >= GNUNET_MESH_LOCAL_CHANNEL_ID_CLI or 0 )
183      */
184   MESH_ChannelNumber lid_root;
185
186     /**
187      * Local tunnel number for local destination clients (incoming number)
188      * ( >= GNUNET_MESH_LOCAL_CHANNEL_ID_SERV or 0).
189      */
190   MESH_ChannelNumber lid_dest;
191
192     /**
193      * Channel state.
194      */
195   enum MeshChannelState state;
196
197     /**
198      * Is the tunnel bufferless (minimum latency)?
199      */
200   int nobuffer;
201
202     /**
203      * Is the tunnel reliable?
204      */
205   int reliable;
206
207     /**
208      * Last time the channel was used
209      */
210   struct GNUNET_TIME_Absolute timestamp;
211
212     /**
213      * Client owner of the tunnel, if any
214      */
215   struct MeshClient *root;
216
217     /**
218      * Client destination of the tunnel, if any.
219      */
220   struct MeshClient *dest;
221
222     /**
223      * Flag to signal the destruction of the channel.
224      * If this is set GNUNET_YES the channel will be destroyed
225      * when the queue is empty.
226      */
227   int destroy;
228
229     /**
230      * Total messages pending for this channel, payload or not.
231      */
232   unsigned int pending_messages;
233
234     /**
235      * Reliability data.
236      * Only present (non-NULL) at the owner of a tunnel.
237      */
238   struct MeshChannelReliability *root_rel;
239
240     /**
241      * Reliability data.
242      * Only present (non-NULL) at the destination of a tunnel.
243      */
244   struct MeshChannelReliability *dest_rel;
245
246 };
247
248
249 /******************************************************************************/
250 /*******************************   GLOBALS  ***********************************/
251 /******************************************************************************/
252
253 /**
254  * Global handle to the statistics service.
255  */
256 extern struct GNUNET_STATISTICS_Handle *stats;
257
258
259 /******************************************************************************/
260 /********************************   STATIC  ***********************************/
261 /******************************************************************************/
262
263 /**
264  * Destroy a reliable message after it has been acknowledged, either by
265  * direct mid ACK or bitfield. Updates the appropriate data structures and
266  * timers and frees all memory.
267  *
268  * @param copy Message that is no longer needed: remote peer got it.
269  */
270 static void
271 rel_message_free (struct MeshReliableMessage *copy);
272
273 /**
274  * We have received a message out of order, or the client is not ready.
275  * Buffer it until we receive an ACK from the client or the missing
276  * message from the channel.
277  *
278  * @param msg Message to buffer (MUST be of type MESH_DATA).
279  * @param rel Reliability data to the corresponding direction.
280  */
281 static void
282 add_buffered_data (const struct GNUNET_MESH_Data *msg,
283                    struct MeshChannelReliability *rel)
284 {
285   struct MeshReliableMessage *copy;
286   struct MeshReliableMessage *prev;
287   uint32_t mid;
288   uint16_t size;
289
290   size = ntohs (msg->header.size);
291   mid = ntohl (msg->mid);
292
293   LOG (GNUNET_ERROR_TYPE_DEBUG, "add_buffered_data %u\n", mid);
294
295   copy = GNUNET_malloc (sizeof (*copy) + size);
296   copy->mid = mid;
297   copy->rel = rel;
298   memcpy (&copy[1], msg, size);
299
300   rel->n_recv++;
301
302   // FIXME do something better than O(n), although n < 64...
303   // FIXME start from the end (most messages are the latest ones)
304   for (prev = rel->head_recv; NULL != prev; prev = prev->next)
305   {
306     LOG (GNUNET_ERROR_TYPE_DEBUG, " prev %u\n", prev->mid);
307     if (GMC_is_pid_bigger (prev->mid, mid))
308     {
309       LOG (GNUNET_ERROR_TYPE_DEBUG, " bingo!\n");
310       GNUNET_CONTAINER_DLL_insert_before (rel->head_recv, rel->tail_recv,
311                                           prev, copy);
312       return;
313     }
314   }
315     LOG (GNUNET_ERROR_TYPE_DEBUG, " insert at tail!\n");
316     GNUNET_CONTAINER_DLL_insert_tail (rel->head_recv, rel->tail_recv, copy);
317     LOG (GNUNET_ERROR_TYPE_DEBUG, "add_buffered_data END\n");
318 }
319
320
321 /**
322  * Send data to a client.
323  *
324  * If the client is ready, send directly, otherwise buffer while listening
325  * for a local ACK.
326  *
327  * @param ch Channel
328  * @param msg Message.
329  * @param fwd Is this a fwd (root->dest) message?
330  */
331 static void
332 send_client_data (struct MeshChannel *ch,
333                   const struct GNUNET_MESH_Data *msg,
334                   int fwd)
335 {
336   if (fwd)
337   {
338     if (ch->dest_rel->client_ready)
339       GML_send_data (ch, msg, ch->dest, ch->lid_dest);
340     else
341       add_buffered_data (msg, ch->dest_rel);
342   }
343   else
344   {
345     if (ch->root_rel->client_ready)
346       GML_send_data (ch, msg, ch->root, ch->lid_root);
347     else
348       add_buffered_data (msg, ch->root_rel);
349   }
350 }
351
352
353 /**
354  * Add a client to a channel, initializing all needed data structures.
355  *
356  * @param ch Channel to which add the client.
357  * @param c Client which to add to the channel.
358  */
359 static void
360 channel_add_client (struct MeshChannel *ch, struct MeshClient *c)
361 {
362   struct MeshTunnel3 *t = ch->t;
363
364   if (NULL != ch->dest)
365   {
366     GNUNET_break (0);
367     return;
368   }
369
370   /* Assign local id as destination */
371   while (NULL != GML_channel_get (c, t->next_local_chid))
372     t->next_local_chid = (t->next_local_chid + 1) | GNUNET_MESH_LOCAL_CHANNEL_ID_SERV;
373   ch->lid_dest = t->next_local_chid++;
374   t->next_local_chid = t->next_local_chid | GNUNET_MESH_LOCAL_CHANNEL_ID_SERV;
375
376   /* Store in client's hashmap */
377   if (GNUNET_OK !=
378       GNUNET_CONTAINER_multihashmap32_put (c->incoming_channels,
379                                            ch->lid_dest, ch,
380                                            GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
381   {
382     GNUNET_break (0);
383     return;
384   }
385
386   GNUNET_break (NULL == ch->dest_rel);
387   ch->dest_rel = GNUNET_new (struct MeshChannelReliability);
388   ch->dest_rel->ch = ch;
389   ch->dest_rel->expected_delay = MESH_RETRANSMIT_TIME;
390
391   ch->dest = c;
392 }
393
394
395 /**
396  * Destroy all reliable messages queued for a channel,
397  * during a channel destruction.
398  * Frees the reliability structure itself.
399  *
400  * @param rel Reliability data for a channel.
401  */
402 static void
403 channel_rel_free_all (struct MeshChannelReliability *rel)
404 {
405   struct MeshReliableMessage *copy;
406   struct MeshReliableMessage *next;
407
408   if (NULL == rel)
409     return;
410
411   for (copy = rel->head_recv; NULL != copy; copy = next)
412   {
413     next = copy->next;
414     GNUNET_CONTAINER_DLL_remove (rel->head_recv, rel->tail_recv, copy);
415     GNUNET_free (copy);
416   }
417   for (copy = rel->head_sent; NULL != copy; copy = next)
418   {
419     next = copy->next;
420     GNUNET_CONTAINER_DLL_remove (rel->head_sent, rel->tail_sent, copy);
421     GNUNET_free (copy);
422   }
423   if (GNUNET_SCHEDULER_NO_TASK != rel->retry_task)
424     GNUNET_SCHEDULER_cancel (rel->retry_task);
425   GNUNET_free (rel);
426 }
427
428
429 /**
430  * Mark future messages as ACK'd.
431  *
432  * @param rel Reliability data.
433  * @param msg DataACK message with a bitfield of future ACK'd messages.
434  */
435 static void
436 channel_rel_free_sent (struct MeshChannelReliability *rel,
437                        const struct GNUNET_MESH_DataACK *msg)
438 {
439   struct MeshReliableMessage *copy;
440   struct MeshReliableMessage *next;
441   uint64_t bitfield;
442   uint64_t mask;
443   uint32_t mid;
444   uint32_t target;
445   unsigned int i;
446
447   bitfield = msg->futures;
448   mid = ntohl (msg->mid);
449   LOG (GNUNET_ERROR_TYPE_DEBUG,
450               "free_sent_reliable %u %llX\n",
451               mid, bitfield);
452   LOG (GNUNET_ERROR_TYPE_DEBUG,
453               " rel %p, head %p\n",
454               rel, rel->head_sent);
455   for (i = 0, copy = rel->head_sent;
456        i < 64 && NULL != copy && 0 != bitfield;
457        i++)
458   {
459     LOG (GNUNET_ERROR_TYPE_DEBUG,
460                 " trying bit %u (mid %u)\n",
461                 i, mid + i + 1);
462     mask = 0x1LL << i;
463     if (0 == (bitfield & mask))
464      continue;
465
466     LOG (GNUNET_ERROR_TYPE_DEBUG, " set!\n");
467     /* Bit was set, clear the bit from the bitfield */
468     bitfield &= ~mask;
469
470     /* The i-th bit was set. Do we have that copy? */
471     /* Skip copies with mid < target */
472     target = mid + i + 1;
473     LOG (GNUNET_ERROR_TYPE_DEBUG, " target %u\n", target);
474     while (NULL != copy && GMC_is_pid_bigger (target, copy->mid))
475      copy = copy->next;
476
477     /* Did we run out of copies? (previously freed, it's ok) */
478     if (NULL == copy)
479     {
480      LOG (GNUNET_ERROR_TYPE_DEBUG, "run out of copies...\n");
481      return;
482     }
483
484     /* Did we overshoot the target? (previously freed, it's ok) */
485     if (GMC_is_pid_bigger (copy->mid, target))
486     {
487      LOG (GNUNET_ERROR_TYPE_DEBUG, " next copy %u\n", copy->mid);
488      continue;
489     }
490
491     /* Now copy->mid == target, free it */
492     next = copy->next;
493     rel_message_free (copy);
494     copy = next;
495   }
496   LOG (GNUNET_ERROR_TYPE_DEBUG, "free_sent_reliable END\n");
497 }
498
499
500 /**
501  * We haven't received an ACK after a certain time: restransmit the message.
502  *
503  * @param cls Closure (MeshReliableMessage with the message to restransmit)
504  * @param tc TaskContext.
505  */
506 static void
507 channel_retransmit_message (void *cls,
508                             const struct GNUNET_SCHEDULER_TaskContext *tc)
509 {
510   struct MeshChannelReliability *rel = cls;
511   struct MeshReliableMessage *copy;
512   struct MeshPeerQueue *q;
513   struct MeshChannel *ch;
514   struct MeshConnection *c;
515   struct GNUNET_MESH_Data *payload;
516   struct MeshPeer *hop;
517   int fwd;
518
519   rel->retry_task = GNUNET_SCHEDULER_NO_TASK;
520   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
521     return;
522
523   ch = rel->ch;
524   copy = rel->head_sent;
525   if (NULL == copy)
526   {
527     GNUNET_break (0);
528     return;
529   }
530
531   /* Search the message to be retransmitted in the outgoing queue.
532    * Check only the queue for the connection that is going to be used,
533    * if the message is stuck in some other connection's queue we shouldn't
534    * act upon it:
535    * - cancelling it and sending the new one doesn't guarantee it's delivery,
536    *   the old connection could be temporary stalled or the queue happened to
537    *   be long at time of insertion.
538    * - not sending the new one could cause terrible delays the old connection
539    *   is stalled.
540    */
541   payload = (struct GNUNET_MESH_Data *) &copy[1];
542   fwd = (rel == ch->root_rel);
543   c = tunnel_get_connection (ch->t, fwd);
544   hop = connection_get_hop (c, fwd);
545   for (q = hop->queue_head; NULL != q; q = q->next)
546   {
547     if (ntohs (payload->header.type) == q->type && ch == q->ch)
548     {
549       struct GNUNET_MESH_Data *queued_data = q->cls;
550
551       if (queued_data->mid == payload->mid)
552         break;
553     }
554   }
555
556   /* Message not found in the queue that we are going to use. */
557   if (NULL == q)
558   {
559     LOG (GNUNET_ERROR_TYPE_DEBUG, "!!! RETRANSMIT %u\n", copy->mid);
560
561     send_prebuilt_message_channel (&payload->header, ch, fwd);
562     GNUNET_STATISTICS_update (stats, "# data retransmitted", 1, GNUNET_NO);
563   }
564   else
565   {
566     LOG (GNUNET_ERROR_TYPE_DEBUG, "!!! ALREADY IN QUEUE %u\n", copy->mid);
567   }
568
569   rel->retry_timer = GNUNET_TIME_STD_BACKOFF (rel->retry_timer);
570   rel->retry_task = GNUNET_SCHEDULER_add_delayed (rel->retry_timer,
571                                                   &channel_retransmit_message,
572                                                   cls);
573 }
574
575
576 /**
577  * Send ACK on one or more connections due to buffer space to the client.
578  *
579  * Iterates all connections of the tunnel and sends ACKs appropriately.
580  *
581  * @param ch Channel which has some free buffer space.
582  * @param fwd Is this in for FWD traffic? (ACK goes dest->root)
583  */
584 static void
585 channel_send_connections_ack (struct MeshChannel *ch,
586                               unsigned int buffer,
587                               int fwd)
588 {
589   struct MeshTunnel3 *t = ch->t;
590   struct MeshConnection *c;
591   struct MeshFlowControl *fc;
592   uint32_t allowed;
593   uint32_t to_allow;
594   uint32_t allow_per_connection;
595   unsigned int cs;
596
597   LOG (GNUNET_ERROR_TYPE_DEBUG,
598               "Channel send connection %s ack on %s:%X\n",
599               fwd ? "FWD" : "BCK", peer2s (ch->t->peer), ch->gid);
600
601   /* Count connections, how many messages are already allowed */
602   for (cs = 0, allowed = 0, c = t->connection_head; NULL != c; c = c->next)
603   {
604     fc = fwd ? &c->fwd_fc : &c->bck_fc;
605     if (GMC_is_pid_bigger(fc->last_pid_recv, fc->last_ack_sent))
606     {
607       GNUNET_break (0);
608       continue;
609     }
610     allowed += fc->last_ack_sent - fc->last_pid_recv;
611     cs++;
612   }
613
614   /* Make sure there is no overflow */
615   if (allowed > buffer)
616   {
617     GNUNET_break (0);
618     return;
619   }
620
621   /* Authorize connections to send more data */
622   to_allow = buffer - allowed;
623
624   for (c = t->connection_head; NULL != c && to_allow > 0; c = c->next)
625   {
626     allow_per_connection = to_allow/cs;
627     to_allow -= allow_per_connection;
628     cs--;
629     fc = fwd ? &c->fwd_fc : &c->bck_fc;
630     if (fc->last_ack_sent - fc->last_pid_recv > 64 / 3)
631     {
632       continue;
633     }
634     connection_send_ack (c, allow_per_connection, fwd);
635   }
636
637   LOG (GNUNET_ERROR_TYPE_DEBUG,
638                 "Channel send connection %s ack on %s:%X\n",
639                 fwd ? "FWD" : "BCK", GMT_2s (ch->t), ch->gid);
640   GNUNET_break (to_allow == 0);
641 }
642
643
644 /**
645  * Destroy a reliable message after it has been acknowledged, either by
646  * direct mid ACK or bitfield. Updates the appropriate data structures and
647  * timers and frees all memory.
648  *
649  * @param copy Message that is no longer needed: remote peer got it.
650  */
651 static void
652 rel_message_free (struct MeshReliableMessage *copy)
653 {
654   struct MeshChannelReliability *rel;
655   struct GNUNET_TIME_Relative time;
656
657   rel = copy->rel;
658   time = GNUNET_TIME_absolute_get_duration (copy->timestamp);
659   rel->expected_delay.rel_value_us *= 7;
660   rel->expected_delay.rel_value_us += time.rel_value_us;
661   rel->expected_delay.rel_value_us /= 8;
662   rel->n_sent--;
663   LOG (GNUNET_ERROR_TYPE_DEBUG, "!!! Freeing %u\n", copy->mid);
664   LOG (GNUNET_ERROR_TYPE_DEBUG, "    n_sent %u\n", rel->n_sent);
665   LOG (GNUNET_ERROR_TYPE_DEBUG, "!!!  took %s\n",
666               GNUNET_STRINGS_relative_time_to_string (time, GNUNET_NO));
667   LOG (GNUNET_ERROR_TYPE_DEBUG, "!!!  new expected delay %s\n",
668               GNUNET_STRINGS_relative_time_to_string (rel->expected_delay,
669                                                       GNUNET_NO));
670   rel->retry_timer = rel->expected_delay;
671   GNUNET_CONTAINER_DLL_remove (rel->head_sent, rel->tail_sent, copy);
672   GNUNET_free (copy);
673 }
674
675
676
677 /**
678  * Channel was ACK'd by remote peer, mark as ready and cancel retransmission.
679  *
680  * @param ch Channel to mark as ready.
681  * @param fwd Was the CREATE message sent fwd?
682  */
683 static void
684 channel_confirm (struct MeshChannel *ch, int fwd)
685 {
686   struct MeshChannelReliability *rel;
687   struct MeshReliableMessage *copy;
688   struct MeshReliableMessage *next;
689
690   LOG (GNUNET_ERROR_TYPE_DEBUG,
691               "  channel confirm %s %s:%X\n",
692               fwd ? "FWD" : "BCK", GMT_2s (ch->t), ch->gid);
693   ch->state = MESH_CHANNEL_READY;
694
695   rel = fwd ? ch->root_rel : ch->dest_rel;
696   for (copy = rel->head_sent; NULL != copy; copy = next)
697   {
698     struct GNUNET_MessageHeader *msg;
699
700     next = copy->next;
701     msg = (struct GNUNET_MessageHeader *) &copy[1];
702     if (ntohs (msg->type) == GNUNET_MESSAGE_TYPE_MESH_CHANNEL_CREATE)
703     {
704       rel_message_free (copy);
705       /* TODO return? */
706     }
707   }
708   send_ack (NULL, ch, fwd);
709 }
710
711
712 /**
713  * Save a copy to retransmit in case it gets lost.
714  *
715  * Initializes all needed callbacks and timers.
716  *
717  * @param ch Channel this message goes on.
718  * @param msg Message to copy.
719  * @param fwd Is this fwd traffic?
720  */
721 static void
722 channel_save_copy (struct MeshChannel *ch,
723                    const struct GNUNET_MessageHeader *msg,
724                    int fwd)
725 {
726   struct MeshChannelReliability *rel;
727   struct MeshReliableMessage *copy;
728   uint32_t mid;
729   uint16_t type;
730   uint16_t size;
731
732   rel = fwd ? ch->root_rel : ch->dest_rel;
733   mid = rel->mid_send;
734   type = ntohs (msg->type);
735   size = ntohs (msg->size);
736
737   LOG (GNUNET_ERROR_TYPE_DEBUG, "!!! SAVE %u\n", mid);
738   copy = GNUNET_malloc (sizeof (struct MeshReliableMessage) + size);
739   copy->mid = mid;
740   copy->timestamp = GNUNET_TIME_absolute_get ();
741   copy->rel = rel;
742   copy->type = type;
743   memcpy (&copy[1], msg, size);
744   rel->n_sent++;
745   LOG (GNUNET_ERROR_TYPE_DEBUG, " n_sent %u\n", rel->n_sent);
746   GNUNET_CONTAINER_DLL_insert_tail (rel->head_sent, rel->tail_sent, copy);
747   if (GNUNET_SCHEDULER_NO_TASK == rel->retry_task)
748   {
749     rel->retry_timer =
750         GNUNET_TIME_relative_multiply (rel->expected_delay,
751                                         MESH_RETRANSMIT_MARGIN);
752     rel->retry_task =
753         GNUNET_SCHEDULER_add_delayed (rel->retry_timer,
754                                       &channel_retransmit_message,
755                                       rel);
756   }
757 }
758
759
760
761 /**
762  * Send a buffered message to the client, for in order delivery or
763  * as result of client ACK.
764  *
765  * @param ch Channel on which to empty the message buffer.
766  * @param c Client to send to.
767  * @param rel Reliability structure to corresponding peer.
768  *            If rel == bck_rel, this is FWD data.
769  */
770 static void
771 send_client_buffered_data (struct MeshChannel *ch,
772                                    struct MeshClient *c,
773                                    int fwd)
774 {
775   struct MeshReliableMessage *copy;
776   struct MeshChannelReliability *rel;
777
778   LOG (GNUNET_ERROR_TYPE_DEBUG, "send_buffered_data\n");
779   rel = fwd ? ch->dest_rel : ch->root_rel;
780   if (GNUNET_NO == rel->client_ready)
781   {
782     LOG (GNUNET_ERROR_TYPE_DEBUG, "client not ready\n");
783     return;
784   }
785
786   copy = rel->head_recv;
787   /* We never buffer channel management messages */
788   if (NULL != copy)
789   {
790     if (copy->mid == rel->mid_recv || GNUNET_NO == ch->reliable)
791     {
792       struct GNUNET_MESH_Data *msg = (struct GNUNET_MESH_Data *) &copy[1];
793
794       LOG (GNUNET_ERROR_TYPE_DEBUG,
795                   " have %u! now expecting %u\n",
796                   copy->mid, rel->mid_recv + 1);
797       send_client_data (ch, msg, fwd);
798       rel->n_recv--;
799       rel->mid_recv++;
800       GNUNET_CONTAINER_DLL_remove (rel->head_recv, rel->tail_recv, copy);
801       GNUNET_free (copy);
802     }
803     else
804     {
805       LOG (GNUNET_ERROR_TYPE_DEBUG,
806                   " reliable && don't have %u, next is %u\n",
807                   rel->mid_recv,
808                   copy->mid);
809       return;
810     }
811   }
812   LOG (GNUNET_ERROR_TYPE_DEBUG, "send_buffered_data END\n");
813 }
814
815
816
817
818 /**
819  * Destroy a channel and free all resources.
820  *
821  * @param ch Channel to destroy.
822  */
823 static void
824 channel_destroy (struct MeshChannel *ch)
825 {
826   struct MeshClient *c;
827
828   if (NULL == ch)
829     return;
830
831   LOG (GNUNET_ERROR_TYPE_DEBUG, "destroying channel %s:%u\n",
832               GMT_2s (ch->t), ch->gid);
833   GMCH_debug (ch);
834
835   c = ch->root;
836   if (NULL != c)
837   {
838     GML_channel_remove (c, ch->lid_root, ch);
839   }
840
841   c = ch->dest;
842   if (NULL != c)
843   {
844     GML_channel_remove (c, ch->lid_dest, ch);
845   }
846
847   channel_rel_free_all (ch->root_rel);
848   channel_rel_free_all (ch->dest_rel);
849
850   GMT_remove_channel (ch->t, ch);
851   GNUNET_STATISTICS_update (stats, "# channels", -1, GNUNET_NO);
852
853   GNUNET_free (ch);
854 }
855
856
857 /**
858  * Create a new channel.
859  *
860  * @param t Tunnel this channel is in.
861  * @param owner Client that owns the channel, NULL for foreign channels.
862  * @param lid_root Local ID for root client.
863  *
864  * @return A new initialized channel. NULL on error.
865  */
866 static struct MeshChannel *
867 channel_new (struct MeshTunnel3 *t,
868              struct MeshClient *owner, MESH_ChannelNumber lid_root)
869 {
870   struct MeshChannel *ch;
871
872   ch = GNUNET_new (struct MeshChannel);
873   ch->root = owner;
874   ch->lid_root = lid_root;
875   ch->t = t;
876
877   GNUNET_STATISTICS_update (stats, "# channels", 1, GNUNET_NO);
878
879   if (NULL != owner)
880   {
881     ch->gid = GMT_get_next_chid (t);
882     GML_channel_add (owner, lid_root, ch);
883   }
884   GMT_add_channel (t, ch);
885
886   return ch;
887 }
888
889
890 /**
891  * Set options in a channel, extracted from a bit flag field
892  *
893  * @param ch Channel to set options to.
894  * @param options Bit array in host byte order.
895  */
896 static void
897 channel_set_options (struct MeshChannel *ch, uint32_t options)
898 {
899   ch->nobuffer = (options & GNUNET_MESH_OPTION_NOBUFFER) != 0 ?
900                  GNUNET_YES : GNUNET_NO;
901   ch->reliable = (options & GNUNET_MESH_OPTION_RELIABLE) != 0 ?
902                  GNUNET_YES : GNUNET_NO;
903 }
904
905
906
907 /**
908  * Confirm we got a channel create.
909  *
910  * @param ch The channel to confirm.
911  * @param fwd Should we send the ACK fwd?
912  */
913 static void
914 channel_send_ack (struct MeshChannel *ch, int fwd)
915 {
916   struct GNUNET_MESH_ChannelManage msg;
917
918   msg.header.size = htons (sizeof (msg));
919   msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_CHANNEL_ACK);
920   LOG (GNUNET_ERROR_TYPE_DEBUG,
921               "  sending channel %s ack for channel %s:%X\n",
922               fwd ? "FWD" : "BCK", GMT_2s (ch->t),
923               ch->gid);
924
925   msg.chid = htonl (ch->gid);
926   GMCH_send_prebuilt_message (&msg.header, ch, !fwd);
927 }
928
929
930 /**
931  * Iterator for deleting each channel whose client endpoint disconnected.
932  *
933  * @param cls Closure (client that has disconnected).
934  * @param key The local channel id (used to access the hashmap).
935  * @param value The value stored at the key (channel to destroy).
936  *
937  * @return GNUNET_OK, keep iterating.
938  */
939 static int
940 channel_destroy_iterator (void *cls,
941                           uint32_t key,
942                           void *value)
943 {
944   struct MeshChannel *ch = value;
945   struct MeshClient *c = cls;
946   struct MeshTunnel3 *t;
947
948   LOG (GNUNET_ERROR_TYPE_DEBUG,
949               " Channel %X (%X / %X) destroy, due to client %s shutdown.\n",
950               ch->gid, ch->lid_root, ch->lid_dest, GML_2s (c));
951   GMCH_debug (ch);
952
953   if (c == ch->dest)
954   {
955     LOG (GNUNET_ERROR_TYPE_DEBUG, " Client %s is destination.\n", GML_2s (c));
956   }
957   if (c == ch->root)
958   {
959     LOG (GNUNET_ERROR_TYPE_DEBUG, " Client %s is owner.\n", GML_2s (c));
960   }
961
962   t = ch->t;
963   GMCH_send_destroy (ch);
964   channel_destroy (ch);
965   GMT_destroy_if_empty (t);
966
967   return GNUNET_OK;
968 }
969
970
971 /**
972  * Handle a loopback message: call the appropriate handler for the message type.
973  *
974  * @param ch Channel this message is on.
975  * @param msgh Message header.
976  * @param fwd Is this FWD traffic?
977  */
978 void
979 handle_loopback (struct MeshChannel *ch,
980                  struct GNUNET_MessageHeader *msgh,
981                  int fwd)
982 {
983   uint16_t type;
984
985   type = ntohs (msgh->type);
986   LOG (GNUNET_ERROR_TYPE_DEBUG,
987        "Loopback %s message!\n",
988        GNUNET_MESH_DEBUG_M2S (type));
989
990   switch (type)
991   {
992     case GNUNET_MESSAGE_TYPE_MESH_DATA:
993       /* Don't send hop ACK, wait for client to ACK */
994       GMCH_handle_data (ch, (struct GNUNET_MESH_Data *) msgh, fwd);
995       break;
996
997     case GNUNET_MESSAGE_TYPE_MESH_DATA_ACK:
998       GMCH_handle_data_ack (ch, (struct GNUNET_MESH_DataACK *) msgh, fwd);
999       break;
1000
1001     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_CREATE:
1002        // FIXME store channel in loopback tunnel?
1003       GMCH_handle_create ((struct GNUNET_MESH_ChannelCreate *) msgh,
1004                           fwd);
1005       break;
1006
1007     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_ACK:
1008       GMCH_handle_ack (ch,
1009                        (struct GNUNET_MESH_ChannelManage *) msgh,
1010                        fwd);
1011       break;
1012
1013     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_DESTROY:
1014       GMCH_handle_destroy (ch,
1015                            (struct GNUNET_MESH_ChannelManage *) msgh,
1016                            fwd);
1017       break;
1018
1019     default:
1020       GNUNET_break_op (0);
1021       LOG (GNUNET_ERROR_TYPE_DEBUG,
1022            "end-to-end message not known (%u)\n",
1023            ntohs (msgh->type));
1024   }
1025 }
1026
1027
1028
1029 /******************************************************************************/
1030 /********************************    API    ***********************************/
1031 /******************************************************************************/
1032
1033 /**
1034  * Get channel ID.
1035  *
1036  * @param ch Channel.
1037  *
1038  * @return ID
1039  */
1040 MESH_ChannelNumber
1041 GMCH_get_id (const struct MeshChannel *ch)
1042 {
1043   return ch->gid;
1044 }
1045
1046
1047 /**
1048  * Get the channel tunnel.
1049  *
1050  * @param ch Channel to get the tunnel from.
1051  *
1052  * @return tunnel of the channel.
1053  */
1054 struct MeshTunnel3 *
1055 GMCH_get_tunnel (const struct MeshChannel *ch)
1056 {
1057   return ch->t;
1058 }
1059
1060
1061 /**
1062  * Get free buffer space towards the client on a specific channel.
1063  *
1064  * @param ch Channel.
1065  * @param fwd Is query about FWD traffic?
1066  *
1067  * @return Free buffer space [0 - 64]
1068  */
1069 unsigned int
1070 GMCH_get_buffer (struct MeshChannel *ch, int fwd)
1071 {
1072   struct MeshChannelReliability *rel;
1073
1074   rel = fwd ? ch->dest_rel : ch->root_rel;
1075
1076   /* If rel is NULL it means that the end is not yet created,
1077    * most probably is a loopback channel at the point of sending
1078    * the ChannelCreate to itself.
1079    */
1080   if (NULL == rel)
1081     return 64;
1082
1083   return (64 - rel->n_recv);
1084 }
1085
1086
1087 /**
1088  * Is the root client for this channel on this peer?
1089  *
1090  * @param ch Channel.
1091  * @param fwd Is this for fwd traffic?
1092  *
1093  * @return GNUNET_YES in case it is.
1094  */
1095 int
1096 GMCH_is_origin (struct MeshChannel *ch, int fwd)
1097 {
1098   struct MeshClient *c;
1099
1100   c = fwd ? ch->root : ch->dest;
1101   return NULL != c;
1102 }
1103
1104
1105 /**
1106  * Is the destination client for this channel on this peer?
1107  *
1108  * @param ch Channel.
1109  * @param fwd Is this for fwd traffic?
1110  *
1111  * @return GNUNET_YES in case it is.
1112  */
1113 int
1114 GMCH_is_terminal (struct MeshChannel *ch, int fwd)
1115 {
1116   struct MeshClient *c;
1117
1118   c = fwd ? ch->dest : ch->root;
1119   return NULL != c;
1120 }
1121
1122
1123 /**
1124  * Notify the destination client that a new incoming channel was created.
1125  *
1126  * @param ch Channel that was created.
1127  */
1128 void
1129 GMCH_send_create (struct MeshChannel *ch)
1130 {
1131   struct GNUNET_MESH_ChannelMessage msg;
1132   uint32_t opt;
1133
1134   if (NULL == ch->dest)
1135     return;
1136
1137   opt = 0;
1138   opt |= GNUNET_YES == ch->reliable ? GNUNET_MESH_OPTION_RELIABLE : 0;
1139   opt |= GNUNET_YES == ch->nobuffer ? GNUNET_MESH_OPTION_NOBUFFER : 0;
1140   GML_send_channel_create (ch->dest, ch->lid_dest, ch->port, opt,
1141                            GMT_get_destination (ch->t));
1142
1143 }
1144
1145 /**
1146  * Notify a client that the channel is no longer valid.
1147  * FIXME send on tunnel if some client == NULL?
1148  *
1149  * @param ch Channel that is destroyed.
1150  */
1151 void
1152 GMCH_send_destroy (struct MeshChannel *ch)
1153 {
1154   if (NULL != ch->root)
1155     GML_send_channel_destroy (ch->root, ch->lid_root);
1156
1157   if (NULL != ch->dest)
1158     GML_send_channel_destroy (ch->dest, ch->lid_dest);
1159 }
1160
1161
1162 /**
1163  * Send data on a channel.
1164  *
1165  * If the destination is local, send it to client, otherwise encrypt and
1166  * send to next hop.
1167  *
1168  * @param ch Channel
1169  * @param msg Message.
1170  * @param fwd Is this a fwd (root->dest) message?
1171  */
1172 void
1173 GMCH_send_data (struct MeshChannel *ch,
1174                 const struct GNUNET_MESH_Data *msg,
1175                 int fwd)
1176 {
1177 }
1178
1179
1180 /**
1181  * Send an end-to-end ACK message for the most recent in-sequence payload.
1182  *
1183  * If channel is not reliable, do nothing.
1184  *
1185  * @param ch Channel this is about.
1186  * @param fwd Is for FWD traffic? (ACK dest->owner)
1187  */
1188 void
1189 GMCH_send_ack (struct MeshChannel *ch, int fwd)
1190 {
1191   struct GNUNET_MESH_DataACK msg;
1192   struct MeshChannelReliability *rel;
1193   struct MeshReliableMessage *copy;
1194   unsigned int delta;
1195   uint64_t mask;
1196   uint16_t type;
1197
1198   if (GNUNET_NO == ch->reliable)
1199   {
1200     return;
1201   }
1202   rel = fwd ? ch->dest_rel : ch->root_rel;
1203   LOG (GNUNET_ERROR_TYPE_DEBUG,
1204               "send_data_ack for %u\n",
1205               rel->mid_recv - 1);
1206
1207   type = GNUNET_MESSAGE_TYPE_MESH_DATA_ACK;
1208   msg.header.type = htons (type);
1209   msg.header.size = htons (sizeof (msg));
1210   msg.chid = htonl (ch->gid);
1211   msg.mid = htonl (rel->mid_recv - 1);
1212   msg.futures = 0;
1213   for (copy = rel->head_recv; NULL != copy; copy = copy->next)
1214   {
1215     if (copy->type != type)
1216       continue;
1217     delta = copy->mid - rel->mid_recv;
1218     if (63 < delta)
1219       break;
1220     mask = 0x1LL << delta;
1221     msg.futures |= mask;
1222     LOG (GNUNET_ERROR_TYPE_DEBUG,
1223                 " setting bit for %u (delta %u) (%llX) -> %llX\n",
1224                 copy->mid, delta, mask, msg.futures);
1225   }
1226   LOG (GNUNET_ERROR_TYPE_DEBUG, " final futures %llX\n", msg.futures);
1227
1228   GMCH_send_prebuilt_message (&msg.header, ch, fwd);
1229   LOG (GNUNET_ERROR_TYPE_DEBUG, "send_data_ack END\n");
1230 }
1231
1232
1233 /**
1234  * Log channel info.
1235  *
1236  * @param ch Channel.
1237  */
1238 void
1239 GMCH_debug (struct MeshChannel *ch)
1240 {
1241   if (NULL == ch)
1242   {
1243     LOG (GNUNET_ERROR_TYPE_DEBUG, "*** DEBUG NULL CHANNEL ***\n");
1244     return;
1245   }
1246   LOG (GNUNET_ERROR_TYPE_DEBUG, "Channel %s:%X (%p)\n",
1247               GMT_2s (ch->t), ch->gid, ch);
1248   LOG (GNUNET_ERROR_TYPE_DEBUG, "  root %p/%p\n",
1249               ch->root, ch->root_rel);
1250   if (NULL != ch->root)
1251   {
1252     LOG (GNUNET_ERROR_TYPE_DEBUG, "  cli %s\n", GML_2s (ch->root));
1253     LOG (GNUNET_ERROR_TYPE_DEBUG, "  ready %s\n",
1254                 ch->root_rel->client_ready ? "YES" : "NO");
1255     LOG (GNUNET_ERROR_TYPE_DEBUG, "  id %X\n", ch->lid_root);
1256   }
1257   LOG (GNUNET_ERROR_TYPE_DEBUG, "  dest %p/%p\n",
1258               ch->dest, ch->dest_rel);
1259   if (NULL != ch->dest)
1260   {
1261     LOG (GNUNET_ERROR_TYPE_DEBUG, "  cli %s\n", GML_2s (ch->dest));
1262     LOG (GNUNET_ERROR_TYPE_DEBUG, "  ready %s\n",
1263                 ch->dest_rel->client_ready ? "YES" : "NO");
1264     LOG (GNUNET_ERROR_TYPE_DEBUG, "  id %X\n", ch->lid_dest);
1265   }
1266 }
1267
1268
1269 /**
1270  * Handler for mesh network payload traffic.
1271  *
1272  * @param ch Channel for the message.
1273  * @param message Unencryted data message.
1274  * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO;
1275  */
1276 void
1277 GMCH_handle_data (struct MeshChannel *ch,
1278                   const struct GNUNET_MESH_Data *msg,
1279                   int fwd)
1280 {
1281   struct MeshChannelReliability *rel;
1282   struct MeshClient *c;
1283   uint32_t mid;
1284   uint16_t type;
1285   size_t size;
1286
1287   /*  Initialize FWD/BCK data */
1288   c   = fwd ? ch->dest     : ch->root;
1289   rel = fwd ? ch->dest_rel : ch->root_rel;
1290
1291   if (NULL == c)
1292   {
1293     GNUNET_break (0);
1294     return;
1295   }
1296
1297   GNUNET_STATISTICS_update (stats, "# data received", 1, GNUNET_NO);
1298
1299   mid = ntohl (msg->mid);
1300   LOG (GNUNET_ERROR_TYPE_DEBUG, " mid %u\n", mid);
1301
1302   if (GNUNET_NO == ch->reliable ||
1303       ( !GMC_is_pid_bigger (rel->mid_recv, mid) &&
1304         GMC_is_pid_bigger (rel->mid_recv + 64, mid) ) )
1305   {
1306     LOG (GNUNET_ERROR_TYPE_DEBUG, "!!! RECV %u\n", mid);
1307     if (GNUNET_YES == ch->reliable)
1308     {
1309       /* Is this the exact next expected messasge? */
1310       if (mid == rel->mid_recv)
1311       {
1312         LOG (GNUNET_ERROR_TYPE_DEBUG, "as expected\n");
1313         rel->mid_recv++;
1314         send_client_data (ch, msg, fwd);
1315       }
1316       else
1317       {
1318         LOG (GNUNET_ERROR_TYPE_DEBUG, "save for later\n");
1319         add_buffered_data (msg, rel);
1320       }
1321     }
1322     else
1323     {
1324       /* Tunnel is unreliable: send to clients directly */
1325       /* FIXME: accept Out Of Order traffic */
1326       rel->mid_recv = mid + 1;
1327       send_client_data (ch, msg, fwd);
1328     }
1329   }
1330   else
1331   {
1332     GNUNET_break_op (0);
1333     LOG (GNUNET_ERROR_TYPE_DEBUG,
1334                 " MID %u not expected (%u - %u), dropping!\n",
1335                 mid, rel->mid_recv, rel->mid_recv + 64);
1336   }
1337
1338   GMCH_send_ack (ch, fwd);
1339 }
1340
1341
1342 /**
1343  * Handler for mesh network traffic end-to-end ACKs.
1344  *
1345  * @param t Tunnel on which we got this message.
1346  * @param message Data message.
1347  * @param fwd Is this a fwd ACK? (dest->orig)
1348  */
1349 void
1350 GMCH_handle_data_ack (struct MeshChannel *ch,
1351                       const struct GNUNET_MESH_DataACK *msg,
1352                       int fwd)
1353 {
1354   struct MeshChannelReliability *rel;
1355   struct MeshReliableMessage *copy;
1356   struct MeshReliableMessage *next;
1357   uint32_t ack;
1358   int work;
1359
1360   ack = ntohl (msg->mid);
1361   LOG (GNUNET_ERROR_TYPE_DEBUG, "!!! %s ACK %u\n",
1362               (GNUNET_YES == fwd) ? "FWD" : "BCK", ack);
1363
1364   if (GNUNET_YES == fwd)
1365   {
1366     rel = ch->root_rel;
1367   }
1368   else
1369   {
1370     rel = ch->dest_rel;
1371   }
1372   if (NULL == rel)
1373   {
1374     GNUNET_break (0);
1375     return;
1376   }
1377
1378   for (work = GNUNET_NO, copy = rel->head_sent; copy != NULL; copy = next)
1379   {
1380     if (GMC_is_pid_bigger (copy->mid, ack))
1381     {
1382       LOG (GNUNET_ERROR_TYPE_DEBUG, "!!!  head %u, out!\n", copy->mid);
1383       channel_rel_free_sent (rel, msg);
1384       break;
1385     }
1386     work = GNUNET_YES;
1387     LOG (GNUNET_ERROR_TYPE_DEBUG, "!!!  id %u\n", copy->mid);
1388     next = copy->next;
1389     rel_message_free (copy);
1390   }
1391   /* ACK client if needed */
1392 //   channel_send_ack (t, type, GNUNET_MESSAGE_TYPE_MESH_UNICAST_ACK == type);
1393
1394   /* If some message was free'd, update the retransmission delay*/
1395   if (GNUNET_YES == work)
1396   {
1397     if (GNUNET_SCHEDULER_NO_TASK != rel->retry_task)
1398     {
1399       GNUNET_SCHEDULER_cancel (rel->retry_task);
1400       if (NULL == rel->head_sent)
1401       {
1402         rel->retry_task = GNUNET_SCHEDULER_NO_TASK;
1403       }
1404       else
1405       {
1406         struct GNUNET_TIME_Absolute new_target;
1407         struct GNUNET_TIME_Relative delay;
1408
1409         delay = GNUNET_TIME_relative_multiply (rel->retry_timer,
1410                                                MESH_RETRANSMIT_MARGIN);
1411         new_target = GNUNET_TIME_absolute_add (rel->head_sent->timestamp,
1412                                                delay);
1413         delay = GNUNET_TIME_absolute_get_remaining (new_target);
1414         rel->retry_task =
1415             GNUNET_SCHEDULER_add_delayed (delay,
1416                                           &channel_retransmit_message,
1417                                           rel);
1418       }
1419     }
1420     else
1421       GNUNET_break (0);
1422   }
1423 }
1424
1425
1426 /**
1427  * Handler for channel create messages.
1428  *
1429  * @param msg Message.
1430  * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO;
1431  */
1432 struct MeshChannel *
1433 GMCH_handle_create (const struct GNUNET_MESH_ChannelCreate *msg,
1434                     int fwd)
1435 {
1436   MESH_ChannelNumber chid;
1437   struct MeshChannel *ch;
1438   struct MeshClient *c;
1439   uint32_t port;
1440
1441   chid = ntohl (msg->chid);
1442
1443   /* Create channel */
1444   ch = channel_new (NULL, NULL, 0); /* FIXME t */
1445   ch->gid = chid;
1446   channel_set_options (ch, ntohl (msg->opt));
1447
1448   /* Find a destination client */
1449   port = ntohl (msg->port);
1450   LOG (GNUNET_ERROR_TYPE_DEBUG, "   port %u\n", port);
1451   c = GML_client_get_by_port (port);
1452   if (NULL == c)
1453   {
1454     /* TODO send reject */
1455     LOG (GNUNET_ERROR_TYPE_DEBUG, "  no client has port registered\n");
1456     /* TODO free ch */
1457     return;
1458   }
1459
1460   channel_add_client (ch, c);
1461   if (GNUNET_YES == ch->reliable)
1462     LOG (GNUNET_ERROR_TYPE_DEBUG, "!!! Reliable\n");
1463
1464   GMCH_send_create (ch);
1465   GMCH_send_ack (ch, fwd);
1466   GML_send_ack (ch, !fwd);
1467
1468   return ch;
1469 }
1470
1471
1472 /**
1473  * Handler for channel ack messages.
1474  *
1475  * @param ch Channel.
1476  * @param msg Message.
1477  * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO;
1478  */
1479 void
1480 GMCH_handle_ack (struct MeshChannel *ch,
1481                  const struct GNUNET_MESH_ChannelManage *msg,
1482                  int fwd)
1483 {
1484   channel_confirm (ch, !fwd);
1485 }
1486
1487
1488 /**
1489  * Handler for channel destroy messages.
1490  *
1491  * @param ch Channel to be destroyed of.
1492  * @param msg Message.
1493  * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO;
1494  */
1495 void
1496 GMCH_handle_destroy (struct MeshChannel *ch,
1497                      const struct GNUNET_MESH_ChannelManage *msg,
1498                      int fwd)
1499 {
1500   MESH_ChannelNumber chid;
1501
1502   /* Check if channel exists */
1503   chid = ntohl (msg->chid);
1504   if ( (fwd && NULL == ch->dest) || (!fwd && NULL == ch->root) )
1505   {
1506     /* Not for us (don't destroy twice a half-open loopback channel) */
1507     return;
1508   }
1509
1510   GMCH_send_destroy (ch);
1511   channel_destroy (ch);
1512 }
1513
1514
1515 /**
1516  * Sends an already built message on a channel.
1517  *
1518  * @param message Message to send. Function makes a copy of it.
1519  * @param ch Channel on which this message is transmitted.
1520  * @param fwd Is this a fwd message?
1521  */
1522 void
1523 GMCH_send_prebuilt_message (const struct GNUNET_MessageHeader *message,
1524                             struct MeshChannel *ch, int fwd)
1525 {
1526   size_t size = ntohs (message->size);
1527
1528   LOG (GNUNET_ERROR_TYPE_DEBUG, "Send on Channel %s:%X %s\n",
1529        GMT_2s (ch->t), ch->gid, fwd ? "FWD" : "BCK");
1530   LOG (GNUNET_ERROR_TYPE_DEBUG, "  %s\n",
1531        GNUNET_MESH_DEBUG_M2S (ntohs (message->type)));
1532
1533   if (GMT_is_loopback (ch->t))
1534   {
1535     handle_loopback (ch->t, message, fwd);
1536     return;
1537   }
1538
1539   GMT_send_prebuilt_message (message, ch->t, ch, fwd);
1540 }