8717c7dcd9c2c5cec0a326e761a3cc139a4ab19d
[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         struct GNUNET_TIME_Relative delay;
737
738         GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == rel->retry_task);
739         rel->retry_timer = GNUNET_TIME_STD_BACKOFF (rel->retry_timer);
740         rel->retry_task = GNUNET_SCHEDULER_add_delayed (rel->retry_timer,
741                                                         &channel_recreate, rel);
742       }
743       rel->uniq = NULL;
744       break;
745
746
747     default:
748       GNUNET_break (0);
749   }
750
751   GNUNET_free (ch_q);
752 }
753
754
755 /**
756  * send a channel create message.
757  *
758  * @param ch Channel for which to send.
759  */
760 static void
761 send_create (struct MeshChannel *ch)
762 {
763   struct GNUNET_MESH_ChannelCreate msgcc;
764   struct MeshChannelQueue *q;
765
766   msgcc.header.size = htons (sizeof (msgcc));
767   msgcc.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_CHANNEL_CREATE);
768   msgcc.chid = htonl (ch->gid);
769   msgcc.port = htonl (ch->port);
770   msgcc.opt = htonl (channel_get_options (ch));
771
772   q = GNUNET_new (struct MeshChannelQueue);
773   q->rel = ch->root_rel;
774
775   /* FIXME cancel on confirm */
776   q->q = GMT_send_prebuilt_message (&msgcc.header, ch->t, ch,
777                                     GNUNET_YES, GNUNET_YES,
778                                     ch_message_sent, q);
779   q->rel->uniq = q;
780 }
781
782
783 /**
784  * Notify a client that the channel is no longer valid.
785  *
786  * @param ch Channel that is destroyed.
787  * @param local_only Should we avoid sending it to other peers?
788  */
789 static void
790 send_destroy (struct MeshChannel *ch, int local_only)
791 {
792   struct GNUNET_MESH_ChannelManage msg;
793
794   msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_CHANNEL_DESTROY);
795   msg.header.size = htons (sizeof (msg));
796   msg.chid = htonl (ch->gid);
797
798   /* If root is not NULL, notify.
799    * If it's NULL, check lid_root. When a local destroy comes in, root
800    * is set to NULL but lid_root is left untouched. In this case, do nothing,
801    * the client is the one who reuqested the channel to be destroyed.
802    */
803   if (NULL != ch->root)
804     GML_send_channel_destroy (ch->root, ch->lid_root);
805   else if (0 == ch->lid_root && GNUNET_NO == local_only)
806     GMCH_send_prebuilt_message (&msg.header, ch, GNUNET_NO, NULL);
807
808   if (NULL != ch->dest)
809     GML_send_channel_destroy (ch->dest, ch->lid_dest);
810   else if (0 == ch->lid_dest && GNUNET_NO == local_only)
811     GMCH_send_prebuilt_message (&msg.header, ch, GNUNET_YES, NULL);
812 }
813
814
815 /**
816  * Destroy all reliable messages queued for a channel,
817  * during a channel destruction.
818  * Frees the reliability structure itself.
819  *
820  * @param rel Reliability data for a channel.
821  */
822 static void
823 channel_rel_free_all (struct MeshChannelReliability *rel)
824 {
825   struct MeshReliableMessage *copy;
826   struct MeshReliableMessage *next;
827
828   if (NULL == rel)
829     return;
830
831   for (copy = rel->head_recv; NULL != copy; copy = next)
832   {
833     next = copy->next;
834     GNUNET_CONTAINER_DLL_remove (rel->head_recv, rel->tail_recv, copy);
835     LOG (GNUNET_ERROR_TYPE_DEBUG, " COPYFREE BATCH RECV %p\n", copy);
836     GNUNET_free (copy);
837   }
838   for (copy = rel->head_sent; NULL != copy; copy = next)
839   {
840     next = copy->next;
841     GNUNET_CONTAINER_DLL_remove (rel->head_sent, rel->tail_sent, copy);
842     LOG (GNUNET_ERROR_TYPE_DEBUG, " COPYFREE BATCH %p\n", copy);
843     GNUNET_free (copy);
844   }
845   if (GNUNET_SCHEDULER_NO_TASK != rel->retry_task)
846   {
847     GNUNET_SCHEDULER_cancel (rel->retry_task);
848   }
849   if (NULL != rel->uniq)
850     GMT_cancel (rel->uniq->q);
851   GNUNET_free (rel);
852 }
853
854
855 /**
856  * Mark future messages as ACK'd.
857  *
858  * @param rel Reliability data.
859  * @param msg DataACK message with a bitfield of future ACK'd messages.
860  */
861 static void
862 channel_rel_free_sent (struct MeshChannelReliability *rel,
863                        const struct GNUNET_MESH_DataACK *msg)
864 {
865   struct MeshReliableMessage *copy;
866   struct MeshReliableMessage *next;
867   uint64_t bitfield;
868   uint64_t mask;
869   uint32_t mid;
870   uint32_t target;
871   unsigned int i;
872
873   bitfield = msg->futures;
874   mid = ntohl (msg->mid);
875   LOG (GNUNET_ERROR_TYPE_DEBUG,
876               "!!! free_sent_reliable %u %llX\n",
877               mid, bitfield);
878   LOG (GNUNET_ERROR_TYPE_DEBUG,
879               " rel %p, head %p\n",
880               rel, rel->head_sent);
881   for (i = 0, copy = rel->head_sent;
882        i < 64 && NULL != copy && 0 != bitfield;
883        i++)
884   {
885     LOG (GNUNET_ERROR_TYPE_DEBUG,
886                 " trying bit %u (mid %u)\n",
887                 i, mid + i + 1);
888     mask = 0x1LL << i;
889     if (0 == (bitfield & mask))
890      continue;
891
892     LOG (GNUNET_ERROR_TYPE_DEBUG, " set!\n");
893     /* Bit was set, clear the bit from the bitfield */
894     bitfield &= ~mask;
895
896     /* The i-th bit was set. Do we have that copy? */
897     /* Skip copies with mid < target */
898     target = mid + i + 1;
899     LOG (GNUNET_ERROR_TYPE_DEBUG, " target %u\n", target);
900     while (NULL != copy && GM_is_pid_bigger (target, copy->mid))
901      copy = copy->next;
902
903     /* Did we run out of copies? (previously freed, it's ok) */
904     if (NULL == copy)
905     {
906      LOG (GNUNET_ERROR_TYPE_DEBUG, "run out of copies...\n");
907      return;
908     }
909
910     /* Did we overshoot the target? (previously freed, it's ok) */
911     if (GM_is_pid_bigger (copy->mid, target))
912     {
913      LOG (GNUNET_ERROR_TYPE_DEBUG, " next copy %u\n", copy->mid);
914      continue;
915     }
916
917     /* Now copy->mid == target, free it */
918     next = copy->next;
919     rel_message_free (copy, GNUNET_YES);
920     copy = next;
921   }
922   LOG (GNUNET_ERROR_TYPE_DEBUG, "free_sent_reliable END\n");
923 }
924
925
926 /**
927  * Destroy a reliable message after it has been acknowledged, either by
928  * direct mid ACK or bitfield. Updates the appropriate data structures and
929  * timers and frees all memory.
930  *
931  * @param copy Message that is no longer needed: remote peer got it.
932  * @param update_time Is the timing information relevant?
933  *                    If this message is ACK in a batch the timing information
934  *                    is skewed by the retransmission, count only for the
935  *                    retransmitted message.
936  */
937 static void
938 rel_message_free (struct MeshReliableMessage *copy, int update_time)
939 {
940   struct MeshChannelReliability *rel;
941   struct GNUNET_TIME_Relative time;
942
943   rel = copy->rel;
944   LOG (GNUNET_ERROR_TYPE_DEBUG, "!!! Freeing %u\n", copy->mid);
945   if (update_time)
946   {
947     time = GNUNET_TIME_absolute_get_duration (copy->timestamp);
948     if (0 == rel->expected_delay.rel_value_us)
949       rel->expected_delay = time;
950     else
951     {
952       rel->expected_delay.rel_value_us *= 7;
953       rel->expected_delay.rel_value_us += time.rel_value_us;
954       rel->expected_delay.rel_value_us /= 8;
955     }
956     LOG (GNUNET_ERROR_TYPE_DEBUG, "!!!  took %s\n",
957                 GNUNET_STRINGS_relative_time_to_string (time, GNUNET_NO));
958     LOG (GNUNET_ERROR_TYPE_DEBUG, "!!!  new expected delay %s\n",
959                 GNUNET_STRINGS_relative_time_to_string (rel->expected_delay,
960                                                         GNUNET_NO));
961     rel->retry_timer = rel->expected_delay;
962   }
963   else
964   {
965     LOG (GNUNET_ERROR_TYPE_DEBUG, "!!! batch free, ignoring timing\n");
966   }
967   rel->ch->pending_messages--;
968   if (GNUNET_NO != rel->ch->destroy && 0 == rel->ch->pending_messages)
969   {
970     struct MeshTunnel3 *t = rel->ch->t;
971     GMCH_destroy (rel->ch);
972     GMT_destroy_if_empty (t);
973   }
974   if (NULL != copy->q)
975   {
976     GMT_cancel (copy->q->q);
977   }
978   GNUNET_CONTAINER_DLL_remove (rel->head_sent, rel->tail_sent, copy);
979   LOG (GNUNET_ERROR_TYPE_DEBUG, " COPYFREE %p\n", copy);
980   GNUNET_free (copy);
981 }
982
983
984 /**
985  * Confirm we got a channel create.
986  *
987  * @param ch The channel to confirm.
988  * @param fwd Should we send a FWD ACK? (going dest->root)
989  */
990 static void
991 channel_send_ack (struct MeshChannel *ch, int fwd)
992 {
993   struct GNUNET_MESH_ChannelManage msg;
994
995   msg.header.size = htons (sizeof (msg));
996   msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_CHANNEL_ACK);
997   LOG (GNUNET_ERROR_TYPE_DEBUG,
998               "  sending channel %s ack for channel %s\n",
999               GM_f2s (fwd), GMCH_2s (ch));
1000
1001   msg.chid = htonl (ch->gid);
1002   GMCH_send_prebuilt_message (&msg.header, ch, !fwd, NULL);
1003 }
1004
1005
1006 /**
1007  * Notify that a channel create didn't succeed.
1008  *
1009  * @param ch The channel to reject.
1010  */
1011 static void
1012 channel_send_nack (struct MeshChannel *ch)
1013 {
1014   struct GNUNET_MESH_ChannelManage msg;
1015
1016   msg.header.size = htons (sizeof (msg));
1017   msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_CHANNEL_NACK);
1018   LOG (GNUNET_ERROR_TYPE_DEBUG,
1019        "  sending channel NACK for channel %s\n",
1020        GMCH_2s (ch));
1021
1022   msg.chid = htonl (ch->gid);
1023   GMCH_send_prebuilt_message (&msg.header, ch, GNUNET_NO, NULL);
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     channel_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     /* TODO send reject */
1972     LOG (GNUNET_ERROR_TYPE_DEBUG, "  no client has port registered\n");
1973     if (is_loopback (ch))
1974     {
1975       LOG (GNUNET_ERROR_TYPE_DEBUG, "  loopback: destroy on handler\n");
1976       channel_send_nack (ch);
1977     }
1978     else
1979     {
1980       LOG (GNUNET_ERROR_TYPE_DEBUG, "  not loopback: destroy now\n");
1981       channel_send_nack (ch);
1982       GMCH_destroy (ch);
1983     }
1984     return NULL;
1985   }
1986   else
1987   {
1988     LOG (GNUNET_ERROR_TYPE_DEBUG, "  client %p has port registered\n", c);
1989   }
1990
1991   add_destination (ch, c);
1992   if (GNUNET_YES == ch->reliable)
1993     LOG (GNUNET_ERROR_TYPE_DEBUG, "!!! Reliable\n");
1994   else
1995     LOG (GNUNET_ERROR_TYPE_DEBUG, "!!! Not Reliable\n");
1996
1997   send_client_create (ch);
1998   channel_send_ack (ch, GNUNET_YES);
1999
2000   return ch;
2001 }
2002
2003
2004 /**
2005  * Handler for channel NACK messages.
2006  *
2007  * NACK messages always go dest -> root, no need for 'fwd' or 'msg' parameter.
2008  *
2009  * @param ch Channel.
2010  */
2011 void
2012 GMCH_handle_nack (struct MeshChannel *ch)
2013 {
2014   send_client_nack (ch);
2015   GMCH_destroy (ch);
2016 }
2017
2018
2019 /**
2020  * Handler for channel ack messages.
2021  *
2022  * @param ch Channel.
2023  * @param msg Message.
2024  * @param fwd Is this message fwd? This only is meaningful in loopback channels.
2025  *            #GNUNET_YES if message is FWD on the respective channel (loopback)
2026  *            #GNUNET_NO if message is BCK on the respective channel (loopback)
2027  *            #GNUNET_SYSERR if message on a one-ended channel (remote)
2028  */
2029 void
2030 GMCH_handle_ack (struct MeshChannel *ch,
2031                  const struct GNUNET_MESH_ChannelManage *msg,
2032                  int fwd)
2033 {
2034   /* If this is a remote (non-loopback) channel, find 'fwd'. */
2035   if (GNUNET_SYSERR == fwd)
2036   {
2037     if (is_loopback (ch))
2038     {
2039       /* It is a loopback channel after all... */
2040       GNUNET_break (0);
2041       return;
2042     }
2043     fwd = (NULL != ch->dest) ? GNUNET_YES : GNUNET_NO;
2044   }
2045
2046   channel_confirm (ch, !fwd);
2047 }
2048
2049
2050 /**
2051  * Handler for channel destroy messages.
2052  *
2053  * @param ch Channel to be destroyed of.
2054  * @param msg Message.
2055  * @param fwd Is this message fwd? This only is meaningful in loopback channels.
2056  *            #GNUNET_YES if message is FWD on the respective channel (loopback)
2057  *            #GNUNET_NO if message is BCK on the respective channel (loopback)
2058  *            #GNUNET_SYSERR if message on a one-ended channel (remote)
2059  */
2060 void
2061 GMCH_handle_destroy (struct MeshChannel *ch,
2062                      const struct GNUNET_MESH_ChannelManage *msg,
2063                      int fwd)
2064 {
2065   struct MeshTunnel3 *t;
2066
2067   /* If this is a remote (non-loopback) channel, find 'fwd'. */
2068   if (GNUNET_SYSERR == fwd)
2069   {
2070     if (is_loopback (ch))
2071     {
2072       /* It is a loopback channel after all... */
2073       GNUNET_break (0);
2074       return;
2075     }
2076     fwd = (NULL != ch->dest) ? GNUNET_YES : GNUNET_NO;
2077   }
2078
2079   GMCH_debug (ch);
2080   if ( (fwd && NULL == ch->dest) || (!fwd && NULL == ch->root) )
2081   {
2082     /* Not for us (don't destroy twice a half-open loopback channel) */
2083     return;
2084   }
2085
2086   t = ch->t;
2087   send_destroy (ch, GNUNET_YES);
2088   GMCH_destroy (ch);
2089   GMT_destroy_if_empty (t);
2090 }
2091
2092
2093 /**
2094  * Sends an already built message on a channel.
2095  *
2096  * If the channel is on a loopback tunnel, notifies the appropriate destination
2097  * client locally.
2098  *
2099  * On a normal channel passes the message to the tunnel for encryption and
2100  * sending on a connection.
2101  *
2102  * This function DOES NOT save the message for retransmission.
2103  *
2104  * @param message Message to send. Function makes a copy of it.
2105  * @param ch Channel on which this message is transmitted.
2106  * @param fwd Is this a fwd message?
2107  * @param existing_copy This is a retransmission, don't save a copy.
2108  */
2109 void
2110 GMCH_send_prebuilt_message (const struct GNUNET_MessageHeader *message,
2111                             struct MeshChannel *ch, int fwd,
2112                             void *existing_copy)
2113 {
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         struct MeshChannelQueue *q;
2134
2135         q = GNUNET_new (struct MeshChannelQueue);
2136         q->type = type;
2137         if (NULL == existing_copy)
2138           q->copy = channel_save_copy (ch, message, fwd);
2139         else
2140         {
2141           q->copy = (struct MeshReliableMessage *) existing_copy;
2142           if (NULL != q->copy->q)
2143           {
2144             /* Last retransmission was queued but not yet sent!
2145              * This retransmission was scheduled by a ch_message_sent which
2146              * followed a very fast RTT, so the tiny delay made the
2147              * retransmission function to execute before the previous
2148              * retransmitted message even had a chance to leave the peer.
2149              * Cancel this message and wait until the pending
2150              * retransmission leaves the peer and ch_message_sent starts
2151              * the timer for the next one.
2152              */
2153             GNUNET_free (q);
2154             return;
2155           }
2156           LOG (GNUNET_ERROR_TYPE_DEBUG,
2157                "  using existing copy: %p {r:%p q:%p t:%u}\n",
2158                existing_copy,
2159                q->copy->rel, q->copy->q, q->copy->type);
2160         }
2161         LOG (GNUNET_ERROR_TYPE_DEBUG, "  new q: %p\n", q);
2162         q->copy->q = q;
2163         q->q = GMT_send_prebuilt_message (message, ch->t, ch,
2164                                           fwd, NULL != existing_copy,
2165                                           &ch_message_sent, q);
2166         /* q itself is stored in copy */
2167       }
2168       else
2169       {
2170         GNUNET_break (NULL == GMT_send_prebuilt_message (message, ch->t, ch,
2171                                                          fwd, GNUNET_NO,
2172                                                          NULL, NULL));
2173       }
2174       break;
2175
2176       
2177     case GNUNET_MESSAGE_TYPE_MESH_DATA_ACK:
2178       {
2179         struct MeshChannelReliability *rel;
2180
2181         rel = fwd ? ch->root_rel : ch->dest_rel;
2182         if (NULL != rel->uniq)
2183         {
2184           GMT_cancel (rel->uniq->q);
2185           /* ch_message_sent is called, freeing ack_q */
2186         }
2187         rel->uniq = GNUNET_new (struct MeshChannelQueue);
2188         rel->uniq->type = type;
2189         rel->uniq->rel = rel;
2190         rel->uniq->q = GMT_send_prebuilt_message (message, ch->t, ch,
2191                                                    fwd, GNUNET_YES,
2192                                                    &ch_message_sent,
2193                                                   rel->uniq);
2194       }
2195       break;
2196
2197
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 }