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