- one catch-all ack handles renedered obsolete
[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   struct MeshTunnel3 *t = ch->t;
365
366   if (NULL != ch->dest)
367   {
368     GNUNET_break (0);
369     return;
370   }
371
372   /* Assign local id as destination */
373   ch->lid_dest = GML_get_next_chid (c);
374
375   /* Store in client's hashmap */
376   GML_channel_add (c, ch->lid_dest, ch);
377
378   GNUNET_break (NULL == ch->dest_rel);
379   ch->dest_rel = GNUNET_new (struct MeshChannelReliability);
380   ch->dest_rel->ch = ch;
381   ch->dest_rel->expected_delay = MESH_RETRANSMIT_TIME;
382
383   ch->dest = c;
384 }
385
386
387 /**
388  * Destroy all reliable messages queued for a channel,
389  * during a channel destruction.
390  * Frees the reliability structure itself.
391  *
392  * @param rel Reliability data for a channel.
393  */
394 static void
395 channel_rel_free_all (struct MeshChannelReliability *rel)
396 {
397   struct MeshReliableMessage *copy;
398   struct MeshReliableMessage *next;
399
400   if (NULL == rel)
401     return;
402
403   for (copy = rel->head_recv; NULL != copy; copy = next)
404   {
405     next = copy->next;
406     GNUNET_CONTAINER_DLL_remove (rel->head_recv, rel->tail_recv, copy);
407     GNUNET_free (copy);
408   }
409   for (copy = rel->head_sent; NULL != copy; copy = next)
410   {
411     next = copy->next;
412     GNUNET_CONTAINER_DLL_remove (rel->head_sent, rel->tail_sent, copy);
413     GNUNET_free (copy);
414   }
415   if (GNUNET_SCHEDULER_NO_TASK != rel->retry_task)
416     GNUNET_SCHEDULER_cancel (rel->retry_task);
417   GNUNET_free (rel);
418 }
419
420
421 /**
422  * Mark future messages as ACK'd.
423  *
424  * @param rel Reliability data.
425  * @param msg DataACK message with a bitfield of future ACK'd messages.
426  */
427 static void
428 channel_rel_free_sent (struct MeshChannelReliability *rel,
429                        const struct GNUNET_MESH_DataACK *msg)
430 {
431   struct MeshReliableMessage *copy;
432   struct MeshReliableMessage *next;
433   uint64_t bitfield;
434   uint64_t mask;
435   uint32_t mid;
436   uint32_t target;
437   unsigned int i;
438
439   bitfield = msg->futures;
440   mid = ntohl (msg->mid);
441   LOG (GNUNET_ERROR_TYPE_DEBUG,
442               "free_sent_reliable %u %llX\n",
443               mid, bitfield);
444   LOG (GNUNET_ERROR_TYPE_DEBUG,
445               " rel %p, head %p\n",
446               rel, rel->head_sent);
447   for (i = 0, copy = rel->head_sent;
448        i < 64 && NULL != copy && 0 != bitfield;
449        i++)
450   {
451     LOG (GNUNET_ERROR_TYPE_DEBUG,
452                 " trying bit %u (mid %u)\n",
453                 i, mid + i + 1);
454     mask = 0x1LL << i;
455     if (0 == (bitfield & mask))
456      continue;
457
458     LOG (GNUNET_ERROR_TYPE_DEBUG, " set!\n");
459     /* Bit was set, clear the bit from the bitfield */
460     bitfield &= ~mask;
461
462     /* The i-th bit was set. Do we have that copy? */
463     /* Skip copies with mid < target */
464     target = mid + i + 1;
465     LOG (GNUNET_ERROR_TYPE_DEBUG, " target %u\n", target);
466     while (NULL != copy && GMC_is_pid_bigger (target, copy->mid))
467      copy = copy->next;
468
469     /* Did we run out of copies? (previously freed, it's ok) */
470     if (NULL == copy)
471     {
472      LOG (GNUNET_ERROR_TYPE_DEBUG, "run out of copies...\n");
473      return;
474     }
475
476     /* Did we overshoot the target? (previously freed, it's ok) */
477     if (GMC_is_pid_bigger (copy->mid, target))
478     {
479      LOG (GNUNET_ERROR_TYPE_DEBUG, " next copy %u\n", copy->mid);
480      continue;
481     }
482
483     /* Now copy->mid == target, free it */
484     next = copy->next;
485     rel_message_free (copy);
486     copy = next;
487   }
488   LOG (GNUNET_ERROR_TYPE_DEBUG, "free_sent_reliable END\n");
489 }
490
491
492 /**
493  * We haven't received an ACK after a certain time: restransmit the message.
494  *
495  * @param cls Closure (MeshReliableMessage with the message to restransmit)
496  * @param tc TaskContext.
497  */
498 static void
499 channel_retransmit_message (void *cls,
500                             const struct GNUNET_SCHEDULER_TaskContext *tc)
501 {
502   struct MeshChannelReliability *rel = cls;
503   struct MeshReliableMessage *copy;
504   struct MeshPeerQueue *q;
505   struct MeshChannel *ch;
506   struct MeshConnection *c;
507   struct GNUNET_MESH_Data *payload;
508   struct MeshPeer *hop;
509   int fwd;
510
511   rel->retry_task = GNUNET_SCHEDULER_NO_TASK;
512   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
513     return;
514
515   ch = rel->ch;
516   copy = rel->head_sent;
517   if (NULL == copy)
518   {
519     GNUNET_break (0);
520     return;
521   }
522
523   /* Search the message to be retransmitted in the outgoing queue.
524    * Check only the queue for the connection that is going to be used,
525    * if the message is stuck in some other connection's queue we shouldn't
526    * act upon it:
527    * - cancelling it and sending the new one doesn't guarantee it's delivery,
528    *   the old connection could be temporary stalled or the queue happened to
529    *   be long at time of insertion.
530    * - not sending the new one could cause terrible delays the old connection
531    *   is stalled.
532    */
533 //   FIXME access to queue elements is limited
534 //   payload = (struct GNUNET_MESH_Data *) &copy[1];
535 //   fwd = (rel == ch->root_rel);
536 //   c = GMT_get_connection (ch->t, fwd);
537 //   hop = connection_get_hop (c, fwd);
538 //   for (q = hop->queue_head; NULL != q; q = q->next)
539 //   {
540 //     if (ntohs (payload->header.type) == q->type && ch == q->ch)
541 //     {
542 //       struct GNUNET_MESH_Data *queued_data = q->cls;
543 // 
544 //       if (queued_data->mid == payload->mid)
545 //         break;
546 //     }
547 //   }
548
549   /* Message not found in the queue that we are going to use. */
550 //   if (NULL == q)
551 //   {
552     LOG (GNUNET_ERROR_TYPE_DEBUG, "!!! RETRANSMIT %u\n", copy->mid);
553
554     GMCH_send_prebuilt_message (&payload->header, ch, fwd);
555     GNUNET_STATISTICS_update (stats, "# data retransmitted", 1, GNUNET_NO);
556 //   }
557 //   else
558 //   {
559 //     LOG (GNUNET_ERROR_TYPE_DEBUG, "!!! ALREADY IN QUEUE %u\n", copy->mid);
560 //   }
561
562   rel->retry_timer = GNUNET_TIME_STD_BACKOFF (rel->retry_timer);
563   rel->retry_task = GNUNET_SCHEDULER_add_delayed (rel->retry_timer,
564                                                   &channel_retransmit_message,
565                                                   cls);
566 }
567
568
569 /**
570  * Destroy a reliable message after it has been acknowledged, either by
571  * direct mid ACK or bitfield. Updates the appropriate data structures and
572  * timers and frees all memory.
573  *
574  * @param copy Message that is no longer needed: remote peer got it.
575  */
576 static void
577 rel_message_free (struct MeshReliableMessage *copy)
578 {
579   struct MeshChannelReliability *rel;
580   struct GNUNET_TIME_Relative time;
581
582   rel = copy->rel;
583   time = GNUNET_TIME_absolute_get_duration (copy->timestamp);
584   rel->expected_delay.rel_value_us *= 7;
585   rel->expected_delay.rel_value_us += time.rel_value_us;
586   rel->expected_delay.rel_value_us /= 8;
587   rel->n_sent--;
588   LOG (GNUNET_ERROR_TYPE_DEBUG, "!!! Freeing %u\n", copy->mid);
589   LOG (GNUNET_ERROR_TYPE_DEBUG, "    n_sent %u\n", rel->n_sent);
590   LOG (GNUNET_ERROR_TYPE_DEBUG, "!!!  took %s\n",
591               GNUNET_STRINGS_relative_time_to_string (time, GNUNET_NO));
592   LOG (GNUNET_ERROR_TYPE_DEBUG, "!!!  new expected delay %s\n",
593               GNUNET_STRINGS_relative_time_to_string (rel->expected_delay,
594                                                       GNUNET_NO));
595   rel->retry_timer = rel->expected_delay;
596   GNUNET_CONTAINER_DLL_remove (rel->head_sent, rel->tail_sent, copy);
597   GNUNET_free (copy);
598 }
599
600
601
602 /**
603  * Channel was ACK'd by remote peer, mark as ready and cancel retransmission.
604  *
605  * @param ch Channel to mark as ready.
606  * @param fwd Was the CREATE message sent fwd?
607  */
608 static void
609 channel_confirm (struct MeshChannel *ch, int fwd)
610 {
611   struct MeshChannelReliability *rel;
612   struct MeshReliableMessage *copy;
613   struct MeshReliableMessage *next;
614
615   LOG (GNUNET_ERROR_TYPE_DEBUG,
616               "  channel confirm %s %s:%X\n",
617               fwd ? "FWD" : "BCK", GMT_2s (ch->t), ch->gid);
618   ch->state = MESH_CHANNEL_READY;
619
620   rel = fwd ? ch->root_rel : ch->dest_rel;
621   for (copy = rel->head_sent; NULL != copy; copy = next)
622   {
623     struct GNUNET_MessageHeader *msg;
624
625     next = copy->next;
626     msg = (struct GNUNET_MessageHeader *) &copy[1];
627     if (ntohs (msg->type) == GNUNET_MESSAGE_TYPE_MESH_CHANNEL_CREATE)
628     {
629       rel_message_free (copy);
630       /* TODO return? */
631     }
632   }
633   send_ack (NULL, ch, fwd);
634 }
635
636
637 /**
638  * Save a copy to retransmit in case it gets lost.
639  *
640  * Initializes all needed callbacks and timers.
641  *
642  * @param ch Channel this message goes on.
643  * @param msg Message to copy.
644  * @param fwd Is this fwd traffic?
645  */
646 static void
647 channel_save_copy (struct MeshChannel *ch,
648                    const struct GNUNET_MessageHeader *msg,
649                    int fwd)
650 {
651   struct MeshChannelReliability *rel;
652   struct MeshReliableMessage *copy;
653   uint32_t mid;
654   uint16_t type;
655   uint16_t size;
656
657   rel = fwd ? ch->root_rel : ch->dest_rel;
658   mid = rel->mid_send;
659   type = ntohs (msg->type);
660   size = ntohs (msg->size);
661
662   LOG (GNUNET_ERROR_TYPE_DEBUG, "!!! SAVE %u\n", mid);
663   copy = GNUNET_malloc (sizeof (struct MeshReliableMessage) + size);
664   copy->mid = mid;
665   copy->timestamp = GNUNET_TIME_absolute_get ();
666   copy->rel = rel;
667   copy->type = type;
668   memcpy (&copy[1], msg, size);
669   rel->n_sent++;
670   LOG (GNUNET_ERROR_TYPE_DEBUG, " n_sent %u\n", rel->n_sent);
671   GNUNET_CONTAINER_DLL_insert_tail (rel->head_sent, rel->tail_sent, copy);
672   if (GNUNET_SCHEDULER_NO_TASK == rel->retry_task)
673   {
674     rel->retry_timer =
675         GNUNET_TIME_relative_multiply (rel->expected_delay,
676                                         MESH_RETRANSMIT_MARGIN);
677     rel->retry_task =
678         GNUNET_SCHEDULER_add_delayed (rel->retry_timer,
679                                       &channel_retransmit_message,
680                                       rel);
681   }
682 }
683
684
685
686 /**
687  * Send a buffered message to the client, for in order delivery or
688  * as result of client ACK.
689  *
690  * @param ch Channel on which to empty the message buffer.
691  * @param c Client to send to.
692  * @param rel Reliability structure to corresponding peer.
693  *            If rel == bck_rel, this is FWD data.
694  */
695 static void
696 send_client_buffered_data (struct MeshChannel *ch,
697                                    struct MeshClient *c,
698                                    int fwd)
699 {
700   struct MeshReliableMessage *copy;
701   struct MeshChannelReliability *rel;
702
703   LOG (GNUNET_ERROR_TYPE_DEBUG, "send_buffered_data\n");
704   rel = fwd ? ch->dest_rel : ch->root_rel;
705   if (GNUNET_NO == rel->client_ready)
706   {
707     LOG (GNUNET_ERROR_TYPE_DEBUG, "client not ready\n");
708     return;
709   }
710
711   copy = rel->head_recv;
712   /* We never buffer channel management messages */
713   if (NULL != copy)
714   {
715     if (copy->mid == rel->mid_recv || GNUNET_NO == ch->reliable)
716     {
717       struct GNUNET_MESH_Data *msg = (struct GNUNET_MESH_Data *) &copy[1];
718
719       LOG (GNUNET_ERROR_TYPE_DEBUG,
720                   " have %u! now expecting %u\n",
721                   copy->mid, rel->mid_recv + 1);
722       send_client_data (ch, msg, fwd);
723       rel->n_recv--;
724       rel->mid_recv++;
725       GNUNET_CONTAINER_DLL_remove (rel->head_recv, rel->tail_recv, copy);
726       GNUNET_free (copy);
727     }
728     else
729     {
730       LOG (GNUNET_ERROR_TYPE_DEBUG,
731                   " reliable && don't have %u, next is %u\n",
732                   rel->mid_recv,
733                   copy->mid);
734       return;
735     }
736   }
737   LOG (GNUNET_ERROR_TYPE_DEBUG, "send_buffered_data END\n");
738 }
739
740
741
742
743 /**
744  * Destroy a channel and free all resources.
745  *
746  * @param ch Channel to destroy.
747  */
748 static void
749 channel_destroy (struct MeshChannel *ch)
750 {
751   struct MeshClient *c;
752
753   if (NULL == ch)
754     return;
755
756   LOG (GNUNET_ERROR_TYPE_DEBUG, "destroying channel %s:%u\n",
757               GMT_2s (ch->t), ch->gid);
758   GMCH_debug (ch);
759
760   c = ch->root;
761   if (NULL != c)
762   {
763     GML_channel_remove (c, ch->lid_root, ch);
764   }
765
766   c = ch->dest;
767   if (NULL != c)
768   {
769     GML_channel_remove (c, ch->lid_dest, ch);
770   }
771
772   channel_rel_free_all (ch->root_rel);
773   channel_rel_free_all (ch->dest_rel);
774
775   GMT_remove_channel (ch->t, ch);
776   GNUNET_STATISTICS_update (stats, "# channels", -1, GNUNET_NO);
777
778   GNUNET_free (ch);
779 }
780
781
782 /**
783  * Create a new channel.
784  *
785  * @param t Tunnel this channel is in.
786  * @param owner Client that owns the channel, NULL for foreign channels.
787  * @param lid_root Local ID for root client.
788  *
789  * @return A new initialized channel. NULL on error.
790  */
791 static struct MeshChannel *
792 channel_new (struct MeshTunnel3 *t,
793              struct MeshClient *owner, MESH_ChannelNumber lid_root)
794 {
795   struct MeshChannel *ch;
796
797   ch = GNUNET_new (struct MeshChannel);
798   ch->root = owner;
799   ch->lid_root = lid_root;
800   ch->t = t;
801
802   GNUNET_STATISTICS_update (stats, "# channels", 1, GNUNET_NO);
803
804   if (NULL != owner)
805   {
806     ch->gid = GMT_get_next_chid (t);
807     GML_channel_add (owner, lid_root, ch);
808   }
809   GMT_add_channel (t, ch);
810
811   return ch;
812 }
813
814
815 /**
816  * Set options in a channel, extracted from a bit flag field
817  *
818  * @param ch Channel to set options to.
819  * @param options Bit array in host byte order.
820  */
821 static void
822 channel_set_options (struct MeshChannel *ch, uint32_t options)
823 {
824   ch->nobuffer = (options & GNUNET_MESH_OPTION_NOBUFFER) != 0 ?
825                  GNUNET_YES : GNUNET_NO;
826   ch->reliable = (options & GNUNET_MESH_OPTION_RELIABLE) != 0 ?
827                  GNUNET_YES : GNUNET_NO;
828 }
829
830
831
832 /**
833  * Confirm we got a channel create.
834  *
835  * @param ch The channel to confirm.
836  * @param fwd Should we send the ACK fwd?
837  */
838 static void
839 channel_send_ack (struct MeshChannel *ch, int fwd)
840 {
841   struct GNUNET_MESH_ChannelManage msg;
842
843   msg.header.size = htons (sizeof (msg));
844   msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_CHANNEL_ACK);
845   LOG (GNUNET_ERROR_TYPE_DEBUG,
846               "  sending channel %s ack for channel %s:%X\n",
847               fwd ? "FWD" : "BCK", GMT_2s (ch->t),
848               ch->gid);
849
850   msg.chid = htonl (ch->gid);
851   GMCH_send_prebuilt_message (&msg.header, ch, !fwd);
852 }
853
854
855 /**
856  * Iterator for deleting each channel whose client endpoint disconnected.
857  *
858  * @param cls Closure (client that has disconnected).
859  * @param key The local channel id (used to access the hashmap).
860  * @param value The value stored at the key (channel to destroy).
861  *
862  * @return GNUNET_OK, keep iterating.
863  */
864 static int
865 channel_destroy_iterator (void *cls,
866                           uint32_t key,
867                           void *value)
868 {
869   struct MeshChannel *ch = value;
870   struct MeshClient *c = cls;
871   struct MeshTunnel3 *t;
872
873   LOG (GNUNET_ERROR_TYPE_DEBUG,
874               " Channel %X (%X / %X) destroy, due to client %s shutdown.\n",
875               ch->gid, ch->lid_root, ch->lid_dest, GML_2s (c));
876   GMCH_debug (ch);
877
878   if (c == ch->dest)
879   {
880     LOG (GNUNET_ERROR_TYPE_DEBUG, " Client %s is destination.\n", GML_2s (c));
881   }
882   if (c == ch->root)
883   {
884     LOG (GNUNET_ERROR_TYPE_DEBUG, " Client %s is owner.\n", GML_2s (c));
885   }
886
887   t = ch->t;
888   GMCH_send_destroy (ch);
889   channel_destroy (ch);
890   GMT_destroy_if_empty (t);
891
892   return GNUNET_OK;
893 }
894
895
896 /**
897  * Handle a loopback message: call the appropriate handler for the message type.
898  *
899  * @param ch Channel this message is on.
900  * @param msgh Message header.
901  * @param fwd Is this FWD traffic?
902  */
903 void
904 handle_loopback (struct MeshChannel *ch,
905                  struct GNUNET_MessageHeader *msgh,
906                  int fwd)
907 {
908   uint16_t type;
909
910   type = ntohs (msgh->type);
911   LOG (GNUNET_ERROR_TYPE_DEBUG,
912        "Loopback %s message!\n",
913        GNUNET_MESH_DEBUG_M2S (type));
914
915   switch (type)
916   {
917     case GNUNET_MESSAGE_TYPE_MESH_DATA:
918       /* Don't send hop ACK, wait for client to ACK */
919       GMCH_handle_data (ch, (struct GNUNET_MESH_Data *) msgh, fwd);
920       break;
921
922     case GNUNET_MESSAGE_TYPE_MESH_DATA_ACK:
923       GMCH_handle_data_ack (ch, (struct GNUNET_MESH_DataACK *) msgh, fwd);
924       break;
925
926     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_CREATE:
927        // FIXME store channel in loopback tunnel?
928       GMCH_handle_create ((struct GNUNET_MESH_ChannelCreate *) msgh,
929                           fwd);
930       break;
931
932     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_ACK:
933       GMCH_handle_ack (ch,
934                        (struct GNUNET_MESH_ChannelManage *) msgh,
935                        fwd);
936       break;
937
938     case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_DESTROY:
939       GMCH_handle_destroy (ch,
940                            (struct GNUNET_MESH_ChannelManage *) msgh,
941                            fwd);
942       break;
943
944     default:
945       GNUNET_break_op (0);
946       LOG (GNUNET_ERROR_TYPE_DEBUG,
947            "end-to-end message not known (%u)\n",
948            ntohs (msgh->type));
949   }
950 }
951
952
953
954 /******************************************************************************/
955 /********************************    API    ***********************************/
956 /******************************************************************************/
957
958 /**
959  * Get channel ID.
960  *
961  * @param ch Channel.
962  *
963  * @return ID
964  */
965 MESH_ChannelNumber
966 GMCH_get_id (const struct MeshChannel *ch)
967 {
968   return ch->gid;
969 }
970
971
972 /**
973  * Get the channel tunnel.
974  *
975  * @param ch Channel to get the tunnel from.
976  *
977  * @return tunnel of the channel.
978  */
979 struct MeshTunnel3 *
980 GMCH_get_tunnel (const struct MeshChannel *ch)
981 {
982   return ch->t;
983 }
984
985
986 /**
987  * Get free buffer space towards the client on a specific channel.
988  *
989  * @param ch Channel.
990  * @param fwd Is query about FWD traffic?
991  *
992  * @return Free buffer space [0 - 64]
993  */
994 unsigned int
995 GMCH_get_buffer (struct MeshChannel *ch, int fwd)
996 {
997   struct MeshChannelReliability *rel;
998
999   rel = fwd ? ch->dest_rel : ch->root_rel;
1000
1001   /* If rel is NULL it means that the end is not yet created,
1002    * most probably is a loopback channel at the point of sending
1003    * the ChannelCreate to itself.
1004    */
1005   if (NULL == rel)
1006     return 64;
1007
1008   return (64 - rel->n_recv);
1009 }
1010
1011
1012 /**
1013  * Is the root client for this channel on this peer?
1014  *
1015  * @param ch Channel.
1016  * @param fwd Is this for fwd traffic?
1017  *
1018  * @return GNUNET_YES in case it is.
1019  */
1020 int
1021 GMCH_is_origin (struct MeshChannel *ch, int fwd)
1022 {
1023   struct MeshClient *c;
1024
1025   c = fwd ? ch->root : ch->dest;
1026   return NULL != c;
1027 }
1028
1029
1030 /**
1031  * Is the destination client for this channel on this peer?
1032  *
1033  * @param ch Channel.
1034  * @param fwd Is this for fwd traffic?
1035  *
1036  * @return GNUNET_YES in case it is.
1037  */
1038 int
1039 GMCH_is_terminal (struct MeshChannel *ch, int fwd)
1040 {
1041   struct MeshClient *c;
1042
1043   c = fwd ? ch->dest : ch->root;
1044   return NULL != c;
1045 }
1046
1047
1048 /**
1049  * Notify the destination client that a new incoming channel was created.
1050  *
1051  * @param ch Channel that was created.
1052  */
1053 void
1054 GMCH_send_create (struct MeshChannel *ch)
1055 {
1056   struct GNUNET_MESH_ChannelMessage msg;
1057   uint32_t opt;
1058
1059   if (NULL == ch->dest)
1060     return;
1061
1062   opt = 0;
1063   opt |= GNUNET_YES == ch->reliable ? GNUNET_MESH_OPTION_RELIABLE : 0;
1064   opt |= GNUNET_YES == ch->nobuffer ? GNUNET_MESH_OPTION_NOBUFFER : 0;
1065   GML_send_channel_create (ch->dest, ch->lid_dest, ch->port, opt,
1066                            GMT_get_destination (ch->t));
1067
1068 }
1069
1070 /**
1071  * Notify a client that the channel is no longer valid.
1072  * FIXME send on tunnel if some client == NULL?
1073  *
1074  * @param ch Channel that is destroyed.
1075  */
1076 void
1077 GMCH_send_destroy (struct MeshChannel *ch)
1078 {
1079   if (NULL != ch->root)
1080     GML_send_channel_destroy (ch->root, ch->lid_root);
1081
1082   if (NULL != ch->dest)
1083     GML_send_channel_destroy (ch->dest, ch->lid_dest);
1084 }
1085
1086
1087 /**
1088  * Send data on a channel.
1089  *
1090  * If the destination is local, send it to client, otherwise encrypt and
1091  * send to next hop.
1092  *
1093  * @param ch Channel
1094  * @param msg Message.
1095  * @param fwd Is this a fwd (root->dest) message?
1096  */
1097 void
1098 GMCH_send_data (struct MeshChannel *ch,
1099                 const struct GNUNET_MESH_Data *msg,
1100                 int fwd)
1101 {
1102 }
1103
1104
1105 /**
1106  * Send an end-to-end ACK message for the most recent in-sequence payload.
1107  *
1108  * If channel is not reliable, do nothing.
1109  *
1110  * @param ch Channel this is about.
1111  * @param fwd Is for FWD traffic? (ACK dest->owner)
1112  */
1113 void
1114 GMCH_send_ack (struct MeshChannel *ch, int fwd)
1115 {
1116   struct GNUNET_MESH_DataACK msg;
1117   struct MeshChannelReliability *rel;
1118   struct MeshReliableMessage *copy;
1119   unsigned int delta;
1120   uint64_t mask;
1121   uint16_t type;
1122
1123   if (GNUNET_NO == ch->reliable)
1124   {
1125     return;
1126   }
1127   rel = fwd ? ch->dest_rel : ch->root_rel;
1128   LOG (GNUNET_ERROR_TYPE_DEBUG,
1129               "send_data_ack for %u\n",
1130               rel->mid_recv - 1);
1131
1132   type = GNUNET_MESSAGE_TYPE_MESH_DATA_ACK;
1133   msg.header.type = htons (type);
1134   msg.header.size = htons (sizeof (msg));
1135   msg.chid = htonl (ch->gid);
1136   msg.mid = htonl (rel->mid_recv - 1);
1137   msg.futures = 0;
1138   for (copy = rel->head_recv; NULL != copy; copy = copy->next)
1139   {
1140     if (copy->type != type)
1141       continue;
1142     delta = copy->mid - rel->mid_recv;
1143     if (63 < delta)
1144       break;
1145     mask = 0x1LL << delta;
1146     msg.futures |= mask;
1147     LOG (GNUNET_ERROR_TYPE_DEBUG,
1148                 " setting bit for %u (delta %u) (%llX) -> %llX\n",
1149                 copy->mid, delta, mask, msg.futures);
1150   }
1151   LOG (GNUNET_ERROR_TYPE_DEBUG, " final futures %llX\n", msg.futures);
1152
1153   GMCH_send_prebuilt_message (&msg.header, ch, fwd);
1154   LOG (GNUNET_ERROR_TYPE_DEBUG, "send_data_ack END\n");
1155 }
1156
1157
1158 /**
1159  * Log channel info.
1160  *
1161  * @param ch Channel.
1162  */
1163 void
1164 GMCH_debug (struct MeshChannel *ch)
1165 {
1166   if (NULL == ch)
1167   {
1168     LOG (GNUNET_ERROR_TYPE_DEBUG, "*** DEBUG NULL CHANNEL ***\n");
1169     return;
1170   }
1171   LOG (GNUNET_ERROR_TYPE_DEBUG, "Channel %s:%X (%p)\n",
1172               GMT_2s (ch->t), ch->gid, ch);
1173   LOG (GNUNET_ERROR_TYPE_DEBUG, "  root %p/%p\n",
1174               ch->root, ch->root_rel);
1175   if (NULL != ch->root)
1176   {
1177     LOG (GNUNET_ERROR_TYPE_DEBUG, "  cli %s\n", GML_2s (ch->root));
1178     LOG (GNUNET_ERROR_TYPE_DEBUG, "  ready %s\n",
1179                 ch->root_rel->client_ready ? "YES" : "NO");
1180     LOG (GNUNET_ERROR_TYPE_DEBUG, "  id %X\n", ch->lid_root);
1181   }
1182   LOG (GNUNET_ERROR_TYPE_DEBUG, "  dest %p/%p\n",
1183               ch->dest, ch->dest_rel);
1184   if (NULL != ch->dest)
1185   {
1186     LOG (GNUNET_ERROR_TYPE_DEBUG, "  cli %s\n", GML_2s (ch->dest));
1187     LOG (GNUNET_ERROR_TYPE_DEBUG, "  ready %s\n",
1188                 ch->dest_rel->client_ready ? "YES" : "NO");
1189     LOG (GNUNET_ERROR_TYPE_DEBUG, "  id %X\n", ch->lid_dest);
1190   }
1191 }
1192
1193
1194 /**
1195  * Handler for mesh network payload traffic.
1196  *
1197  * @param ch Channel for the message.
1198  * @param message Unencryted data message.
1199  * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO;
1200  */
1201 void
1202 GMCH_handle_data (struct MeshChannel *ch,
1203                   const struct GNUNET_MESH_Data *msg,
1204                   int fwd)
1205 {
1206   struct MeshChannelReliability *rel;
1207   struct MeshClient *c;
1208   uint32_t mid;
1209   uint16_t type;
1210   size_t size;
1211
1212   /*  Initialize FWD/BCK data */
1213   c   = fwd ? ch->dest     : ch->root;
1214   rel = fwd ? ch->dest_rel : ch->root_rel;
1215
1216   if (NULL == c)
1217   {
1218     GNUNET_break (0);
1219     return;
1220   }
1221
1222   GNUNET_STATISTICS_update (stats, "# data received", 1, GNUNET_NO);
1223
1224   mid = ntohl (msg->mid);
1225   LOG (GNUNET_ERROR_TYPE_DEBUG, " mid %u\n", mid);
1226
1227   if (GNUNET_NO == ch->reliable ||
1228       ( !GMC_is_pid_bigger (rel->mid_recv, mid) &&
1229         GMC_is_pid_bigger (rel->mid_recv + 64, mid) ) )
1230   {
1231     LOG (GNUNET_ERROR_TYPE_DEBUG, "!!! RECV %u\n", mid);
1232     if (GNUNET_YES == ch->reliable)
1233     {
1234       /* Is this the exact next expected messasge? */
1235       if (mid == rel->mid_recv)
1236       {
1237         LOG (GNUNET_ERROR_TYPE_DEBUG, "as expected\n");
1238         rel->mid_recv++;
1239         send_client_data (ch, msg, fwd);
1240       }
1241       else
1242       {
1243         LOG (GNUNET_ERROR_TYPE_DEBUG, "save for later\n");
1244         add_buffered_data (msg, rel);
1245       }
1246     }
1247     else
1248     {
1249       /* Tunnel is unreliable: send to clients directly */
1250       /* FIXME: accept Out Of Order traffic */
1251       rel->mid_recv = mid + 1;
1252       send_client_data (ch, msg, fwd);
1253     }
1254   }
1255   else
1256   {
1257     GNUNET_break_op (0);
1258     LOG (GNUNET_ERROR_TYPE_DEBUG,
1259                 " MID %u not expected (%u - %u), dropping!\n",
1260                 mid, rel->mid_recv, rel->mid_recv + 64);
1261   }
1262
1263   GMCH_send_ack (ch, fwd);
1264 }
1265
1266
1267 /**
1268  * Handler for mesh network traffic end-to-end ACKs.
1269  *
1270  * @param t Tunnel on which we got this message.
1271  * @param message Data message.
1272  * @param fwd Is this a fwd ACK? (dest->orig)
1273  */
1274 void
1275 GMCH_handle_data_ack (struct MeshChannel *ch,
1276                       const struct GNUNET_MESH_DataACK *msg,
1277                       int fwd)
1278 {
1279   struct MeshChannelReliability *rel;
1280   struct MeshReliableMessage *copy;
1281   struct MeshReliableMessage *next;
1282   uint32_t ack;
1283   int work;
1284
1285   ack = ntohl (msg->mid);
1286   LOG (GNUNET_ERROR_TYPE_DEBUG, "!!! %s ACK %u\n",
1287               (GNUNET_YES == fwd) ? "FWD" : "BCK", ack);
1288
1289   if (GNUNET_YES == fwd)
1290   {
1291     rel = ch->root_rel;
1292   }
1293   else
1294   {
1295     rel = ch->dest_rel;
1296   }
1297   if (NULL == rel)
1298   {
1299     GNUNET_break (0);
1300     return;
1301   }
1302
1303   for (work = GNUNET_NO, copy = rel->head_sent; copy != NULL; copy = next)
1304   {
1305     if (GMC_is_pid_bigger (copy->mid, ack))
1306     {
1307       LOG (GNUNET_ERROR_TYPE_DEBUG, "!!!  head %u, out!\n", copy->mid);
1308       channel_rel_free_sent (rel, msg);
1309       break;
1310     }
1311     work = GNUNET_YES;
1312     LOG (GNUNET_ERROR_TYPE_DEBUG, "!!!  id %u\n", copy->mid);
1313     next = copy->next;
1314     rel_message_free (copy);
1315   }
1316   /* ACK client if needed */
1317 //   channel_send_ack (t, type, GNUNET_MESSAGE_TYPE_MESH_UNICAST_ACK == type);
1318
1319   /* If some message was free'd, update the retransmission delay*/
1320   if (GNUNET_YES == work)
1321   {
1322     if (GNUNET_SCHEDULER_NO_TASK != rel->retry_task)
1323     {
1324       GNUNET_SCHEDULER_cancel (rel->retry_task);
1325       if (NULL == rel->head_sent)
1326       {
1327         rel->retry_task = GNUNET_SCHEDULER_NO_TASK;
1328       }
1329       else
1330       {
1331         struct GNUNET_TIME_Absolute new_target;
1332         struct GNUNET_TIME_Relative delay;
1333
1334         delay = GNUNET_TIME_relative_multiply (rel->retry_timer,
1335                                                MESH_RETRANSMIT_MARGIN);
1336         new_target = GNUNET_TIME_absolute_add (rel->head_sent->timestamp,
1337                                                delay);
1338         delay = GNUNET_TIME_absolute_get_remaining (new_target);
1339         rel->retry_task =
1340             GNUNET_SCHEDULER_add_delayed (delay,
1341                                           &channel_retransmit_message,
1342                                           rel);
1343       }
1344     }
1345     else
1346       GNUNET_break (0);
1347   }
1348 }
1349
1350
1351 /**
1352  * Handler for channel create messages.
1353  *
1354  * @param msg Message.
1355  * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO;
1356  */
1357 struct MeshChannel *
1358 GMCH_handle_create (const struct GNUNET_MESH_ChannelCreate *msg,
1359                     int fwd)
1360 {
1361   MESH_ChannelNumber chid;
1362   struct MeshChannel *ch;
1363   struct MeshClient *c;
1364   uint32_t port;
1365
1366   chid = ntohl (msg->chid);
1367
1368   /* Create channel */
1369   ch = channel_new (NULL, NULL, 0); /* FIXME t */
1370   ch->gid = chid;
1371   channel_set_options (ch, ntohl (msg->opt));
1372
1373   /* Find a destination client */
1374   port = ntohl (msg->port);
1375   LOG (GNUNET_ERROR_TYPE_DEBUG, "   port %u\n", port);
1376   c = GML_client_get_by_port (port);
1377   if (NULL == c)
1378   {
1379     /* TODO send reject */
1380     LOG (GNUNET_ERROR_TYPE_DEBUG, "  no client has port registered\n");
1381     /* TODO free ch */
1382     return;
1383   }
1384
1385   channel_add_client (ch, c);
1386   if (GNUNET_YES == ch->reliable)
1387     LOG (GNUNET_ERROR_TYPE_DEBUG, "!!! Reliable\n");
1388
1389   GMCH_send_create (ch);
1390   GMCH_send_ack (ch, fwd);
1391   GML_send_ack (ch, !fwd);
1392
1393   return ch;
1394 }
1395
1396
1397 /**
1398  * Handler for channel ack messages.
1399  *
1400  * @param ch Channel.
1401  * @param msg Message.
1402  * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO;
1403  */
1404 void
1405 GMCH_handle_ack (struct MeshChannel *ch,
1406                  const struct GNUNET_MESH_ChannelManage *msg,
1407                  int fwd)
1408 {
1409   channel_confirm (ch, !fwd);
1410 }
1411
1412
1413 /**
1414  * Handler for channel destroy messages.
1415  *
1416  * @param ch Channel to be destroyed of.
1417  * @param msg Message.
1418  * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO;
1419  */
1420 void
1421 GMCH_handle_destroy (struct MeshChannel *ch,
1422                      const struct GNUNET_MESH_ChannelManage *msg,
1423                      int fwd)
1424 {
1425   MESH_ChannelNumber chid;
1426
1427   /* Check if channel exists */
1428   chid = ntohl (msg->chid);
1429   if ( (fwd && NULL == ch->dest) || (!fwd && NULL == ch->root) )
1430   {
1431     /* Not for us (don't destroy twice a half-open loopback channel) */
1432     return;
1433   }
1434
1435   GMCH_send_destroy (ch);
1436   channel_destroy (ch);
1437 }
1438
1439
1440 /**
1441  * Sends an already built message on a channel.
1442  *
1443  * @param message Message to send. Function makes a copy of it.
1444  * @param ch Channel on which this message is transmitted.
1445  * @param fwd Is this a fwd message?
1446  */
1447 void
1448 GMCH_send_prebuilt_message (const struct GNUNET_MessageHeader *message,
1449                             struct MeshChannel *ch, int fwd)
1450 {
1451   size_t size = ntohs (message->size);
1452
1453   LOG (GNUNET_ERROR_TYPE_DEBUG, "Send on Channel %s:%X %s\n",
1454        GMT_2s (ch->t), ch->gid, fwd ? "FWD" : "BCK");
1455   LOG (GNUNET_ERROR_TYPE_DEBUG, "  %s\n",
1456        GNUNET_MESH_DEBUG_M2S (ntohs (message->type)));
1457
1458   if (GMT_is_loopback (ch->t))
1459   {
1460     handle_loopback (ch->t, message, fwd);
1461     return;
1462   }
1463
1464   GMT_send_prebuilt_message (message, ch->t, ch, fwd);
1465 }