5f2ce2f8da33a2a1f80d376705cdcd17408d2ba8
[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_enc.h"
28 #include "mesh_protocol_enc.h"
29
30 #include "gnunet-service-mesh_channel.h"
31 #include "gnunet-service-mesh_local.h"
32 #include "gnunet-service-mesh_tunnel.h"
33
34 #define LOG(level, ...) GNUNET_log_from(level,"mesh-chn",__VA_ARGS__)
35
36 #define MESH_RETRANSMIT_TIME    GNUNET_TIME_UNIT_SECONDS
37 #define MESH_RETRANSMIT_MARGIN  4
38
39
40 /**
41  * All the states a connection can be in.
42  */
43 enum MeshChannelState
44 {
45   /**
46    * Uninitialized status, should never appear in operation.
47    */
48   MESH_CHANNEL_NEW,
49
50   /**
51    * Connection create message sent, waiting for ACK.
52    */
53   MESH_CHANNEL_SENT,
54
55   /**
56    * Connection confirmed, ready to carry traffic..
57    */
58   MESH_CHANNEL_READY,
59 };
60
61
62
63 /**
64  * Info needed to retry a message in case it gets lost.
65  */
66 struct MeshReliableMessage
67 {
68     /**
69      * Double linked list, FIFO style
70      */
71   struct MeshReliableMessage    *next;
72   struct MeshReliableMessage    *prev;
73
74     /**
75      * Type of message (payload, channel management).
76      */
77   int16_t type;
78
79     /**
80      * Tunnel Reliability queue this message is in.
81      */
82   struct MeshChannelReliability  *rel;
83
84     /**
85      * ID of the message (ACK needed to free)
86      */
87   uint32_t                      mid;
88
89     /**
90      * When was this message issued (to calculate ACK delay)
91      */
92   struct GNUNET_TIME_Absolute   timestamp;
93
94   /* struct GNUNET_MESH_Data with payload */
95 };
96
97
98 /**
99  * Info about the traffic state for a client in a channel.
100  */
101 struct MeshChannelReliability
102 {
103     /**
104      * Channel this is about.
105      */
106   struct MeshChannel *ch;
107
108     /**
109      * DLL of messages sent and not yet ACK'd.
110      */
111   struct MeshReliableMessage        *head_sent;
112   struct MeshReliableMessage        *tail_sent;
113
114     /**
115      * Messages pending to send.
116      */
117   unsigned int                      n_sent;
118
119     /**
120      * DLL of messages received out of order.
121      */
122   struct MeshReliableMessage        *head_recv;
123   struct MeshReliableMessage        *tail_recv;
124
125     /**
126      * Messages received.
127      */
128   unsigned int                      n_recv;
129
130     /**
131      * Next MID to use for outgoing traffic.
132      */
133   uint32_t                          mid_send;
134
135     /**
136      * Next MID expected for incoming traffic.
137      */
138   uint32_t                          mid_recv;
139
140     /**
141      * Can we send data to the client?
142      */
143   int                               client_ready;
144
145     /**
146      * Task to resend/poll in case no ACK is received.
147      */
148   GNUNET_SCHEDULER_TaskIdentifier   retry_task;
149
150     /**
151      * Counter for exponential backoff.
152      */
153   struct GNUNET_TIME_Relative       retry_timer;
154
155     /**
156      * How long does it usually take to get an ACK.
157      */
158   struct GNUNET_TIME_Relative       expected_delay;
159 };
160
161
162 /**
163  * Struct containing all information regarding a channel to a remote client.
164  */
165 struct MeshChannel
166 {
167     /**
168      * Tunnel this channel is in.
169      */
170   struct MeshTunnel3 *t;
171
172     /**
173      * Destination port of the channel.
174      */
175   uint32_t port;
176
177     /**
178      * Global channel number ( < GNUNET_MESH_LOCAL_CHANNEL_ID_CLI)
179      */
180   MESH_ChannelNumber gid;
181
182     /**
183      * Local tunnel number for root (owner) client.
184      * ( >= GNUNET_MESH_LOCAL_CHANNEL_ID_CLI or 0 )
185      */
186   MESH_ChannelNumber lid_root;
187
188     /**
189      * Local tunnel number for local destination clients (incoming number)
190      * ( >= GNUNET_MESH_LOCAL_CHANNEL_ID_SERV or 0).
191      */
192   MESH_ChannelNumber lid_dest;
193
194     /**
195      * Channel state.
196      */
197   enum MeshChannelState state;
198
199     /**
200      * Is the tunnel bufferless (minimum latency)?
201      */
202   int nobuffer;
203
204     /**
205      * Is the tunnel reliable?
206      */
207   int reliable;
208
209     /**
210      * Last time the channel was used
211      */
212   struct GNUNET_TIME_Absolute timestamp;
213
214     /**
215      * Client owner of the tunnel, if any
216      */
217   struct MeshClient *root;
218
219     /**
220      * Client destination of the tunnel, if any.
221      */
222   struct MeshClient *dest;
223
224     /**
225      * Flag to signal the destruction of the channel.
226      * If this is set GNUNET_YES the channel will be destroyed
227      * when the queue is empty.
228      */
229   int destroy;
230
231     /**
232      * Total messages pending for this channel, payload or not.
233      */
234   unsigned int pending_messages;
235
236     /**
237      * Reliability data.
238      * Only present (non-NULL) at the owner of a tunnel.
239      */
240   struct MeshChannelReliability *root_rel;
241
242     /**
243      * Reliability data.
244      * Only present (non-NULL) at the destination of a tunnel.
245      */
246   struct MeshChannelReliability *dest_rel;
247
248 };
249
250
251 /******************************************************************************/
252 /*******************************   GLOBALS  ***********************************/
253 /******************************************************************************/
254
255 /**
256  * Global handle to the statistics service.
257  */
258 extern struct GNUNET_STATISTICS_Handle *stats;
259
260
261 /******************************************************************************/
262 /********************************   STATIC  ***********************************/
263 /******************************************************************************/
264
265 /**
266  * Destroy a reliable message after it has been acknowledged, either by
267  * direct mid ACK or bitfield. Updates the appropriate data structures and
268  * timers and frees all memory.
269  *
270  * @param copy Message that is no longer needed: remote peer got it.
271  */
272 static void
273 rel_message_free (struct MeshReliableMessage *copy);
274
275 /**
276  * We have received a message out of order, or the client is not ready.
277  * Buffer it until we receive an ACK from the client or the missing
278  * message from the channel.
279  *
280  * @param msg Message to buffer (MUST be of type MESH_DATA).
281  * @param rel Reliability data to the corresponding direction.
282  */
283 static void
284 add_buffered_data (const struct GNUNET_MESH_Data *msg,
285                    struct MeshChannelReliability *rel)
286 {
287   struct MeshReliableMessage *copy;
288   struct MeshReliableMessage *prev;
289   uint32_t mid;
290   uint16_t size;
291
292   size = ntohs (msg->header.size);
293   mid = ntohl (msg->mid);
294
295   LOG (GNUNET_ERROR_TYPE_DEBUG, "add_buffered_data %u\n", mid);
296
297   copy = GNUNET_malloc (sizeof (*copy) + size);
298   copy->mid = mid;
299   copy->rel = rel;
300   memcpy (&copy[1], msg, size);
301
302   rel->n_recv++;
303
304   // FIXME do something better than O(n), although n < 64...
305   // FIXME start from the end (most messages are the latest ones)
306   for (prev = rel->head_recv; NULL != prev; prev = prev->next)
307   {
308     LOG (GNUNET_ERROR_TYPE_DEBUG, " prev %u\n", prev->mid);
309     if (GMC_is_pid_bigger (prev->mid, mid))
310     {
311       LOG (GNUNET_ERROR_TYPE_DEBUG, " bingo!\n");
312       GNUNET_CONTAINER_DLL_insert_before (rel->head_recv, rel->tail_recv,
313                                           prev, copy);
314       return;
315     }
316   }
317     LOG (GNUNET_ERROR_TYPE_DEBUG, " insert at tail!\n");
318     GNUNET_CONTAINER_DLL_insert_tail (rel->head_recv, rel->tail_recv, copy);
319     LOG (GNUNET_ERROR_TYPE_DEBUG, "add_buffered_data END\n");
320 }
321
322
323 /**
324  * Send data to a client.
325  *
326  * If the client is ready, send directly, otherwise buffer while listening
327  * for a local ACK.
328  *
329  * @param ch Channel
330  * @param msg Message.
331  * @param fwd Is this a fwd (root->dest) message?
332  */
333 static void
334 send_client_data (struct MeshChannel *ch,
335                   const struct GNUNET_MESH_Data *msg,
336                   int fwd)
337 {
338   if (fwd)
339   {
340     if (ch->dest_rel->client_ready)
341       GML_send_data (ch, msg, ch->dest, ch->lid_dest);
342     else
343       add_buffered_data (msg, ch->dest_rel);
344   }
345   else
346   {
347     if (ch->root_rel->client_ready)
348       GML_send_data (ch, msg, ch->root, ch->lid_root);
349     else
350       add_buffered_data (msg, ch->root_rel);
351   }
352 }
353
354
355 /**
356  * Add a client to a channel, initializing all needed data structures.
357  *
358  * @param ch Channel to which add the client.
359  * @param c Client which to add to the channel.
360  */
361 void
362 GMCH_add_client (struct MeshChannel *ch, struct MeshClient *c)
363 {
364   if (NULL != ch->dest)
365   {
366     GNUNET_break (0);
367     return;
368   }
369
370   /* Assign local id as destination */
371   ch->lid_dest = GML_get_next_chid (c);
372
373   /* Store in client's hashmap */
374   GML_channel_add (c, ch->lid_dest, ch);
375
376   GNUNET_break (NULL == ch->dest_rel);
377   ch->dest_rel = GNUNET_new (struct MeshChannelReliability);
378   ch->dest_rel->ch = ch;
379   ch->dest_rel->expected_delay = MESH_RETRANSMIT_TIME;
380
381   ch->dest = c;
382 }
383
384
385 /**
386  * Destroy all reliable messages queued for a channel,
387  * during a channel destruction.
388  * Frees the reliability structure itself.
389  *
390  * @param rel Reliability data for a channel.
391  */
392 static void
393 channel_rel_free_all (struct MeshChannelReliability *rel)
394 {
395   struct MeshReliableMessage *copy;
396   struct MeshReliableMessage *next;
397
398   if (NULL == rel)
399     return;
400
401   for (copy = rel->head_recv; NULL != copy; copy = next)
402   {
403     next = copy->next;
404     GNUNET_CONTAINER_DLL_remove (rel->head_recv, rel->tail_recv, copy);
405     GNUNET_free (copy);
406   }
407   for (copy = rel->head_sent; NULL != copy; copy = next)
408   {
409     next = copy->next;
410     GNUNET_CONTAINER_DLL_remove (rel->head_sent, rel->tail_sent, copy);
411     GNUNET_free (copy);
412   }
413   if (GNUNET_SCHEDULER_NO_TASK != rel->retry_task)
414     GNUNET_SCHEDULER_cancel (rel->retry_task);
415   GNUNET_free (rel);
416 }
417
418
419 /**
420  * Mark future messages as ACK'd.
421  *
422  * @param rel Reliability data.
423  * @param msg DataACK message with a bitfield of future ACK'd messages.
424  */
425 static void
426 channel_rel_free_sent (struct MeshChannelReliability *rel,
427                        const struct GNUNET_MESH_DataACK *msg)
428 {
429   struct MeshReliableMessage *copy;
430   struct MeshReliableMessage *next;
431   uint64_t bitfield;
432   uint64_t mask;
433   uint32_t mid;
434   uint32_t target;
435   unsigned int i;
436
437   bitfield = msg->futures;
438   mid = ntohl (msg->mid);
439   LOG (GNUNET_ERROR_TYPE_DEBUG,
440               "free_sent_reliable %u %llX\n",
441               mid, bitfield);
442   LOG (GNUNET_ERROR_TYPE_DEBUG,
443               " rel %p, head %p\n",
444               rel, rel->head_sent);
445   for (i = 0, copy = rel->head_sent;
446        i < 64 && NULL != copy && 0 != bitfield;
447        i++)
448   {
449     LOG (GNUNET_ERROR_TYPE_DEBUG,
450                 " trying bit %u (mid %u)\n",
451                 i, mid + i + 1);
452     mask = 0x1LL << i;
453     if (0 == (bitfield & mask))
454      continue;
455
456     LOG (GNUNET_ERROR_TYPE_DEBUG, " set!\n");
457     /* Bit was set, clear the bit from the bitfield */
458     bitfield &= ~mask;
459
460     /* The i-th bit was set. Do we have that copy? */
461     /* Skip copies with mid < target */
462     target = mid + i + 1;
463     LOG (GNUNET_ERROR_TYPE_DEBUG, " target %u\n", target);
464     while (NULL != copy && GMC_is_pid_bigger (target, copy->mid))
465      copy = copy->next;
466
467     /* Did we run out of copies? (previously freed, it's ok) */
468     if (NULL == copy)
469     {
470      LOG (GNUNET_ERROR_TYPE_DEBUG, "run out of copies...\n");
471      return;
472     }
473
474     /* Did we overshoot the target? (previously freed, it's ok) */
475     if (GMC_is_pid_bigger (copy->mid, target))
476     {
477      LOG (GNUNET_ERROR_TYPE_DEBUG, " next copy %u\n", copy->mid);
478      continue;
479     }
480
481     /* Now copy->mid == target, free it */
482     next = copy->next;
483     rel_message_free (copy);
484     copy = next;
485   }
486   LOG (GNUNET_ERROR_TYPE_DEBUG, "free_sent_reliable END\n");
487 }
488
489
490 /**
491  * We haven't received an ACK after a certain time: restransmit the message.
492  *
493  * @param cls Closure (MeshReliableMessage with the message to restransmit)
494  * @param tc TaskContext.
495  */
496 static void
497 channel_retransmit_message (void *cls,
498                             const struct GNUNET_SCHEDULER_TaskContext *tc)
499 {
500   struct MeshChannelReliability *rel = cls;
501   struct MeshReliableMessage *copy;
502   struct MeshChannel *ch;
503   struct GNUNET_MESH_Data *payload;
504   int fwd;
505
506   rel->retry_task = GNUNET_SCHEDULER_NO_TASK;
507   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
508     return;
509
510   ch = rel->ch;
511   copy = rel->head_sent;
512   if (NULL == copy)
513   {
514     GNUNET_break (0);
515     return;
516   }
517
518   /* Search the message to be retransmitted in the outgoing queue.
519    * Check only the queue for the connection that is going to be used,
520    * if the message is stuck in some other connection's queue we shouldn't
521    * act upon it:
522    * - cancelling it and sending the new one doesn't guarantee it's delivery,
523    *   the old connection could be temporary stalled or the queue happened to
524    *   be long at time of insertion.
525    * - not sending the new one could cause terrible delays the old connection
526    *   is stalled.
527    */
528 //   FIXME access to queue elements is limited
529 //   payload = (struct GNUNET_MESH_Data *) &copy[1];
530 //   fwd = (rel == ch->root_rel);
531 //   c = GMT_get_connection (ch->t, fwd);
532 //   hop = connection_get_hop (c, fwd);
533 //   for (q = hop->queue_head; NULL != q; q = q->next)
534 //   {
535 //     if (ntohs (payload->header.type) == q->type && ch == q->ch)
536 //     {
537 //       struct GNUNET_MESH_Data *queued_data = q->cls;
538 // 
539 //       if (queued_data->mid == payload->mid)
540 //         break;
541 //     }
542 //   }
543
544   /* Message not found in the queue that we are going to use. */
545 //   if (NULL == q)
546 //   {
547     LOG (GNUNET_ERROR_TYPE_DEBUG, "!!! RETRANSMIT %u\n", copy->mid);
548
549     GMCH_send_prebuilt_message (&payload->header, ch, fwd);
550     GNUNET_STATISTICS_update (stats, "# data retransmitted", 1, GNUNET_NO);
551 //   }
552 //   else
553 //   {
554 //     LOG (GNUNET_ERROR_TYPE_DEBUG, "!!! ALREADY IN QUEUE %u\n", copy->mid);
555 //   }
556
557   rel->retry_timer = GNUNET_TIME_STD_BACKOFF (rel->retry_timer);
558   rel->retry_task = GNUNET_SCHEDULER_add_delayed (rel->retry_timer,
559                                                   &channel_retransmit_message,
560                                                   cls);
561 }
562
563
564 /**
565  * Destroy a reliable message after it has been acknowledged, either by
566  * direct mid ACK or bitfield. Updates the appropriate data structures and
567  * timers and frees all memory.
568  *
569  * @param copy Message that is no longer needed: remote peer got it.
570  */
571 static void
572 rel_message_free (struct MeshReliableMessage *copy)
573 {
574   struct MeshChannelReliability *rel;
575   struct GNUNET_TIME_Relative time;
576
577   rel = copy->rel;
578   time = GNUNET_TIME_absolute_get_duration (copy->timestamp);
579   rel->expected_delay.rel_value_us *= 7;
580   rel->expected_delay.rel_value_us += time.rel_value_us;
581   rel->expected_delay.rel_value_us /= 8;
582   rel->n_sent--;
583   LOG (GNUNET_ERROR_TYPE_DEBUG, "!!! Freeing %u\n", copy->mid);
584   LOG (GNUNET_ERROR_TYPE_DEBUG, "    n_sent %u\n", rel->n_sent);
585   LOG (GNUNET_ERROR_TYPE_DEBUG, "!!!  took %s\n",
586               GNUNET_STRINGS_relative_time_to_string (time, GNUNET_NO));
587   LOG (GNUNET_ERROR_TYPE_DEBUG, "!!!  new expected delay %s\n",
588               GNUNET_STRINGS_relative_time_to_string (rel->expected_delay,
589                                                       GNUNET_NO));
590   rel->retry_timer = rel->expected_delay;
591   GNUNET_CONTAINER_DLL_remove (rel->head_sent, rel->tail_sent, copy);
592   GNUNET_free (copy);
593 }
594
595
596
597 /**
598  * Channel was ACK'd by remote peer, mark as ready and cancel retransmission.
599  *
600  * @param ch Channel to mark as ready.
601  * @param fwd Was the CREATE message sent fwd?
602  */
603 static void
604 channel_confirm (struct MeshChannel *ch, int fwd)
605 {
606   struct MeshChannelReliability *rel;
607   struct MeshReliableMessage *copy;
608   struct MeshReliableMessage *next;
609
610   LOG (GNUNET_ERROR_TYPE_DEBUG,
611               "  channel confirm %s %s:%X\n",
612               fwd ? "FWD" : "BCK", GMT_2s (ch->t), ch->gid);
613   ch->state = MESH_CHANNEL_READY;
614
615   rel = fwd ? ch->root_rel : ch->dest_rel;
616   for (copy = rel->head_sent; NULL != copy; copy = next)
617   {
618     struct GNUNET_MessageHeader *msg;
619
620     next = copy->next;
621     msg = (struct GNUNET_MessageHeader *) &copy[1];
622     if (ntohs (msg->type) == GNUNET_MESSAGE_TYPE_MESH_CHANNEL_CREATE)
623     {
624       rel_message_free (copy);
625       /* TODO return? */
626     }
627   }
628   send_ack (NULL, ch, fwd);
629 }
630
631
632 /**
633  * Save a copy to retransmit in case it gets lost.
634  *
635  * Initializes all needed callbacks and timers.
636  *
637  * @param ch Channel this message goes on.
638  * @param msg Message to copy.
639  * @param fwd Is this fwd traffic?
640  */
641 static void
642 channel_save_copy (struct MeshChannel *ch,
643                    const struct GNUNET_MessageHeader *msg,
644                    int fwd)
645 {
646   struct MeshChannelReliability *rel;
647   struct MeshReliableMessage *copy;
648   uint32_t mid;
649   uint16_t type;
650   uint16_t size;
651
652   rel = fwd ? ch->root_rel : ch->dest_rel;
653   mid = rel->mid_send;
654   type = ntohs (msg->type);
655   size = ntohs (msg->size);
656
657   LOG (GNUNET_ERROR_TYPE_DEBUG, "!!! SAVE %u\n", mid);
658   copy = GNUNET_malloc (sizeof (struct MeshReliableMessage) + size);
659   copy->mid = mid;
660   copy->timestamp = GNUNET_TIME_absolute_get ();
661   copy->rel = rel;
662   copy->type = type;
663   memcpy (&copy[1], msg, size);
664   rel->n_sent++;
665   LOG (GNUNET_ERROR_TYPE_DEBUG, " n_sent %u\n", rel->n_sent);
666   GNUNET_CONTAINER_DLL_insert_tail (rel->head_sent, rel->tail_sent, copy);
667   if (GNUNET_SCHEDULER_NO_TASK == rel->retry_task)
668   {
669     rel->retry_timer =
670         GNUNET_TIME_relative_multiply (rel->expected_delay,
671                                         MESH_RETRANSMIT_MARGIN);
672     rel->retry_task =
673         GNUNET_SCHEDULER_add_delayed (rel->retry_timer,
674                                       &channel_retransmit_message,
675                                       rel);
676   }
677 }
678
679
680
681 /**
682  * Send a buffered message to the client, for in order delivery or
683  * as result of client ACK.
684  *
685  * @param ch Channel on which to empty the message buffer.
686  * @param c Client to send to.
687  * @param rel Reliability structure to corresponding peer.
688  *            If rel == bck_rel, this is FWD data.
689  */
690 static void
691 send_client_buffered_data (struct MeshChannel *ch,
692                                    struct MeshClient *c,
693                                    int fwd)
694 {
695   struct MeshReliableMessage *copy;
696   struct MeshChannelReliability *rel;
697
698   LOG (GNUNET_ERROR_TYPE_DEBUG, "send_buffered_data\n");
699   rel = fwd ? ch->dest_rel : ch->root_rel;
700   if (GNUNET_NO == rel->client_ready)
701   {
702     LOG (GNUNET_ERROR_TYPE_DEBUG, "client not ready\n");
703     return;
704   }
705
706   copy = rel->head_recv;
707   /* We never buffer channel management messages */
708   if (NULL != copy)
709   {
710     if (copy->mid == rel->mid_recv || GNUNET_NO == ch->reliable)
711     {
712       struct GNUNET_MESH_Data *msg = (struct GNUNET_MESH_Data *) &copy[1];
713
714       LOG (GNUNET_ERROR_TYPE_DEBUG,
715                   " have %u! now expecting %u\n",
716                   copy->mid, rel->mid_recv + 1);
717       send_client_data (ch, msg, fwd);
718       rel->n_recv--;
719       rel->mid_recv++;
720       GNUNET_CONTAINER_DLL_remove (rel->head_recv, rel->tail_recv, copy);
721       GNUNET_free (copy);
722     }
723     else
724     {
725       LOG (GNUNET_ERROR_TYPE_DEBUG,
726                   " reliable && don't have %u, next is %u\n",
727                   rel->mid_recv,
728                   copy->mid);
729       return;
730     }
731   }
732   LOG (GNUNET_ERROR_TYPE_DEBUG, "send_buffered_data END\n");
733 }
734
735
736
737
738 /**
739  * Destroy a channel and free all resources.
740  *
741  * @param ch Channel to destroy.
742  */
743 static void
744 channel_destroy (struct MeshChannel *ch)
745 {
746   struct MeshClient *c;
747
748   if (NULL == ch)
749     return;
750
751   LOG (GNUNET_ERROR_TYPE_DEBUG, "destroying channel %s:%u\n",
752               GMT_2s (ch->t), ch->gid);
753   GMCH_debug (ch);
754
755   c = ch->root;
756   if (NULL != c)
757   {
758     GML_channel_remove (c, ch->lid_root, ch);
759   }
760
761   c = ch->dest;
762   if (NULL != c)
763   {
764     GML_channel_remove (c, ch->lid_dest, ch);
765   }
766
767   channel_rel_free_all (ch->root_rel);
768   channel_rel_free_all (ch->dest_rel);
769
770   GMT_remove_channel (ch->t, ch);
771   GNUNET_STATISTICS_update (stats, "# channels", -1, GNUNET_NO);
772
773   GNUNET_free (ch);
774 }
775
776
777 /**
778  * Create a new channel.
779  *
780  * @param t Tunnel this channel is in.
781  * @param owner Client that owns the channel, NULL for foreign channels.
782  * @param lid_root Local ID for root client.
783  *
784  * @return A new initialized channel. NULL on error.
785  */
786 static struct MeshChannel *
787 channel_new (struct MeshTunnel3 *t,
788              struct MeshClient *owner, MESH_ChannelNumber lid_root)
789 {
790   struct MeshChannel *ch;
791
792   ch = GNUNET_new (struct MeshChannel);
793   ch->root = owner;
794   ch->lid_root = lid_root;
795   ch->t = t;
796
797   GNUNET_STATISTICS_update (stats, "# channels", 1, GNUNET_NO);
798
799   if (NULL != owner)
800   {
801     ch->gid = GMT_get_next_chid (t);
802     GML_channel_add (owner, lid_root, ch);
803   }
804   GMT_add_channel (t, ch);
805
806   return ch;
807 }
808
809
810 /**
811  * Set options in a channel, extracted from a bit flag field
812  *
813  * @param ch Channel to set options to.
814  * @param options Bit array in host byte order.
815  */
816 static void
817 channel_set_options (struct MeshChannel *ch, uint32_t options)
818 {
819   ch->nobuffer = (options & GNUNET_MESH_OPTION_NOBUFFER) != 0 ?
820                  GNUNET_YES : GNUNET_NO;
821   ch->reliable = (options & GNUNET_MESH_OPTION_RELIABLE) != 0 ?
822                  GNUNET_YES : GNUNET_NO;
823 }
824
825
826
827 /**
828  * Confirm we got a channel create.
829  *
830  * @param ch The channel to confirm.
831  * @param fwd Should we send the ACK fwd?
832  */
833 static void
834 channel_send_ack (struct MeshChannel *ch, int fwd)
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:%X\n",
842               fwd ? "FWD" : "BCK", GMT_2s (ch->t),
843               ch->gid);
844
845   msg.chid = htonl (ch->gid);
846   GMCH_send_prebuilt_message (&msg.header, ch, !fwd);
847 }
848
849
850 /**
851  * Iterator for deleting each channel whose client endpoint disconnected.
852  *
853  * @param cls Closure (client that has disconnected).
854  * @param key The local channel id (used to access the hashmap).
855  * @param value The value stored at the key (channel to destroy).
856  *
857  * @return GNUNET_OK, keep iterating.
858  */
859 static int
860 channel_destroy_iterator (void *cls,
861                           uint32_t key,
862                           void *value)
863 {
864   struct MeshChannel *ch = value;
865   struct MeshClient *c = cls;
866   struct MeshTunnel3 *t;
867
868   LOG (GNUNET_ERROR_TYPE_DEBUG,
869               " Channel %X (%X / %X) destroy, due to client %s shutdown.\n",
870               ch->gid, ch->lid_root, ch->lid_dest, GML_2s (c));
871   GMCH_debug (ch);
872
873   if (c == ch->dest)
874   {
875     LOG (GNUNET_ERROR_TYPE_DEBUG, " Client %s is destination.\n", GML_2s (c));
876   }
877   if (c == ch->root)
878   {
879     LOG (GNUNET_ERROR_TYPE_DEBUG, " Client %s is owner.\n", GML_2s (c));
880   }
881
882   t = ch->t;
883   GMCH_send_destroy (ch);
884   channel_destroy (ch);
885   GMT_destroy_if_empty (t);
886
887   return GNUNET_OK;
888 }
889
890
891 /**
892  * Handle a loopback message: call the appropriate handler for the message type.
893  *
894  * @param ch Channel this message is on.
895  * @param msgh Message header.
896  * @param fwd Is this FWD traffic?
897  */
898 void
899 handle_loopback (struct MeshChannel *ch,
900                  struct GNUNET_MessageHeader *msgh,
901                  int fwd)
902 {
903   uint16_t type;
904
905   type = ntohs (msgh->type);
906   LOG (GNUNET_ERROR_TYPE_DEBUG,
907        "Loopback %s message!\n",
908        GNUNET_MESH_DEBUG_M2S (type));
909
910   switch (type)
911   {
912     case GNUNET_MESSAGE_TYPE_MESH_DATA:
913       /* Don't send hop ACK, wait for client to ACK */
914       GMCH_handle_data (ch, (struct GNUNET_MESH_Data *) msgh, fwd);
915       break;
916
917     case GNUNET_MESSAGE_TYPE_MESH_DATA_ACK:
918       GMCH_handle_data_ack (ch, (struct GNUNET_MESH_DataACK *) msgh, fwd);
919       break;
920
921     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_CREATE:
922        // FIXME store channel in loopback tunnel?
923       GMCH_handle_create ((struct GNUNET_MESH_ChannelCreate *) msgh,
924                           fwd);
925       break;
926
927     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_ACK:
928       GMCH_handle_ack (ch,
929                        (struct GNUNET_MESH_ChannelManage *) msgh,
930                        fwd);
931       break;
932
933     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_DESTROY:
934       GMCH_handle_destroy (ch,
935                            (struct GNUNET_MESH_ChannelManage *) msgh,
936                            fwd);
937       break;
938
939     default:
940       GNUNET_break_op (0);
941       LOG (GNUNET_ERROR_TYPE_DEBUG,
942            "end-to-end message not known (%u)\n",
943            ntohs (msgh->type));
944   }
945 }
946
947
948
949 /******************************************************************************/
950 /********************************    API    ***********************************/
951 /******************************************************************************/
952
953 /**
954  * Get channel ID.
955  *
956  * @param ch Channel.
957  *
958  * @return ID
959  */
960 MESH_ChannelNumber
961 GMCH_get_id (const struct MeshChannel *ch)
962 {
963   return ch->gid;
964 }
965
966
967 /**
968  * Get the channel tunnel.
969  *
970  * @param ch Channel to get the tunnel from.
971  *
972  * @return tunnel of the channel.
973  */
974 struct MeshTunnel3 *
975 GMCH_get_tunnel (const struct MeshChannel *ch)
976 {
977   return ch->t;
978 }
979
980
981 /**
982  * Get free buffer space towards the client on a specific channel.
983  *
984  * @param ch Channel.
985  * @param fwd Is query about FWD traffic?
986  *
987  * @return Free buffer space [0 - 64]
988  */
989 unsigned int
990 GMCH_get_buffer (struct MeshChannel *ch, int fwd)
991 {
992   struct MeshChannelReliability *rel;
993
994   rel = fwd ? ch->dest_rel : ch->root_rel;
995
996   /* If rel is NULL it means that the end is not yet created,
997    * most probably is a loopback channel at the point of sending
998    * the ChannelCreate to itself.
999    */
1000   if (NULL == rel)
1001     return 64;
1002
1003   return (64 - rel->n_recv);
1004 }
1005
1006
1007 /**
1008  * Is the root client for this channel on this peer?
1009  *
1010  * @param ch Channel.
1011  * @param fwd Is this for fwd traffic?
1012  *
1013  * @return GNUNET_YES in case it is.
1014  */
1015 int
1016 GMCH_is_origin (struct MeshChannel *ch, int fwd)
1017 {
1018   struct MeshClient *c;
1019
1020   c = fwd ? ch->root : ch->dest;
1021   return NULL != c;
1022 }
1023
1024
1025 /**
1026  * Is the destination client for this channel on this peer?
1027  *
1028  * @param ch Channel.
1029  * @param fwd Is this for fwd traffic?
1030  *
1031  * @return GNUNET_YES in case it is.
1032  */
1033 int
1034 GMCH_is_terminal (struct MeshChannel *ch, int fwd)
1035 {
1036   struct MeshClient *c;
1037
1038   c = fwd ? ch->dest : ch->root;
1039   return NULL != c;
1040 }
1041
1042
1043 /**
1044  * Notify the destination client that a new incoming channel was created.
1045  *
1046  * @param ch Channel that was created.
1047  */
1048 void
1049 GMCH_send_create (struct MeshChannel *ch)
1050 {
1051   uint32_t opt;
1052
1053   if (NULL == ch->dest)
1054     return;
1055
1056   opt = 0;
1057   opt |= GNUNET_YES == ch->reliable ? GNUNET_MESH_OPTION_RELIABLE : 0;
1058   opt |= GNUNET_YES == ch->nobuffer ? GNUNET_MESH_OPTION_NOBUFFER : 0;
1059   GML_send_channel_create (ch->dest, ch->lid_dest, ch->port, opt,
1060                            GMT_get_destination (ch->t));
1061
1062 }
1063
1064 /**
1065  * Notify a client that the channel is no longer valid.
1066  * FIXME send on tunnel if some client == NULL?
1067  *
1068  * @param ch Channel that is destroyed.
1069  */
1070 void
1071 GMCH_send_destroy (struct MeshChannel *ch)
1072 {
1073   if (NULL != ch->root)
1074     GML_send_channel_destroy (ch->root, ch->lid_root);
1075
1076   if (NULL != ch->dest)
1077     GML_send_channel_destroy (ch->dest, ch->lid_dest);
1078 }
1079
1080
1081 /**
1082  * Send data on a channel.
1083  *
1084  * If the destination is local, send it to client, otherwise encrypt and
1085  * send to next hop.
1086  *
1087  * @param ch Channel
1088  * @param msg Message.
1089  * @param fwd Is this a fwd (root->dest) message?
1090  */
1091 void
1092 GMCH_send_data (struct MeshChannel *ch,
1093                 const struct GNUNET_MESH_Data *msg,
1094                 int fwd)
1095 {
1096 }
1097
1098
1099 /**
1100  * Send an end-to-end ACK message for the most recent in-sequence payload.
1101  *
1102  * If channel is not reliable, do nothing.
1103  *
1104  * @param ch Channel this is about.
1105  * @param fwd Is for FWD traffic? (ACK dest->owner)
1106  */
1107 void
1108 GMCH_send_ack (struct MeshChannel *ch, int fwd)
1109 {
1110   struct GNUNET_MESH_DataACK msg;
1111   struct MeshChannelReliability *rel;
1112   struct MeshReliableMessage *copy;
1113   unsigned int delta;
1114   uint64_t mask;
1115   uint16_t type;
1116
1117   if (GNUNET_NO == ch->reliable)
1118   {
1119     return;
1120   }
1121   rel = fwd ? ch->dest_rel : ch->root_rel;
1122   LOG (GNUNET_ERROR_TYPE_DEBUG,
1123               "send_data_ack for %u\n",
1124               rel->mid_recv - 1);
1125
1126   type = GNUNET_MESSAGE_TYPE_MESH_DATA_ACK;
1127   msg.header.type = htons (type);
1128   msg.header.size = htons (sizeof (msg));
1129   msg.chid = htonl (ch->gid);
1130   msg.mid = htonl (rel->mid_recv - 1);
1131   msg.futures = 0;
1132   for (copy = rel->head_recv; NULL != copy; copy = copy->next)
1133   {
1134     if (copy->type != type)
1135       continue;
1136     delta = copy->mid - rel->mid_recv;
1137     if (63 < delta)
1138       break;
1139     mask = 0x1LL << delta;
1140     msg.futures |= mask;
1141     LOG (GNUNET_ERROR_TYPE_DEBUG,
1142                 " setting bit for %u (delta %u) (%llX) -> %llX\n",
1143                 copy->mid, delta, mask, msg.futures);
1144   }
1145   LOG (GNUNET_ERROR_TYPE_DEBUG, " final futures %llX\n", msg.futures);
1146
1147   GMCH_send_prebuilt_message (&msg.header, ch, fwd);
1148   LOG (GNUNET_ERROR_TYPE_DEBUG, "send_data_ack END\n");
1149 }
1150
1151
1152 /**
1153  * Log channel info.
1154  *
1155  * @param ch Channel.
1156  */
1157 void
1158 GMCH_debug (struct MeshChannel *ch)
1159 {
1160   if (NULL == ch)
1161   {
1162     LOG (GNUNET_ERROR_TYPE_DEBUG, "*** DEBUG NULL CHANNEL ***\n");
1163     return;
1164   }
1165   LOG (GNUNET_ERROR_TYPE_DEBUG, "Channel %s:%X (%p)\n",
1166               GMT_2s (ch->t), ch->gid, ch);
1167   LOG (GNUNET_ERROR_TYPE_DEBUG, "  root %p/%p\n",
1168               ch->root, ch->root_rel);
1169   if (NULL != ch->root)
1170   {
1171     LOG (GNUNET_ERROR_TYPE_DEBUG, "  cli %s\n", GML_2s (ch->root));
1172     LOG (GNUNET_ERROR_TYPE_DEBUG, "  ready %s\n",
1173                 ch->root_rel->client_ready ? "YES" : "NO");
1174     LOG (GNUNET_ERROR_TYPE_DEBUG, "  id %X\n", ch->lid_root);
1175   }
1176   LOG (GNUNET_ERROR_TYPE_DEBUG, "  dest %p/%p\n",
1177               ch->dest, ch->dest_rel);
1178   if (NULL != ch->dest)
1179   {
1180     LOG (GNUNET_ERROR_TYPE_DEBUG, "  cli %s\n", GML_2s (ch->dest));
1181     LOG (GNUNET_ERROR_TYPE_DEBUG, "  ready %s\n",
1182                 ch->dest_rel->client_ready ? "YES" : "NO");
1183     LOG (GNUNET_ERROR_TYPE_DEBUG, "  id %X\n", ch->lid_dest);
1184   }
1185 }
1186
1187
1188 /**
1189  * Handler for mesh network payload traffic.
1190  *
1191  * @param ch Channel for the message.
1192  * @param message Unencryted data message.
1193  * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO;
1194  */
1195 void
1196 GMCH_handle_data (struct MeshChannel *ch,
1197                   const struct GNUNET_MESH_Data *msg,
1198                   int fwd)
1199 {
1200   struct MeshChannelReliability *rel;
1201   struct MeshClient *c;
1202   uint32_t mid;
1203   uint16_t type;
1204   size_t size;
1205
1206   /*  Initialize FWD/BCK data */
1207   c   = fwd ? ch->dest     : ch->root;
1208   rel = fwd ? ch->dest_rel : ch->root_rel;
1209
1210   if (NULL == c)
1211   {
1212     GNUNET_break (0);
1213     return;
1214   }
1215
1216   GNUNET_STATISTICS_update (stats, "# data received", 1, GNUNET_NO);
1217
1218   mid = ntohl (msg->mid);
1219   LOG (GNUNET_ERROR_TYPE_DEBUG, " mid %u\n", mid);
1220
1221   if (GNUNET_NO == ch->reliable ||
1222       ( !GMC_is_pid_bigger (rel->mid_recv, mid) &&
1223         GMC_is_pid_bigger (rel->mid_recv + 64, mid) ) )
1224   {
1225     LOG (GNUNET_ERROR_TYPE_DEBUG, "!!! RECV %u\n", mid);
1226     if (GNUNET_YES == ch->reliable)
1227     {
1228       /* Is this the exact next expected messasge? */
1229       if (mid == rel->mid_recv)
1230       {
1231         LOG (GNUNET_ERROR_TYPE_DEBUG, "as expected\n");
1232         rel->mid_recv++;
1233         send_client_data (ch, msg, fwd);
1234       }
1235       else
1236       {
1237         LOG (GNUNET_ERROR_TYPE_DEBUG, "save for later\n");
1238         add_buffered_data (msg, rel);
1239       }
1240     }
1241     else
1242     {
1243       /* Tunnel is unreliable: send to clients directly */
1244       /* FIXME: accept Out Of Order traffic */
1245       rel->mid_recv = mid + 1;
1246       send_client_data (ch, msg, fwd);
1247     }
1248   }
1249   else
1250   {
1251     GNUNET_break_op (0);
1252     LOG (GNUNET_ERROR_TYPE_DEBUG,
1253                 " MID %u not expected (%u - %u), dropping!\n",
1254                 mid, rel->mid_recv, rel->mid_recv + 64);
1255   }
1256
1257   GMCH_send_ack (ch, fwd);
1258 }
1259
1260
1261 /**
1262  * Handler for mesh network traffic end-to-end ACKs.
1263  *
1264  * @param t Tunnel on which we got this message.
1265  * @param message Data message.
1266  * @param fwd Is this a fwd ACK? (dest->orig)
1267  */
1268 void
1269 GMCH_handle_data_ack (struct MeshChannel *ch,
1270                       const struct GNUNET_MESH_DataACK *msg,
1271                       int fwd)
1272 {
1273   struct MeshChannelReliability *rel;
1274   struct MeshReliableMessage *copy;
1275   struct MeshReliableMessage *next;
1276   uint32_t ack;
1277   int work;
1278
1279   ack = ntohl (msg->mid);
1280   LOG (GNUNET_ERROR_TYPE_DEBUG, "!!! %s ACK %u\n",
1281               (GNUNET_YES == fwd) ? "FWD" : "BCK", ack);
1282
1283   if (GNUNET_YES == fwd)
1284   {
1285     rel = ch->root_rel;
1286   }
1287   else
1288   {
1289     rel = ch->dest_rel;
1290   }
1291   if (NULL == rel)
1292   {
1293     GNUNET_break (0);
1294     return;
1295   }
1296
1297   for (work = GNUNET_NO, copy = rel->head_sent; copy != NULL; copy = next)
1298   {
1299     if (GMC_is_pid_bigger (copy->mid, ack))
1300     {
1301       LOG (GNUNET_ERROR_TYPE_DEBUG, "!!!  head %u, out!\n", copy->mid);
1302       channel_rel_free_sent (rel, msg);
1303       break;
1304     }
1305     work = GNUNET_YES;
1306     LOG (GNUNET_ERROR_TYPE_DEBUG, "!!!  id %u\n", copy->mid);
1307     next = copy->next;
1308     rel_message_free (copy);
1309   }
1310   /* ACK client if needed */
1311 //   channel_send_ack (t, type, GNUNET_MESSAGE_TYPE_MESH_UNICAST_ACK == type);
1312
1313   /* If some message was free'd, update the retransmission delay*/
1314   if (GNUNET_YES == work)
1315   {
1316     if (GNUNET_SCHEDULER_NO_TASK != rel->retry_task)
1317     {
1318       GNUNET_SCHEDULER_cancel (rel->retry_task);
1319       if (NULL == rel->head_sent)
1320       {
1321         rel->retry_task = GNUNET_SCHEDULER_NO_TASK;
1322       }
1323       else
1324       {
1325         struct GNUNET_TIME_Absolute new_target;
1326         struct GNUNET_TIME_Relative delay;
1327
1328         delay = GNUNET_TIME_relative_multiply (rel->retry_timer,
1329                                                MESH_RETRANSMIT_MARGIN);
1330         new_target = GNUNET_TIME_absolute_add (rel->head_sent->timestamp,
1331                                                delay);
1332         delay = GNUNET_TIME_absolute_get_remaining (new_target);
1333         rel->retry_task =
1334             GNUNET_SCHEDULER_add_delayed (delay,
1335                                           &channel_retransmit_message,
1336                                           rel);
1337       }
1338     }
1339     else
1340       GNUNET_break (0);
1341   }
1342 }
1343
1344
1345 /**
1346  * Handler for channel create messages.
1347  *
1348  * @param msg Message.
1349  * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO;
1350  */
1351 struct MeshChannel *
1352 GMCH_handle_create (const struct GNUNET_MESH_ChannelCreate *msg,
1353                     int fwd)
1354 {
1355   MESH_ChannelNumber chid;
1356   struct MeshChannel *ch;
1357   struct MeshClient *c;
1358   uint32_t port;
1359
1360   chid = ntohl (msg->chid);
1361
1362   /* Create channel */
1363   ch = channel_new (NULL, NULL, 0); /* FIXME t */
1364   ch->gid = chid;
1365   channel_set_options (ch, ntohl (msg->opt));
1366
1367   /* Find a destination client */
1368   port = ntohl (msg->port);
1369   LOG (GNUNET_ERROR_TYPE_DEBUG, "   port %u\n", port);
1370   c = GML_client_get_by_port (port);
1371   if (NULL == c)
1372   {
1373     /* TODO send reject */
1374     LOG (GNUNET_ERROR_TYPE_DEBUG, "  no client has port registered\n");
1375     /* TODO free ch */
1376     return;
1377   }
1378
1379   channel_add_client (ch, c);
1380   if (GNUNET_YES == ch->reliable)
1381     LOG (GNUNET_ERROR_TYPE_DEBUG, "!!! Reliable\n");
1382
1383   GMCH_send_create (ch);
1384   GMCH_send_ack (ch, fwd);
1385   GML_send_ack (ch, !fwd);
1386
1387   return ch;
1388 }
1389
1390
1391 /**
1392  * Handler for channel ack messages.
1393  *
1394  * @param ch Channel.
1395  * @param msg Message.
1396  * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO;
1397  */
1398 void
1399 GMCH_handle_ack (struct MeshChannel *ch,
1400                  const struct GNUNET_MESH_ChannelManage *msg,
1401                  int fwd)
1402 {
1403   channel_confirm (ch, !fwd);
1404 }
1405
1406
1407 /**
1408  * Handler for channel destroy messages.
1409  *
1410  * @param ch Channel to be destroyed of.
1411  * @param msg Message.
1412  * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO;
1413  */
1414 void
1415 GMCH_handle_destroy (struct MeshChannel *ch,
1416                      const struct GNUNET_MESH_ChannelManage *msg,
1417                      int fwd)
1418 {
1419   MESH_ChannelNumber chid;
1420
1421   /* Check if channel exists */
1422   chid = ntohl (msg->chid);
1423   if ( (fwd && NULL == ch->dest) || (!fwd && NULL == ch->root) )
1424   {
1425     /* Not for us (don't destroy twice a half-open loopback channel) */
1426     return;
1427   }
1428
1429   GMCH_send_destroy (ch);
1430   channel_destroy (ch);
1431 }
1432
1433
1434 /**
1435  * Sends an already built message on a channel.
1436  *
1437  * @param message Message to send. Function makes a copy of it.
1438  * @param ch Channel on which this message is transmitted.
1439  * @param fwd Is this a fwd message?
1440  */
1441 void
1442 GMCH_send_prebuilt_message (const struct GNUNET_MessageHeader *message,
1443                             struct MeshChannel *ch, int fwd)
1444 {
1445   size_t size = ntohs (message->size);
1446
1447   LOG (GNUNET_ERROR_TYPE_DEBUG, "Send on Channel %s:%X %s\n",
1448        GMT_2s (ch->t), ch->gid, fwd ? "FWD" : "BCK");
1449   LOG (GNUNET_ERROR_TYPE_DEBUG, "  %s\n",
1450        GNUNET_MESH_DEBUG_M2S (ntohs (message->type)));
1451
1452   if (GMT_is_loopback (ch->t))
1453   {
1454     handle_loopback (ch->t, message, fwd);
1455     return;
1456   }
1457
1458   GMT_send_prebuilt_message (message, ch->t, ch, fwd);
1459 }