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