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