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