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