3 This file is part of GNUnet.
4 Copyright (C) 2001-2017 GNUnet e.V.
6 GNUnet is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published
8 by the Free Software Foundation; either version 3, or (at your
9 option) any later version.
11 GNUnet is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNUnet; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA.
22 * @file cadet/gnunet-service-cadet-new_channel.c
23 * @brief logical links between CADET clients
24 * @author Bartlomiej Polot
25 * @author Christian Grothoff
28 * - introduce shutdown so we can have half-closed channels, modify
29 * destroy to include MID to have FIN-ACK equivalents, etc.
30 * - estimate max bandwidth using bursts and use to for CONGESTION CONTROL!
31 * - check that '0xFFULL' really is sufficient for flow control!
32 * - revisit handling of 'unreliable' traffic!
33 * - revisit handling of 'out-of-order' option, especially in combination with/without 'reliable'.
34 * - figure out flow control without ACKs (unreliable traffic!)
37 #include "gnunet_util_lib.h"
39 #include "gnunet_statistics_service.h"
40 #include "gnunet-service-cadet-new.h"
41 #include "gnunet-service-cadet-new_channel.h"
42 #include "gnunet-service-cadet-new_connection.h"
43 #include "gnunet-service-cadet-new_tunnels.h"
44 #include "gnunet-service-cadet-new_peer.h"
45 #include "gnunet-service-cadet-new_paths.h"
47 #define LOG(level,...) GNUNET_log_from (level,"cadet-chn",__VA_ARGS__)
50 * How long do we initially wait before retransmitting?
52 #define CADET_INITIAL_RETRANSMIT_TIME GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 250)
55 * How long do we wait before dropping state about incoming
56 * connection to closed port?
58 #define TIMEOUT_CLOSED_PORT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 30)
62 * All the states a connection can be in.
64 enum CadetChannelState
67 * Uninitialized status, should never appear in operation.
72 * Connection create message sent, waiting for ACK.
74 CADET_CHANNEL_OPEN_SENT,
77 * Connection confirmed, ready to carry traffic.
84 * Info needed to retry a message in case it gets lost.
85 * Note that we DO use this structure also for unreliable
88 struct CadetReliableMessage
91 * Double linked list, FIFO style
93 struct CadetReliableMessage *next;
96 * Double linked list, FIFO style
98 struct CadetReliableMessage *prev;
101 * Which channel is this message in?
103 struct CadetChannel *ch;
106 * Entry in the tunnels queue for this message, NULL if it has left
107 * the tunnel. Used to cancel transmission in case we receive an
110 struct CadetTunnelQueueEntry *qe;
113 * How soon should we retry if we fail to get an ACK?
114 * Messages in the queue are sorted by this value.
116 struct GNUNET_TIME_Absolute next_retry;
119 * How long do we wait for an ACK after transmission?
120 * Use for the back-off calculation.
122 struct GNUNET_TIME_Relative retry_delay;
125 * Data message we are trying to send.
127 struct GNUNET_CADET_ChannelAppDataMessage data_message;
129 /* followed by variable-size payload */
134 * List of received out-of-order data messages.
136 struct CadetOutOfOrderMessage
139 * Double linked list, FIFO style
141 struct CadetOutOfOrderMessage *next;
144 * Double linked list, FIFO style
146 struct CadetOutOfOrderMessage *prev;
149 * ID of the message (messages up to this point needed
150 * before we give this one to the client).
152 struct ChannelMessageIdentifier mid;
155 * The envelope with the payload of the out-of-order message
157 struct GNUNET_MQ_Envelope *env;
163 * Struct containing all information regarding a channel to a remote client.
168 * Tunnel this channel is in.
170 struct CadetTunnel *t;
173 * Client owner of the tunnel, if any.
174 * (Used if this channel represends the initiating end of the tunnel.)
176 struct CadetClient *owner;
179 * Client destination of the tunnel, if any.
180 * (Used if this channel represents the listening end of the tunnel.)
182 struct CadetClient *dest;
185 * Last entry in the tunnel's queue relating to control messages
186 * (#GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN or
187 * #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK). Used to cancel
188 * transmission in case we receive updated information.
190 struct CadetTunnelQueueEntry *last_control_qe;
193 * Head of DLL of messages sent and not yet ACK'd.
195 struct CadetReliableMessage *head_sent;
198 * Tail of DLL of messages sent and not yet ACK'd.
200 struct CadetReliableMessage *tail_sent;
203 * Head of DLL of messages received out of order or while client was unready.
205 struct CadetOutOfOrderMessage *head_recv;
208 * Tail DLL of messages received out of order or while client was unready.
210 struct CadetOutOfOrderMessage *tail_recv;
213 * Task to resend/poll in case no ACK is received.
215 struct GNUNET_SCHEDULER_Task *retry_control_task;
218 * Task to resend/poll in case no ACK is received.
220 struct GNUNET_SCHEDULER_Task *retry_data_task;
223 * Last time the channel was used
225 struct GNUNET_TIME_Absolute timestamp;
228 * Destination port of the channel.
230 struct GNUNET_HashCode port;
233 * Counter for exponential backoff.
235 struct GNUNET_TIME_Relative retry_time;
238 * How long does it usually take to get an ACK.
240 struct GNUNET_TIME_Relative expected_delay;
243 * Bitfield of already-received messages past @e mid_recv.
245 uint64_t mid_futures;
248 * Next MID expected for incoming traffic.
250 struct ChannelMessageIdentifier mid_recv;
253 * Next MID to use for outgoing traffic.
255 struct ChannelMessageIdentifier mid_send;
258 * Total (reliable) messages pending ACK for this channel.
260 unsigned int pending_messages;
263 * Maximum (reliable) messages pending ACK for this channel
264 * before we throttle the client.
266 unsigned int max_pending_messages;
269 * Number identifying this channel in its tunnel.
271 struct GNUNET_CADET_ChannelTunnelNumber ctn;
274 * Local tunnel number for local client owning the channel.
275 * ( >= #GNUNET_CADET_LOCAL_CHANNEL_ID_CLI or 0 )
277 struct GNUNET_CADET_ClientChannelNumber ccn;
282 enum CadetChannelState state;
285 * Can we send data to the client?
290 * Can the client send data to us?
295 * Is the tunnel bufferless (minimum latency)?
300 * Is the tunnel reliable?
305 * Is the tunnel out-of-order?
310 * Flag to signal the destruction of the channel. If this is set to
311 * #GNUNET_YES the channel will be destroyed once the queue is
320 * Get the static string for identification of the channel.
324 * @return Static string with the channel IDs.
327 GCCH_2s (const struct CadetChannel *ch)
329 static char buf[128];
331 GNUNET_snprintf (buf,
333 "Channel %s:%s ctn:%X(%X)",
334 GNUNET_i2s (GCP_get_id (GCT_get_destination (ch->t))),
335 GNUNET_h2s (&ch->port),
337 ntohl (ch->ccn.channel_of_client));
343 * Get the channel's public ID.
347 * @return ID used to identify the channel with the remote peer.
349 struct GNUNET_CADET_ChannelTunnelNumber
350 GCCH_get_id (const struct CadetChannel *ch)
357 * Destroy the given channel.
359 * @param ch channel to destroy
362 channel_destroy (struct CadetChannel *ch)
364 struct CadetReliableMessage *crm;
365 struct CadetOutOfOrderMessage *com;
367 while (NULL != (crm = ch->head_sent))
369 GNUNET_assert (ch == crm->ch);
372 GCT_send_cancel (crm->qe);
375 GNUNET_CONTAINER_DLL_remove (ch->head_sent,
380 while (NULL != (com = ch->head_recv))
382 GNUNET_CONTAINER_DLL_remove (ch->head_recv,
385 GNUNET_MQ_discard (com->env);
388 if (NULL != ch->last_control_qe)
390 GCT_send_cancel (ch->last_control_qe);
391 ch->last_control_qe = NULL;
393 if (NULL != ch->retry_data_task)
395 GNUNET_SCHEDULER_cancel (ch->retry_data_task);
396 ch->retry_data_task = NULL;
398 if (NULL != ch->retry_control_task)
400 GNUNET_SCHEDULER_cancel (ch->retry_control_task);
401 ch->retry_control_task = NULL;
403 GCT_remove_channel (ch->t,
411 * Send a channel create message.
413 * @param cls Channel for which to send.
416 send_channel_open (void *cls);
420 * Function called once the tunnel confirms that we sent the
421 * create message. Delays for a bit until we retry.
423 * @param cls our `struct CadetChannel`.
426 channel_open_sent_cb (void *cls)
428 struct CadetChannel *ch = cls;
430 GNUNET_assert (NULL != ch->last_control_qe);
431 ch->last_control_qe = NULL;
432 ch->retry_time = GNUNET_TIME_STD_BACKOFF (ch->retry_time);
433 ch->retry_control_task
434 = GNUNET_SCHEDULER_add_delayed (ch->retry_time,
441 * Send a channel open message.
443 * @param cls Channel for which to send.
446 send_channel_open (void *cls)
448 struct CadetChannel *ch = cls;
449 struct GNUNET_CADET_ChannelOpenMessage msgcc;
452 ch->retry_control_task = NULL;
453 LOG (GNUNET_ERROR_TYPE_DEBUG,
454 "Sending CHANNEL_OPEN message for %s\n",
458 options |= GNUNET_CADET_OPTION_NOBUFFER;
460 options |= GNUNET_CADET_OPTION_RELIABLE;
461 if (ch->out_of_order)
462 options |= GNUNET_CADET_OPTION_OUT_OF_ORDER;
463 msgcc.header.size = htons (sizeof (msgcc));
464 msgcc.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN);
465 msgcc.opt = htonl (options);
466 msgcc.port = ch->port;
468 ch->state = CADET_CHANNEL_OPEN_SENT;
469 ch->last_control_qe = GCT_send (ch->t,
471 &channel_open_sent_cb,
477 * Function called once and only once after a channel was bound
478 * to its tunnel via #GCT_add_channel() is ready for transmission.
479 * Note that this is only the case for channels that this peer
480 * initiates, as for incoming channels we assume that they are
481 * ready for transmission immediately upon receiving the open
482 * message. Used to bootstrap the #GCT_send() process.
484 * @param ch the channel for which the tunnel is now ready
487 GCCH_tunnel_up (struct CadetChannel *ch)
489 GNUNET_assert (NULL == ch->retry_control_task);
490 ch->retry_control_task
491 = GNUNET_SCHEDULER_add_now (&send_channel_open,
497 * Create a new channel.
499 * @param owner local client owning the channel
500 * @param ccn local number of this channel at the @a owner
501 * @param destination peer to which we should build the channel
502 * @param port desired port at @a destination
503 * @param options options for the channel
504 * @return handle to the new channel
506 struct CadetChannel *
507 GCCH_channel_local_new (struct CadetClient *owner,
508 struct GNUNET_CADET_ClientChannelNumber ccn,
509 struct CadetPeer *destination,
510 const struct GNUNET_HashCode *port,
513 struct CadetChannel *ch;
515 ch = GNUNET_new (struct CadetChannel);
516 ch->nobuffer = (0 != (options & GNUNET_CADET_OPTION_NOBUFFER));
517 ch->reliable = (0 != (options & GNUNET_CADET_OPTION_RELIABLE));
518 ch->out_of_order = (0 != (options & GNUNET_CADET_OPTION_OUT_OF_ORDER));
519 ch->max_pending_messages = (ch->nobuffer) ? 1 : 32; /* FIXME: 32!? Do not hardcode! */
523 ch->t = GCP_get_tunnel (destination,
525 ch->retry_time = CADET_INITIAL_RETRANSMIT_TIME;
526 ch->ctn = GCT_add_channel (ch->t,
528 GNUNET_STATISTICS_update (stats,
532 LOG (GNUNET_ERROR_TYPE_DEBUG,
533 "Created channel to port %s at peer %s for %s using %s\n",
535 GCP_2s (destination),
543 * We had an incoming channel to a port that is closed.
544 * It has not been opened for a while, drop it.
546 * @param cls the channel to drop
549 timeout_closed_cb (void *cls)
551 struct CadetChannel *ch = cls;
553 ch->retry_control_task = NULL;
554 LOG (GNUNET_ERROR_TYPE_DEBUG,
555 "Closing incoming channel to port %s from peer %s due to timeout\n",
556 GNUNET_h2s (&ch->port),
557 GCP_2s (GCT_get_destination (ch->t)));
558 channel_destroy (ch);
563 * Create a new channel based on a request coming in over the network.
565 * @param t tunnel to the remote peer
566 * @param ctn identifier of this channel in the tunnel
567 * @param port desired local port
568 * @param options options for the channel
569 * @return handle to the new channel
571 struct CadetChannel *
572 GCCH_channel_incoming_new (struct CadetTunnel *t,
573 struct GNUNET_CADET_ChannelTunnelNumber ctn,
574 const struct GNUNET_HashCode *port,
577 struct CadetChannel *ch;
578 struct CadetClient *c;
580 ch = GNUNET_new (struct CadetChannel);
584 ch->retry_time = CADET_INITIAL_RETRANSMIT_TIME;
585 ch->nobuffer = (0 != (options & GNUNET_CADET_OPTION_NOBUFFER));
586 ch->reliable = (0 != (options & GNUNET_CADET_OPTION_RELIABLE));
587 ch->out_of_order = (0 != (options & GNUNET_CADET_OPTION_OUT_OF_ORDER));
588 ch->max_pending_messages = (ch->nobuffer) ? 1 : 32; /* FIXME: 32!? Do not hardcode! */
589 GNUNET_STATISTICS_update (stats,
594 c = GNUNET_CONTAINER_multihashmap_get (open_ports,
598 /* port closed, wait for it to possibly open */
599 (void) GNUNET_CONTAINER_multihashmap_put (loose_channels,
602 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
603 ch->retry_control_task
604 = GNUNET_SCHEDULER_add_delayed (TIMEOUT_CLOSED_PORT,
607 LOG (GNUNET_ERROR_TYPE_DEBUG,
608 "Created loose incoming channel to port %s from peer %s\n",
609 GNUNET_h2s (&ch->port),
610 GCP_2s (GCT_get_destination (ch->t)));
617 GNUNET_STATISTICS_update (stats,
626 * Function called once the tunnel confirms that we sent the
627 * ACK message. Just remembers it was sent, we do not expect
630 * @param cls our `struct CadetChannel`.
633 send_ack_cb (void *cls)
635 struct CadetChannel *ch = cls;
637 GNUNET_assert (NULL != ch->last_control_qe);
638 ch->last_control_qe = NULL;
643 * Compute and send the current ACK to the other peer.
645 * @param ch channel to send the ACK for
648 send_channel_data_ack (struct CadetChannel *ch)
650 struct GNUNET_CADET_ChannelDataAckMessage msg;
652 msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK);
653 msg.header.size = htons (sizeof (msg));
655 msg.mid.mid = htonl (ntohl (ch->mid_recv.mid) - 1);
656 msg.futures = GNUNET_htonll (ch->mid_futures);
657 if (NULL != ch->last_control_qe)
658 GCT_send_cancel (ch->last_control_qe);
659 ch->last_control_qe = GCT_send (ch->t,
667 * Send our initial ACK to the client confirming that the
670 * @param cls the `struct CadetChannel`
673 send_open_ack (void *cls)
675 struct CadetChannel *ch = cls;
676 struct GNUNET_CADET_ChannelManageMessage msg;
678 LOG (GNUNET_ERROR_TYPE_DEBUG,
679 "Sending CHANNEL_OPEN_ACK on channel %s\n",
681 ch->retry_control_task = NULL;
682 msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK);
683 msg.header.size = htons (sizeof (msg));
684 msg.reserved = htonl (0);
686 if (NULL != ch->last_control_qe)
687 GCT_send_cancel (ch->last_control_qe);
688 ch->last_control_qe = GCT_send (ch->t,
696 * We got a #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN message again for
697 * this channel. If the binding was successful, (re)transmit the
698 * #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK.
700 * @param ch channel that got the duplicate open
703 GCCH_handle_duplicate_open (struct CadetChannel *ch)
705 if (NULL == ch->dest)
707 LOG (GNUNET_ERROR_TYPE_DEBUG,
708 "Ignoring duplicate channel OPEN on %s: port is closed\n",
712 if (NULL != ch->retry_control_task)
714 LOG (GNUNET_ERROR_TYPE_DEBUG,
715 "Ignoring duplicate channel OPEN on %s: control message is pending\n",
719 ch->retry_control_task
720 = GNUNET_SCHEDULER_add_now (&send_open_ack,
726 * Send a LOCAL ACK to the client to solicit more messages.
728 * @param ch channel the ack is for
729 * @param c client to send the ACK to
732 send_ack_to_client (struct CadetChannel *ch,
733 struct CadetClient *c)
735 struct GNUNET_MQ_Envelope *env;
736 struct GNUNET_CADET_LocalAck *ack;
738 env = GNUNET_MQ_msg (ack,
739 GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK);
741 GSC_send_to_client (c,
747 * A client is bound to the port that we have a channel
748 * open to. Send the acknowledgement for the connection
749 * request and establish the link with the client.
751 * @param ch open incoming channel
752 * @param c client listening on the respective port
755 GCCH_bind (struct CadetChannel *ch,
756 struct CadetClient *c)
758 struct GNUNET_MQ_Envelope *env;
759 struct GNUNET_CADET_LocalChannelCreateMessage *tcm;
762 LOG (GNUNET_ERROR_TYPE_DEBUG,
763 "Binding %s from %s to port %s of %s\n",
766 GNUNET_h2s (&ch->port),
768 if (NULL != ch->retry_control_task)
770 /* there might be a timeout task here */
771 GNUNET_SCHEDULER_cancel (ch->retry_control_task);
772 ch->retry_control_task = NULL;
776 options |= GNUNET_CADET_OPTION_NOBUFFER;
778 options |= GNUNET_CADET_OPTION_RELIABLE;
779 if (ch->out_of_order)
780 options |= GNUNET_CADET_OPTION_OUT_OF_ORDER;
782 ch->ccn = GSC_bind (c,
784 GCT_get_destination (ch->t),
787 ch->mid_recv.mid = htonl (1); /* The CONNECT counts as message 0! */
789 /* notify other peer that we accepted the connection */
790 ch->retry_control_task
791 = GNUNET_SCHEDULER_add_now (&send_open_ack,
793 /* give client it's initial supply of ACKs */
794 env = GNUNET_MQ_msg (tcm,
795 GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_CREATE);
797 tcm->peer = *GCP_get_id (GCT_get_destination (ch->t));
798 tcm->port = ch->port;
799 tcm->opt = htonl (options);
800 GSC_send_to_client (ch->dest,
802 for (unsigned int i=0;i<ch->max_pending_messages;i++)
803 send_ack_to_client (ch,
809 * Destroy locally created channel. Called by the
810 * local client, so no need to tell the client.
812 * @param ch channel to destroy
815 GCCH_channel_local_destroy (struct CadetChannel *ch)
817 if (GNUNET_YES == ch->destroy)
819 /* other end already destroyed, with the local client gone, no need
820 to finish transmissions, just destroy immediately. */
821 channel_destroy (ch);
824 if (NULL != ch->head_sent)
826 /* allow send queue to train first */
827 ch->destroy = GNUNET_YES;
830 /* If the we ever sent the CHANNEL_CREATE, we need to send a destroy message. */
831 if (CADET_CHANNEL_NEW != ch->state)
832 GCT_send_channel_destroy (ch->t,
834 /* Now finish our clean up */
835 channel_destroy (ch);
840 * Destroy channel that was incoming. Called by the
841 * local client, so no need to tell the client.
843 * @param ch channel to destroy
846 GCCH_channel_incoming_destroy (struct CadetChannel *ch)
848 if (GNUNET_YES == ch->destroy)
850 /* other end already destroyed, with the remote client gone, no need
851 to finish transmissions, just destroy immediately. */
852 channel_destroy (ch);
855 if (NULL != ch->head_recv)
857 /* allow local client to see all data first */
858 ch->destroy = GNUNET_YES;
861 /* Nothing left to do, just finish destruction */
862 GCT_send_channel_destroy (ch->t,
864 channel_destroy (ch);
869 * We got an acknowledgement for the creation of the channel
870 * (the port is open on the other side). Begin transmissions.
872 * @param ch channel to destroy
875 GCCH_handle_channel_open_ack (struct CadetChannel *ch)
879 case CADET_CHANNEL_NEW:
880 /* this should be impossible */
883 case CADET_CHANNEL_OPEN_SENT:
884 if (NULL == ch->owner)
886 /* We're not the owner, wrong direction! */
890 LOG (GNUNET_ERROR_TYPE_DEBUG,
891 "Received channel OPEN_ACK for waiting %s, entering READY state\n",
893 GNUNET_SCHEDULER_cancel (ch->retry_control_task);
894 ch->retry_control_task = NULL;
895 ch->state = CADET_CHANNEL_READY;
896 /* On first connect, send client as many ACKs as we allow messages
898 for (unsigned int i=0;i<ch->max_pending_messages;i++)
899 send_ack_to_client (ch,
902 case CADET_CHANNEL_READY:
903 /* duplicate ACK, maybe we retried the CREATE. Ignore. */
904 LOG (GNUNET_ERROR_TYPE_DEBUG,
905 "Received duplicate channel OPEN_ACK for %s\n",
907 GNUNET_STATISTICS_update (stats,
908 "# duplicate CREATE_ACKs",
917 * Test if element @a e1 comes before element @a e2.
919 * TODO: use opportunity to create generic list insertion sort
920 * logic in container!
922 * @param cls closure, our `struct CadetChannel`
923 * @param e1 an element of to sort
924 * @param e2 another element to sort
925 * @return #GNUNET_YES if @e1 < @e2, otherwise #GNUNET_NO
928 is_before (void *cls,
932 struct CadetOutOfOrderMessage *m1 = e1;
933 struct CadetOutOfOrderMessage *m2 = e2;
934 uint32_t v1 = ntohl (m1->mid.mid);
935 uint32_t v2 = ntohl (m2->mid.mid);
939 if (delta > (uint32_t) INT_MAX)
941 /* in overflow range, we can safely assume we wrapped around */
952 * We got payload data for a channel. Pass it on to the client
953 * and send an ACK to the other end (once flow control allows it!)
955 * @param ch channel that got data
958 GCCH_handle_channel_plaintext_data (struct CadetChannel *ch,
959 const struct GNUNET_CADET_ChannelAppDataMessage *msg)
961 struct GNUNET_MQ_Envelope *env;
962 struct GNUNET_CADET_LocalData *ld;
963 struct CadetOutOfOrderMessage *com;
966 payload_size = ntohs (msg->header.size) - sizeof (*msg);
967 LOG (GNUNET_ERROR_TYPE_DEBUG,
968 "Receicved %u bytes of application data on %s\n",
969 (unsigned int) payload_size,
971 env = GNUNET_MQ_msg_extra (ld,
973 GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA);
975 GNUNET_memcpy (&ld[1],
978 if ( (GNUNET_YES == ch->client_ready) &&
979 ( (GNUNET_YES == ch->out_of_order) ||
980 (msg->mid.mid == ch->mid_recv.mid) ) )
982 GSC_send_to_client (ch->owner ? ch->owner : ch->dest,
984 ch->mid_recv.mid = htonl (1 + ntohl (ch->mid_recv.mid));
985 ch->mid_futures >>= 1;
989 /* FIXME-SECURITY: if the element is WAY too far ahead,
990 drop it (can't buffer too much!) */
991 com = GNUNET_new (struct CadetOutOfOrderMessage);
994 /* sort into list ordered by "is_before" */
995 if ( (NULL == ch->head_recv) ||
996 (GNUNET_YES == is_before (ch,
1000 GNUNET_CONTAINER_DLL_insert (ch->head_recv,
1006 struct CadetOutOfOrderMessage *pos;
1008 for (pos = ch->head_recv;
1019 GNUNET_CONTAINER_DLL_insert_tail (ch->head_recv,
1023 GNUNET_CONTAINER_DLL_insert_after (ch->head_recv,
1033 * We got an acknowledgement for payload data for a channel.
1034 * Possibly resume transmissions.
1036 * @param ch channel that got the ack
1037 * @param ack details about what was received
1040 GCCH_handle_channel_plaintext_data_ack (struct CadetChannel *ch,
1041 const struct GNUNET_CADET_ChannelDataAckMessage *ack)
1043 struct CadetReliableMessage *crm;
1045 if (GNUNET_NO == ch->reliable)
1047 /* not expecting ACKs on unreliable channel, odd */
1048 GNUNET_break_op (0);
1051 for (crm = ch->head_sent;
1054 if (ack->mid.mid == crm->data_message.mid.mid)
1058 /* ACK for message we already dropped, might have been a
1059 duplicate ACK? Ignore. */
1060 GNUNET_STATISTICS_update (stats,
1061 "# duplicate DATA_ACKs",
1066 GNUNET_CONTAINER_DLL_remove (ch->head_sent,
1069 ch->pending_messages--;
1071 GNUNET_assert (ch->pending_messages < ch->max_pending_messages);
1072 send_ack_to_client (ch,
1073 (NULL == ch->owner) ? ch->dest : ch->owner);
1078 * Destroy channel, based on the other peer closing the
1079 * connection. Also needs to remove this channel from
1082 * @param ch channel to destroy
1085 GCCH_handle_remote_destroy (struct CadetChannel *ch)
1087 LOG (GNUNET_ERROR_TYPE_DEBUG,
1088 "Received remote channel DESTROY for %s\n",
1090 ch->destroy = GNUNET_YES;
1091 GSC_handle_remote_channel_destroy ((NULL != ch->owner) ? ch->owner : ch->dest,
1094 channel_destroy (ch);
1099 * Function called once the tunnel has sent one of our messages.
1100 * If the message is unreliable, simply frees the `crm`. If the
1101 * message was reliable, calculate retransmission time and
1102 * wait for ACK (or retransmit).
1104 * @param cls the `struct CadetReliableMessage` that was sent
1107 data_sent_cb (void *cls);
1111 * We need to retry a transmission, the last one took too long to
1114 * @param cls the `struct CadetChannel` where we need to retransmit
1117 retry_transmission (void *cls)
1119 struct CadetChannel *ch = cls;
1120 struct CadetReliableMessage *crm = ch->head_sent;
1122 ch->retry_data_task = NULL;
1123 GNUNET_assert (NULL == crm->qe);
1124 crm->qe = GCT_send (ch->t,
1125 &crm->data_message.header,
1132 * Check if we can now allow the client to transmit, and if so,
1133 * let the client know about it.
1135 * @param ch channel to check
1138 GCCH_check_allow_client (struct CadetChannel *ch)
1140 struct GNUNET_MQ_Envelope *env;
1141 struct GNUNET_CADET_LocalAck *msg;
1143 if (GNUNET_YES == ch->client_allowed)
1144 return; /* client already allowed! */
1145 if (CADET_CHANNEL_READY != ch->state)
1147 /* destination did not yet ACK our CREATE! */
1148 LOG (GNUNET_ERROR_TYPE_DEBUG,
1149 "%s not yet ready, throttling client until ACK.\n",
1153 if (ch->pending_messages > ch->max_pending_messages)
1155 /* Too many messages in queue. */
1156 LOG (GNUNET_ERROR_TYPE_DEBUG,
1157 "Message queue still too long on %s, throttling client until ACK.\n",
1161 if ( (NULL != ch->head_sent) &&
1162 (64 <= ntohl (ch->mid_send.mid) - ntohl (ch->head_sent->data_message.mid.mid)) )
1164 LOG (GNUNET_ERROR_TYPE_DEBUG,
1165 "Gap in ACKs too big on %s, throttling client until ACK.\n",
1169 ch->client_allowed = GNUNET_YES;
1172 LOG (GNUNET_ERROR_TYPE_DEBUG,
1173 "Sending local ack to %s client\n",
1175 env = GNUNET_MQ_msg (msg,
1176 GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK);
1178 GSC_send_to_client (ch->owner ? ch->owner : ch->dest,
1184 * Function called once the tunnel has sent one of our messages.
1185 * If the message is unreliable, simply frees the `crm`. If the
1186 * message was reliable, calculate retransmission time and
1187 * wait for ACK (or retransmit).
1189 * @param cls the `struct CadetReliableMessage` that was sent
1192 data_sent_cb (void *cls)
1194 struct CadetReliableMessage *crm = cls;
1195 struct CadetChannel *ch = crm->ch;
1196 struct CadetReliableMessage *off;
1199 GNUNET_CONTAINER_DLL_remove (ch->head_sent,
1202 if (GNUNET_NO == ch->reliable)
1205 ch->pending_messages--;
1206 GCCH_check_allow_client (ch);
1209 if (0 == crm->retry_delay.rel_value_us)
1210 crm->retry_delay = ch->expected_delay;
1211 crm->next_retry = GNUNET_TIME_relative_to_absolute (crm->retry_delay);
1213 /* find position for re-insertion into the DLL */
1214 if ( (NULL == ch->head_sent) ||
1215 (crm->next_retry.abs_value_us < ch->head_sent->next_retry.abs_value_us) )
1217 /* insert at HEAD, also (re)schedule retry task! */
1218 GNUNET_CONTAINER_DLL_insert (ch->head_sent,
1221 if (NULL != ch->retry_data_task)
1222 GNUNET_SCHEDULER_cancel (ch->retry_data_task);
1224 = GNUNET_SCHEDULER_add_delayed (crm->retry_delay,
1225 &retry_transmission,
1229 for (off = ch->head_sent; NULL != off; off = off->next)
1230 if (crm->next_retry.abs_value_us < off->next_retry.abs_value_us)
1234 /* insert at tail */
1235 GNUNET_CONTAINER_DLL_insert_tail (ch->head_sent,
1241 /* insert before off */
1242 GNUNET_CONTAINER_DLL_insert_after (ch->head_sent,
1251 * Handle data given by a client.
1253 * Check whether the client is allowed to send in this tunnel, save if
1254 * channel is reliable and send an ACK to the client if there is still
1255 * buffer space in the tunnel.
1257 * @param ch Channel.
1258 * @param message payload to transmit.
1259 * @return #GNUNET_OK if everything goes well,
1260 * #GNUNET_SYSERR in case of an error.
1263 GCCH_handle_local_data (struct CadetChannel *ch,
1264 const struct GNUNET_MessageHeader *message)
1266 uint16_t payload_size = ntohs (message->size);
1267 struct CadetReliableMessage *crm;
1269 if (GNUNET_NO == ch->client_allowed)
1271 GNUNET_break_op (0);
1272 return GNUNET_SYSERR;
1274 ch->client_allowed = GNUNET_NO;
1275 ch->pending_messages++;
1277 /* Everything is correct, send the message. */
1278 crm = GNUNET_malloc (sizeof (*crm) + payload_size);
1280 crm->data_message.header.size = htons (sizeof (struct GNUNET_CADET_ChannelAppDataMessage) + payload_size);
1281 crm->data_message.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA);
1282 ch->mid_send.mid = htonl (ntohl (ch->mid_send.mid) + 1);
1283 crm->data_message.mid = ch->mid_send;
1284 crm->data_message.ctn = ch->ctn;
1285 GNUNET_memcpy (&crm[1],
1288 GNUNET_CONTAINER_DLL_insert (ch->head_sent,
1291 LOG (GNUNET_ERROR_TYPE_DEBUG,
1292 "Sending %u bytes from local client to %s\n",
1295 crm->qe = GCT_send (ch->t,
1296 &crm->data_message.header,
1299 GCCH_check_allow_client (ch);
1305 * Try to deliver messages to the local client, if it is ready for more.
1307 * @param ch channel to process
1310 send_client_buffered_data (struct CadetChannel *ch)
1312 struct CadetOutOfOrderMessage *com;
1314 if (GNUNET_NO == ch->client_ready)
1315 return; /* client not ready */
1316 com = ch->head_recv;
1318 return; /* none pending */
1319 if ( (com->mid.mid != ch->mid_recv.mid) &&
1320 (GNUNET_NO == ch->out_of_order) )
1321 return; /* missing next one in-order */
1323 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1324 "Passing payload message to client on %s\n",
1327 /* all good, pass next message to client */
1328 GNUNET_CONTAINER_DLL_remove (ch->head_recv,
1331 /* FIXME: if unreliable, this is not aggressive
1332 enough, as it would be OK to have lost some! */
1333 ch->mid_recv.mid = htonl (1 + ntohl (com->mid.mid));
1334 ch->mid_futures >>= 1; /* equivalent to division by 2 */
1335 GSC_send_to_client (ch->owner ? ch->owner : ch->dest,
1338 if ( (0xFFULL == (ch->mid_futures & 0xFFULL)) &&
1339 (GNUNET_YES == ch->reliable) )
1341 /* The next 15 messages were also already received (0xFF), this
1342 suggests that the sender may be blocked on flow control
1343 urgently waiting for an ACK from us. (As we have an inherent
1344 maximum of 64 bits, and 15 is getting too close for comfort.)
1345 So we should send one now. */
1346 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1347 "Sender on %s likely blocked on flow-control, sending ACK now.\n",
1349 if (GNUNET_YES == ch->reliable)
1350 send_channel_data_ack (ch);
1353 if (NULL != ch->head_recv)
1355 if (GNUNET_NO == ch->destroy)
1357 GCT_send_channel_destroy (ch->t,
1359 channel_destroy (ch);
1364 * Handle ACK from client on local channel.
1366 * @param ch channel to destroy
1369 GCCH_handle_local_ack (struct CadetChannel *ch)
1371 ch->client_ready = GNUNET_YES;
1372 send_client_buffered_data (ch);
1376 #define LOG2(level, ...) GNUNET_log_from_nocheck(level,"cadet-chn",__VA_ARGS__)
1382 * @param ch Channel.
1383 * @param level Debug level to use.
1386 GCCH_debug (struct CadetChannel *ch,
1387 enum GNUNET_ErrorType level)
1391 do_log = GNUNET_get_log_call_status (level & (~GNUNET_ERROR_TYPE_BULK),
1393 __FILE__, __FUNCTION__, __LINE__);
1399 LOG2 (level, "CHN *** DEBUG NULL CHANNEL ***\n");
1407 if (NULL != ch->owner)
1410 "CHN origin %s ready %s local-id: %u\n",
1412 ch->client_ready ? "YES" : "NO",
1413 ntohl (ch->ccn.channel_of_client));
1415 if (NULL != ch->dest)
1418 "CHN destination %s ready %s local-id: %u\n",
1420 ch->client_ready ? "YES" : "NO",
1421 ntohl (ch->ccn.channel_of_client));
1424 "CHN Message IDs recv: %d (%LLX), send: %d\n",
1425 ntohl (ch->mid_recv.mid),
1426 (unsigned long long) ch->mid_futures,
1427 ntohl (ch->mid_send.mid));
1432 /* end of gnunet-service-cadet-new_channel.c */