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
29 * - handle plaintext data
30 * - handle plaintext ACK
32 * - estimate max bandwidth using bursts and use to for CONGESTION CONTROL!
33 * - check that '0xFFULL' really is sufficient for flow control!
34 * - what about the 'no buffer' option?
35 * - what about the 'out-of-order' option?
38 #include "gnunet_util_lib.h"
40 #include "gnunet_statistics_service.h"
41 #include "gnunet-service-cadet-new.h"
42 #include "gnunet-service-cadet-new_channel.h"
43 #include "gnunet-service-cadet-new_connection.h"
44 #include "gnunet-service-cadet-new_tunnels.h"
45 #include "gnunet-service-cadet-new_peer.h"
46 #include "gnunet-service-cadet-new_paths.h"
48 #define LOG(level, ...) GNUNET_log (level,__VA_ARGS__)
51 * How long do we initially wait before retransmitting?
53 #define CADET_INITIAL_RETRANSMIT_TIME GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 250)
56 * How long do we wait before dropping state about incoming
57 * connection to closed port?
59 #define TIMEOUT_CLOSED_PORT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 30)
63 * All the states a connection can be in.
65 enum CadetChannelState
68 * Uninitialized status, should never appear in operation.
73 * Connection create message sent, waiting for ACK.
75 CADET_CHANNEL_CREATE_SENT,
78 * Connection confirmed, ready to carry traffic.
85 * Info needed to retry a message in case it gets lost.
86 * Note that we DO use this structure also for unreliable
89 struct CadetReliableMessage
92 * Double linked list, FIFO style
94 struct CadetReliableMessage *next;
97 * Double linked list, FIFO style
99 struct CadetReliableMessage *prev;
102 * Which channel is this message in?
104 struct CadetChannel *ch;
107 * Entry in the tunnels queue for this message, NULL if it has left
108 * the tunnel. Used to cancel transmission in case we receive an
111 struct CadetTunnelQueueEntry *qe;
114 * How soon should we retry if we fail to get an ACK?
115 * Messages in the queue are sorted by this value.
117 struct GNUNET_TIME_Absolute next_retry;
120 * How long do we wait for an ACK after transmission?
121 * Use for the back-off calculation.
123 struct GNUNET_TIME_Relative retry_delay;
126 * Data message we are trying to send.
128 struct GNUNET_CADET_ChannelAppDataMessage data_message;
130 /* followed by variable-size payload */
135 * List of received out-of-order data messages.
137 struct CadetOutOfOrderMessage
140 * Double linked list, FIFO style
142 struct CadetOutOfOrderMessage *next;
145 * Double linked list, FIFO style
147 struct CadetOutOfOrderMessage *prev;
150 * ID of the message (ACK needed to free)
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 chid;
269 * Local tunnel number for local client owning the channel.
270 * ( >= #GNUNET_CADET_LOCAL_CHANNEL_ID_CLI or 0 )
272 struct GNUNET_CADET_ClientChannelNumber lid;
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
316 * Get the static string for identification of the channel.
320 * @return Static string with the channel IDs.
323 GCCH_2s (const struct CadetChannel *ch)
325 static char buf[128];
328 return "(NULL Channel)";
329 GNUNET_snprintf (buf,
331 "%s:%s chid:%X (%X)",
333 GNUNET_h2s (&ch->port),
335 ntohl (ch->lid.channel_of_client));
341 * Get the channel's public ID.
345 * @return ID used to identify the channel with the remote peer.
347 struct GNUNET_CADET_ChannelTunnelNumber
348 GCCH_get_id (const struct CadetChannel *ch)
355 * Destroy the given channel.
357 * @param ch channel to destroy
360 channel_destroy (struct CadetChannel *ch)
362 struct CadetReliableMessage *crm;
363 struct CadetOutOfOrderMessage *com;
365 while (NULL != (crm = ch->head_sent))
367 GNUNET_assert (ch == crm->ch);
370 GCT_send_cancel (crm->qe);
373 GNUNET_CONTAINER_DLL_remove (ch->head_sent,
378 while (NULL != (com = ch->head_recv))
380 GNUNET_CONTAINER_DLL_remove (ch->head_recv,
383 GNUNET_MQ_discard (com->env);
386 if (NULL != ch->last_control_qe)
388 GCT_send_cancel (ch->last_control_qe);
389 ch->last_control_qe = NULL;
391 if (NULL != ch->retry_task)
393 GNUNET_SCHEDULER_cancel (ch->retry_task);
394 ch->retry_task = NULL;
396 GCT_remove_channel (ch->t,
404 * Send a channel create message.
406 * @param cls Channel for which to send.
409 send_create (void *cls);
413 * Function called once the tunnel confirms that we sent the
414 * create message. Delays for a bit until we retry.
416 * @param cls our `struct CadetChannel`.
419 create_sent_cb (void *cls)
421 struct CadetChannel *ch = cls;
423 ch->last_control_qe = NULL;
424 ch->retry_time = GNUNET_TIME_STD_BACKOFF (ch->retry_time);
425 ch->retry_task = GNUNET_SCHEDULER_add_delayed (ch->retry_time,
432 * Send a channel create message.
434 * @param cls Channel for which to send.
437 send_create (void *cls)
439 struct CadetChannel *ch = cls;
440 struct GNUNET_CADET_ChannelOpenMessage msgcc;
445 options |= GNUNET_CADET_OPTION_NOBUFFER;
447 options |= GNUNET_CADET_OPTION_RELIABLE;
448 if (ch->out_of_order)
449 options |= GNUNET_CADET_OPTION_OUT_OF_ORDER;
450 msgcc.header.size = htons (sizeof (msgcc));
451 msgcc.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN);
452 msgcc.opt = htonl (options);
453 msgcc.port = ch->port;
454 msgcc.chid = ch->chid;
455 ch->state = CADET_CHANNEL_CREATE_SENT;
456 ch->last_control_qe = GCT_send (ch->t,
464 * Create a new channel.
466 * @param owner local client owning the channel
467 * @param owner_id local chid of this channel at the @a owner
468 * @param destination peer to which we should build the channel
469 * @param port desired port at @a destination
470 * @param options options for the channel
471 * @return handle to the new channel
473 struct CadetChannel *
474 GCCH_channel_local_new (struct CadetClient *owner,
475 struct GNUNET_CADET_ClientChannelNumber owner_id,
476 struct CadetPeer *destination,
477 const struct GNUNET_HashCode *port,
480 struct CadetChannel *ch;
482 ch = GNUNET_new (struct CadetChannel);
483 ch->max_pending_messages = 32; /* FIXME: allow control via options
484 or adjust dynamically... */
488 ch->t = GCP_get_tunnel (destination,
490 ch->chid = GCT_add_channel (ch->t,
492 ch->retry_time = CADET_INITIAL_RETRANSMIT_TIME;
493 ch->nobuffer = (0 != (options & GNUNET_CADET_OPTION_NOBUFFER));
494 ch->reliable = (0 != (options & GNUNET_CADET_OPTION_RELIABLE));
495 ch->out_of_order = (0 != (options & GNUNET_CADET_OPTION_OUT_OF_ORDER));
496 ch->retry_task = GNUNET_SCHEDULER_add_now (&send_create,
498 GNUNET_STATISTICS_update (stats,
507 * We had an incoming channel to a port that is closed.
508 * It has not been opened for a while, drop it.
510 * @param cls the channel to drop
513 timeout_closed_cb (void *cls)
515 struct CadetChannel *ch = cls;
517 ch->retry_task = NULL;
518 channel_destroy (ch);
523 * Create a new channel based on a request coming in over the network.
525 * @param t tunnel to the remote peer
526 * @param chid identifier of this channel in the tunnel
527 * @param port desired local port
528 * @param options options for the channel
529 * @return handle to the new channel
531 struct CadetChannel *
532 GCCH_channel_incoming_new (struct CadetTunnel *t,
533 struct GNUNET_CADET_ChannelTunnelNumber chid,
534 const struct GNUNET_HashCode *port,
537 struct CadetChannel *ch;
538 struct CadetClient *c;
540 ch = GNUNET_new (struct CadetChannel);
541 ch->max_pending_messages = 32; /* FIXME: allow control via options
542 or adjust dynamically... */
546 ch->retry_time = CADET_INITIAL_RETRANSMIT_TIME;
547 ch->nobuffer = (0 != (options & GNUNET_CADET_OPTION_NOBUFFER));
548 ch->reliable = (0 != (options & GNUNET_CADET_OPTION_RELIABLE));
549 ch->out_of_order = (0 != (options & GNUNET_CADET_OPTION_OUT_OF_ORDER));
550 GNUNET_STATISTICS_update (stats,
555 c = GNUNET_CONTAINER_multihashmap_get (open_ports,
559 /* port closed, wait for it to possibly open */
560 (void) GNUNET_CONTAINER_multihashmap_put (loose_channels,
563 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
564 ch->retry_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT_CLOSED_PORT,
573 GNUNET_STATISTICS_update (stats,
582 * Function called once the tunnel confirms that we sent the
583 * ACK message. Just remembers it was sent, we do not expect
586 * @param cls our `struct CadetChannel`.
589 send_ack_cb (void *cls)
591 struct CadetChannel *ch = cls;
593 ch->last_control_qe = NULL;
598 * Compute and send the current ACK to the other peer.
600 * @param ch channel to send the ACK for
603 send_channel_ack (struct CadetChannel *ch)
605 struct GNUNET_CADET_ChannelDataAckMessage msg;
607 msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK);
608 msg.header.size = htons (sizeof (msg));
610 msg.mid.mid = htonl (ntohl (ch->mid_recv.mid) - 1);
611 msg.futures = GNUNET_htonll (ch->mid_futures);
612 if (NULL != ch->last_control_qe)
613 GCT_send_cancel (ch->last_control_qe);
614 ch->last_control_qe = GCT_send (ch->t,
622 * Send our initial ACK to the client confirming that the
625 * @param cls the `struct CadetChannel`
628 send_connect_ack (void *cls)
630 struct CadetChannel *ch = cls;
632 ch->retry_task = NULL;
633 send_channel_ack (ch);
638 * A client is bound to the port that we have a channel
639 * open to. Send the acknowledgement for the connection
640 * request and establish the link with the client.
642 * @param ch open incoming channel
643 * @param c client listening on the respective port
646 GCCH_bind (struct CadetChannel *ch,
647 struct CadetClient *c)
651 if (NULL != ch->retry_task)
653 /* there might be a timeout task here */
654 GNUNET_SCHEDULER_cancel (ch->retry_task);
655 ch->retry_task = NULL;
659 options |= GNUNET_CADET_OPTION_NOBUFFER;
661 options |= GNUNET_CADET_OPTION_RELIABLE;
662 if (ch->out_of_order)
663 options |= GNUNET_CADET_OPTION_OUT_OF_ORDER;
665 ch->lid = GSC_bind (c,
667 GCT_get_destination (ch->t),
670 ch->mid_recv.mid = htonl (1); /* The CONNECT counts as message 0! */
672 /* notify other peer that we accepted the connection */
673 ch->retry_task = GNUNET_SCHEDULER_add_now (&send_connect_ack,
679 * Destroy locally created channel. Called by the
680 * local client, so no need to tell the client.
682 * @param ch channel to destroy
685 GCCH_channel_local_destroy (struct CadetChannel *ch)
687 if (GNUNET_YES == ch->destroy)
689 /* other end already destroyed, with the local client gone, no need
690 to finish transmissions, just destroy immediately. */
691 channel_destroy (ch);
694 if (NULL != ch->head_sent)
696 /* allow send queue to train first */
697 ch->destroy = GNUNET_YES;
700 /* Nothing left to do, just finish destruction */
701 GCT_send_channel_destroy (ch->t,
703 channel_destroy (ch);
708 * Destroy channel that was incoming. Called by the
709 * local client, so no need to tell the client.
711 * @param ch channel to destroy
714 GCCH_channel_incoming_destroy (struct CadetChannel *ch)
716 if (GNUNET_YES == ch->destroy)
718 /* other end already destroyed, with the remote client gone, no need
719 to finish transmissions, just destroy immediately. */
720 channel_destroy (ch);
723 if (NULL != ch->head_recv)
725 /* allow local client to see all data first */
726 ch->destroy = GNUNET_YES;
729 /* Nothing left to do, just finish destruction */
730 GCT_send_channel_destroy (ch->t,
732 channel_destroy (ch);
737 * We got an acknowledgement for the creation of the channel
738 * (the port is open on the other side). Begin transmissions.
740 * @param ch channel to destroy
743 GCCH_handle_channel_create_ack (struct CadetChannel *ch)
745 GNUNET_break (0); // FIXME!
750 * We got payload data for a channel. Pass it on to the client.
752 * @param ch channel that got data
755 GCCH_handle_channel_plaintext_data (struct CadetChannel *ch,
756 const struct GNUNET_CADET_ChannelAppDataMessage *msg)
758 GNUNET_break (0); // FIXME!
763 * We got an acknowledgement for payload data for a channel.
764 * Possibly resume transmissions.
766 * @param ch channel that got the ack
767 * @param ack details about what was received
770 GCCH_handle_channel_plaintext_data_ack (struct CadetChannel *ch,
771 const struct GNUNET_CADET_ChannelDataAckMessage *ack)
773 GNUNET_break (0); // FIXME!
778 * Destroy channel, based on the other peer closing the
779 * connection. Also needs to remove this channel from
782 * FIXME: need to make it possible to defer destruction until we have
783 * received all messages up to the destroy, and right now the destroy
784 * message (and this API) fails to give is the information we need!
786 * FIXME: also need to know if the other peer got a destroy from
789 * @param ch channel to destroy
792 GCCH_handle_remote_destroy (struct CadetChannel *ch)
794 GNUNET_break (0); // FIXME!
799 * Function called once the tunnel has sent one of our messages.
800 * If the message is unreliable, simply frees the `crm`. If the
801 * message was reliable, calculate retransmission time and
802 * wait for ACK (or retransmit).
804 * @param cls the `struct CadetReliableMessage` that was sent
807 data_sent_cb (void *cls);
811 * We need to retry a transmission, the last one took too long to
814 * @param cls the `struct CadetChannel` where we need to retransmit
817 retry_transmission (void *cls)
819 struct CadetChannel *ch = cls;
820 struct CadetReliableMessage *crm = ch->head_sent;
822 GNUNET_assert (NULL == crm->qe);
823 crm->qe = GCT_send (ch->t,
824 &crm->data_message.header,
831 * Check if we can now allow the client to transmit, and if so,
832 * let the client know about it.
834 * @param ch channel to check
837 GCCH_check_allow_client (struct CadetChannel *ch)
839 struct GNUNET_MQ_Envelope *env;
840 struct GNUNET_CADET_LocalAck *msg;
842 if (GNUNET_YES == ch->client_allowed)
843 return; /* client already allowed! */
844 if (CADET_CHANNEL_READY != ch->state)
846 /* destination did not yet ACK our CREATE! */
847 LOG (GNUNET_ERROR_TYPE_DEBUG,
848 "Channel %s not yet ready, throttling client until ACK.\n",
852 if (ch->pending_messages > ch->max_pending_messages)
854 /* Too many messages in queue. */
855 LOG (GNUNET_ERROR_TYPE_DEBUG,
856 "Message queue still too long on channel %s, throttling client until ACK.\n",
860 if ( (NULL != ch->head_sent) &&
861 (64 <= ntohl (ch->mid_send.mid) - ntohl (ch->head_sent->data_message.mid.mid)) )
863 LOG (GNUNET_ERROR_TYPE_DEBUG,
864 "Gap in ACKs too big on channel %s, throttling client until ACK.\n",
868 ch->client_allowed = GNUNET_YES;
871 LOG (GNUNET_ERROR_TYPE_DEBUG,
872 "Sending local ack to channel %s client\n",
874 env = GNUNET_MQ_msg (msg,
875 GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK);
876 msg->channel_id = ch->lid;
877 GSC_send_to_client (ch->owner ? ch->owner : ch->dest,
883 * Function called once the tunnel has sent one of our messages.
884 * If the message is unreliable, simply frees the `crm`. If the
885 * message was reliable, calculate retransmission time and
886 * wait for ACK (or retransmit).
888 * @param cls the `struct CadetReliableMessage` that was sent
891 data_sent_cb (void *cls)
893 struct CadetReliableMessage *crm = cls;
894 struct CadetChannel *ch = crm->ch;
895 struct CadetReliableMessage *off;
898 GNUNET_CONTAINER_DLL_remove (ch->head_sent,
901 if (GNUNET_NO == ch->reliable)
904 ch->pending_messages--;
905 GCCH_check_allow_client (ch);
908 if (0 == crm->retry_delay.rel_value_us)
909 crm->retry_delay = ch->expected_delay;
910 crm->next_retry = GNUNET_TIME_relative_to_absolute (crm->retry_delay);
912 /* find position for re-insertion into the DLL */
913 if ( (NULL == ch->head_sent) ||
914 (crm->next_retry.abs_value_us < ch->head_sent->next_retry.abs_value_us) )
916 /* insert at HEAD, also (re)schedule retry task! */
917 GNUNET_CONTAINER_DLL_insert (ch->head_sent,
920 if (NULL != ch->retry_task)
921 GNUNET_SCHEDULER_cancel (ch->retry_task);
922 ch->retry_task = GNUNET_SCHEDULER_add_delayed (crm->retry_delay,
927 for (off = ch->head_sent; NULL != off; off = off->next)
928 if (crm->next_retry.abs_value_us < off->next_retry.abs_value_us)
933 GNUNET_CONTAINER_DLL_insert_tail (ch->head_sent,
939 /* insert before off */
940 GNUNET_CONTAINER_DLL_insert_after (ch->head_sent,
949 * Handle data given by a client.
951 * Check whether the client is allowed to send in this tunnel, save if
952 * channel is reliable and send an ACK to the client if there is still
953 * buffer space in the tunnel.
956 * @param message payload to transmit.
957 * @return #GNUNET_OK if everything goes well,
958 * #GNUNET_SYSERR in case of an error.
961 GCCH_handle_local_data (struct CadetChannel *ch,
962 const struct GNUNET_MessageHeader *message)
964 uint16_t payload_size = ntohs (message->size);
965 struct CadetReliableMessage *crm;
967 if (GNUNET_NO == ch->client_allowed)
970 return GNUNET_SYSERR;
972 ch->client_allowed = GNUNET_NO;
973 ch->pending_messages++;
975 /* Everything is correct, send the message. */
976 crm = GNUNET_malloc (sizeof (*crm) + payload_size);
978 crm->data_message.header.size = htons (sizeof (struct GNUNET_CADET_ChannelAppDataMessage) + payload_size);
979 crm->data_message.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA);
980 ch->mid_send.mid = htonl (ntohl (ch->mid_send.mid) + 1);
981 crm->data_message.mid = ch->mid_send;
982 crm->data_message.chid = ch->chid;
983 GNUNET_memcpy (&crm[1],
986 GNUNET_CONTAINER_DLL_insert (ch->head_sent,
989 LOG (GNUNET_ERROR_TYPE_DEBUG,
990 "Sending %u bytes from local client to channel %s\n",
993 crm->qe = GCT_send (ch->t,
994 &crm->data_message.header,
997 GCCH_check_allow_client (ch);
1003 * Try to deliver messages to the local client, if it is ready for more.
1005 * @param ch channel to process
1008 send_client_buffered_data (struct CadetChannel *ch)
1010 struct CadetOutOfOrderMessage *com;
1012 if (GNUNET_NO == ch->client_ready)
1013 return; /* client not ready */
1014 com = ch->head_recv;
1016 return; /* none pending */
1017 if ( (com->mid.mid != ch->mid_recv.mid) &&
1018 (GNUNET_NO == ch->out_of_order) )
1019 return; /* missing next one in-order */
1021 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1022 "Passing payload message to client on channel %s\n",
1025 /* all good, pass next message to client */
1026 GNUNET_CONTAINER_DLL_remove (ch->head_recv,
1029 ch->mid_recv.mid = htonl (1 + ntohl (com->mid.mid));
1030 ch->mid_futures >>= 1; /* equivalent to division by 2 */
1031 GSC_send_to_client (ch->owner ? ch->owner : ch->dest,
1034 if ( (0xFFULL == (ch->mid_futures & 0xFFULL)) &&
1035 (GNUNET_YES == ch->reliable) )
1037 /* The next 15 messages were also already received (0xFF), this
1038 suggests that the sender may be blocked on flow control
1039 urgently waiting for an ACK from us. (As we have an inherent
1040 maximum of 64 bits, and 15 is getting too close for comfort.)
1041 So we should send one now. */
1042 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1043 "Sender on channel %s likely blocked on flow-control, sending ACK now.\n",
1045 if (GNUNET_YES == ch->reliable)
1046 send_channel_ack (ch);
1049 if (NULL != ch->head_recv)
1051 if (GNUNET_NO == ch->destroy)
1053 GCT_send_channel_destroy (ch->t,
1055 channel_destroy (ch);
1060 * Handle ACK from client on local channel.
1062 * @param ch channel to destroy
1065 GCCH_handle_local_ack (struct CadetChannel *ch)
1067 ch->client_ready = GNUNET_YES;
1068 send_client_buffered_data (ch);
1072 #define LOG2(level, ...) GNUNET_log_from_nocheck(level,"cadet-chn",__VA_ARGS__)
1078 * @param ch Channel.
1079 * @param level Debug level to use.
1082 GCCH_debug (struct CadetChannel *ch,
1083 enum GNUNET_ErrorType level)
1087 do_log = GNUNET_get_log_call_status (level & (~GNUNET_ERROR_TYPE_BULK),
1089 __FILE__, __FUNCTION__, __LINE__);
1095 LOG2 (level, "CHN *** DEBUG NULL CHANNEL ***\n");
1099 "CHN Channel %s:%X (%p)\n",
1103 if (NULL != ch->owner)
1106 "CHN origin %s ready %s local-id: %u\n",
1108 ch->client_ready ? "YES" : "NO",
1109 ntohl (ch->lid.channel_of_client));
1111 if (NULL != ch->dest)
1114 "CHN destination %s ready %s local-id: %u\n",
1116 ch->client_ready ? "YES" : "NO",
1117 ntohl (ch->lid.channel_of_client));
1120 "CHN Message IDs recv: %d (%LLX), send: %d\n",
1121 ntohl (ch->mid_recv.mid),
1122 (unsigned long long) ch->mid_futures,
1123 ntohl (ch->mid_send.mid));
1128 /* end of gnunet-service-cadet-new_channel.c */