- use queue/task mechanism for SYNACKs
[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.h"
28 #include "mesh_protocol.h"
29
30 #include "gnunet-service-mesh_channel.h"
31 #include "gnunet-service-mesh_local.h"
32 #include "gnunet-service-mesh_tunnel.h"
33 #include "gnunet-service-mesh_peer.h"
34
35 #define LOG(level, ...) GNUNET_log_from(level,"mesh-chn",__VA_ARGS__)
36
37 #define MESH_RETRANSMIT_TIME    GNUNET_TIME_UNIT_SECONDS
38 #define MESH_RETRANSMIT_MARGIN  4
39
40
41 /**
42  * All the states a connection can be in.
43  */
44 enum MeshChannelState
45 {
46   /**
47    * Uninitialized status, should never appear in operation.
48    */
49   MESH_CHANNEL_NEW,
50
51   /**
52    * Connection create message sent, waiting for ACK.
53    */
54   MESH_CHANNEL_SENT,
55
56   /**
57    * Connection confirmed, ready to carry traffic.
58    */
59   MESH_CHANNEL_READY,
60 };
61
62
63 /**
64  * Info holder for channel messages in queues.
65  */
66 struct MeshChannelQueue
67 {
68   /**
69    * Tunnel Queue.
70    */
71   struct MeshTunnel3Queue *q;
72
73   /**
74    * Message type (DATA/DATA_ACK)
75    */
76   uint16_t type;
77
78   /**
79    * Message copy (for DATAs, to start retransmission timer)
80    */
81   struct MeshReliableMessage *copy;
82
83   /**
84    * Reliability (for DATA_ACKs, to access rel->ack_q)
85    */
86   struct MeshChannelReliability *rel;
87 };
88
89
90 /**
91  * Info needed to retry a message in case it gets lost.
92  */
93 struct MeshReliableMessage
94 {
95     /**
96      * Double linked list, FIFO style
97      */
98   struct MeshReliableMessage    *next;
99   struct MeshReliableMessage    *prev;
100
101     /**
102      * Type of message (payload, channel management).
103      */
104   int16_t type;
105
106     /**
107      * Tunnel Reliability queue this message is in.
108      */
109   struct MeshChannelReliability  *rel;
110
111     /**
112      * ID of the message (ACK needed to free)
113      */
114   uint32_t                      mid;
115
116   /**
117    * Tunnel Queue.
118    */
119   struct MeshChannelQueue       *q;
120
121     /**
122      * When was this message issued (to calculate ACK delay)
123      */
124   struct GNUNET_TIME_Absolute   timestamp;
125
126   /* struct GNUNET_MESH_Data with payload */
127 };
128
129
130 /**
131  * Info about the traffic state for a client in a channel.
132  */
133 struct MeshChannelReliability
134 {
135     /**
136      * Channel this is about.
137      */
138   struct MeshChannel *ch;
139
140     /**
141      * DLL of messages sent and not yet ACK'd.
142      */
143   struct MeshReliableMessage        *head_sent;
144   struct MeshReliableMessage        *tail_sent;
145
146     /**
147      * DLL of messages received out of order.
148      */
149   struct MeshReliableMessage        *head_recv;
150   struct MeshReliableMessage        *tail_recv;
151
152     /**
153      * Messages received.
154      */
155   unsigned int                      n_recv;
156
157     /**
158      * Next MID to use for outgoing traffic.
159      */
160   uint32_t                          mid_send;
161
162     /**
163      * Next MID expected for incoming traffic.
164      */
165   uint32_t                          mid_recv;
166
167     /**
168      * Handle for queued unique data CREATE, DATA_ACK.
169      */
170   struct MeshChannelQueue           *uniq;
171
172     /**
173      * Can we send data to the client?
174      */
175   int                               client_ready;
176
177   /**
178    * Can the client send data to us?
179    */
180   int                               client_allowed;
181
182     /**
183      * Task to resend/poll in case no ACK is received.
184      */
185   GNUNET_SCHEDULER_TaskIdentifier   retry_task;
186
187     /**
188      * Counter for exponential backoff.
189      */
190   struct GNUNET_TIME_Relative       retry_timer;
191
192     /**
193      * How long does it usually take to get an ACK.
194      */
195   struct GNUNET_TIME_Relative       expected_delay;
196 };
197
198
199 /**
200  * Struct containing all information regarding a channel to a remote client.
201  */
202 struct MeshChannel
203 {
204     /**
205      * Tunnel this channel is in.
206      */
207   struct MeshTunnel3 *t;
208
209     /**
210      * Destination port of the channel.
211      */
212   uint32_t port;
213
214     /**
215      * Global channel number ( < GNUNET_MESH_LOCAL_CHANNEL_ID_CLI)
216      */
217   MESH_ChannelNumber gid;
218
219     /**
220      * Local tunnel number for root (owner) client.
221      * ( >= GNUNET_MESH_LOCAL_CHANNEL_ID_CLI or 0 )
222      */
223   MESH_ChannelNumber lid_root;
224
225     /**
226      * Local tunnel number for local destination clients (incoming number)
227      * ( >= GNUNET_MESH_LOCAL_CHANNEL_ID_SERV or 0).
228      */
229   MESH_ChannelNumber lid_dest;
230
231     /**
232      * Channel state.
233      */
234   enum MeshChannelState state;
235
236     /**
237      * Is the tunnel bufferless (minimum latency)?
238      */
239   int nobuffer;
240
241     /**
242      * Is the tunnel reliable?
243      */
244   int reliable;
245
246     /**
247      * Last time the channel was used
248      */
249   struct GNUNET_TIME_Absolute timestamp;
250
251     /**
252      * Client owner of the tunnel, if any
253      */
254   struct MeshClient *root;
255
256     /**
257      * Client destination of the tunnel, if any.
258      */
259   struct MeshClient *dest;
260
261     /**
262      * Flag to signal the destruction of the channel.
263      * If this is set GNUNET_YES the channel will be destroyed
264      * when the queue is empty.
265      */
266   int destroy;
267
268     /**
269      * Total (reliable) messages pending ACK for this channel.
270      */
271   unsigned int pending_messages;
272
273     /**
274      * Reliability data.
275      * Only present (non-NULL) at the owner of a tunnel.
276      */
277   struct MeshChannelReliability *root_rel;
278
279     /**
280      * Reliability data.
281      * Only present (non-NULL) at the destination of a tunnel.
282      */
283   struct MeshChannelReliability *dest_rel;
284
285 };
286
287
288 /******************************************************************************/
289 /*******************************   GLOBALS  ***********************************/
290 /******************************************************************************/
291
292 /**
293  * Global handle to the statistics service.
294  */
295 extern struct GNUNET_STATISTICS_Handle *stats;
296
297 /**
298  * Local peer own ID (memory efficient handle).
299  */
300 extern GNUNET_PEER_Id myid;
301
302
303 /******************************************************************************/
304 /********************************   STATIC  ***********************************/
305 /******************************************************************************/
306
307 /**
308  * Destroy a reliable message after it has been acknowledged, either by
309  * direct mid ACK or bitfield. Updates the appropriate data structures and
310  * timers and frees all memory.
311  *
312  * @param copy Message that is no longer needed: remote peer got it.
313  * @param update_time Is the timing information relevant?
314  *                    If this message is ACK in a batch the timing information
315  *                    is skewed by the retransmission, count only for the
316  *                    retransmitted message.
317  */
318 static void
319 rel_message_free (struct MeshReliableMessage *copy, int update_time);
320
321 /**
322  * send a channel create message.
323  *
324  * @param ch Channel for which to send.
325  */
326 static void
327 send_create (struct MeshChannel *ch);
328
329 /**
330  * Confirm we got a channel create, FWD ack.
331  *
332  * @param ch The channel to confirm.
333  * @param fwd Should we send a FWD ACK? (going dest->root)
334  */
335 static void
336 send_ack (struct MeshChannel *ch, int fwd);
337
338
339
340 /**
341  * We have received a message out of order, or the client is not ready.
342  * Buffer it until we receive an ACK from the client or the missing
343  * message from the channel.
344  *
345  * @param msg Message to buffer (MUST be of type MESH_DATA).
346  * @param rel Reliability data to the corresponding direction.
347  */
348 static void
349 add_buffered_data (const struct GNUNET_MESH_Data *msg,
350                    struct MeshChannelReliability *rel)
351 {
352   struct MeshReliableMessage *copy;
353   struct MeshReliableMessage *prev;
354   uint32_t mid;
355   uint16_t size;
356
357   size = ntohs (msg->header.size);
358   mid = ntohl (msg->mid);
359
360   LOG (GNUNET_ERROR_TYPE_DEBUG, "add_buffered_data %u\n", mid);
361
362   copy = GNUNET_malloc (sizeof (*copy) + size);
363   copy->mid = mid;
364   copy->rel = rel;
365   copy->type = GNUNET_MESSAGE_TYPE_MESH_DATA;
366   memcpy (&copy[1], msg, size);
367
368   rel->n_recv++;
369
370   // FIXME do something better than O(n), although n < 64...
371   // FIXME start from the end (most messages are the latest ones)
372   for (prev = rel->head_recv; NULL != prev; prev = prev->next)
373   {
374     LOG (GNUNET_ERROR_TYPE_DEBUG, " prev %u\n", prev->mid);
375     if (GM_is_pid_bigger (prev->mid, mid))
376     {
377       LOG (GNUNET_ERROR_TYPE_DEBUG, " bingo!\n");
378       GNUNET_CONTAINER_DLL_insert_before (rel->head_recv, rel->tail_recv,
379                                           prev, copy);
380       return;
381     }
382   }
383     LOG (GNUNET_ERROR_TYPE_DEBUG, " insert at tail!\n");
384     GNUNET_CONTAINER_DLL_insert_tail (rel->head_recv, rel->tail_recv, copy);
385     LOG (GNUNET_ERROR_TYPE_DEBUG, "add_buffered_data END\n");
386 }
387
388 /**
389  * Add a destination client to a channel, initializing all data structures
390  * in the channel and the client.
391  *
392  * @param ch Channel to which add the destination.
393  * @param c Client which to add to the channel.
394  */
395 static void
396 add_destination (struct MeshChannel *ch, struct MeshClient *c)
397 {
398   if (NULL != ch->dest)
399   {
400     GNUNET_break (0);
401     return;
402   }
403
404   /* Assign local id as destination */
405   ch->lid_dest = GML_get_next_chid (c);
406
407   /* Store in client's hashmap */
408   GML_channel_add (c, ch->lid_dest, ch);
409
410   GNUNET_break (NULL == ch->dest_rel);
411   ch->dest_rel = GNUNET_new (struct MeshChannelReliability);
412   ch->dest_rel->ch = ch;
413   ch->dest_rel->expected_delay.rel_value_us = 0;
414
415   ch->dest = c;
416 }
417
418
419 /**
420  * Set options in a channel, extracted from a bit flag field.
421  *
422  * @param ch Channel to set options to.
423  * @param options Bit array in host byte order.
424  */
425 static void
426 channel_set_options (struct MeshChannel *ch, uint32_t options)
427 {
428   ch->nobuffer = (options & GNUNET_MESH_OPTION_NOBUFFER) != 0 ?
429   GNUNET_YES : GNUNET_NO;
430   ch->reliable = (options & GNUNET_MESH_OPTION_RELIABLE) != 0 ?
431   GNUNET_YES : GNUNET_NO;
432 }
433
434
435 /**
436  * Get a bit flag field with the options of a channel.
437  *
438  * @param ch Channel to get options from.
439  *
440  * @return Bit array in host byte order.
441  */
442 static uint32_t
443 channel_get_options (struct MeshChannel *ch)
444 {
445   uint32_t options;
446
447   options = 0;
448   if (ch->nobuffer)
449     options |= GNUNET_MESH_OPTION_NOBUFFER;
450   if (ch->reliable)
451     options |= GNUNET_MESH_OPTION_RELIABLE;
452
453   return options;
454 }
455
456
457 /**
458  * Notify the destination client that a new incoming channel was created.
459  *
460  * @param ch Channel that was created.
461  */
462 static void
463 send_client_create (struct MeshChannel *ch)
464 {
465   uint32_t opt;
466
467   if (NULL == ch->dest)
468     return;
469
470   opt = 0;
471   opt |= GNUNET_YES == ch->reliable ? GNUNET_MESH_OPTION_RELIABLE : 0;
472   opt |= GNUNET_YES == ch->nobuffer ? GNUNET_MESH_OPTION_NOBUFFER : 0;
473   GML_send_channel_create (ch->dest, ch->lid_dest, ch->port, opt,
474                            GMT_get_destination (ch->t));
475
476 }
477
478
479 /**
480  * Send data to a client.
481  *
482  * If the client is ready, send directly, otherwise buffer while listening
483  * for a local ACK.
484  *
485  * @param ch Channel
486  * @param msg Message.
487  * @param fwd Is this a fwd (root->dest) message?
488  */
489 static void
490 send_client_data (struct MeshChannel *ch,
491                   const struct GNUNET_MESH_Data *msg,
492                   int fwd)
493 {
494   if (fwd)
495   {
496     if (ch->dest_rel->client_ready)
497       GML_send_data (ch->dest, msg, ch->lid_dest);
498     else
499       add_buffered_data (msg, ch->dest_rel);
500   }
501   else
502   {
503     if (ch->root_rel->client_ready)
504       GML_send_data (ch->root, msg, ch->lid_root);
505     else
506       add_buffered_data (msg, ch->root_rel);
507   }
508 }
509
510
511 /**
512  * Send a buffered message to the client, for in order delivery or
513  * as result of client ACK.
514  *
515  * @param ch Channel on which to empty the message buffer.
516  * @param c Client to send to.
517  * @param fwd Is this to send FWD data?.
518  */
519 static void
520 send_client_buffered_data (struct MeshChannel *ch,
521                            struct MeshClient *c,
522                            int fwd)
523 {
524   struct MeshReliableMessage *copy;
525   struct MeshChannelReliability *rel;
526
527   LOG (GNUNET_ERROR_TYPE_DEBUG, "send_buffered_data\n");
528   rel = fwd ? ch->dest_rel : ch->root_rel;
529   if (GNUNET_NO == rel->client_ready)
530   {
531     LOG (GNUNET_ERROR_TYPE_DEBUG, "client not ready\n");
532     return;
533   }
534
535   copy = rel->head_recv;
536   /* We never buffer channel management messages */
537   if (NULL != copy)
538   {
539     if (copy->mid == rel->mid_recv || GNUNET_NO == ch->reliable)
540     {
541       struct GNUNET_MESH_Data *msg = (struct GNUNET_MESH_Data *) &copy[1];
542
543       LOG (GNUNET_ERROR_TYPE_DEBUG,
544            " have %u! now expecting %u\n",
545            copy->mid, rel->mid_recv + 1);
546       send_client_data (ch, msg, fwd);
547       rel->n_recv--;
548       rel->mid_recv++;
549       GNUNET_CONTAINER_DLL_remove (rel->head_recv, rel->tail_recv, copy);
550       LOG (GNUNET_ERROR_TYPE_DEBUG, " COPYFREE RECV %p\n", copy);
551       GNUNET_free (copy);
552     }
553     else
554     {
555       LOG (GNUNET_ERROR_TYPE_DEBUG,
556            " reliable && don't have %u, next is %u\n",
557            rel->mid_recv,
558            copy->mid);
559       return;
560     }
561   }
562   LOG (GNUNET_ERROR_TYPE_DEBUG, "send_buffered_data END\n");
563 }
564
565
566 /**
567  * Allow a client to send more data.
568  *
569  * In case the client was already allowed to send data, do nothing.
570  *
571  * @param ch Channel.
572  * @param fwd Is this a FWD ACK? (FWD ACKs are sent to root)
573  */
574 static void
575 send_client_ack (struct MeshChannel *ch, int fwd)
576 {
577   struct MeshChannelReliability *rel = fwd ? ch->root_rel : ch->dest_rel;
578
579   LOG (GNUNET_ERROR_TYPE_DEBUG,
580        "  sending %s ack to client on channel %s\n",
581        GM_f2s (fwd), GMCH_2s (ch));
582
583   if (NULL == rel)
584   {
585     GNUNET_break (0);
586     return;
587   }
588
589   if (GNUNET_YES == rel->client_allowed)
590   {
591     LOG (GNUNET_ERROR_TYPE_DEBUG, "  already allowed\n");
592     return;
593   }
594   rel->client_allowed = GNUNET_YES;
595
596   GML_send_ack (fwd ? ch->root : ch->dest, fwd ? ch->lid_root : ch->lid_dest);
597 }
598
599
600 /**
601  * Notify the root that the destination rejected the channel.
602  *
603  * @param ch Rejected channel.
604  */
605 static void
606 send_client_nack (struct MeshChannel *ch)
607 {
608   if (NULL == ch->root)
609   {
610     GNUNET_break (0);
611     return;
612   }
613   GML_send_nack (ch->root, ch->lid_root);
614 }
615
616
617 /**
618  * We haven't received an ACK after a certain time: restransmit the message.
619  *
620  * @param cls Closure (MeshChannelReliability with the message to restransmit)
621  * @param tc TaskContext.
622  */
623 static void
624 channel_retransmit_message (void *cls,
625                             const struct GNUNET_SCHEDULER_TaskContext *tc)
626 {
627   struct MeshChannelReliability *rel = cls;
628   struct MeshReliableMessage *copy;
629   struct MeshChannel *ch;
630   struct GNUNET_MESH_Data *payload;
631   int fwd;
632
633   rel->retry_task = GNUNET_SCHEDULER_NO_TASK;
634   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
635     return;
636
637   ch = rel->ch;
638   copy = rel->head_sent;
639   if (NULL == copy)
640   {
641     GNUNET_break (0);
642     return;
643   }
644
645   payload = (struct GNUNET_MESH_Data *) &copy[1];
646   fwd = (rel == ch->root_rel);
647
648   /* Message not found in the queue that we are going to use. */
649   LOG (GNUNET_ERROR_TYPE_DEBUG, "!!! RETRANSMIT %u\n", copy->mid);
650
651   GMCH_send_prebuilt_message (&payload->header, ch, fwd, copy);
652   GNUNET_STATISTICS_update (stats, "# data retransmitted", 1, GNUNET_NO);
653 }
654
655
656 /**
657  * We haven't received an Channel ACK after a certain time: resend the CREATE.
658  *
659  * @param cls Closure (MeshChannelReliability of the channel to recreate)
660  * @param tc TaskContext.
661  */
662 static void
663 channel_recreate (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
664 {
665   struct MeshChannelReliability *rel = cls;
666
667   rel->retry_task = GNUNET_SCHEDULER_NO_TASK;
668   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
669     return;
670
671   LOG (GNUNET_ERROR_TYPE_DEBUG, "!!! RE-CREATE\n");
672   GNUNET_STATISTICS_update (stats, "# data retransmitted", 1, GNUNET_NO);
673
674   if (rel == rel->ch->root_rel)
675   {
676     send_create (rel->ch);
677   }
678   else if (rel == rel->ch->dest_rel)
679   {
680     send_ack (rel->ch, GNUNET_YES);
681   }
682   else
683   {
684     GNUNET_break (0);
685   }
686
687 }
688
689
690 /**
691  * Message has been sent: start retransmission timer.
692  *
693  * @param cls Closure (queue structure).
694  * @param t Tunnel.
695  * @param q Queue handler (no longer valid).
696  * @param type Type of message.
697  * @param size Size of the message.
698  */
699 static void
700 ch_message_sent (void *cls,
701                  struct MeshTunnel3 *t,
702                  struct MeshTunnel3Queue *q,
703                  uint16_t type, size_t size)
704 {
705   struct MeshChannelQueue *ch_q = cls;
706   struct MeshReliableMessage *copy = ch_q->copy;
707   struct MeshChannelReliability *rel;
708
709   switch (ch_q->type)
710   {
711     case GNUNET_MESSAGE_TYPE_MESH_DATA:
712       LOG (GNUNET_ERROR_TYPE_DEBUG, "!!! SENT %u %s (c: %p, q: %p)\n",
713            copy->mid, GM_m2s (type), copy, copy->q);
714       GNUNET_assert (ch_q == copy->q);
715       copy->timestamp = GNUNET_TIME_absolute_get ();
716       rel = copy->rel;
717       if (GNUNET_SCHEDULER_NO_TASK == rel->retry_task)
718       {
719         if (0 != rel->expected_delay.rel_value_us)
720         {
721           rel->retry_timer =
722           GNUNET_TIME_relative_multiply (rel->expected_delay,
723                                          MESH_RETRANSMIT_MARGIN);
724         }
725         else
726         {
727           rel->retry_timer = MESH_RETRANSMIT_TIME;
728         }
729         rel->retry_task =
730             GNUNET_SCHEDULER_add_delayed (rel->retry_timer,
731                                           &channel_retransmit_message, rel);
732       }
733       copy->q = NULL;
734       break;
735
736
737     case GNUNET_MESSAGE_TYPE_MESH_DATA_ACK:
738     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_CREATE:
739     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_ACK:
740       rel = ch_q->rel;
741       GNUNET_assert (rel->uniq == ch_q);
742       rel->uniq = NULL;
743
744       if (MESH_CHANNEL_READY != rel->ch->state
745           && GNUNET_MESSAGE_TYPE_MESH_DATA_ACK != type)
746       {
747         GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == rel->retry_task);
748         rel->retry_timer = GNUNET_TIME_STD_BACKOFF (rel->retry_timer);
749         rel->retry_task = GNUNET_SCHEDULER_add_delayed (rel->retry_timer,
750                                                         &channel_recreate, rel);
751       }
752       break;
753
754
755     default:
756       GNUNET_break (0);
757   }
758
759   GNUNET_free (ch_q);
760 }
761
762
763 /**
764  * send a channel create message.
765  *
766  * @param ch Channel for which to send.
767  */
768 static void
769 send_create (struct MeshChannel *ch)
770 {
771   struct GNUNET_MESH_ChannelCreate msgcc;
772
773   msgcc.header.size = htons (sizeof (msgcc));
774   msgcc.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_CHANNEL_CREATE);
775   msgcc.chid = htonl (ch->gid);
776   msgcc.port = htonl (ch->port);
777   msgcc.opt = htonl (channel_get_options (ch));
778
779   GMCH_send_prebuilt_message (&msgcc.header, ch, GNUNET_YES, NULL);
780 }
781
782
783 /**
784  * Confirm we got a channel create, FWD ack.
785  *
786  * @param ch The channel to confirm.
787  * @param fwd Should we send a FWD ACK? (going dest->root)
788  */
789 static void
790 send_ack (struct MeshChannel *ch, int fwd)
791 {
792   struct GNUNET_MESH_ChannelManage msg;
793
794   msg.header.size = htons (sizeof (msg));
795   msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_CHANNEL_ACK);
796   LOG (GNUNET_ERROR_TYPE_DEBUG,
797        "  sending channel %s ack for channel %s\n",
798        GM_f2s (fwd), GMCH_2s (ch));
799
800   msg.chid = htonl (ch->gid);
801   GMCH_send_prebuilt_message (&msg.header, ch, !fwd, NULL);
802 }
803
804
805 /**
806  * Notify that a channel create didn't succeed.
807  *
808  * @param ch The channel to reject.
809  */
810 static void
811 send_nack (struct MeshChannel *ch)
812 {
813   struct GNUNET_MESH_ChannelManage msg;
814
815   msg.header.size = htons (sizeof (msg));
816   msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_CHANNEL_NACK);
817   LOG (GNUNET_ERROR_TYPE_DEBUG,
818        "  sending channel NACK for channel %s\n",
819        GMCH_2s (ch));
820
821   msg.chid = htonl (ch->gid);
822   GMCH_send_prebuilt_message (&msg.header, ch, GNUNET_NO, NULL);
823 }
824
825
826 /**
827  * Notify a client that the channel is no longer valid.
828  *
829  * @param ch Channel that is destroyed.
830  * @param local_only Should we avoid sending it to other peers?
831  */
832 static void
833 send_destroy (struct MeshChannel *ch, int local_only)
834 {
835   struct GNUNET_MESH_ChannelManage msg;
836
837   msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_CHANNEL_DESTROY);
838   msg.header.size = htons (sizeof (msg));
839   msg.chid = htonl (ch->gid);
840
841   /* If root is not NULL, notify.
842    * If it's NULL, check lid_root. When a local destroy comes in, root
843    * is set to NULL but lid_root is left untouched. In this case, do nothing,
844    * the client is the one who reuqested the channel to be destroyed.
845    */
846   if (NULL != ch->root)
847     GML_send_channel_destroy (ch->root, ch->lid_root);
848   else if (0 == ch->lid_root && GNUNET_NO == local_only)
849     GMCH_send_prebuilt_message (&msg.header, ch, GNUNET_NO, NULL);
850
851   if (NULL != ch->dest)
852     GML_send_channel_destroy (ch->dest, ch->lid_dest);
853   else if (0 == ch->lid_dest && GNUNET_NO == local_only)
854     GMCH_send_prebuilt_message (&msg.header, ch, GNUNET_YES, NULL);
855 }
856
857
858 /**
859  * Destroy all reliable messages queued for a channel,
860  * during a channel destruction.
861  * Frees the reliability structure itself.
862  *
863  * @param rel Reliability data for a channel.
864  */
865 static void
866 channel_rel_free_all (struct MeshChannelReliability *rel)
867 {
868   struct MeshReliableMessage *copy;
869   struct MeshReliableMessage *next;
870
871   if (NULL == rel)
872     return;
873
874   for (copy = rel->head_recv; NULL != copy; copy = next)
875   {
876     next = copy->next;
877     GNUNET_CONTAINER_DLL_remove (rel->head_recv, rel->tail_recv, copy);
878     LOG (GNUNET_ERROR_TYPE_DEBUG, " COPYFREE BATCH RECV %p\n", copy);
879     GNUNET_free (copy);
880   }
881   for (copy = rel->head_sent; NULL != copy; copy = next)
882   {
883     next = copy->next;
884     GNUNET_CONTAINER_DLL_remove (rel->head_sent, rel->tail_sent, copy);
885     LOG (GNUNET_ERROR_TYPE_DEBUG, " COPYFREE BATCH %p\n", copy);
886     GNUNET_free (copy);
887   }
888   if (GNUNET_SCHEDULER_NO_TASK != rel->retry_task)
889   {
890     GNUNET_SCHEDULER_cancel (rel->retry_task);
891   }
892   if (NULL != rel->uniq)
893     GMT_cancel (rel->uniq->q);
894   GNUNET_free (rel);
895 }
896
897
898 /**
899  * Mark future messages as ACK'd.
900  *
901  * @param rel Reliability data.
902  * @param msg DataACK message with a bitfield of future ACK'd messages.
903  */
904 static void
905 channel_rel_free_sent (struct MeshChannelReliability *rel,
906                        const struct GNUNET_MESH_DataACK *msg)
907 {
908   struct MeshReliableMessage *copy;
909   struct MeshReliableMessage *next;
910   uint64_t bitfield;
911   uint64_t mask;
912   uint32_t mid;
913   uint32_t target;
914   unsigned int i;
915
916   bitfield = msg->futures;
917   mid = ntohl (msg->mid);
918   LOG (GNUNET_ERROR_TYPE_DEBUG,
919               "!!! free_sent_reliable %u %llX\n",
920               mid, bitfield);
921   LOG (GNUNET_ERROR_TYPE_DEBUG,
922               " rel %p, head %p\n",
923               rel, rel->head_sent);
924   for (i = 0, copy = rel->head_sent;
925        i < 64 && NULL != copy && 0 != bitfield;
926        i++)
927   {
928     LOG (GNUNET_ERROR_TYPE_DEBUG,
929                 " trying bit %u (mid %u)\n",
930                 i, mid + i + 1);
931     mask = 0x1LL << i;
932     if (0 == (bitfield & mask))
933      continue;
934
935     LOG (GNUNET_ERROR_TYPE_DEBUG, " set!\n");
936     /* Bit was set, clear the bit from the bitfield */
937     bitfield &= ~mask;
938
939     /* The i-th bit was set. Do we have that copy? */
940     /* Skip copies with mid < target */
941     target = mid + i + 1;
942     LOG (GNUNET_ERROR_TYPE_DEBUG, " target %u\n", target);
943     while (NULL != copy && GM_is_pid_bigger (target, copy->mid))
944      copy = copy->next;
945
946     /* Did we run out of copies? (previously freed, it's ok) */
947     if (NULL == copy)
948     {
949      LOG (GNUNET_ERROR_TYPE_DEBUG, "run out of copies...\n");
950      return;
951     }
952
953     /* Did we overshoot the target? (previously freed, it's ok) */
954     if (GM_is_pid_bigger (copy->mid, target))
955     {
956      LOG (GNUNET_ERROR_TYPE_DEBUG, " next copy %u\n", copy->mid);
957      continue;
958     }
959
960     /* Now copy->mid == target, free it */
961     next = copy->next;
962     rel_message_free (copy, GNUNET_YES);
963     copy = next;
964   }
965   LOG (GNUNET_ERROR_TYPE_DEBUG, "free_sent_reliable END\n");
966 }
967
968
969 /**
970  * Destroy a reliable message after it has been acknowledged, either by
971  * direct mid ACK or bitfield. Updates the appropriate data structures and
972  * timers and frees all memory.
973  *
974  * @param copy Message that is no longer needed: remote peer got it.
975  * @param update_time Is the timing information relevant?
976  *                    If this message is ACK in a batch the timing information
977  *                    is skewed by the retransmission, count only for the
978  *                    retransmitted message.
979  */
980 static void
981 rel_message_free (struct MeshReliableMessage *copy, int update_time)
982 {
983   struct MeshChannelReliability *rel;
984   struct GNUNET_TIME_Relative time;
985
986   rel = copy->rel;
987   LOG (GNUNET_ERROR_TYPE_DEBUG, "!!! Freeing %u\n", copy->mid);
988   if (update_time)
989   {
990     time = GNUNET_TIME_absolute_get_duration (copy->timestamp);
991     if (0 == rel->expected_delay.rel_value_us)
992       rel->expected_delay = time;
993     else
994     {
995       rel->expected_delay.rel_value_us *= 7;
996       rel->expected_delay.rel_value_us += time.rel_value_us;
997       rel->expected_delay.rel_value_us /= 8;
998     }
999     LOG (GNUNET_ERROR_TYPE_DEBUG, "!!!  took %s\n",
1000                 GNUNET_STRINGS_relative_time_to_string (time, GNUNET_NO));
1001     LOG (GNUNET_ERROR_TYPE_DEBUG, "!!!  new expected delay %s\n",
1002                 GNUNET_STRINGS_relative_time_to_string (rel->expected_delay,
1003                                                         GNUNET_NO));
1004     rel->retry_timer = rel->expected_delay;
1005   }
1006   else
1007   {
1008     LOG (GNUNET_ERROR_TYPE_DEBUG, "!!! batch free, ignoring timing\n");
1009   }
1010   rel->ch->pending_messages--;
1011   if (GNUNET_NO != rel->ch->destroy && 0 == rel->ch->pending_messages)
1012   {
1013     struct MeshTunnel3 *t = rel->ch->t;
1014     GMCH_destroy (rel->ch);
1015     GMT_destroy_if_empty (t);
1016   }
1017   if (NULL != copy->q)
1018   {
1019     GMT_cancel (copy->q->q);
1020   }
1021   GNUNET_CONTAINER_DLL_remove (rel->head_sent, rel->tail_sent, copy);
1022   LOG (GNUNET_ERROR_TYPE_DEBUG, " COPYFREE %p\n", copy);
1023   GNUNET_free (copy);
1024 }
1025
1026
1027 /**
1028  * Channel was ACK'd by remote peer, mark as ready and cancel retransmission.
1029  *
1030  * @param ch Channel to mark as ready.
1031  * @param fwd Was the ACK message a FWD ACK? (dest->root, SYNACK)
1032  */
1033 static void
1034 channel_confirm (struct MeshChannel *ch, int fwd)
1035 {
1036   struct MeshChannelReliability *rel;
1037
1038   LOG (GNUNET_ERROR_TYPE_DEBUG,
1039               "  channel confirm %s %s:%X\n",
1040               GM_f2s (fwd), GMT_2s (ch->t), ch->gid);
1041   ch->state = MESH_CHANNEL_READY;
1042
1043   rel = fwd ? ch->root_rel : ch->dest_rel;
1044   rel->client_ready = GNUNET_YES;
1045   rel->expected_delay = rel->retry_timer;
1046   send_client_ack (ch, fwd);
1047
1048   if (GNUNET_SCHEDULER_NO_TASK != rel->retry_task)
1049   {
1050     GNUNET_SCHEDULER_cancel (rel->retry_task);
1051     rel->retry_task = GNUNET_SCHEDULER_NO_TASK;
1052   }
1053   else if (NULL != rel->uniq)
1054   {
1055     GMT_cancel (rel->uniq->q);
1056     /* ch_sent_message will free and NULL uniq */
1057   }
1058   else
1059   {
1060     /* We SHOULD have been trying to retransmit this! */
1061     GNUNET_break (0);
1062   }
1063
1064   /* In case of a FWD ACK (SYNACK) send a BCK ACK (ACK). */
1065   if (GNUNET_YES == fwd)
1066     send_ack (ch, GNUNET_NO);
1067 }
1068
1069
1070 /**
1071  * Save a copy to retransmit in case it gets lost.
1072  *
1073  * Initializes all needed callbacks and timers.
1074  *
1075  * @param ch Channel this message goes on.
1076  * @param msg Message to copy.
1077  * @param fwd Is this fwd traffic?
1078  */
1079 static struct MeshReliableMessage *
1080 channel_save_copy (struct MeshChannel *ch,
1081                    const struct GNUNET_MessageHeader *msg,
1082                    int fwd)
1083 {
1084   struct MeshChannelReliability *rel;
1085   struct MeshReliableMessage *copy;
1086   uint32_t mid;
1087   uint16_t type;
1088   uint16_t size;
1089
1090   rel = fwd ? ch->root_rel : ch->dest_rel;
1091   mid = rel->mid_send - 1;
1092   type = ntohs (msg->type);
1093   size = ntohs (msg->size);
1094
1095   LOG (GNUNET_ERROR_TYPE_DEBUG, "!!! SAVE %u %s\n", mid, GM_m2s (type));
1096   copy = GNUNET_malloc (sizeof (struct MeshReliableMessage) + size);
1097   LOG (GNUNET_ERROR_TYPE_DEBUG, "  at %p\n", copy);
1098   copy->mid = mid;
1099   copy->rel = rel;
1100   copy->type = type;
1101   memcpy (&copy[1], msg, size);
1102   GNUNET_CONTAINER_DLL_insert_tail (rel->head_sent, rel->tail_sent, copy);
1103   ch->pending_messages++;
1104
1105   return copy;
1106 }
1107
1108
1109 /**
1110  * Create a new channel.
1111  *
1112  * @param t Tunnel this channel is in.
1113  * @param owner Client that owns the channel, NULL for foreign channels.
1114  * @param lid_root Local ID for root client.
1115  *
1116  * @return A new initialized channel. NULL on error.
1117  */
1118 static struct MeshChannel *
1119 channel_new (struct MeshTunnel3 *t,
1120              struct MeshClient *owner,
1121              MESH_ChannelNumber lid_root)
1122 {
1123   struct MeshChannel *ch;
1124
1125   ch = GNUNET_new (struct MeshChannel);
1126   ch->root = owner;
1127   ch->lid_root = lid_root;
1128   ch->t = t;
1129
1130   GNUNET_STATISTICS_update (stats, "# channels", 1, GNUNET_NO);
1131
1132   if (NULL != owner)
1133   {
1134     ch->gid = GMT_get_next_chid (t);
1135     GML_channel_add (owner, lid_root, ch);
1136   }
1137   GMT_add_channel (t, ch);
1138
1139   return ch;
1140 }
1141
1142
1143 /**
1144  * Test if the channel is loopback: both root and dest are on the local peer.
1145  *
1146  * @param ch Channel to test.
1147  *
1148  * @return #GNUNET_YES if channel is loopback, #NGUNET_NO otherwise.
1149  */
1150 static int
1151 is_loopback (const struct MeshChannel *ch)
1152 {
1153   if (NULL != ch->t)
1154     return GMT_is_loopback (ch->t);
1155
1156   return (NULL != ch->root && NULL != ch->dest);
1157 }
1158
1159
1160 /**
1161  * Handle a loopback message: call the appropriate handler for the message type.
1162  *
1163  * @param ch Channel this message is on.
1164  * @param msgh Message header.
1165  * @param fwd Is this FWD traffic?
1166  */
1167 void
1168 handle_loopback (struct MeshChannel *ch,
1169                  const struct GNUNET_MessageHeader *msgh,
1170                  int fwd)
1171 {
1172   uint16_t type;
1173
1174   type = ntohs (msgh->type);
1175   LOG (GNUNET_ERROR_TYPE_DEBUG,
1176        "Loopback %s %s message!\n",
1177        GM_f2s (fwd), GM_m2s (type));
1178
1179   switch (type)
1180   {
1181     case GNUNET_MESSAGE_TYPE_MESH_DATA:
1182       /* Don't send hop ACK, wait for client to ACK */
1183       GMCH_handle_data (ch, (struct GNUNET_MESH_Data *) msgh, fwd);
1184       break;
1185
1186     case GNUNET_MESSAGE_TYPE_MESH_DATA_ACK:
1187       GMCH_handle_data_ack (ch, (struct GNUNET_MESH_DataACK *) msgh, fwd);
1188       break;
1189
1190     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_CREATE:
1191       GMCH_handle_create (ch->t,
1192                           (struct GNUNET_MESH_ChannelCreate *) msgh);
1193       break;
1194
1195     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_ACK:
1196       GMCH_handle_ack (ch,
1197                        (struct GNUNET_MESH_ChannelManage *) msgh,
1198                        fwd);
1199       break;
1200
1201     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_NACK:
1202       GMCH_handle_nack (ch);
1203       break;
1204
1205     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_DESTROY:
1206       GMCH_handle_destroy (ch,
1207                            (struct GNUNET_MESH_ChannelManage *) msgh,
1208                            fwd);
1209       break;
1210
1211     default:
1212       GNUNET_break_op (0);
1213       LOG (GNUNET_ERROR_TYPE_DEBUG,
1214            "end-to-end message not known (%u)\n",
1215            ntohs (msgh->type));
1216   }
1217 }
1218
1219
1220
1221 /******************************************************************************/
1222 /********************************    API    ***********************************/
1223 /******************************************************************************/
1224
1225 /**
1226  * Destroy a channel and free all resources.
1227  *
1228  * @param ch Channel to destroy.
1229  */
1230 void
1231 GMCH_destroy (struct MeshChannel *ch)
1232 {
1233   struct MeshClient *c;
1234
1235   if (NULL == ch)
1236     return;
1237
1238   LOG (GNUNET_ERROR_TYPE_DEBUG, "destroying channel %s:%u\n",
1239               GMT_2s (ch->t), ch->gid);
1240   GMCH_debug (ch);
1241
1242   c = ch->root;
1243   if (NULL != c)
1244   {
1245     GML_channel_remove (c, ch->lid_root, ch);
1246   }
1247
1248   c = ch->dest;
1249   if (NULL != c)
1250   {
1251     GML_channel_remove (c, ch->lid_dest, ch);
1252   }
1253
1254   channel_rel_free_all (ch->root_rel);
1255   channel_rel_free_all (ch->dest_rel);
1256
1257   GMT_remove_channel (ch->t, ch);
1258   GNUNET_STATISTICS_update (stats, "# channels", -1, GNUNET_NO);
1259
1260   GNUNET_free (ch);
1261 }
1262
1263
1264 /**
1265  * Get channel ID.
1266  *
1267  * @param ch Channel.
1268  *
1269  * @return ID
1270  */
1271 MESH_ChannelNumber
1272 GMCH_get_id (const struct MeshChannel *ch)
1273 {
1274   return ch->gid;
1275 }
1276
1277
1278 /**
1279  * Get the channel tunnel.
1280  *
1281  * @param ch Channel to get the tunnel from.
1282  *
1283  * @return tunnel of the channel.
1284  */
1285 struct MeshTunnel3 *
1286 GMCH_get_tunnel (const struct MeshChannel *ch)
1287 {
1288   return ch->t;
1289 }
1290
1291
1292 /**
1293  * Get free buffer space towards the client on a specific channel.
1294  *
1295  * @param ch Channel.
1296  * @param fwd Is query about FWD traffic?
1297  *
1298  * @return Free buffer space [0 - 64]
1299  */
1300 unsigned int
1301 GMCH_get_buffer (struct MeshChannel *ch, int fwd)
1302 {
1303   struct MeshChannelReliability *rel;
1304
1305   rel = fwd ? ch->dest_rel : ch->root_rel;
1306
1307   /* If rel is NULL it means that the end is not yet created,
1308    * most probably is a loopback channel at the point of sending
1309    * the ChannelCreate to itself.
1310    */
1311   if (NULL == rel)
1312     return 64;
1313
1314   return (64 - rel->n_recv);
1315 }
1316
1317
1318 /**
1319  * Get flow control status of end point: is client allow to send?
1320  *
1321  * @param ch Channel.
1322  * @param fwd Is query about FWD traffic? (Request root status).
1323  *
1324  * @return #GNUNET_YES if client is allowed to send us data.
1325  */
1326 int
1327 GMCH_get_allowed (struct MeshChannel *ch, int fwd)
1328 {
1329   struct MeshChannelReliability *rel;
1330
1331   rel = fwd ? ch->root_rel : ch->dest_rel;
1332
1333   if (NULL == rel)
1334   {
1335     /* Probably shutting down: root/dest NULL'ed to mark disconnection */
1336     GNUNET_break (GNUNET_NO != ch->destroy);
1337     return 0;
1338   }
1339
1340   return rel->client_allowed;
1341 }
1342
1343
1344 /**
1345  * Is the root client for this channel on this peer?
1346  *
1347  * @param ch Channel.
1348  * @param fwd Is this for fwd traffic?
1349  *
1350  * @return #GNUNET_YES in case it is.
1351  */
1352 int
1353 GMCH_is_origin (struct MeshChannel *ch, int fwd)
1354 {
1355   struct MeshClient *c;
1356
1357   c = fwd ? ch->root : ch->dest;
1358   return NULL != c;
1359 }
1360
1361
1362 /**
1363  * Is the destination client for this channel on this peer?
1364  *
1365  * @param ch Channel.
1366  * @param fwd Is this for fwd traffic?
1367  *
1368  * @return #GNUNET_YES in case it is.
1369  */
1370 int
1371 GMCH_is_terminal (struct MeshChannel *ch, int fwd)
1372 {
1373   struct MeshClient *c;
1374
1375   c = fwd ? ch->dest : ch->root;
1376   return NULL != c;
1377 }
1378
1379
1380 /**
1381  * Send an end-to-end ACK message for the most recent in-sequence payload.
1382  *
1383  * If channel is not reliable, do nothing.
1384  *
1385  * @param ch Channel this is about.
1386  * @param fwd Is for FWD traffic? (ACK dest->owner)
1387  */
1388 void
1389 GMCH_send_data_ack (struct MeshChannel *ch, int fwd)
1390 {
1391   struct GNUNET_MESH_DataACK msg;
1392   struct MeshChannelReliability *rel;
1393   struct MeshReliableMessage *copy;
1394   unsigned int delta;
1395   uint64_t mask;
1396   uint32_t ack;
1397
1398   if (GNUNET_NO == ch->reliable)
1399   {
1400     return;
1401   }
1402   rel = fwd ? ch->dest_rel : ch->root_rel;
1403   ack = rel->mid_recv - 1;
1404   LOG (GNUNET_ERROR_TYPE_DEBUG,
1405               " !! Send DATA_ACK for %u\n",
1406               ack);
1407
1408   msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_DATA_ACK);
1409   msg.header.size = htons (sizeof (msg));
1410   msg.chid = htonl (ch->gid);
1411   msg.futures = 0;
1412   for (copy = rel->head_recv; NULL != copy; copy = copy->next)
1413   {
1414     if (copy->type != GNUNET_MESSAGE_TYPE_MESH_DATA)
1415     {
1416       LOG (GNUNET_ERROR_TYPE_DEBUG,
1417            "!!  Type %s, expected DATA\n",
1418            GM_m2s (copy->type));
1419       continue;
1420     }
1421     if (copy->mid == ack + 1)
1422     {
1423       ack++;
1424       continue;
1425     }
1426     delta = copy->mid - (ack + 1);
1427     if (63 < delta)
1428       break;
1429     mask = 0x1LL << delta;
1430     msg.futures |= mask;
1431     LOG (GNUNET_ERROR_TYPE_DEBUG,
1432          " !! setting bit for %u (delta %u) (%llX) -> %llX\n",
1433          copy->mid, delta, mask, msg.futures);
1434   }
1435   msg.mid = htonl (ack);
1436   LOG (GNUNET_ERROR_TYPE_DEBUG,
1437        "!!! ACK for %u, futures %llX\n",
1438        ack, msg.futures);
1439
1440   GMCH_send_prebuilt_message (&msg.header, ch, !fwd, NULL);
1441   LOG (GNUNET_ERROR_TYPE_DEBUG, "send_data_ack END\n");
1442 }
1443
1444
1445 /**
1446  * Allow a client to send us more data, in case it was choked.
1447  *
1448  * @param ch Channel.
1449  * @param fwd Is this about FWD traffic? (Root client).
1450  */
1451 void
1452 GMCH_allow_client (struct MeshChannel *ch, int fwd)
1453 {
1454   struct MeshChannelReliability *rel;
1455   unsigned int buffer;
1456
1457   LOG (GNUNET_ERROR_TYPE_DEBUG, "GMCH allow\n");
1458
1459   if (MESH_CHANNEL_READY != ch->state)
1460   {
1461     LOG (GNUNET_ERROR_TYPE_DEBUG, " channel not ready yet!\n");
1462     return;
1463   }
1464
1465   if (GNUNET_YES == ch->reliable)
1466   {
1467     rel = fwd ? ch->root_rel : ch->dest_rel;
1468     if (NULL == rel)
1469     {
1470       GNUNET_break (GNUNET_NO != ch->destroy);
1471       return;
1472     }
1473     if (NULL != rel->head_sent && 64 <= rel->mid_send - rel->head_sent->mid)
1474     {
1475       LOG (GNUNET_ERROR_TYPE_DEBUG, " too big MID gap! Wait for ACK.\n");
1476       return;
1477     }
1478   }
1479
1480   if (is_loopback (ch))
1481     buffer = GMCH_get_buffer (ch, fwd);
1482   else
1483     buffer = GMT_get_connections_buffer (ch->t);
1484
1485   if (0 == buffer)
1486   {
1487     LOG (GNUNET_ERROR_TYPE_DEBUG, " no buffer space.\n");
1488     return;
1489   }
1490
1491   LOG (GNUNET_ERROR_TYPE_DEBUG, " buffer space %u, allowing\n", buffer);
1492   send_client_ack (ch, fwd);
1493 }
1494
1495
1496 /**
1497  * Log channel info.
1498  *
1499  * @param ch Channel.
1500  */
1501 void
1502 GMCH_debug (struct MeshChannel *ch)
1503 {
1504   if (NULL == ch)
1505   {
1506     LOG (GNUNET_ERROR_TYPE_DEBUG, "*** DEBUG NULL CHANNEL ***\n");
1507     return;
1508   }
1509   LOG (GNUNET_ERROR_TYPE_DEBUG, "Channel %s:%X (%p)\n",
1510               GMT_2s (ch->t), ch->gid, ch);
1511   LOG (GNUNET_ERROR_TYPE_DEBUG, "  root %p/%p\n",
1512               ch->root, ch->root_rel);
1513   if (NULL != ch->root)
1514   {
1515     LOG (GNUNET_ERROR_TYPE_DEBUG, "  cli %s\n", GML_2s (ch->root));
1516     LOG (GNUNET_ERROR_TYPE_DEBUG, "  ready %s\n",
1517                 ch->root_rel->client_ready ? "YES" : "NO");
1518     LOG (GNUNET_ERROR_TYPE_DEBUG, "  id %X\n", ch->lid_root);
1519   }
1520   LOG (GNUNET_ERROR_TYPE_DEBUG, "  dest %p/%p\n",
1521               ch->dest, ch->dest_rel);
1522   if (NULL != ch->dest)
1523   {
1524     LOG (GNUNET_ERROR_TYPE_DEBUG, "  cli %s\n", GML_2s (ch->dest));
1525     LOG (GNUNET_ERROR_TYPE_DEBUG, "  ready %s\n",
1526                 ch->dest_rel->client_ready ? "YES" : "NO");
1527     LOG (GNUNET_ERROR_TYPE_DEBUG, "  id %X\n", ch->lid_dest);
1528   }
1529 }
1530
1531
1532 /**
1533  * Handle an ACK given by a client.
1534  *
1535  * Mark client as ready and send him any buffered data we could have for him.
1536  *
1537  * @param ch Channel.
1538  * @param fwd Is this a "FWD ACK"? (FWD ACKs are sent by dest and go BCK)
1539  */
1540 void
1541 GMCH_handle_local_ack (struct MeshChannel *ch, int fwd)
1542 {
1543   struct MeshChannelReliability *rel;
1544   struct MeshClient *c;
1545
1546   rel = fwd ? ch->dest_rel : ch->root_rel;
1547   c   = fwd ? ch->dest     : ch->root;
1548
1549   rel->client_ready = GNUNET_YES;
1550   send_client_buffered_data (ch, c, fwd);
1551   if (is_loopback (ch))
1552   {
1553     unsigned int buffer;
1554
1555     buffer = GMCH_get_buffer (ch, fwd);
1556     if (0 < buffer)
1557       GMCH_allow_client (ch, fwd);
1558
1559     return;
1560   }
1561   GMT_send_connection_acks (ch->t);
1562 }
1563
1564
1565 /**
1566  * Handle data given by a client.
1567  *
1568  * Check whether the client is allowed to send in this tunnel, save if channel
1569  * is reliable and send an ACK to the client if there is still buffer space
1570  * in the tunnel.
1571  *
1572  * @param ch Channel.
1573  * @param c Client which sent the data.
1574  * @param message Message.
1575  * @param fwd Is this a FWD data?
1576  *
1577  * @return GNUNET_OK if everything goes well, GNUNET_SYSERR in case of en error.
1578  */
1579 int
1580 GMCH_handle_local_data (struct MeshChannel *ch,
1581                         struct MeshClient *c,
1582                         struct GNUNET_MessageHeader *message,
1583                         int fwd)
1584 {
1585   struct MeshChannelReliability *rel;
1586   struct GNUNET_MESH_Data *payload;
1587   size_t size = ntohs (message->size);
1588   uint16_t p2p_size = sizeof(struct GNUNET_MESH_Data) + size;
1589   unsigned char cbuf[p2p_size];
1590
1591   /* Is the client in the channel? */
1592   if ( !( (fwd &&
1593            ch->root == c)
1594          ||
1595           (!fwd &&
1596            ch->dest == c) ) )
1597   {
1598     GNUNET_break_op (0);
1599     return GNUNET_SYSERR;
1600   }
1601
1602   rel = fwd ? ch->root_rel : ch->dest_rel;
1603
1604   if (GNUNET_NO == rel->client_allowed)
1605   {
1606     GNUNET_break_op (0);
1607     return GNUNET_SYSERR;
1608   }
1609
1610   rel->client_allowed = GNUNET_NO;
1611
1612   /* Ok, everything is correct, send the message. */
1613   payload = (struct GNUNET_MESH_Data *) cbuf;
1614   payload->mid = htonl (rel->mid_send);
1615   rel->mid_send++;
1616   memcpy (&payload[1], message, size);
1617   payload->header.size = htons (p2p_size);
1618   payload->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_DATA);
1619   payload->chid = htonl (ch->gid);
1620   LOG (GNUNET_ERROR_TYPE_DEBUG, "  sending on channel...\n");
1621   GMCH_send_prebuilt_message (&payload->header, ch, fwd, NULL);
1622
1623   if (is_loopback (ch))
1624   {
1625     if (GMCH_get_buffer (ch, fwd) > 0)
1626       send_client_ack (ch, fwd);
1627
1628     return GNUNET_OK;
1629   }
1630
1631   if (GMT_get_connections_buffer (ch->t) > 0)
1632   {
1633     send_client_ack (ch, fwd);
1634   }
1635
1636   return GNUNET_OK;
1637 }
1638
1639
1640 /**
1641  * Handle a channel destroy requested by a client.
1642  *
1643  * Destroy the channel and the tunnel in case this was the last channel.
1644  *
1645  * @param ch Channel.
1646  * @param c Client that requested the destruction (to avoid notifying him).
1647  * @param is_root Is the request coming from root?
1648  */
1649 void
1650 GMCH_handle_local_destroy (struct MeshChannel *ch,
1651                            struct MeshClient *c,
1652                            int is_root)
1653 {
1654   struct MeshTunnel3 *t;
1655
1656   ch->destroy = GNUNET_YES;
1657   /* Cleanup after the tunnel */
1658   if (GNUNET_NO == is_root && c == ch->dest)
1659   {
1660     LOG (GNUNET_ERROR_TYPE_DEBUG, " Client %s is destination.\n", GML_2s (c));
1661     GML_client_delete_channel (c, ch, ch->lid_dest);
1662     ch->dest = NULL;
1663   }
1664   if (GNUNET_YES == is_root && c == ch->root)
1665   {
1666     LOG (GNUNET_ERROR_TYPE_DEBUG, " Client %s is owner.\n", GML_2s (c));
1667     GML_client_delete_channel (c, ch, ch->lid_root);
1668     ch->root = NULL;
1669   }
1670
1671   t = ch->t;
1672   send_destroy (ch, GNUNET_NO);
1673   if (0 == ch->pending_messages)
1674   {
1675     GMCH_destroy (ch);
1676     GMT_destroy_if_empty (t);
1677   }
1678 }
1679
1680
1681 /**
1682  * Handle a channel create requested by a client.
1683  *
1684  * Create the channel and the tunnel in case this was the first0 channel.
1685  *
1686  * @param c Client that requested the creation (will be the root).
1687  * @param msg Create Channel message.
1688  *
1689  * @return GNUNET_OK if everything went fine, GNUNET_SYSERR otherwise.
1690  */
1691 int
1692 GMCH_handle_local_create (struct MeshClient *c,
1693                           struct GNUNET_MESH_ChannelMessage *msg)
1694 {
1695   struct MeshChannel *ch;
1696   struct MeshTunnel3 *t;
1697   struct MeshPeer *peer;
1698   MESH_ChannelNumber chid;
1699
1700   LOG (GNUNET_ERROR_TYPE_DEBUG, "  towards %s:%u\n",
1701               GNUNET_i2s (&msg->peer), ntohl (msg->port));
1702   chid = ntohl (msg->channel_id);
1703
1704   /* Sanity check for duplicate channel IDs */
1705   if (NULL != GML_channel_get (c, chid))
1706   {
1707     GNUNET_break (0);
1708     return GNUNET_SYSERR;
1709   }
1710
1711   peer = GMP_get (&msg->peer);
1712   GMP_add_tunnel (peer);
1713   t = GMP_get_tunnel (peer);
1714
1715   if (GMP_get_short_id (peer) == myid)
1716   {
1717     GMT_change_cstate (t, MESH_TUNNEL3_READY);
1718   }
1719   else
1720   {
1721     GMP_connect (peer);
1722   }
1723
1724   /* Create channel */
1725   ch = channel_new (t, c, chid);
1726   if (NULL == ch)
1727   {
1728     GNUNET_break (0);
1729     return GNUNET_SYSERR;
1730   }
1731   ch->port = ntohl (msg->port);
1732   channel_set_options (ch, ntohl (msg->opt));
1733
1734   /* In unreliable channels, we'll use the DLL to buffer BCK data */
1735   ch->root_rel = GNUNET_new (struct MeshChannelReliability);
1736   ch->root_rel->ch = ch;
1737   ch->root_rel->retry_timer = GNUNET_TIME_UNIT_SECONDS;
1738   ch->root_rel->expected_delay.rel_value_us = 0;
1739
1740   LOG (GNUNET_ERROR_TYPE_DEBUG, "CREATED CHANNEL %s\n", GMCH_2s (ch));
1741
1742   send_create (ch);
1743
1744   return GNUNET_OK;
1745 }
1746
1747
1748 /**
1749  * Handler for mesh network payload traffic.
1750  *
1751  * @param ch Channel for the message.
1752  * @param msg Unencryted data message.
1753  * @param fwd Is this message fwd? This only is meaningful in loopback channels.
1754  *            #GNUNET_YES if message is FWD on the respective channel (loopback)
1755  *            #GNUNET_NO if message is BCK on the respective channel (loopback)
1756  *            #GNUNET_SYSERR if message on a one-ended channel (remote)
1757  */
1758 void
1759 GMCH_handle_data (struct MeshChannel *ch,
1760                   const struct GNUNET_MESH_Data *msg,
1761                   int fwd)
1762 {
1763   struct MeshChannelReliability *rel;
1764   struct MeshClient *c;
1765   uint32_t mid;
1766
1767   /* If this is a remote (non-loopback) channel, find 'fwd'. */
1768   if (GNUNET_SYSERR == fwd)
1769   {
1770     if (is_loopback (ch))
1771     {
1772       /* It is a loopback channel after all... */
1773       GNUNET_break (0);
1774       return;
1775     }
1776     fwd = (NULL != ch->dest) ? GNUNET_YES : GNUNET_NO;
1777   }
1778
1779   /*  Initialize FWD/BCK data */
1780   c   = fwd ? ch->dest     : ch->root;
1781   rel = fwd ? ch->dest_rel : ch->root_rel;
1782
1783   if (NULL == c)
1784   {
1785     GNUNET_break (0);
1786     return;
1787   }
1788
1789   GNUNET_STATISTICS_update (stats, "# data received", 1, GNUNET_NO);
1790
1791   mid = ntohl (msg->mid);
1792   LOG (GNUNET_ERROR_TYPE_DEBUG, "!! got mid %u\n", mid);
1793
1794   if (GNUNET_NO == ch->reliable ||
1795       ( !GM_is_pid_bigger (rel->mid_recv, mid) &&
1796         GM_is_pid_bigger (rel->mid_recv + 64, mid) ) )
1797   {
1798     LOG (GNUNET_ERROR_TYPE_DEBUG, "!!! RECV %u\n", mid);
1799     if (GNUNET_YES == ch->reliable)
1800     {
1801       /* Is this the exact next expected messasge? */
1802       if (mid == rel->mid_recv)
1803       {
1804         LOG (GNUNET_ERROR_TYPE_DEBUG, "as expected\n");
1805         rel->mid_recv++;
1806         send_client_data (ch, msg, fwd);
1807       }
1808       else
1809       {
1810         LOG (GNUNET_ERROR_TYPE_DEBUG, "save for later\n");
1811         add_buffered_data (msg, rel);
1812       }
1813     }
1814     else
1815     {
1816       /* Tunnel is unreliable: send to clients directly */
1817       /* FIXME: accept Out Of Order traffic */
1818       rel->mid_recv = mid + 1;
1819       send_client_data (ch, msg, fwd);
1820     }
1821   }
1822   else
1823   {
1824     GNUNET_break_op (GM_is_pid_bigger (rel->mid_recv, mid));
1825     LOG (GNUNET_ERROR_TYPE_DEBUG,
1826                 " !!! MID %u not expected (%u - %u), dropping!\n",
1827                 mid, rel->mid_recv, rel->mid_recv + 63);
1828   }
1829
1830   GMCH_send_data_ack (ch, fwd);
1831 }
1832
1833
1834 /**
1835  * Handler for mesh network traffic end-to-end ACKs.
1836  *
1837  * @param ch Channel on which we got this message.
1838  * @param msg Data message.
1839  * @param fwd Is this message fwd? This only is meaningful in loopback channels.
1840  *            #GNUNET_YES if message is FWD on the respective channel (loopback)
1841  *            #GNUNET_NO if message is BCK on the respective channel (loopback)
1842  *            #GNUNET_SYSERR if message on a one-ended channel (remote)
1843  */
1844 void
1845 GMCH_handle_data_ack (struct MeshChannel *ch,
1846                       const struct GNUNET_MESH_DataACK *msg,
1847                       int fwd)
1848 {
1849   struct MeshChannelReliability *rel;
1850   struct MeshReliableMessage *copy;
1851   struct MeshReliableMessage *next;
1852   uint32_t ack;
1853   int work;
1854
1855   /* If this is a remote (non-loopback) channel, find 'fwd'. */
1856   if (GNUNET_SYSERR == fwd)
1857   {
1858     if (is_loopback (ch))
1859     {
1860       /* It is a loopback channel after all... */
1861       GNUNET_break (0);
1862       return;
1863     }
1864     /* Inverted: if message came 'FWD' is a 'BCK ACK'. */
1865     fwd = (NULL != ch->dest) ? GNUNET_NO : GNUNET_YES;
1866   }
1867
1868   ack = ntohl (msg->mid);
1869   LOG (GNUNET_ERROR_TYPE_DEBUG, "!!! %s ACK %u\n",
1870        (GNUNET_YES == fwd) ? "FWD" : "BCK", ack);
1871
1872   if (GNUNET_YES == fwd)
1873   {
1874     rel = ch->root_rel;
1875   }
1876   else
1877   {
1878     rel = ch->dest_rel;
1879   }
1880   if (NULL == rel)
1881   {
1882     GNUNET_break_op (0);
1883     return;
1884   }
1885
1886   /* Free ACK'd copies: no need to retransmit those anymore */
1887   for (work = GNUNET_NO, copy = rel->head_sent; copy != NULL; copy = next)
1888   {
1889     if (GM_is_pid_bigger (copy->mid, ack))
1890     {
1891       LOG (GNUNET_ERROR_TYPE_DEBUG, "!!!  head %u, out!\n", copy->mid);
1892       channel_rel_free_sent (rel, msg);
1893       break;
1894     }
1895     work = GNUNET_YES;
1896     LOG (GNUNET_ERROR_TYPE_DEBUG, " !!  id %u\n", copy->mid);
1897     next = copy->next;
1898     rel_message_free (copy, GNUNET_YES);
1899   }
1900
1901   /* ACK client if needed */
1902   GMCH_allow_client (ch, fwd);
1903
1904   /* If some message was free'd, update the retransmission delay */
1905   if (GNUNET_YES == work)
1906   {
1907     if (GNUNET_SCHEDULER_NO_TASK != rel->retry_task)
1908     {
1909       GNUNET_SCHEDULER_cancel (rel->retry_task);
1910       if (NULL != rel->head_sent && NULL == rel->head_sent->q)
1911       {
1912         struct GNUNET_TIME_Absolute new_target;
1913         struct GNUNET_TIME_Relative delay;
1914
1915         delay = GNUNET_TIME_relative_multiply (rel->retry_timer,
1916                                                MESH_RETRANSMIT_MARGIN);
1917         new_target = GNUNET_TIME_absolute_add (rel->head_sent->timestamp,
1918                                                delay);
1919         delay = GNUNET_TIME_absolute_get_remaining (new_target);
1920         rel->retry_task =
1921             GNUNET_SCHEDULER_add_delayed (delay,
1922                                           &channel_retransmit_message,
1923                                           rel);
1924       }
1925       else /* either no more traffic to ack or traffic has just been queued */
1926       {
1927         rel->retry_task = GNUNET_SCHEDULER_NO_TASK;
1928       }
1929     }
1930     else /* work was done but no task was pending? shouldn't happen! */
1931     {
1932       GNUNET_break (0);
1933     }
1934   }
1935 }
1936
1937
1938 /**
1939  * Handler for channel create messages.
1940  *
1941  * Does not have fwd parameter because it's always 'FWD': channel is incoming.
1942  *
1943  * @param t Tunnel this channel will be in.
1944  * @param msg Channel crate message.
1945  */
1946 struct MeshChannel *
1947 GMCH_handle_create (struct MeshTunnel3 *t,
1948                     const struct GNUNET_MESH_ChannelCreate *msg)
1949 {
1950   MESH_ChannelNumber chid;
1951   struct MeshChannel *ch;
1952   struct MeshClient *c;
1953
1954   chid = ntohl (msg->chid);
1955
1956   ch = GMT_get_channel (t, chid);
1957   if (NULL == ch)
1958   {
1959     /* Create channel */
1960     ch = channel_new (t, NULL, 0);
1961     ch->gid = chid;
1962   }
1963   channel_set_options (ch, ntohl (msg->opt));
1964
1965   /* Find a destination client */
1966   ch->port = ntohl (msg->port);
1967   LOG (GNUNET_ERROR_TYPE_DEBUG, "   port %u\n", ch->port);
1968   c = GML_client_get_by_port (ch->port);
1969   if (NULL == c)
1970   {
1971     LOG (GNUNET_ERROR_TYPE_DEBUG, "  no client has port registered\n");
1972     if (is_loopback (ch))
1973     {
1974       LOG (GNUNET_ERROR_TYPE_DEBUG, "  loopback: destroy on handler\n");
1975       send_nack (ch);
1976     }
1977     else
1978     {
1979       LOG (GNUNET_ERROR_TYPE_DEBUG, "  not loopback: destroy now\n");
1980       send_nack (ch);
1981       GMCH_destroy (ch);
1982     }
1983     return NULL;
1984   }
1985   else
1986   {
1987     LOG (GNUNET_ERROR_TYPE_DEBUG, "  client %p has port registered\n", c);
1988   }
1989
1990   add_destination (ch, c);
1991   if (GNUNET_YES == ch->reliable)
1992     LOG (GNUNET_ERROR_TYPE_DEBUG, "!!! Reliable\n");
1993   else
1994     LOG (GNUNET_ERROR_TYPE_DEBUG, "!!! Not Reliable\n");
1995
1996   send_client_create (ch);
1997   send_ack (ch, GNUNET_YES);
1998
1999   return ch;
2000 }
2001
2002
2003 /**
2004  * Handler for channel NACK messages.
2005  *
2006  * NACK messages always go dest -> root, no need for 'fwd' or 'msg' parameter.
2007  *
2008  * @param ch Channel.
2009  */
2010 void
2011 GMCH_handle_nack (struct MeshChannel *ch)
2012 {
2013   send_client_nack (ch);
2014   GMCH_destroy (ch);
2015 }
2016
2017
2018 /**
2019  * Handler for channel ack messages.
2020  *
2021  * @param ch Channel.
2022  * @param msg Message.
2023  * @param fwd Is this message fwd? This only is meaningful in loopback channels.
2024  *            #GNUNET_YES if message is FWD on the respective channel (loopback)
2025  *            #GNUNET_NO if message is BCK on the respective channel (loopback)
2026  *            #GNUNET_SYSERR if message on a one-ended channel (remote)
2027  */
2028 void
2029 GMCH_handle_ack (struct MeshChannel *ch,
2030                  const struct GNUNET_MESH_ChannelManage *msg,
2031                  int fwd)
2032 {
2033   /* If this is a remote (non-loopback) channel, find 'fwd'. */
2034   if (GNUNET_SYSERR == fwd)
2035   {
2036     if (is_loopback (ch))
2037     {
2038       /* It is a loopback channel after all... */
2039       GNUNET_break (0);
2040       return;
2041     }
2042     fwd = (NULL != ch->dest) ? GNUNET_YES : GNUNET_NO;
2043   }
2044
2045   channel_confirm (ch, !fwd);
2046 }
2047
2048
2049 /**
2050  * Handler for channel destroy messages.
2051  *
2052  * @param ch Channel to be destroyed of.
2053  * @param msg Message.
2054  * @param fwd Is this message fwd? This only is meaningful in loopback channels.
2055  *            #GNUNET_YES if message is FWD on the respective channel (loopback)
2056  *            #GNUNET_NO if message is BCK on the respective channel (loopback)
2057  *            #GNUNET_SYSERR if message on a one-ended channel (remote)
2058  */
2059 void
2060 GMCH_handle_destroy (struct MeshChannel *ch,
2061                      const struct GNUNET_MESH_ChannelManage *msg,
2062                      int fwd)
2063 {
2064   struct MeshTunnel3 *t;
2065
2066   /* If this is a remote (non-loopback) channel, find 'fwd'. */
2067   if (GNUNET_SYSERR == fwd)
2068   {
2069     if (is_loopback (ch))
2070     {
2071       /* It is a loopback channel after all... */
2072       GNUNET_break (0);
2073       return;
2074     }
2075     fwd = (NULL != ch->dest) ? GNUNET_YES : GNUNET_NO;
2076   }
2077
2078   GMCH_debug (ch);
2079   if ( (fwd && NULL == ch->dest) || (!fwd && NULL == ch->root) )
2080   {
2081     /* Not for us (don't destroy twice a half-open loopback channel) */
2082     return;
2083   }
2084
2085   t = ch->t;
2086   send_destroy (ch, GNUNET_YES);
2087   GMCH_destroy (ch);
2088   GMT_destroy_if_empty (t);
2089 }
2090
2091
2092 /**
2093  * Sends an already built message on a channel.
2094  *
2095  * If the channel is on a loopback tunnel, notifies the appropriate destination
2096  * client locally.
2097  *
2098  * On a normal channel passes the message to the tunnel for encryption and
2099  * sending on a connection.
2100  *
2101  * This function DOES NOT save the message for retransmission.
2102  *
2103  * @param message Message to send. Function makes a copy of it.
2104  * @param ch Channel on which this message is transmitted.
2105  * @param fwd Is this a fwd message?
2106  * @param existing_copy This is a retransmission, don't save a copy.
2107  */
2108 void
2109 GMCH_send_prebuilt_message (const struct GNUNET_MessageHeader *message,
2110                             struct MeshChannel *ch, int fwd,
2111                             void *existing_copy)
2112 {
2113   struct MeshChannelQueue *q;
2114   uint16_t type;
2115
2116   type = ntohs (message->type);
2117   LOG (GNUNET_ERROR_TYPE_DEBUG, "GMCH Send %s %s on channel %s\n",
2118        GM_f2s (fwd), GM_m2s (type),
2119        GMCH_2s (ch));
2120
2121   if (GMT_is_loopback (ch->t))
2122   {
2123     handle_loopback (ch, message, fwd);
2124     return;
2125   }
2126
2127   switch (type)
2128   {
2129     case GNUNET_MESSAGE_TYPE_MESH_DATA:
2130
2131       if (GNUNET_YES == ch->reliable)
2132       {
2133         q = GNUNET_new (struct MeshChannelQueue);
2134         q->type = type;
2135         if (NULL == existing_copy)
2136           q->copy = channel_save_copy (ch, message, fwd);
2137         else
2138         {
2139           q->copy = (struct MeshReliableMessage *) existing_copy;
2140           if (NULL != q->copy->q)
2141           {
2142             /* Last retransmission was queued but not yet sent!
2143              * This retransmission was scheduled by a ch_message_sent which
2144              * followed a very fast RTT, so the tiny delay made the
2145              * retransmission function to execute before the previous
2146              * retransmitted message even had a chance to leave the peer.
2147              * Cancel this message and wait until the pending
2148              * retransmission leaves the peer and ch_message_sent starts
2149              * the timer for the next one.
2150              */
2151             GNUNET_free (q);
2152             return;
2153           }
2154           LOG (GNUNET_ERROR_TYPE_DEBUG,
2155                "  using existing copy: %p {r:%p q:%p t:%u}\n",
2156                existing_copy,
2157                q->copy->rel, q->copy->q, q->copy->type);
2158         }
2159         LOG (GNUNET_ERROR_TYPE_DEBUG, "  new q: %p\n", q);
2160         q->copy->q = q;
2161         q->q = GMT_send_prebuilt_message (message, ch->t, ch,
2162                                           fwd, NULL != existing_copy,
2163                                           &ch_message_sent, q);
2164         /* q itself is stored in copy */
2165       }
2166       else
2167       {
2168         goto fire_and_forget;
2169       }
2170       break;
2171
2172
2173     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_ACK:
2174       if (GNUNET_YES == fwd)
2175       {
2176         /* BCK ACK (going FWD) is just a response for a SYNACK, don't keep*/
2177         goto fire_and_forget;
2178       }
2179       /* fall-trough */
2180     case GNUNET_MESSAGE_TYPE_MESH_DATA_ACK:
2181     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_CREATE:
2182       q = GNUNET_new (struct MeshChannelQueue);
2183       q->type = type;
2184       q->rel = fwd ? ch->root_rel : ch->dest_rel;
2185       if (NULL != q->rel->uniq)
2186       {
2187         GMT_cancel (q->rel->uniq->q);
2188         /* ch_message_sent is called, freeing and NULLing uniq */
2189       }
2190       q->q = GMT_send_prebuilt_message (message, ch->t, ch,
2191                                         fwd, GNUNET_YES,
2192                                         &ch_message_sent, q);
2193       q->rel->uniq = q;
2194       break;
2195
2196
2197     fire_and_forget:
2198     default:
2199       GNUNET_break (NULL == GMT_send_prebuilt_message (message, ch->t, ch,
2200                                                        fwd, GNUNET_YES,
2201                                                        NULL, NULL));
2202   }
2203 }
2204
2205
2206 /**
2207  * Get the static string for identification of the channel.
2208  *
2209  * @param ch Channel.
2210  *
2211  * @return Static string with the channel IDs.
2212  */
2213 const char *
2214 GMCH_2s (const struct MeshChannel *ch)
2215 {
2216   static char buf[64];
2217
2218   if (NULL == ch)
2219     return "(NULL Channel)";
2220
2221   sprintf (buf, "%s:%u gid:%X (%X / %X)",
2222            GMT_2s (ch->t), ch->port, ch->gid, ch->lid_root, ch->lid_dest);
2223
2224   return buf;
2225 }