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_CREATE_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 * Last entry in the tunnel's queue relating to control messages
174 * (#GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN or
175 * #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK). Used to cancel
176 * transmission in case we receive updated information.
178 struct CadetTunnelQueueEntry *last_control_qe;
181 * Client owner of the tunnel, if any.
182 * (Used if this channel represends the initiating end of the tunnel.)
184 struct CadetClient *owner;
187 * Client destination of the tunnel, if any.
188 * (Used if this channel represents the listening end of the tunnel.)
190 struct CadetClient *dest;
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_task;
218 * Last time the channel was used
220 struct GNUNET_TIME_Absolute timestamp;
223 * Destination port of the channel.
225 struct GNUNET_HashCode port;
228 * Counter for exponential backoff.
230 struct GNUNET_TIME_Relative retry_time;
233 * How long does it usually take to get an ACK.
235 struct GNUNET_TIME_Relative expected_delay;
238 * Bitfield of already-received messages past @e mid_recv.
240 uint64_t mid_futures;
243 * Next MID expected for incoming traffic.
245 struct ChannelMessageIdentifier mid_recv;
248 * Next MID to use for outgoing traffic.
250 struct ChannelMessageIdentifier mid_send;
253 * Total (reliable) messages pending ACK for this channel.
255 unsigned int pending_messages;
258 * Maximum (reliable) messages pending ACK for this channel
259 * before we throttle the client.
261 unsigned int max_pending_messages;
264 * Number identifying this channel in its tunnel.
266 struct GNUNET_CADET_ChannelTunnelNumber ctn;
269 * Local tunnel number for local client owning the channel.
270 * ( >= #GNUNET_CADET_LOCAL_CHANNEL_ID_CLI or 0 )
272 struct GNUNET_CADET_ClientChannelNumber ccn;
277 enum CadetChannelState state;
280 * Can we send data to the client?
285 * Can the client send data to us?
290 * Is the tunnel bufferless (minimum latency)?
295 * Is the tunnel reliable?
300 * Is the tunnel out-of-order?
305 * Flag to signal the destruction of the channel. If this is set to
306 * #GNUNET_YES the channel will be destroyed once the queue is
315 * Get the static string for identification of the channel.
319 * @return Static string with the channel IDs.
322 GCCH_2s (const struct CadetChannel *ch)
324 static char buf[128];
327 return "(NULL Channel)";
328 GNUNET_snprintf (buf,
332 GNUNET_h2s (&ch->port),
334 ntohl (ch->ccn.channel_of_client));
340 * Get the channel's public ID.
344 * @return ID used to identify the channel with the remote peer.
346 struct GNUNET_CADET_ChannelTunnelNumber
347 GCCH_get_id (const struct CadetChannel *ch)
354 * Destroy the given channel.
356 * @param ch channel to destroy
359 channel_destroy (struct CadetChannel *ch)
361 struct CadetReliableMessage *crm;
362 struct CadetOutOfOrderMessage *com;
364 while (NULL != (crm = ch->head_sent))
366 GNUNET_assert (ch == crm->ch);
369 GCT_send_cancel (crm->qe);
372 GNUNET_CONTAINER_DLL_remove (ch->head_sent,
377 while (NULL != (com = ch->head_recv))
379 GNUNET_CONTAINER_DLL_remove (ch->head_recv,
382 GNUNET_MQ_discard (com->env);
385 if (NULL != ch->last_control_qe)
387 GCT_send_cancel (ch->last_control_qe);
388 ch->last_control_qe = NULL;
390 if (NULL != ch->retry_task)
392 GNUNET_SCHEDULER_cancel (ch->retry_task);
393 ch->retry_task = NULL;
395 GCT_remove_channel (ch->t,
403 * Send a channel create message.
405 * @param cls Channel for which to send.
408 send_channel_open (void *cls);
412 * Function called once the tunnel confirms that we sent the
413 * create message. Delays for a bit until we retry.
415 * @param cls our `struct CadetChannel`.
418 channel_open_sent_cb (void *cls)
420 struct CadetChannel *ch = cls;
422 ch->last_control_qe = NULL;
423 ch->retry_time = GNUNET_TIME_STD_BACKOFF (ch->retry_time);
424 ch->retry_task = GNUNET_SCHEDULER_add_delayed (ch->retry_time,
431 * Send a channel open message.
433 * @param cls Channel for which to send.
436 send_channel_open (void *cls)
438 struct CadetChannel *ch = cls;
439 struct GNUNET_CADET_ChannelOpenMessage msgcc;
442 ch->retry_task = NULL;
443 LOG (GNUNET_ERROR_TYPE_DEBUG,
444 "Sending CHANNEL_OPEN message for channel %s\n",
448 options |= GNUNET_CADET_OPTION_NOBUFFER;
450 options |= GNUNET_CADET_OPTION_RELIABLE;
451 if (ch->out_of_order)
452 options |= GNUNET_CADET_OPTION_OUT_OF_ORDER;
453 msgcc.header.size = htons (sizeof (msgcc));
454 msgcc.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN);
455 msgcc.opt = htonl (options);
456 msgcc.port = ch->port;
458 ch->state = CADET_CHANNEL_CREATE_SENT;
459 ch->last_control_qe = GCT_send (ch->t,
461 &channel_open_sent_cb,
467 * Function called once and only once after a channel was bound
468 * to its tunnel via #GCT_add_channel() is ready for transmission.
469 * Note that this is only the case for channels that this peer
470 * initiates, as for incoming channels we assume that they are
471 * ready for transmission immediately upon receiving the open
472 * message. Used to bootstrap the #GCT_send() process.
474 * @param ch the channel for which the tunnel is now ready
477 GCCH_tunnel_up (struct CadetChannel *ch)
479 GNUNET_assert (NULL == ch->retry_task);
480 ch->retry_task = GNUNET_SCHEDULER_add_now (&send_channel_open,
486 * Create a new channel.
488 * @param owner local client owning the channel
489 * @param ccn local number of this channel at the @a owner
490 * @param destination peer to which we should build the channel
491 * @param port desired port at @a destination
492 * @param options options for the channel
493 * @return handle to the new channel
495 struct CadetChannel *
496 GCCH_channel_local_new (struct CadetClient *owner,
497 struct GNUNET_CADET_ClientChannelNumber ccn,
498 struct CadetPeer *destination,
499 const struct GNUNET_HashCode *port,
502 struct CadetChannel *ch;
504 ch = GNUNET_new (struct CadetChannel);
505 ch->nobuffer = (0 != (options & GNUNET_CADET_OPTION_NOBUFFER));
506 ch->reliable = (0 != (options & GNUNET_CADET_OPTION_RELIABLE));
507 ch->out_of_order = (0 != (options & GNUNET_CADET_OPTION_OUT_OF_ORDER));
508 ch->max_pending_messages = (ch->nobuffer) ? 1 : 32; /* FIXME: 32!? Do not hardcode! */
512 ch->t = GCP_get_tunnel (destination,
514 ch->retry_time = CADET_INITIAL_RETRANSMIT_TIME;
515 ch->ctn = GCT_add_channel (ch->t,
517 GNUNET_STATISTICS_update (stats,
521 LOG (GNUNET_ERROR_TYPE_DEBUG,
522 "Created channel to port %s at peer %s for client %s using tunnel %s\n",
524 GCP_2s (destination),
532 * We had an incoming channel to a port that is closed.
533 * It has not been opened for a while, drop it.
535 * @param cls the channel to drop
538 timeout_closed_cb (void *cls)
540 struct CadetChannel *ch = cls;
542 ch->retry_task = NULL;
543 LOG (GNUNET_ERROR_TYPE_DEBUG,
544 "Closing incoming channel to port %s from peer %s due to timeout\n",
545 GNUNET_h2s (&ch->port),
546 GCP_2s (GCT_get_destination (ch->t)));
547 channel_destroy (ch);
552 * Create a new channel based on a request coming in over the network.
554 * @param t tunnel to the remote peer
555 * @param ctn identifier of this channel in the tunnel
556 * @param port desired local port
557 * @param options options for the channel
558 * @return handle to the new channel
560 struct CadetChannel *
561 GCCH_channel_incoming_new (struct CadetTunnel *t,
562 struct GNUNET_CADET_ChannelTunnelNumber ctn,
563 const struct GNUNET_HashCode *port,
566 struct CadetChannel *ch;
567 struct CadetClient *c;
569 ch = GNUNET_new (struct CadetChannel);
573 ch->retry_time = CADET_INITIAL_RETRANSMIT_TIME;
574 ch->nobuffer = (0 != (options & GNUNET_CADET_OPTION_NOBUFFER));
575 ch->reliable = (0 != (options & GNUNET_CADET_OPTION_RELIABLE));
576 ch->out_of_order = (0 != (options & GNUNET_CADET_OPTION_OUT_OF_ORDER));
577 ch->max_pending_messages = (ch->nobuffer) ? 1 : 32; /* FIXME: 32!? Do not hardcode! */
578 GNUNET_STATISTICS_update (stats,
583 c = GNUNET_CONTAINER_multihashmap_get (open_ports,
587 /* port closed, wait for it to possibly open */
588 (void) GNUNET_CONTAINER_multihashmap_put (loose_channels,
591 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
592 ch->retry_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT_CLOSED_PORT,
595 LOG (GNUNET_ERROR_TYPE_DEBUG,
596 "Created loose incoming channel to port %s from peer %s\n",
597 GNUNET_h2s (&ch->port),
598 GCP_2s (GCT_get_destination (ch->t)));
605 GNUNET_STATISTICS_update (stats,
614 * Function called once the tunnel confirms that we sent the
615 * ACK message. Just remembers it was sent, we do not expect
618 * @param cls our `struct CadetChannel`.
621 send_ack_cb (void *cls)
623 struct CadetChannel *ch = cls;
625 ch->last_control_qe = NULL;
630 * Compute and send the current ACK to the other peer.
632 * @param ch channel to send the ACK for
635 send_channel_data_ack (struct CadetChannel *ch)
637 struct GNUNET_CADET_ChannelDataAckMessage msg;
639 msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK);
640 msg.header.size = htons (sizeof (msg));
642 msg.mid.mid = htonl (ntohl (ch->mid_recv.mid) - 1);
643 msg.futures = GNUNET_htonll (ch->mid_futures);
644 if (NULL != ch->last_control_qe)
645 GCT_send_cancel (ch->last_control_qe);
646 ch->last_control_qe = GCT_send (ch->t,
654 * Send our initial ACK to the client confirming that the
657 * @param cls the `struct CadetChannel`
660 send_connect_ack (void *cls)
662 struct CadetChannel *ch = cls;
664 ch->retry_task = NULL;
665 send_channel_data_ack (ch);
670 * Send a LOCAL ACK to the client to solicit more messages.
672 * @param ch channel the ack is for
673 * @param c client to send the ACK to
676 send_ack_to_client (struct CadetChannel *ch,
677 struct CadetClient *c)
679 struct GNUNET_MQ_Envelope *env;
680 struct GNUNET_CADET_LocalAck *ack;
682 env = GNUNET_MQ_msg (ack,
683 GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK);
685 GSC_send_to_client (c,
691 * A client is bound to the port that we have a channel
692 * open to. Send the acknowledgement for the connection
693 * request and establish the link with the client.
695 * @param ch open incoming channel
696 * @param c client listening on the respective port
699 GCCH_bind (struct CadetChannel *ch,
700 struct CadetClient *c)
702 struct GNUNET_MQ_Envelope *env;
703 struct GNUNET_CADET_LocalChannelCreateMessage *tcm;
706 LOG (GNUNET_ERROR_TYPE_DEBUG,
707 "Binding channel %s from tunnel %s to port %s of client %s\n",
710 GNUNET_h2s (&ch->port),
712 if (NULL != ch->retry_task)
714 /* there might be a timeout task here */
715 GNUNET_SCHEDULER_cancel (ch->retry_task);
716 ch->retry_task = NULL;
720 options |= GNUNET_CADET_OPTION_NOBUFFER;
722 options |= GNUNET_CADET_OPTION_RELIABLE;
723 if (ch->out_of_order)
724 options |= GNUNET_CADET_OPTION_OUT_OF_ORDER;
726 ch->ccn = GSC_bind (c,
728 GCT_get_destination (ch->t),
731 ch->mid_recv.mid = htonl (1); /* The CONNECT counts as message 0! */
733 /* notify other peer that we accepted the connection */
734 ch->retry_task = GNUNET_SCHEDULER_add_now (&send_connect_ack,
736 /* give client it's initial supply of ACKs */
737 env = GNUNET_MQ_msg (tcm,
738 GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_CREATE);
740 tcm->peer = *GCP_get_id (GCT_get_destination (ch->t));
741 tcm->port = ch->port;
742 tcm->opt = htonl (options);
743 GSC_send_to_client (ch->dest,
745 for (unsigned int i=0;i<ch->max_pending_messages;i++)
746 send_ack_to_client (ch,
752 * Destroy locally created channel. Called by the
753 * local client, so no need to tell the client.
755 * @param ch channel to destroy
758 GCCH_channel_local_destroy (struct CadetChannel *ch)
760 if (GNUNET_YES == ch->destroy)
762 /* other end already destroyed, with the local client gone, no need
763 to finish transmissions, just destroy immediately. */
764 channel_destroy (ch);
767 if (NULL != ch->head_sent)
769 /* allow send queue to train first */
770 ch->destroy = GNUNET_YES;
773 /* Nothing left to do, just finish destruction */
774 GCT_send_channel_destroy (ch->t,
776 channel_destroy (ch);
781 * Destroy channel that was incoming. Called by the
782 * local client, so no need to tell the client.
784 * @param ch channel to destroy
787 GCCH_channel_incoming_destroy (struct CadetChannel *ch)
789 if (GNUNET_YES == ch->destroy)
791 /* other end already destroyed, with the remote client gone, no need
792 to finish transmissions, just destroy immediately. */
793 channel_destroy (ch);
796 if (NULL != ch->head_recv)
798 /* allow local client to see all data first */
799 ch->destroy = GNUNET_YES;
802 /* Nothing left to do, just finish destruction */
803 GCT_send_channel_destroy (ch->t,
805 channel_destroy (ch);
810 * We got an acknowledgement for the creation of the channel
811 * (the port is open on the other side). Begin transmissions.
813 * @param ch channel to destroy
816 GCCH_handle_channel_open_ack (struct CadetChannel *ch)
820 case CADET_CHANNEL_NEW:
821 /* this should be impossible */
824 case CADET_CHANNEL_CREATE_SENT:
825 if (NULL == ch->owner)
827 /* We're not the owner, wrong direction! */
831 LOG (GNUNET_ERROR_TYPE_DEBUG,
832 "Received channel OPEN_ACK for waiting channel %s, entering READY state\n",
834 GNUNET_SCHEDULER_cancel (ch->retry_task);
835 ch->retry_task = NULL;
836 ch->state = CADET_CHANNEL_READY;
837 /* On first connect, send client as many ACKs as we allow messages
839 for (unsigned int i=0;i<ch->max_pending_messages;i++)
840 send_ack_to_client (ch,
843 case CADET_CHANNEL_READY:
844 /* duplicate ACK, maybe we retried the CREATE. Ignore. */
845 LOG (GNUNET_ERROR_TYPE_DEBUG,
846 "Received duplicate channel OPEN_ACK for channel %s\n",
848 GNUNET_STATISTICS_update (stats,
849 "# duplicate CREATE_ACKs",
858 * Test if element @a e1 comes before element @a e2.
860 * TODO: use opportunity to create generic list insertion sort
861 * logic in container!
863 * @param cls closure, our `struct CadetChannel`
864 * @param e1 an element of to sort
865 * @param e2 another element to sort
866 * @return #GNUNET_YES if @e1 < @e2, otherwise #GNUNET_NO
869 is_before (void *cls,
873 struct CadetOutOfOrderMessage *m1 = e1;
874 struct CadetOutOfOrderMessage *m2 = e2;
875 uint32_t v1 = ntohl (m1->mid.mid);
876 uint32_t v2 = ntohl (m2->mid.mid);
880 if (delta > (uint32_t) INT_MAX)
882 /* in overflow range, we can safely assume we wrapped around */
893 * We got payload data for a channel. Pass it on to the client
894 * and send an ACK to the other end (once flow control allows it!)
896 * @param ch channel that got data
899 GCCH_handle_channel_plaintext_data (struct CadetChannel *ch,
900 const struct GNUNET_CADET_ChannelAppDataMessage *msg)
902 struct GNUNET_MQ_Envelope *env;
903 struct GNUNET_CADET_LocalData *ld;
904 struct CadetOutOfOrderMessage *com;
907 payload_size = ntohs (msg->header.size) - sizeof (*msg);
908 LOG (GNUNET_ERROR_TYPE_DEBUG,
909 "Receicved %u bytes of application data on channel %s\n",
910 (unsigned int) payload_size,
912 env = GNUNET_MQ_msg_extra (ld,
914 GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA);
916 GNUNET_memcpy (&ld[1],
919 if ( (GNUNET_YES == ch->client_ready) &&
920 ( (GNUNET_YES == ch->out_of_order) ||
921 (msg->mid.mid == ch->mid_recv.mid) ) )
923 GSC_send_to_client (ch->owner ? ch->owner : ch->dest,
925 ch->mid_recv.mid = htonl (1 + ntohl (ch->mid_recv.mid));
926 ch->mid_futures >>= 1;
930 /* FIXME-SECURITY: if the element is WAY too far ahead,
931 drop it (can't buffer too much!) */
932 com = GNUNET_new (struct CadetOutOfOrderMessage);
935 /* sort into list ordered by "is_before" */
936 if ( (NULL == ch->head_recv) ||
937 (GNUNET_YES == is_before (ch,
941 GNUNET_CONTAINER_DLL_insert (ch->head_recv,
947 struct CadetOutOfOrderMessage *pos;
949 for (pos = ch->head_recv;
960 GNUNET_CONTAINER_DLL_insert_tail (ch->head_recv,
964 GNUNET_CONTAINER_DLL_insert_after (ch->head_recv,
974 * We got an acknowledgement for payload data for a channel.
975 * Possibly resume transmissions.
977 * @param ch channel that got the ack
978 * @param ack details about what was received
981 GCCH_handle_channel_plaintext_data_ack (struct CadetChannel *ch,
982 const struct GNUNET_CADET_ChannelDataAckMessage *ack)
984 struct CadetReliableMessage *crm;
986 if (GNUNET_NO == ch->reliable)
988 /* not expecting ACKs on unreliable channel, odd */
992 for (crm = ch->head_sent;
995 if (ack->mid.mid == crm->data_message.mid.mid)
999 /* ACK for message we already dropped, might have been a
1000 duplicate ACK? Ignore. */
1001 GNUNET_STATISTICS_update (stats,
1002 "# duplicate DATA_ACKs",
1007 GNUNET_CONTAINER_DLL_remove (ch->head_sent,
1010 ch->pending_messages--;
1012 GNUNET_assert (ch->pending_messages < ch->max_pending_messages);
1013 send_ack_to_client (ch,
1014 (NULL == ch->owner) ? ch->dest : ch->owner);
1019 * Destroy channel, based on the other peer closing the
1020 * connection. Also needs to remove this channel from
1023 * @param ch channel to destroy
1026 GCCH_handle_remote_destroy (struct CadetChannel *ch)
1028 struct GNUNET_MQ_Envelope *env;
1029 struct GNUNET_CADET_LocalChannelDestroyMessage *tdm;
1031 LOG (GNUNET_ERROR_TYPE_DEBUG,
1032 "Received remote channel DESTROY for channel %s\n",
1034 ch->destroy = GNUNET_YES;
1035 env = GNUNET_MQ_msg (tdm,
1036 GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_DESTROY);
1038 GSC_send_to_client ((NULL != ch->owner) ? ch->owner : ch->dest,
1040 channel_destroy (ch);
1045 * Function called once the tunnel has sent one of our messages.
1046 * If the message is unreliable, simply frees the `crm`. If the
1047 * message was reliable, calculate retransmission time and
1048 * wait for ACK (or retransmit).
1050 * @param cls the `struct CadetReliableMessage` that was sent
1053 data_sent_cb (void *cls);
1057 * We need to retry a transmission, the last one took too long to
1060 * @param cls the `struct CadetChannel` where we need to retransmit
1063 retry_transmission (void *cls)
1065 struct CadetChannel *ch = cls;
1066 struct CadetReliableMessage *crm = ch->head_sent;
1068 ch->retry_task = NULL;
1069 GNUNET_assert (NULL == crm->qe);
1070 crm->qe = GCT_send (ch->t,
1071 &crm->data_message.header,
1078 * Check if we can now allow the client to transmit, and if so,
1079 * let the client know about it.
1081 * @param ch channel to check
1084 GCCH_check_allow_client (struct CadetChannel *ch)
1086 struct GNUNET_MQ_Envelope *env;
1087 struct GNUNET_CADET_LocalAck *msg;
1089 if (GNUNET_YES == ch->client_allowed)
1090 return; /* client already allowed! */
1091 if (CADET_CHANNEL_READY != ch->state)
1093 /* destination did not yet ACK our CREATE! */
1094 LOG (GNUNET_ERROR_TYPE_DEBUG,
1095 "Channel %s not yet ready, throttling client until ACK.\n",
1099 if (ch->pending_messages > ch->max_pending_messages)
1101 /* Too many messages in queue. */
1102 LOG (GNUNET_ERROR_TYPE_DEBUG,
1103 "Message queue still too long on channel %s, throttling client until ACK.\n",
1107 if ( (NULL != ch->head_sent) &&
1108 (64 <= ntohl (ch->mid_send.mid) - ntohl (ch->head_sent->data_message.mid.mid)) )
1110 LOG (GNUNET_ERROR_TYPE_DEBUG,
1111 "Gap in ACKs too big on channel %s, throttling client until ACK.\n",
1115 ch->client_allowed = GNUNET_YES;
1118 LOG (GNUNET_ERROR_TYPE_DEBUG,
1119 "Sending local ack to channel %s client\n",
1121 env = GNUNET_MQ_msg (msg,
1122 GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK);
1124 GSC_send_to_client (ch->owner ? ch->owner : ch->dest,
1130 * Function called once the tunnel has sent one of our messages.
1131 * If the message is unreliable, simply frees the `crm`. If the
1132 * message was reliable, calculate retransmission time and
1133 * wait for ACK (or retransmit).
1135 * @param cls the `struct CadetReliableMessage` that was sent
1138 data_sent_cb (void *cls)
1140 struct CadetReliableMessage *crm = cls;
1141 struct CadetChannel *ch = crm->ch;
1142 struct CadetReliableMessage *off;
1145 GNUNET_CONTAINER_DLL_remove (ch->head_sent,
1148 if (GNUNET_NO == ch->reliable)
1151 ch->pending_messages--;
1152 GCCH_check_allow_client (ch);
1155 if (0 == crm->retry_delay.rel_value_us)
1156 crm->retry_delay = ch->expected_delay;
1157 crm->next_retry = GNUNET_TIME_relative_to_absolute (crm->retry_delay);
1159 /* find position for re-insertion into the DLL */
1160 if ( (NULL == ch->head_sent) ||
1161 (crm->next_retry.abs_value_us < ch->head_sent->next_retry.abs_value_us) )
1163 /* insert at HEAD, also (re)schedule retry task! */
1164 GNUNET_CONTAINER_DLL_insert (ch->head_sent,
1167 if (NULL != ch->retry_task)
1168 GNUNET_SCHEDULER_cancel (ch->retry_task);
1169 ch->retry_task = GNUNET_SCHEDULER_add_delayed (crm->retry_delay,
1170 &retry_transmission,
1174 for (off = ch->head_sent; NULL != off; off = off->next)
1175 if (crm->next_retry.abs_value_us < off->next_retry.abs_value_us)
1179 /* insert at tail */
1180 GNUNET_CONTAINER_DLL_insert_tail (ch->head_sent,
1186 /* insert before off */
1187 GNUNET_CONTAINER_DLL_insert_after (ch->head_sent,
1196 * Handle data given by a client.
1198 * Check whether the client is allowed to send in this tunnel, save if
1199 * channel is reliable and send an ACK to the client if there is still
1200 * buffer space in the tunnel.
1202 * @param ch Channel.
1203 * @param message payload to transmit.
1204 * @return #GNUNET_OK if everything goes well,
1205 * #GNUNET_SYSERR in case of an error.
1208 GCCH_handle_local_data (struct CadetChannel *ch,
1209 const struct GNUNET_MessageHeader *message)
1211 uint16_t payload_size = ntohs (message->size);
1212 struct CadetReliableMessage *crm;
1214 if (GNUNET_NO == ch->client_allowed)
1216 GNUNET_break_op (0);
1217 return GNUNET_SYSERR;
1219 ch->client_allowed = GNUNET_NO;
1220 ch->pending_messages++;
1222 /* Everything is correct, send the message. */
1223 crm = GNUNET_malloc (sizeof (*crm) + payload_size);
1225 crm->data_message.header.size = htons (sizeof (struct GNUNET_CADET_ChannelAppDataMessage) + payload_size);
1226 crm->data_message.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA);
1227 ch->mid_send.mid = htonl (ntohl (ch->mid_send.mid) + 1);
1228 crm->data_message.mid = ch->mid_send;
1229 crm->data_message.ctn = ch->ctn;
1230 GNUNET_memcpy (&crm[1],
1233 GNUNET_CONTAINER_DLL_insert (ch->head_sent,
1236 LOG (GNUNET_ERROR_TYPE_DEBUG,
1237 "Sending %u bytes from local client to channel %s\n",
1240 crm->qe = GCT_send (ch->t,
1241 &crm->data_message.header,
1244 GCCH_check_allow_client (ch);
1250 * Try to deliver messages to the local client, if it is ready for more.
1252 * @param ch channel to process
1255 send_client_buffered_data (struct CadetChannel *ch)
1257 struct CadetOutOfOrderMessage *com;
1259 if (GNUNET_NO == ch->client_ready)
1260 return; /* client not ready */
1261 com = ch->head_recv;
1263 return; /* none pending */
1264 if ( (com->mid.mid != ch->mid_recv.mid) &&
1265 (GNUNET_NO == ch->out_of_order) )
1266 return; /* missing next one in-order */
1268 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1269 "Passing payload message to client on channel %s\n",
1272 /* all good, pass next message to client */
1273 GNUNET_CONTAINER_DLL_remove (ch->head_recv,
1276 /* FIXME: if unreliable, this is not aggressive
1277 enough, as it would be OK to have lost some! */
1278 ch->mid_recv.mid = htonl (1 + ntohl (com->mid.mid));
1279 ch->mid_futures >>= 1; /* equivalent to division by 2 */
1280 GSC_send_to_client (ch->owner ? ch->owner : ch->dest,
1283 if ( (0xFFULL == (ch->mid_futures & 0xFFULL)) &&
1284 (GNUNET_YES == ch->reliable) )
1286 /* The next 15 messages were also already received (0xFF), this
1287 suggests that the sender may be blocked on flow control
1288 urgently waiting for an ACK from us. (As we have an inherent
1289 maximum of 64 bits, and 15 is getting too close for comfort.)
1290 So we should send one now. */
1291 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1292 "Sender on channel %s likely blocked on flow-control, sending ACK now.\n",
1294 if (GNUNET_YES == ch->reliable)
1295 send_channel_data_ack (ch);
1298 if (NULL != ch->head_recv)
1300 if (GNUNET_NO == ch->destroy)
1302 GCT_send_channel_destroy (ch->t,
1304 channel_destroy (ch);
1309 * Handle ACK from client on local channel.
1311 * @param ch channel to destroy
1314 GCCH_handle_local_ack (struct CadetChannel *ch)
1316 ch->client_ready = GNUNET_YES;
1317 send_client_buffered_data (ch);
1321 #define LOG2(level, ...) GNUNET_log_from_nocheck(level,"cadet-chn",__VA_ARGS__)
1327 * @param ch Channel.
1328 * @param level Debug level to use.
1331 GCCH_debug (struct CadetChannel *ch,
1332 enum GNUNET_ErrorType level)
1336 do_log = GNUNET_get_log_call_status (level & (~GNUNET_ERROR_TYPE_BULK),
1338 __FILE__, __FUNCTION__, __LINE__);
1344 LOG2 (level, "CHN *** DEBUG NULL CHANNEL ***\n");
1348 "CHN Channel %s:%X (%p)\n",
1352 if (NULL != ch->owner)
1355 "CHN origin %s ready %s local-id: %u\n",
1357 ch->client_ready ? "YES" : "NO",
1358 ntohl (ch->ccn.channel_of_client));
1360 if (NULL != ch->dest)
1363 "CHN destination %s ready %s local-id: %u\n",
1365 ch->client_ready ? "YES" : "NO",
1366 ntohl (ch->ccn.channel_of_client));
1369 "CHN Message IDs recv: %d (%LLX), send: %d\n",
1370 ntohl (ch->mid_recv.mid),
1371 (unsigned long long) ch->mid_futures,
1372 ntohl (ch->mid_send.mid));
1377 /* end of gnunet-service-cadet-new_channel.c */