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