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