GNUnet  0.10.x
Data Structures | Macros | Enumerations | Functions
gnunet-service-cadet_channel.c File Reference

logical links between CADET clients More...

#include "platform.h"
#include "cadet.h"
#include "gnunet_statistics_service.h"
#include "gnunet-service-cadet_channel.h"
#include "gnunet-service-cadet_connection.h"
#include "gnunet-service-cadet_tunnels.h"
#include "gnunet-service-cadet_paths.h"
Include dependency graph for gnunet-service-cadet_channel.c:

Go to the source code of this file.

Data Structures

struct  CadetReliableMessage
 Info needed to retry a message in case it gets lost. More...
 
struct  CadetOutOfOrderMessage
 List of received out-of-order data messages. More...
 
struct  CadetChannelClient
 Client endpoint of a struct CadetChannel. More...
 
struct  CadetChannel
 Struct containing all information regarding a channel to a remote client. More...
 

Macros

#define LOG(level, ...)   GNUNET_log_from(level, "cadet-chn", __VA_ARGS__)
 
#define CADET_INITIAL_RETRANSMIT_TIME   GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 250)
 How long do we initially wait before retransmitting? More...
 
#define TIMEOUT_CLOSED_PORT   GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 30)
 How long do we wait before dropping state about incoming connection to closed port? More...
 
#define MIN_RTT_DELAY   GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 75)
 How long do we wait at least before retransmitting ever? More...
 
#define MAX_OUT_OF_ORDER_DISTANCE   1024
 Maximum message ID into the future we accept for out-of-order messages. More...
 
#define LOG2(level, ...)   GNUNET_log_from_nocheck(level, "cadet-chn", __VA_ARGS__)
 

Enumerations

enum  CadetChannelState { CADET_CHANNEL_NEW, CADET_CHANNEL_LOOSE, CADET_CHANNEL_OPEN_SENT, CADET_CHANNEL_READY }
 All the states a channel can be in. More...
 

Functions

const char * GCCH_2s (const struct CadetChannel *ch)
 Get the static string for identification of the channel. More...
 
void GCCH_hash_port (struct GNUNET_HashCode *h_port, const struct GNUNET_HashCode *port, const struct GNUNET_PeerIdentity *listener)
 Hash the port and initiator and listener to calculate the "challenge" h_port we send to the other peer on GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN. More...
 
struct GNUNET_CADET_ChannelTunnelNumber GCCH_get_id (const struct CadetChannel *ch)
 Get the channel's public ID. More...
 
static void free_channel_client (struct CadetChannelClient *ccc)
 Release memory associated with ccc. More...
 
static void channel_destroy (struct CadetChannel *ch)
 Destroy the given channel. More...
 
static void send_channel_open (void *cls)
 Send a channel create message. More...
 
static void channel_open_sent_cb (void *cls, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
 Function called once the tunnel confirms that we sent the create message. More...
 
void GCCH_tunnel_up (struct CadetChannel *ch)
 Function called once and only once after a channel was bound to its tunnel via GCT_add_channel() is ready for transmission. More...
 
struct CadetChannelGCCH_channel_local_new (struct CadetClient *owner, struct GNUNET_CADET_ClientChannelNumber ccn, struct CadetPeer *destination, const struct GNUNET_HashCode *port, uint32_t options)
 Create a new channel. More...
 
static void timeout_closed_cb (void *cls)
 We had an incoming channel to a port that is closed. More...
 
struct CadetChannelGCCH_channel_incoming_new (struct CadetTunnel *t, struct GNUNET_CADET_ChannelTunnelNumber ctn, const struct GNUNET_HashCode *h_port, uint32_t options)
 Create a new channel based on a request coming in over the network. More...
 
static void send_ack_cb (void *cls, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
 Function called once the tunnel confirms that we sent the ACK message. More...
 
static void send_channel_data_ack (struct CadetChannel *ch)
 Compute and send the current GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK to the other peer. More...
 
static void send_open_ack (void *cls)
 Send our initial GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK to the client confirming that the connection is up. More...
 
void GCCH_handle_duplicate_open (struct CadetChannel *ch, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti)
 We got a GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN message again for this channel. More...
 
static void send_ack_to_client (struct CadetChannel *ch, int to_owner)
 Send a GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK to the client to solicit more messages. More...
 
void GCCH_bind (struct CadetChannel *ch, struct CadetClient *c, const struct GNUNET_HashCode *port)
 A client is bound to the port that we have a channel open to. More...
 
static void signal_remote_destroy_cb (void *cls)
 One of our clients has disconnected, tell the other one that we are finished. More...
 
void GCCH_channel_local_destroy (struct CadetChannel *ch, struct CadetClient *c, struct GNUNET_CADET_ClientChannelNumber ccn)
 Destroy locally created channel. More...
 
void GCCH_handle_channel_open_ack (struct CadetChannel *ch, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti, const struct GNUNET_HashCode *port)
 We got an acknowledgement for the creation of the channel (the port is open on the other side). More...
 
static int is_before (void *cls, struct CadetOutOfOrderMessage *m1, struct CadetOutOfOrderMessage *m2)
 Test if element e1 comes before element e2. More...
 
void GCCH_handle_channel_plaintext_data (struct CadetChannel *ch, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti, const struct GNUNET_CADET_ChannelAppDataMessage *msg)
 We got payload data for a channel. More...
 
static void data_sent_cb (void *cls, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
 Function called once the tunnel has sent one of our messages. More...
 
static void retry_transmission (void *cls)
 We need to retry a transmission, the last one took too long to be acknowledged. More...
 
static void handle_matching_ack (struct CadetChannel *ch, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti, struct CadetReliableMessage *crm)
 We got an PLAINTEXT_DATA_ACK for a message in our queue, remove it from the queue and tell our client that it can send more. More...
 
void GCCH_handle_channel_plaintext_data_ack (struct CadetChannel *ch, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti, const struct GNUNET_CADET_ChannelDataAckMessage *ack)
 We got an acknowledgement for payload data for a channel. More...
 
void GCCH_handle_remote_destroy (struct CadetChannel *ch, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti)
 Destroy channel, based on the other peer closing the connection. More...
 
static int cmp_crm_by_next_retry (void *cls, struct CadetReliableMessage *crm1, struct CadetReliableMessage *crm2)
 Test if element e1 comes before element e2. More...
 
int GCCH_handle_local_data (struct CadetChannel *ch, struct GNUNET_CADET_ClientChannelNumber sender_ccn, const char *buf, size_t buf_len)
 Handle data given by a client. More...
 
void GCCH_handle_local_ack (struct CadetChannel *ch, struct GNUNET_CADET_ClientChannelNumber client_ccn)
 Handle ACK from client on local channel. More...
 
void GCCH_debug (struct CadetChannel *ch, enum GNUNET_ErrorType level)
 Log channel info. More...
 

Detailed Description

logical links between CADET clients

Author
Bartlomiej Polot
Christian Grothoff

TODO:

Definition in file gnunet-service-cadet_channel.c.

Macro Definition Documentation

◆ LOG

#define LOG (   level,
  ... 
)    GNUNET_log_from(level, "cadet-chn", __VA_ARGS__)

◆ CADET_INITIAL_RETRANSMIT_TIME

#define CADET_INITIAL_RETRANSMIT_TIME   GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 250)

How long do we initially wait before retransmitting?

Definition at line 49 of file gnunet-service-cadet_channel.c.

Referenced by GCCH_channel_incoming_new(), and GCCH_channel_local_new().

◆ TIMEOUT_CLOSED_PORT

#define TIMEOUT_CLOSED_PORT   GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 30)

How long do we wait before dropping state about incoming connection to closed port?

Definition at line 56 of file gnunet-service-cadet_channel.c.

Referenced by GCCH_channel_incoming_new().

◆ MIN_RTT_DELAY

How long do we wait at least before retransmitting ever?

Definition at line 62 of file gnunet-service-cadet_channel.c.

Referenced by data_sent_cb().

◆ MAX_OUT_OF_ORDER_DISTANCE

#define MAX_OUT_OF_ORDER_DISTANCE   1024

Maximum message ID into the future we accept for out-of-order messages.

If the message is more than this into the future, we drop it. This is important both to detect values that are actually in the past, as well as to limit adversarially triggerable memory consumption.

Note that right now we have "max_pending_messages = 4" hard-coded in the logic below, so a value of 4 would suffice here. But we plan to allow larger windows in the future...

Definition at line 75 of file gnunet-service-cadet_channel.c.

◆ LOG2

#define LOG2 (   level,
  ... 
)    GNUNET_log_from_nocheck(level, "cadet-chn", __VA_ARGS__)

Definition at line 1970 of file gnunet-service-cadet_channel.c.

Referenced by GCCH_debug().

Enumeration Type Documentation

◆ CadetChannelState

All the states a channel can be in.

Enumerator
CADET_CHANNEL_NEW 

Uninitialized status, should never appear in operation.

CADET_CHANNEL_LOOSE 

Channel is to a port that is not open, we're waiting for the port to be opened.

CADET_CHANNEL_OPEN_SENT 

CHANNEL_OPEN message sent, waiting for CHANNEL_OPEN_ACK.

CADET_CHANNEL_READY 

Connection confirmed, ready to carry traffic.

Definition at line 81 of file gnunet-service-cadet_channel.c.

81  {
86 
92 
97 
102 };
Connection confirmed, ready to carry traffic.
Uninitialized status, should never appear in operation.
Channel is to a port that is not open, we're waiting for the port to be opened.
CHANNEL_OPEN message sent, waiting for CHANNEL_OPEN_ACK.

Function Documentation

◆ GCCH_2s()

const char* GCCH_2s ( const struct CadetChannel ch)

Get the static string for identification of the channel.

Parameters
chChannel.
Returns
Static string with the channel IDs.

Definition at line 389 of file gnunet-service-cadet_channel.c.

References buf, CadetChannelClient::ccn, GNUNET_CADET_ClientChannelNumber::channel_of_client, CadetChannel::ctn, CadetChannel::dest, GCP_get_id(), GCT_get_destination(), GNUNET_h2s(), GNUNET_i2s(), GNUNET_snprintf(), GNUNET_YES, CadetChannel::is_loopback, CadetChannel::owner, CadetChannel::port, and CadetChannel::t.

Referenced by channel_destroy_iterator(), channel_open_sent_cb(), data_sent_cb(), GCCH_bind(), GCCH_channel_local_destroy(), GCCH_handle_channel_open_ack(), GCCH_handle_channel_plaintext_data(), GCCH_handle_channel_plaintext_data_ack(), GCCH_handle_duplicate_open(), GCCH_handle_local_ack(), GCCH_handle_local_data(), GCCH_handle_remote_destroy(), GCCH_tunnel_up(), GCT_add_channel(), GCT_remove_channel(), GSC_bind(), handle_channel_destroy(), handle_local_ack(), handle_local_data(), handle_matching_ack(), handle_plaintext_channel_destroy(), handle_plaintext_channel_open(), handle_plaintext_channel_open_ack(), retry_transmission(), send_channel_data_ack(), send_channel_open(), and send_open_ack().

390 {
391  static char buf[128];
392 
393  GNUNET_snprintf(buf,
394  sizeof(buf),
395  "Channel %s:%s ctn:%X(%X/%X)",
396  (GNUNET_YES == ch->is_loopback)
397  ? "loopback"
399  GNUNET_h2s(&ch->port),
400  ch->ctn,
401  (NULL == ch->owner)
402  ? 0
403  : ntohl(ch->owner->ccn.channel_of_client),
404  (NULL == ch->dest)
405  ? 0
406  : ntohl(ch->dest->ccn.channel_of_client));
407  return buf;
408 }
struct CadetPeer * GCT_get_destination(struct CadetTunnel *t)
Return the peer to which this tunnel goes.
uint32_t channel_of_client
Values for channel numbering.
Definition: cadet.h:110
int GNUNET_snprintf(char *buf, size_t size, const char *format,...)
Like snprintf, just aborts if the buffer is of insufficient size.
struct CadetChannelClient * owner
Client owner of the tunnel, if any.
int is_loopback
Is this channel a loopback channel, where the destination is us again?
struct CadetChannelClient * dest
Client destination of the tunnel, if any.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
struct CadetTunnel * t
Tunnel this channel is in.
struct GNUNET_CADET_ClientChannelNumber ccn
Local tunnel number for this client.
static char buf[2048]
struct GNUNET_CADET_ChannelTunnelNumber ctn
Number identifying this channel in its tunnel.
#define GNUNET_YES
Definition: gnunet_common.h:77
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
const struct GNUNET_PeerIdentity * GCP_get_id(struct CadetPeer *cp)
Obtain the peer identity for a struct CadetPeer.
struct GNUNET_HashCode port
Destination port of the channel.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCCH_hash_port()

void GCCH_hash_port ( struct GNUNET_HashCode h_port,
const struct GNUNET_HashCode port,
const struct GNUNET_PeerIdentity listener 
)

Hash the port and initiator and listener to calculate the "challenge" h_port we send to the other peer on GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN.

Parameters
[out]h_portset to the hash of port, initiator and listener
portcadet port, as seen by CADET clients
listenerpeer that is listining on port

Definition at line 421 of file gnunet-service-cadet_channel.c.

References GNUNET_CRYPTO_hash_context_finish(), GNUNET_CRYPTO_hash_context_read(), GNUNET_CRYPTO_hash_context_start(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), and LOG.

Referenced by GCCH_channel_local_new(), and handle_port_open().

424 {
425  struct GNUNET_HashContext *hc;
426 
428  GNUNET_CRYPTO_hash_context_read(hc, port, sizeof(*port));
429  GNUNET_CRYPTO_hash_context_read(hc, listener, sizeof(*listener));
432  "Calculated port hash %s\n",
433  GNUNET_h2s(h_port));
434 }
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
struct GNUNET_HashContext * GNUNET_CRYPTO_hash_context_start(void)
Start incremental hashing operation.
Definition: crypto_hash.c:445
Context for cummulative hashing.
Definition: crypto_hash.c:431
#define LOG(level,...)
void GNUNET_CRYPTO_hash_context_read(struct GNUNET_HashContext *hc, const void *buf, size_t size)
Add data to be hashed.
Definition: crypto_hash.c:471
void GNUNET_CRYPTO_hash_context_finish(struct GNUNET_HashContext *hc, struct GNUNET_HashCode *r_hash)
Finish the hash computation.
Definition: crypto_hash.c:488
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCCH_get_id()

struct GNUNET_CADET_ChannelTunnelNumber GCCH_get_id ( const struct CadetChannel ch)

Get the channel's public ID.

Parameters
chChannel.
Returns
ID used to identify the channel with the remote peer.

Definition at line 445 of file gnunet-service-cadet_channel.c.

References CadetReliableMessage::ch, and CadetChannel::ctn.

446 {
447  return ch->ctn;
448 }
struct GNUNET_CADET_ChannelTunnelNumber ctn
Number identifying this channel in its tunnel.

◆ free_channel_client()

static void free_channel_client ( struct CadetChannelClient ccc)
static

Release memory associated with ccc.

Parameters
cccdata structure to clean up

Definition at line 457 of file gnunet-service-cadet_channel.c.

References CadetOutOfOrderMessage::env, GNUNET_CONTAINER_DLL_remove, GNUNET_free, GNUNET_MQ_discard(), CadetChannelClient::head_recv, CadetChannelClient::num_recv, and CadetChannelClient::tail_recv.

Referenced by channel_destroy(), and GCCH_channel_local_destroy().

458 {
459  struct CadetOutOfOrderMessage *com;
460 
461  while (NULL != (com = ccc->head_recv))
462  {
464  ccc->num_recv--;
465  GNUNET_MQ_discard(com->env);
466  GNUNET_free(com);
467  }
468  GNUNET_free(ccc);
469 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
List of received out-of-order data messages.
struct GNUNET_MQ_Envelope * env
The envelope with the payload of the out-of-order message.
unsigned int num_recv
Number of entries currently in head_recv DLL.
struct CadetOutOfOrderMessage * tail_recv
Tail DLL of messages received out of order or while client was unready.
void GNUNET_MQ_discard(struct GNUNET_MQ_Envelope *mqm)
Discard the message queue message, free all allocated resources.
Definition: mq.c:319
struct CadetOutOfOrderMessage * head_recv
Head of DLL of messages received out of order or while client was unready.
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ channel_destroy()

static void channel_destroy ( struct CadetChannel ch)
static

Destroy the given channel.

Parameters
chchannel to destroy

Definition at line 478 of file gnunet-service-cadet_channel.c.

References CADET_CHANNEL_LOOSE, CadetReliableMessage::ch, CadetChannel::ctn, CadetReliableMessage::data_message, CadetChannel::dest, free_channel_client(), GCT_remove_channel(), GCT_send_cancel(), GNUNET_assert, GNUNET_CONTAINER_DLL_remove, GNUNET_free, GNUNET_NO, GNUNET_SCHEDULER_cancel(), GSC_drop_loose_channel(), CadetChannel::h_port, CadetChannel::head_sent, CadetChannel::is_loopback, CadetChannel::last_control_qe, CadetChannel::owner, CadetReliableMessage::qe, CadetChannel::retry_control_task, CadetChannel::retry_data_task, send_channel_open(), CadetChannel::state, CadetChannel::t, and CadetChannel::tail_sent.

Referenced by GCCH_channel_local_destroy(), GCCH_handle_local_ack(), GCCH_handle_remote_destroy(), reconnect(), run(), signal_remote_destroy_cb(), and timeout_closed_cb().

479 {
480  struct CadetReliableMessage *crm;
481 
482  while (NULL != (crm = ch->head_sent))
483  {
484  GNUNET_assert(ch == crm->ch);
485  if (NULL != crm->qe)
486  {
487  GCT_send_cancel(crm->qe);
488  crm->qe = NULL;
489  }
492  GNUNET_free(crm);
493  }
494  if (CADET_CHANNEL_LOOSE == ch->state)
495  {
496  GSC_drop_loose_channel(&ch->h_port, ch);
497  }
498  if (NULL != ch->owner)
499  {
501  ch->owner = NULL;
502  }
503  if (NULL != ch->dest)
504  {
506  ch->dest = NULL;
507  }
508  if (NULL != ch->last_control_qe)
509  {
511  ch->last_control_qe = NULL;
512  }
513  if (NULL != ch->retry_data_task)
514  {
516  ch->retry_data_task = NULL;
517  }
518  if (NULL != ch->retry_control_task)
519  {
521  ch->retry_control_task = NULL;
522  }
523  if (GNUNET_NO == ch->is_loopback)
524  {
525  GCT_remove_channel(ch->t, ch, ch->ctn);
526  ch->t = NULL;
527  }
528  GNUNET_free(ch);
529 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
void GCT_remove_channel(struct CadetTunnel *t, struct CadetChannel *ch, struct GNUNET_CADET_ChannelTunnelNumber ctn)
Remove a channel from a tunnel.
struct CadetChannel * ch
Which channel is this message in?
struct CadetReliableMessage * head_sent
Head of DLL of messages sent and not yet ACK'd.
enum CadetChannelState state
Channel state.
Info needed to retry a message in case it gets lost.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct CadetChannelClient * owner
Client owner of the tunnel, if any.
void GCT_send_cancel(struct CadetTunnelQueueEntry *tq)
Cancel a previously sent message while it's in the queue.
int is_loopback
Is this channel a loopback channel, where the destination is us again?
struct CadetChannelClient * dest
Client destination of the tunnel, if any.
struct GNUNET_SCHEDULER_Task * retry_data_task
Task to resend/poll in case no ACK is received.
#define GNUNET_NO
Definition: gnunet_common.h:78
static void free_channel_client(struct CadetChannelClient *ccc)
Release memory associated with ccc.
struct CadetTunnel * t
Tunnel this channel is in.
Channel is to a port that is not open, we're waiting for the port to be opened.
struct GNUNET_CADET_ChannelAppDataMessage * data_message
Data message we are trying to send.
struct GNUNET_CADET_ChannelTunnelNumber ctn
Number identifying this channel in its tunnel.
struct CadetReliableMessage * tail_sent
Tail of DLL of messages sent and not yet ACK'd.
struct GNUNET_HashCode h_port
Hash'ed port of the channel with initiator and destination PID.
struct CadetTunnelQueueEntry * qe
Entry in the tunnels queue for this message, NULL if it has left the tunnel.
void GSC_drop_loose_channel(const struct GNUNET_HashCode *h_port, struct CadetChannel *ch)
A client that created a loose channel that was not bound to a port disconnected, drop it from the loo...
struct GNUNET_SCHEDULER_Task * retry_control_task
Task to resend/poll in case no ACK is received.
struct CadetTunnelQueueEntry * last_control_qe
Last entry in the tunnel's queue relating to control messages (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN...
#define GNUNET_free(ptr)
Wrapper around free.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:956
Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_channel_open()

static void send_channel_open ( void *  cls)
static

Send a channel create message.

Send a channel open message.

Parameters
clsChannel for which to send.

Definition at line 573 of file gnunet-service-cadet_channel.c.

References CADET_CHANNEL_OPEN_SENT, CadetReliableMessage::ch, channel_open_sent_cb(), CadetChannel::ctn, GNUNET_CADET_ChannelOpenMessage::ctn, GCCH_2s(), GCT_send(), GCT_send_cancel(), GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN, CadetChannel::h_port, GNUNET_CADET_ChannelOpenMessage::h_port, GNUNET_CADET_ChannelOpenMessage::header, CadetChannel::last_control_qe, LOG, GNUNET_CADET_ChannelOpenMessage::opt, CadetChannel::retry_control_task, GNUNET_MessageHeader::size, CadetChannel::state, CadetChannel::t, and GNUNET_MessageHeader::type.

Referenced by channel_destroy(), channel_open_sent_cb(), and GCCH_tunnel_up().

574 {
575  struct CadetChannel *ch = cls;
576  struct GNUNET_CADET_ChannelOpenMessage msgcc;
577 
578  ch->retry_control_task = NULL;
580  "Sending CHANNEL_OPEN message for %s\n",
581  GCCH_2s(ch));
582  msgcc.header.size = htons(sizeof(msgcc));
583  msgcc.header.type = htons(GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN);
584  //TODO This will be removed in a major release, because this will be a protocol breaking change. We set the deprecated "reliable" bit here that was removed.
585  msgcc.opt = 2;
586  msgcc.h_port = ch->h_port;
587  msgcc.ctn = ch->ctn;
589  if (NULL != ch->last_control_qe)
591  ch->last_control_qe =
592  GCT_send(ch->t, &msgcc.header, &channel_open_sent_cb, ch);
593  GNUNET_assert(NULL == ch->retry_control_task);
594 }
static struct GNUNET_CADET_Channel * ch
Channel handle.
Definition: gnunet-cadet.c:117
enum CadetChannelState state
Channel state.
static void channel_open_sent_cb(void *cls, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
Function called once the tunnel confirms that we sent the create message.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct CadetTunnelQueueEntry * GCT_send(struct CadetTunnel *t, const struct GNUNET_MessageHeader *message, GCT_SendContinuation cont, void *cont_cls)
Sends an already built message on a tunnel, encrypting it and choosing the best connection if not pro...
void GCT_send_cancel(struct CadetTunnelQueueEntry *tq)
Cancel a previously sent message while it's in the queue.
#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN
Ask the cadet service to create a new channel.
struct CadetTunnel * t
Tunnel this channel is in.
#define LOG(level,...)
Struct containing all information regarding a channel to a remote client.
struct GNUNET_CADET_ChannelTunnelNumber ctn
Number identifying this channel in its tunnel.
CHANNEL_OPEN message sent, waiting for CHANNEL_OPEN_ACK.
Message to create a Channel.
const char * GCCH_2s(const struct CadetChannel *ch)
Get the static string for identification of the channel.
struct GNUNET_HashCode h_port
Hash'ed port of the channel with initiator and destination PID.
struct GNUNET_SCHEDULER_Task * retry_control_task
Task to resend/poll in case no ACK is received.
struct CadetTunnelQueueEntry * last_control_qe
Last entry in the tunnel's queue relating to control messages (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN...
Here is the call graph for this function:
Here is the caller graph for this function:

◆ channel_open_sent_cb()

static void channel_open_sent_cb ( void *  cls,
const struct GNUNET_CADET_ConnectionTunnelIdentifier cid 
)
static

Function called once the tunnel confirms that we sent the create message.

Delays for a bit until we retry.

Parameters
clsour struct CadetChannel.
cididentifier of the connection within the tunnel, NULL if transmission failed

Definition at line 550 of file gnunet-service-cadet_channel.c.

References CadetReliableMessage::ch, GCCH_2s(), GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_SCHEDULER_add_delayed(), GNUNET_STRINGS_relative_time_to_string(), GNUNET_TIME_STD_BACKOFF, GNUNET_YES, CadetChannel::last_control_qe, LOG, CadetChannel::retry_control_task, CadetChannel::retry_time, and send_channel_open().

Referenced by send_channel_open().

552 {
553  struct CadetChannel *ch = cls;
554 
555  GNUNET_assert(NULL != ch->last_control_qe);
556  ch->last_control_qe = NULL;
559  "Sent CADET_CHANNEL_OPEN on %s, retrying in %s\n",
560  GCCH_2s(ch),
562  ch->retry_control_task =
564 }
static struct GNUNET_CADET_Channel * ch
Channel handle.
Definition: gnunet-cadet.c:117
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1237
#define LOG(level,...)
Struct containing all information regarding a channel to a remote client.
struct GNUNET_TIME_Relative retry_time
Counter for exponential backoff.
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
Definition: strings.c:686
static void send_channel_open(void *cls)
Send a channel create message.
#define GNUNET_TIME_STD_BACKOFF(r)
Perform our standard exponential back-off calculation, starting at 1 ms and then going by a factor of...
const char * GCCH_2s(const struct CadetChannel *ch)
Get the static string for identification of the channel.
#define GNUNET_YES
Definition: gnunet_common.h:77
struct GNUNET_SCHEDULER_Task * retry_control_task
Task to resend/poll in case no ACK is received.
struct CadetTunnelQueueEntry * last_control_qe
Last entry in the tunnel's queue relating to control messages (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN...
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCCH_tunnel_up()

void GCCH_tunnel_up ( struct CadetChannel ch)

Function called once and only once after a channel was bound to its tunnel via GCT_add_channel() is ready for transmission.

Note that this is only the case for channels that this peer initiates, as for incoming channels we assume that they are ready for transmission immediately upon receiving the open message. Used to bootstrap the GCT_send() process.

Parameters
chthe channel for which the tunnel is now ready

Definition at line 608 of file gnunet-service-cadet_channel.c.

References GCCH_2s(), GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_SCHEDULER_add_now(), LOG, CadetChannel::retry_control_task, and send_channel_open().

Referenced by GCT_add_channel(), and notify_tunnel_up_cb().

609 {
610  GNUNET_assert(NULL == ch->retry_control_task);
612  "Tunnel up, sending CHANNEL_OPEN on %s now\n",
613  GCCH_2s(ch));
615 }
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define LOG(level,...)
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1264
static void send_channel_open(void *cls)
Send a channel create message.
const char * GCCH_2s(const struct CadetChannel *ch)
Get the static string for identification of the channel.
struct GNUNET_SCHEDULER_Task * retry_control_task
Task to resend/poll in case no ACK is received.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCCH_channel_local_new()

struct CadetChannel* GCCH_channel_local_new ( struct CadetClient owner,
struct GNUNET_CADET_ClientChannelNumber  ccn,
struct CadetPeer destination,
const struct GNUNET_HashCode port,
uint32_t  options 
)

Create a new channel.

Parameters
ownerlocal client owning the channel
ccnlocal number of this channel at the owner
destinationpeer to which we should build the channel
portdesired port at destination
optionsoptions for the channel
Returns
handle to the new channel

Definition at line 629 of file gnunet-service-cadet_channel.c.

References OpenPort::c, CadetChannelClient::c, CADET_CHANNEL_LOOSE, CADET_INITIAL_RETRANSMIT_TIME, CadetChannelClient::ccn, CadetReliableMessage::ch, CadetChannelClient::client_ready, CadetChannel::ctn, GCCH_bind(), GCCH_hash_port(), GCP_2s(), GCP_get_id(), GCP_get_tunnel(), GCT_2s(), GCT_add_channel(), GNUNET_CONTAINER_multihashmap_get(), GNUNET_CONTAINER_multihashmap_put(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE, GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_memcmp, GNUNET_new, GNUNET_NO, GNUNET_STATISTICS_update(), GNUNET_YES, GSC_2s(), CadetChannel::h_port, CadetChannel::is_loopback, LOG, loose_channels, CadetChannel::max_pending_messages, ChannelMessageIdentifier::mid, CadetChannel::mid_recv, my_full_id, CadetChannel::nobuffer, op, open_ports, CadetChannel::out_of_order, CadetChannel::owner, port, OpenPort::port, CadetChannel::port, CadetChannel::reliable, CadetChannel::retry_time, CadetChannel::state, stats, and CadetChannel::t.

Referenced by handle_channel_create().

634 {
635  struct CadetChannel *ch;
636  struct CadetChannelClient *ccco;
637 
638  ccco = GNUNET_new(struct CadetChannelClient);
639  ccco->c = owner;
640  ccco->ccn = ccn;
641  ccco->client_ready = GNUNET_YES;
642 
643  ch = GNUNET_new(struct CadetChannel);
644  ch->mid_recv.mid = htonl(1); /* The OPEN_ACK counts as message 0! */
645  ch->nobuffer = GNUNET_NO;
646  ch->reliable = GNUNET_YES;
647  ch->out_of_order = GNUNET_NO;
649  (ch->nobuffer) ? 1 : 4; /* FIXME: 4!? Do not hardcode! */
650  ch->owner = ccco;
651  ch->port = *port;
652  GCCH_hash_port(&ch->h_port, port, GCP_get_id(destination));
653  if (0 == GNUNET_memcmp(&my_full_id, GCP_get_id(destination)))
654  {
655  struct OpenPort *op;
656 
657  ch->is_loopback = GNUNET_YES;
659  if (NULL == op)
660  {
661  /* port closed, wait for it to possibly open */
665  &ch->h_port,
666  ch,
669  "Created loose incoming loopback channel to port %s\n",
670  GNUNET_h2s(&ch->port));
671  }
672  else
673  {
674  GCCH_bind(ch, op->c, &op->port);
675  }
676  }
677  else
678  {
679  ch->t = GCP_get_tunnel(destination, GNUNET_YES);
681  ch->ctn = GCT_add_channel(ch->t, ch);
682  }
683  GNUNET_STATISTICS_update(stats, "# channels", 1, GNUNET_NO);
685  "Created channel to port %s at peer %s for %s using %s\n",
686  GNUNET_h2s(port),
687  GCP_2s(destination),
688  GSC_2s(owner),
689  (GNUNET_YES == ch->is_loopback) ? "loopback" : GCT_2s(ch->t));
690  return ch;
691 }
int out_of_order
Is the tunnel out-of-order?
static struct GNUNET_STATISTICS_Handle * stats
Handle for statistics.
static struct GNUNET_CADET_Channel * ch
Channel handle.
Definition: gnunet-cadet.c:117
enum CadetChannelState state
Channel state.
struct CadetTunnel * GCP_get_tunnel(struct CadetPeer *cp, int create)
Get the tunnel towards a peer.
const char * GCT_2s(const struct CadetTunnel *t)
Get the static string for the peer this tunnel is directed.
struct GNUNET_PeerIdentity my_full_id
Local peer own ID.
struct CadetChannelClient * owner
Client owner of the tunnel, if any.
uint32_t mid
Unique ID of the message, cycles around, in NBO.
int is_loopback
Is this channel a loopback channel, where the destination is us again?
#define CADET_INITIAL_RETRANSMIT_TIME
How long do we initially wait before retransmitting?
unsigned int max_pending_messages
Maximum (reliable) messages pending ACK for this channel before we throttle the client.
int nobuffer
Is the tunnel bufferless (minimum latency)?
#define GNUNET_NO
Definition: gnunet_common.h:78
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
#define GNUNET_new(type)
Allocate a struct or union of the given type.
void GCCH_hash_port(struct GNUNET_HashCode *h_port, const struct GNUNET_HashCode *port, const struct GNUNET_PeerIdentity *listener)
Hash the port and initiator and listener to calculate the "challenge" h_port we send to the other pee...
struct ChannelMessageIdentifier mid_recv
Next MID expected for incoming traffic.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
const char * GCP_2s(const struct CadetPeer *cp)
Get the static string for a peer ID.
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
struct GNUNET_CONTAINER_MultiHashMap * open_ports
All ports clients of this peer have opened.
int reliable
Is the tunnel reliable?
struct GNUNET_CONTAINER_MultiHashMap * loose_channels
Map from ports to channels where the ports were closed at the time we got the inbound connection...
struct CadetTunnel * t
Tunnel this channel is in.
#define LOG(level,...)
Struct containing all information regarding a channel to a remote client.
Channel is to a port that is not open, we're waiting for the port to be opened.
struct GNUNET_TIME_Relative retry_time
Counter for exponential backoff.
struct GNUNET_CADET_ClientChannelNumber ccn
Local tunnel number for this client.
struct GNUNET_HashCode port
Port number.
struct GNUNET_CADET_ChannelTunnelNumber GCT_add_channel(struct CadetTunnel *t, struct CadetChannel *ch)
Add a channel to a tunnel, and notify channel that we are ready for transmission if we are already up...
struct GNUNET_CADET_ChannelTunnelNumber ctn
Number identifying this channel in its tunnel.
int client_ready
Can we send data to the client?
int GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
Allow multiple values with the same key.
struct GNUNET_HashCode h_port
Hash'ed port of the channel with initiator and destination PID.
static uint16_t port
Port number.
Definition: gnunet-bcd.c:81
Client endpoint of a struct CadetChannel.
const char * GSC_2s(struct CadetClient *c)
Return identifier for a client as a string.
struct CadetClient * c
Client handle.
#define GNUNET_YES
Definition: gnunet_common.h:77
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:139
struct CadetClient * c
Client that opened the port.
Port opened by a client.
const struct GNUNET_PeerIdentity * GCP_get_id(struct CadetPeer *cp)
Obtain the peer identity for a struct CadetPeer.
void GCCH_bind(struct CadetChannel *ch, struct CadetClient *c, const struct GNUNET_HashCode *port)
A client is bound to the port that we have a channel open to.
struct GNUNET_HashCode port
Destination port of the channel.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ timeout_closed_cb()

static void timeout_closed_cb ( void *  cls)
static

We had an incoming channel to a port that is closed.

It has not been opened for a while, drop it.

Parameters
clsthe channel to drop

Definition at line 701 of file gnunet-service-cadet_channel.c.

References CadetReliableMessage::ch, channel_destroy(), GCP_2s(), GCT_get_destination(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), LOG, CadetChannel::port, CadetChannel::retry_control_task, and CadetChannel::t.

Referenced by GCCH_channel_incoming_new().

702 {
703  struct CadetChannel *ch = cls;
704 
705  ch->retry_control_task = NULL;
707  "Closing incoming channel to port %s from peer %s due to timeout\n",
708  GNUNET_h2s(&ch->port),
710  channel_destroy(ch);
711 }
static struct GNUNET_CADET_Channel * ch
Channel handle.
Definition: gnunet-cadet.c:117
struct CadetPeer * GCT_get_destination(struct CadetTunnel *t)
Return the peer to which this tunnel goes.
static void channel_destroy(struct CadetChannel *ch)
Destroy the given channel.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
const char * GCP_2s(const struct CadetPeer *cp)
Get the static string for a peer ID.
struct CadetTunnel * t
Tunnel this channel is in.
#define LOG(level,...)
Struct containing all information regarding a channel to a remote client.
struct GNUNET_SCHEDULER_Task * retry_control_task
Task to resend/poll in case no ACK is received.
struct GNUNET_HashCode port
Destination port of the channel.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCCH_channel_incoming_new()

struct CadetChannel* GCCH_channel_incoming_new ( struct CadetTunnel t,
struct GNUNET_CADET_ChannelTunnelNumber  ctn,
const struct GNUNET_HashCode h_port,
uint32_t  options 
)

Create a new channel based on a request coming in over the network.

Parameters
ttunnel to the remote peer
ctnidentifier of this channel in the tunnel
h_portdesired hash of local port
optionsoptions for the channel
Returns
handle to the new channel

Definition at line 724 of file gnunet-service-cadet_channel.c.

References OpenPort::c, CADET_CHANNEL_LOOSE, CADET_INITIAL_RETRANSMIT_TIME, CadetReliableMessage::ch, CadetChannel::ctn, GCCH_bind(), GCP_2s(), GCT_get_destination(), GNUNET_assert, GNUNET_CONTAINER_multihashmap_get(), GNUNET_CONTAINER_multihashmap_put(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE, GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_new, GNUNET_NO, GNUNET_SCHEDULER_add_delayed(), GNUNET_STATISTICS_update(), GNUNET_YES, OpenPort::h_port, CadetChannel::h_port, LOG, loose_channels, CadetChannel::max_pending_messages, CadetChannel::nobuffer, op, open_ports, CadetChannel::out_of_order, OpenPort::port, CadetChannel::port, CadetChannel::reliable, CadetChannel::retry_control_task, CadetChannel::retry_time, CadetChannel::state, stats, t, CadetChannel::t, timeout_closed_cb(), and TIMEOUT_CLOSED_PORT.

Referenced by handle_plaintext_channel_open().

728 {
729  struct CadetChannel *ch;
730  struct OpenPort *op;
731 
732  ch = GNUNET_new(struct CadetChannel);
733  ch->h_port = *h_port;
734  ch->t = t;
735  ch->ctn = ctn;
737  ch->nobuffer = GNUNET_NO;
738  ch->reliable = GNUNET_YES;
739  ch->out_of_order = GNUNET_NO;
741  (ch->nobuffer) ? 1 : 4; /* FIXME: 4!? Do not hardcode! */
742  GNUNET_STATISTICS_update(stats, "# channels", 1, GNUNET_NO);
743 
745  if (NULL == op)
746  {
747  /* port closed, wait for it to possibly open */
751  &ch->h_port,
752  ch,
754  GNUNET_assert(NULL == ch->retry_control_task);
757  ch);
759  "Created loose incoming channel to port %s from peer %s\n",
760  GNUNET_h2s(&ch->port),
762  }
763  else
764  {
765  GCCH_bind(ch, op->c, &op->port);
766  }
767  GNUNET_STATISTICS_update(stats, "# channels", 1, GNUNET_NO);
768  return ch;
769 }
int out_of_order
Is the tunnel out-of-order?
static struct GNUNET_STATISTICS_Handle * stats
Handle for statistics.
static struct GNUNET_CADET_Channel * ch
Channel handle.
Definition: gnunet-cadet.c:117
enum CadetChannelState state
Channel state.
struct CadetPeer * GCT_get_destination(struct CadetTunnel *t)
Return the peer to which this tunnel goes.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define CADET_INITIAL_RETRANSMIT_TIME
How long do we initially wait before retransmitting?
unsigned int max_pending_messages
Maximum (reliable) messages pending ACK for this channel before we throttle the client.
int nobuffer
Is the tunnel bufferless (minimum latency)?
#define GNUNET_NO
Definition: gnunet_common.h:78
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
#define GNUNET_new(type)
Allocate a struct or union of the given type.
static struct GNUNET_SCHEDULER_Task * t
Main task.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
const char * GCP_2s(const struct CadetPeer *cp)
Get the static string for a peer ID.
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
struct GNUNET_CONTAINER_MultiHashMap * open_ports
All ports clients of this peer have opened.
int reliable
Is the tunnel reliable?
struct GNUNET_CONTAINER_MultiHashMap * loose_channels
Map from ports to channels where the ports were closed at the time we got the inbound connection...
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1237
struct CadetTunnel * t
Tunnel this channel is in.
#define LOG(level,...)
struct GNUNET_HashCode h_port
Port hashed with our PID (matches incoming OPEN messages).
Struct containing all information regarding a channel to a remote client.
Channel is to a port that is not open, we're waiting for the port to be opened.
struct GNUNET_TIME_Relative retry_time
Counter for exponential backoff.
struct GNUNET_HashCode port
Port number.
#define TIMEOUT_CLOSED_PORT
How long do we wait before dropping state about incoming connection to closed port?
struct GNUNET_CADET_ChannelTunnelNumber ctn
Number identifying this channel in its tunnel.
int GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
Allow multiple values with the same key.
struct GNUNET_HashCode h_port
Hash'ed port of the channel with initiator and destination PID.
#define GNUNET_YES
Definition: gnunet_common.h:77
static void timeout_closed_cb(void *cls)
We had an incoming channel to a port that is closed.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:139
struct GNUNET_SCHEDULER_Task * retry_control_task
Task to resend/poll in case no ACK is received.
struct CadetClient * c
Client that opened the port.
Port opened by a client.
void GCCH_bind(struct CadetChannel *ch, struct CadetClient *c, const struct GNUNET_HashCode *port)
A client is bound to the port that we have a channel open to.
struct GNUNET_HashCode port
Destination port of the channel.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_ack_cb()

static void send_ack_cb ( void *  cls,
const struct GNUNET_CADET_ConnectionTunnelIdentifier cid 
)
static

Function called once the tunnel confirms that we sent the ACK message.

Just remembers it was sent, we do not expect ACKs for ACKs ;-).

Parameters
clsour struct CadetChannel.
cididentifier of the connection within the tunnel, NULL if transmission failed

Definition at line 782 of file gnunet-service-cadet_channel.c.

References CadetReliableMessage::ch, GNUNET_assert, and CadetChannel::last_control_qe.

Referenced by send_channel_data_ack(), and send_open_ack().

784 {
785  struct CadetChannel *ch = cls;
786 
787  GNUNET_assert(NULL != ch->last_control_qe);
788  ch->last_control_qe = NULL;
789 }
static struct GNUNET_CADET_Channel * ch
Channel handle.
Definition: gnunet-cadet.c:117
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
Struct containing all information regarding a channel to a remote client.
struct CadetTunnelQueueEntry * last_control_qe
Last entry in the tunnel's queue relating to control messages (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN...
Here is the caller graph for this function:

◆ send_channel_data_ack()

static void send_channel_data_ack ( struct CadetChannel ch)
static

Compute and send the current GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK to the other peer.

Parameters
chchannel to send the GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK for

Definition at line 798 of file gnunet-service-cadet_channel.c.

References CadetChannel::ctn, GNUNET_CADET_ChannelDataAckMessage::ctn, GNUNET_CADET_ChannelDataAckMessage::futures, GCCH_2s(), GCT_send(), GCT_send_cancel(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_htonll(), GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK, GNUNET_NO, GNUNET_CADET_ChannelDataAckMessage::header, CadetChannel::last_control_qe, LOG, ChannelMessageIdentifier::mid, GNUNET_CADET_ChannelDataAckMessage::mid, CadetChannel::mid_futures, CadetChannel::mid_recv, CadetChannel::reliable, send_ack_cb(), GNUNET_MessageHeader::size, CadetChannel::t, and GNUNET_MessageHeader::type.

Referenced by GCCH_handle_channel_plaintext_data(), and GCCH_handle_local_ack().

799 {
801 
802  if (GNUNET_NO == ch->reliable)
803  return; /* no ACKs */
805  msg.header.size = htons(sizeof(msg));
806  msg.ctn = ch->ctn;
807  msg.mid.mid = htonl(ntohl(ch->mid_recv.mid));
808  msg.futures = GNUNET_htonll(ch->mid_futures);
810  "Sending DATA_ACK %u:%llX via %s\n",
811  (unsigned int)ntohl(msg.mid.mid),
812  (unsigned long long)ch->mid_futures,
813  GCCH_2s(ch));
814  if (NULL != ch->last_control_qe)
816  ch->last_control_qe = GCT_send(ch->t, &msg.header, &send_ack_cb, ch);
817 }
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
struct CadetTunnelQueueEntry * GCT_send(struct CadetTunnel *t, const struct GNUNET_MessageHeader *message, GCT_SendContinuation cont, void *cont_cls)
Sends an already built message on a tunnel, encrypting it and choosing the best connection if not pro...
uint32_t mid
Unique ID of the message, cycles around, in NBO.
void GCT_send_cancel(struct CadetTunnelQueueEntry *tq)
Cancel a previously sent message while it's in the queue.
#define GNUNET_NO
Definition: gnunet_common.h:78
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
struct ChannelMessageIdentifier mid_recv
Next MID expected for incoming traffic.
int reliable
Is the tunnel reliable?
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
struct CadetTunnel * t
Tunnel this channel is in.
#define LOG(level,...)
struct GNUNET_CADET_ChannelTunnelNumber ctn
Number identifying this channel in its tunnel.
uint64_t GNUNET_htonll(uint64_t n)
Convert unsigned 64-bit integer to network byte order.
Definition: common_endian.c:35
Message to acknowledge end-to-end data.
const char * GCCH_2s(const struct CadetChannel *ch)
Get the static string for identification of the channel.
static void send_ack_cb(void *cls, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
Function called once the tunnel confirms that we sent the ACK message.
#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK
Confirm payload data end-to-end.
struct CadetTunnelQueueEntry * last_control_qe
Last entry in the tunnel's queue relating to control messages (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN...
uint64_t mid_futures
Bitfield of already-received messages past mid_recv.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_open_ack()

static void send_open_ack ( void *  cls)
static

Send our initial GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK to the client confirming that the connection is up.

Parameters
clsthe struct CadetChannel

Definition at line 827 of file gnunet-service-cadet_channel.c.

References CadetReliableMessage::ch, CadetChannel::ctn, GNUNET_CADET_ChannelOpenAckMessage::ctn, GCCH_2s(), GCT_send(), GCT_send_cancel(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK, GNUNET_CADET_ChannelOpenAckMessage::header, CadetChannel::last_control_qe, LOG, CadetChannel::port, GNUNET_CADET_ChannelOpenAckMessage::port, GNUNET_CADET_ChannelOpenAckMessage::reserved, CadetChannel::retry_control_task, send_ack_cb(), GNUNET_MessageHeader::size, CadetChannel::t, and GNUNET_MessageHeader::type.

Referenced by GCCH_bind(), and GCCH_handle_duplicate_open().

828 {
829  struct CadetChannel *ch = cls;
831 
832  ch->retry_control_task = NULL;
834  "Sending CHANNEL_OPEN_ACK on %s\n",
835  GCCH_2s(ch));
837  msg.header.size = htons(sizeof(msg));
838  msg.reserved = htonl(0);
839  msg.ctn = ch->ctn;
840  msg.port = ch->port;
841  if (NULL != ch->last_control_qe)
843  ch->last_control_qe = GCT_send(ch->t, &msg.header, &send_ack_cb, ch);
844 }
static struct GNUNET_CADET_Channel * ch
Channel handle.
Definition: gnunet-cadet.c:117
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
struct CadetTunnelQueueEntry * GCT_send(struct CadetTunnel *t, const struct GNUNET_MessageHeader *message, GCT_SendContinuation cont, void *cont_cls)
Sends an already built message on a tunnel, encrypting it and choosing the best connection if not pro...
void GCT_send_cancel(struct CadetTunnelQueueEntry *tq)
Cancel a previously sent message while it's in the queue.
#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK
Confirm the creation of a channel.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
struct CadetTunnel * t
Tunnel this channel is in.
#define LOG(level,...)
Struct containing all information regarding a channel to a remote client.
struct GNUNET_CADET_ChannelTunnelNumber ctn
Number identifying this channel in its tunnel.
Message to acknowledge opening a channel of type GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK.
const char * GCCH_2s(const struct CadetChannel *ch)
Get the static string for identification of the channel.
static void send_ack_cb(void *cls, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
Function called once the tunnel confirms that we sent the ACK message.
struct GNUNET_SCHEDULER_Task * retry_control_task
Task to resend/poll in case no ACK is received.
struct CadetTunnelQueueEntry * last_control_qe
Last entry in the tunnel's queue relating to control messages (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN...
struct GNUNET_HashCode port
Destination port of the channel.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCCH_handle_duplicate_open()

void GCCH_handle_duplicate_open ( struct CadetChannel ch,
const struct GNUNET_CADET_ConnectionTunnelIdentifier cti 
)

We got a GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN message again for this channel.

If the binding was successful, (re)transmit the GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK.

Parameters
chchannel that got the duplicate open
ctiidentifier of the connection that delivered the message

Definition at line 856 of file gnunet-service-cadet_channel.c.

References CadetChannel::dest, GCCH_2s(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_SCHEDULER_add_now(), LOG, CadetChannel::retry_control_task, and send_open_ack().

Referenced by handle_plaintext_channel_open().

859 {
860  if (NULL == ch->dest)
861  {
863  "Ignoring duplicate CHANNEL_OPEN on %s: port is closed\n",
864  GCCH_2s(ch));
865  return;
866  }
867  if (NULL != ch->retry_control_task)
868  {
870  "Ignoring duplicate CHANNEL_OPEN on %s: control message is pending\n",
871  GCCH_2s(ch));
872  return;
873  }
875  "Retransmitting CHANNEL_OPEN_ACK on %s\n",
876  GCCH_2s(ch));
878 }
struct CadetChannelClient * dest
Client destination of the tunnel, if any.
#define LOG(level,...)
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1264
const char * GCCH_2s(const struct CadetChannel *ch)
Get the static string for identification of the channel.
static void send_open_ack(void *cls)
Send our initial GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK to the client confirming that the connect...
struct GNUNET_SCHEDULER_Task * retry_control_task
Task to resend/poll in case no ACK is received.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_ack_to_client()

static void send_ack_to_client ( struct CadetChannel ch,
int  to_owner 
)
static

Send a GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK to the client to solicit more messages.

Parameters
chchannel the ack is for
to_ownerGNUNET_YES to send to owner, GNUNET_NO to send to dest

Definition at line 889 of file gnunet-service-cadet_channel.c.

References CadetChannelClient::c, GNUNET_CADET_LocalAck::ccn, CadetChannelClient::ccn, GNUNET_CADET_ClientChannelNumber::channel_of_client, CadetChannel::dest, CadetChannel::destroy, env, GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK, GNUNET_MQ_msg, GNUNET_YES, GSC_2s(), GSC_send_to_client(), LOG, CadetChannel::max_pending_messages, CadetChannel::owner, and CadetChannel::pending_messages.

Referenced by data_sent_cb(), GCCH_bind(), GCCH_handle_channel_open_ack(), GCCH_handle_local_ack(), GCCH_handle_local_data(), and handle_matching_ack().

890 {
891  struct GNUNET_MQ_Envelope *env;
892  struct GNUNET_CADET_LocalAck *ack;
893  struct CadetChannelClient *ccc;
894 
895  ccc = (GNUNET_YES == to_owner) ? ch->owner : ch->dest;
896  if (NULL == ccc)
897  {
898  /* This can happen if we are just getting ACKs after
899  our local client already disconnected. */
901  return;
902  }
904  ack->ccn = ccc->ccn;
906  "Sending CADET_LOCAL_ACK to %s (%s) at ccn %X (%u/%u pending)\n",
907  GSC_2s(ccc->c),
908  (GNUNET_YES == to_owner) ? "owner" : "dest",
909  ntohl(ack->ccn.channel_of_client),
910  ch->pending_messages,
912  GSC_send_to_client(ccc->c, env);
913 }
Message to allow the client send more data to the service (always service -> client).
Definition: cadet.h:212
uint32_t channel_of_client
Values for channel numbering.
Definition: cadet.h:110
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct CadetChannelClient * owner
Client owner of the tunnel, if any.
struct CadetChannelClient * dest
Client destination of the tunnel, if any.
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
unsigned int max_pending_messages
Maximum (reliable) messages pending ACK for this channel before we throttle the client.
#define GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK
Local ACK for data.
#define LOG(level,...)
struct GNUNET_CADET_ClientChannelNumber ccn
Local tunnel number for this client.
unsigned int pending_messages
Total (reliable) messages pending ACK for this channel.
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
struct GNUNET_CADET_ClientChannelNumber ccn
ID of the channel allowed to send more data.
Definition: cadet.h:221
int destroy
Flag to signal the destruction of the channel.
Client endpoint of a struct CadetChannel.
const char * GSC_2s(struct CadetClient *c)
Return identifier for a client as a string.
struct CadetClient * c
Client handle.
void GSC_send_to_client(struct CadetClient *c, struct GNUNET_MQ_Envelope *env)
Send a message to a client.
#define GNUNET_YES
Definition: gnunet_common.h:77
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCCH_bind()

void GCCH_bind ( struct CadetChannel ch,
struct CadetClient c,
const struct GNUNET_HashCode port 
)

A client is bound to the port that we have a channel open to.

Send the acknowledgement for the connection request and establish the link with the client.

Parameters
chopen incoming channel
cclient listening on the respective port
portthe port is listening on

Definition at line 926 of file gnunet-service-cadet_channel.c.

References CadetChannelClient::c, CADET_CHANNEL_OPEN_SENT, CADET_CHANNEL_READY, CadetChannelClient::ccn, GNUNET_CADET_ClientChannelNumber::channel_of_client, CadetChannelClient::client_ready, CadetChannel::dest, GCCH_2s(), GCCH_handle_channel_open_ack(), GCP_get(), GCT_2s(), GCT_get_destination(), GNUNET_assert, GNUNET_CADET_LOCAL_CHANNEL_ID_CLI, GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_new, GNUNET_NO, GNUNET_SCHEDULER_add_now(), GNUNET_SCHEDULER_cancel(), GNUNET_YES, GSC_2s(), GSC_bind(), CadetChannel::is_loopback, LOG, CadetChannel::max_pending_messages, ChannelMessageIdentifier::mid, CadetChannel::mid_recv, my_full_id, options, port, CadetChannel::port, CadetChannel::retry_control_task, send_ack_to_client(), send_open_ack(), CadetChannel::state, and CadetChannel::t.

Referenced by bind_loose_channel(), GCCH_channel_incoming_new(), and GCCH_channel_local_new().

929 {
930  uint32_t options;
931  struct CadetChannelClient *cccd;
932 
934  "Binding %s from %s to port %s of %s\n",
935  GCCH_2s(ch),
936  GCT_2s(ch->t),
937  GNUNET_h2s(&ch->port),
938  GSC_2s(c));
939  if (NULL != ch->retry_control_task)
940  {
941  /* there might be a timeout task here */
943  ch->retry_control_task = NULL;
944  }
945  options = 0;
946  cccd = GNUNET_new(struct CadetChannelClient);
947  GNUNET_assert(NULL == ch->dest);
948  ch->dest = cccd;
949  ch->port = *port;
950  cccd->c = c;
951  cccd->client_ready = GNUNET_YES;
952  cccd->ccn = GSC_bind(c,
953  ch,
954  (GNUNET_YES == ch->is_loopback)
956  : GCT_get_destination(ch->t),
957  port,
958  options);
959  GNUNET_assert(ntohl(cccd->ccn.channel_of_client) <
961  ch->mid_recv.mid = htonl(1); /* The OPEN counts as message 0! */
962  if (GNUNET_YES == ch->is_loopback)
963  {
965  GCCH_handle_channel_open_ack(ch, NULL, port);
966  }
967  else
968  {
969  /* notify other peer that we accepted the connection */
972  }
973  /* give client it's initial supply of ACKs */
974  GNUNET_assert(ntohl(cccd->ccn.channel_of_client) <
976  for (unsigned int i = 0; i < ch->max_pending_messages; i++)
978 }
Connection confirmed, ready to carry traffic.
enum CadetChannelState state
Channel state.
struct CadetPeer * GCT_get_destination(struct CadetTunnel *t)
Return the peer to which this tunnel goes.
uint32_t channel_of_client
Values for channel numbering.
Definition: cadet.h:110
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
const char * GCT_2s(const struct CadetTunnel *t)
Get the static string for the peer this tunnel is directed.
struct GNUNET_PeerIdentity my_full_id
Local peer own ID.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static void send_ack_to_client(struct CadetChannel *ch, int to_owner)
Send a GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK to the client to solicit more messages.
uint32_t mid
Unique ID of the message, cycles around, in NBO.
int is_loopback
Is this channel a loopback channel, where the destination is us again?
struct CadetChannelClient * dest
Client destination of the tunnel, if any.
unsigned int max_pending_messages
Maximum (reliable) messages pending ACK for this channel before we throttle the client.
#define GNUNET_NO
Definition: gnunet_common.h:78
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
#define GNUNET_new(type)
Allocate a struct or union of the given type.
struct ChannelMessageIdentifier mid_recv
Next MID expected for incoming traffic.
struct CadetTunnel * t
Tunnel this channel is in.
#define LOG(level,...)
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1264
struct GNUNET_CADET_ClientChannelNumber ccn
Local tunnel number for this client.
#define GNUNET_CADET_LOCAL_CHANNEL_ID_CLI
Minimum value for channel IDs of local clients.
Definition: cadet.h:71
void GCCH_handle_channel_open_ack(struct CadetChannel *ch, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti, const struct GNUNET_HashCode *port)
We got an acknowledgement for the creation of the channel (the port is open on the other side)...
CHANNEL_OPEN message sent, waiting for CHANNEL_OPEN_ACK.
int client_ready
Can we send data to the client?
const char * GCCH_2s(const struct CadetChannel *ch)
Get the static string for identification of the channel.
static uint16_t port
Port number.
Definition: gnunet-bcd.c:81
struct CadetPeer * GCP_get(const struct GNUNET_PeerIdentity *peer_id, int create)
Retrieve the CadetPeer stucture associated with the peer.
Client endpoint of a struct CadetChannel.
const char * GSC_2s(struct CadetClient *c)
Return identifier for a client as a string.
struct CadetClient * c
Client handle.
#define GNUNET_YES
Definition: gnunet_common.h:77
static void send_open_ack(void *cls)
Send our initial GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK to the client confirming that the connect...
struct GNUNET_SCHEDULER_Task * retry_control_task
Task to resend/poll in case no ACK is received.
struct GNUNET_CADET_ClientChannelNumber GSC_bind(struct CadetClient *c, struct CadetChannel *ch, struct CadetPeer *dest, const struct GNUNET_HashCode *port, uint32_t options)
Bind incoming channel to this client, and notify client about incoming connection.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:956
struct GNUNET_HashCode port
Destination port of the channel.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ signal_remote_destroy_cb()

static void signal_remote_destroy_cb ( void *  cls)
static

One of our clients has disconnected, tell the other one that we are finished.

Done asynchronously to avoid concurrent modification issues if this is the same client.

Parameters
clsthe struct CadetChannel where one of the ends is now dead

Definition at line 989 of file gnunet-service-cadet_channel.c.

References CadetChannelClient::c, CadetChannelClient::ccn, CadetReliableMessage::ch, channel_destroy(), CadetChannel::dest, GSC_handle_remote_channel_destroy(), CadetChannel::owner, and CadetChannel::retry_control_task.

Referenced by GCCH_channel_local_destroy().

990 {
991  struct CadetChannel *ch = cls;
992  struct CadetChannelClient *ccc;
993 
994  /* Find which end is left... */
995  ch->retry_control_task = NULL;
996  ccc = (NULL != ch->owner) ? ch->owner : ch->dest;
997  GSC_handle_remote_channel_destroy(ccc->c, ccc->ccn, ch);
998  channel_destroy(ch);
999 }
static struct GNUNET_CADET_Channel * ch
Channel handle.
Definition: gnunet-cadet.c:117
static void channel_destroy(struct CadetChannel *ch)
Destroy the given channel.
struct CadetChannelClient * owner
Client owner of the tunnel, if any.
struct CadetChannelClient * dest
Client destination of the tunnel, if any.
void GSC_handle_remote_channel_destroy(struct CadetClient *c, struct GNUNET_CADET_ClientChannelNumber ccn, struct CadetChannel *ch)
A channel was destroyed by the other peer.
Struct containing all information regarding a channel to a remote client.
struct GNUNET_CADET_ClientChannelNumber ccn
Local tunnel number for this client.
Client endpoint of a struct CadetChannel.
struct CadetClient * c
Client handle.
struct GNUNET_SCHEDULER_Task * retry_control_task
Task to resend/poll in case no ACK is received.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCCH_channel_local_destroy()

void GCCH_channel_local_destroy ( struct CadetChannel ch,
struct CadetClient c,
struct GNUNET_CADET_ClientChannelNumber  ccn 
)

Destroy locally created channel.

Called by the local client, so no need to tell the client.

Parameters
chchannel to destroy
cclient that caused the destruction
ccnclient number of the client c

Definition at line 1011 of file gnunet-service-cadet_channel.c.

References CadetChannelClient::c, CADET_CHANNEL_LOOSE, CADET_CHANNEL_NEW, CadetChannelClient::ccn, channel_destroy(), GNUNET_CADET_ClientChannelNumber::channel_of_client, CadetChannel::ctn, CadetChannel::dest, CadetChannel::destroy, free_channel_client(), GCCH_2s(), GCT_send_channel_destroy(), GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_NO, GNUNET_SCHEDULER_add_now(), GNUNET_SCHEDULER_cancel(), GNUNET_YES, GSC_2s(), CadetChannel::head_sent, CadetChannel::is_loopback, LOG, CadetChannel::owner, CadetChannel::retry_control_task, signal_remote_destroy_cb(), CadetChannel::state, and CadetChannel::t.

Referenced by channel_destroy_iterator(), and handle_channel_destroy().

1014 {
1016  "%s asks for destruction of %s\n",
1017  GSC_2s(c),
1018  GCCH_2s(ch));
1019  GNUNET_assert(NULL != c);
1020  if ((NULL != ch->owner) && (c == ch->owner->c) &&
1022  {
1024  ch->owner = NULL;
1025  }
1026  else if ((NULL != ch->dest) && (c == ch->dest->c) &&
1028  {
1030  ch->dest = NULL;
1031  }
1032  else
1033  {
1034  GNUNET_assert(0);
1035  }
1036 
1037  if (GNUNET_YES == ch->destroy)
1038  {
1039  /* other end already destroyed, with the local client gone, no need
1040  to finish transmissions, just destroy immediately. */
1041  channel_destroy(ch);
1042  return;
1043  }
1044  if ((NULL != ch->head_sent) && ((NULL != ch->owner) || (NULL != ch->dest)))
1045  {
1046  /* Wait for other end to destroy us as well,
1047  and otherwise allow send queue to be transmitted first */
1048  ch->destroy = GNUNET_YES;
1049  return;
1050  }
1051  if ((GNUNET_YES == ch->is_loopback) &&
1052  ((NULL != ch->owner) || (NULL != ch->dest)))
1053  {
1054  if (NULL != ch->retry_control_task)
1056  ch->retry_control_task =
1058  return;
1059  }
1060  if (GNUNET_NO == ch->is_loopback)
1061  {
1062  /* If the we ever sent the CHANNEL_CREATE, we need to send a destroy message. */
1063  switch (ch->state)
1064  {
1065  case CADET_CHANNEL_NEW:
1066  /* We gave up on a channel that we created as a client to a remote
1067  target, but that never went anywhere. Nothing to do here. */
1068  break;
1069 
1070  case CADET_CHANNEL_LOOSE:
1071  break;
1072 
1073  default:
1074  GCT_send_channel_destroy(ch->t, ch->ctn);
1075  }
1076  }
1077  /* Nothing left to do, just finish destruction */
1078  channel_destroy(ch);
1079 }
struct CadetReliableMessage * head_sent
Head of DLL of messages sent and not yet ACK&#39;d.
enum CadetChannelState state
Channel state.
static void channel_destroy(struct CadetChannel *ch)
Destroy the given channel.
uint32_t channel_of_client
Values for channel numbering.
Definition: cadet.h:110
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct CadetChannelClient * owner
Client owner of the tunnel, if any.
int is_loopback
Is this channel a loopback channel, where the destination is us again?
struct CadetChannelClient * dest
Client destination of the tunnel, if any.
Uninitialized status, should never appear in operation.
#define GNUNET_NO
Definition: gnunet_common.h:78
static void signal_remote_destroy_cb(void *cls)
One of our clients has disconnected, tell the other one that we are finished.
void GCT_send_channel_destroy(struct CadetTunnel *t, struct GNUNET_CADET_ChannelTunnelNumber ctn)
Send a DESTROY message via the tunnel.
static void free_channel_client(struct CadetChannelClient *ccc)
Release memory associated with ccc.
struct CadetTunnel * t
Tunnel this channel is in.
#define LOG(level,...)
Channel is to a port that is not open, we&#39;re waiting for the port to be opened.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1264
struct GNUNET_CADET_ClientChannelNumber ccn
Local tunnel number for this client.
struct GNUNET_CADET_ChannelTunnelNumber ctn
Number identifying this channel in its tunnel.
const char * GCCH_2s(const struct CadetChannel *ch)
Get the static string for identification of the channel.
int destroy
Flag to signal the destruction of the channel.
const char * GSC_2s(struct CadetClient *c)
Return identifier for a client as a string.
struct CadetClient * c
Client handle.
#define GNUNET_YES
Definition: gnunet_common.h:77
struct GNUNET_SCHEDULER_Task * retry_control_task
Task to resend/poll in case no ACK is received.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:956
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCCH_handle_channel_open_ack()

void GCCH_handle_channel_open_ack ( struct CadetChannel ch,
const struct GNUNET_CADET_ConnectionTunnelIdentifier cti,
const struct GNUNET_HashCode port 
)

We got an acknowledgement for the creation of the channel (the port is open on the other side).

Verify that the other end really has the right port, and begin transmissions.

Parameters
chchannel to destroy
ctiidentifier of the connection that delivered the message
portport number (needed to verify receiver knows the port)

Definition at line 1092 of file gnunet-service-cadet_channel.c.

References CADET_CHANNEL_LOOSE, CADET_CHANNEL_NEW, CADET_CHANNEL_OPEN_SENT, CADET_CHANNEL_READY, GCCH_2s(), GNUNET_break, GNUNET_break_op, GNUNET_ERROR_TYPE_DEBUG, GNUNET_memcmp, GNUNET_NO, GNUNET_SCHEDULER_cancel(), GNUNET_STATISTICS_update(), GNUNET_YES, LOG, CadetChannel::max_pending_messages, CadetChannel::owner, CadetChannel::port, CadetChannel::retry_control_task, send_ack_to_client(), CadetChannel::state, and stats.

Referenced by GCCH_bind(), and handle_plaintext_channel_open_ack().

1096 {
1097  switch (ch->state)
1098  {
1099  case CADET_CHANNEL_NEW:
1100  /* this should be impossible */
1101  GNUNET_break(0);
1102  break;
1103 
1104  case CADET_CHANNEL_LOOSE:
1105  /* This makes no sense. */
1106  GNUNET_break_op(0);
1107  break;
1108 
1110  if (NULL == ch->owner)
1111  {
1112  /* We're not the owner, wrong direction! */
1113  GNUNET_break_op(0);
1114  return;
1115  }
1116  if (0 != GNUNET_memcmp(&ch->port, port))
1117  {
1118  /* Other peer failed to provide the right port,
1119  refuse connection. */
1120  GNUNET_break_op(0);
1121  return;
1122  }
1124  "Received CHANNEL_OPEN_ACK for waiting %s, entering READY state\n",
1125  GCCH_2s(ch));
1126  if (NULL != ch->retry_control_task) /* can be NULL if ch->is_loopback */
1127  {
1129  ch->retry_control_task = NULL;
1130  }
1131  ch->state = CADET_CHANNEL_READY;
1132  /* On first connect, send client as many ACKs as we allow messages
1133  to be buffered! */
1134  for (unsigned int i = 0; i < ch->max_pending_messages; i++)
1136  break;
1137 
1138  case CADET_CHANNEL_READY:
1139  /* duplicate ACK, maybe we retried the CREATE. Ignore. */
1141  "Received duplicate channel OPEN_ACK for %s\n",
1142  GCCH_2s(ch));
1143  GNUNET_STATISTICS_update(stats, "# duplicate CREATE_ACKs", 1, GNUNET_NO);
1144  break;
1145  }
1146 }
static struct GNUNET_STATISTICS_Handle * stats
Handle for statistics.
Connection confirmed, ready to carry traffic.
enum CadetChannelState state
Channel state.
static void send_ack_to_client(struct CadetChannel *ch, int to_owner)
Send a GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK to the client to solicit more messages.
struct CadetChannelClient * owner
Client owner of the tunnel, if any.
Uninitialized status, should never appear in operation.
unsigned int max_pending_messages
Maximum (reliable) messages pending ACK for this channel before we throttle the client.
#define GNUNET_NO
Definition: gnunet_common.h:78
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define LOG(level,...)
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
Channel is to a port that is not open, we&#39;re waiting for the port to be opened.
CHANNEL_OPEN message sent, waiting for CHANNEL_OPEN_ACK.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
const char * GCCH_2s(const struct CadetChannel *ch)
Get the static string for identification of the channel.
#define GNUNET_YES
Definition: gnunet_common.h:77
struct GNUNET_SCHEDULER_Task * retry_control_task
Task to resend/poll in case no ACK is received.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:956
struct GNUNET_HashCode port
Destination port of the channel.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ is_before()

static int is_before ( void *  cls,
struct CadetOutOfOrderMessage m1,
struct CadetOutOfOrderMessage m2 
)
static

Test if element e1 comes before element e2.

Parameters
clsclosure, to a flag where we indicate duplicate packets
m1a message of to sort
m2another message to sort
Returns
GNUNET_YES if < , otherwise GNUNET_NO

Definition at line 1158 of file gnunet-service-cadet_channel.c.

References delta, GNUNET_NO, GNUNET_YES, INT_MAX, CadetOutOfOrderMessage::mid, and ChannelMessageIdentifier::mid.

Referenced by GCCH_handle_channel_plaintext_data().

1161 {
1162  int *duplicate = cls;
1163  uint32_t v1 = ntohl(m1->mid.mid);
1164  uint32_t v2 = ntohl(m2->mid.mid);
1165  uint32_t delta;
1166 
1167  delta = v2 - v1;
1168  if (0 == delta)
1169  *duplicate = GNUNET_YES;
1170  if (delta > (uint32_t)INT_MAX)
1171  {
1172  /* in overflow range, we can safely assume we wrapped around */
1173  return GNUNET_NO;
1174  }
1175  else
1176  {
1177  /* result is small, thus v2 > v1, thus m1 < m2 */
1178  return GNUNET_YES;
1179  }
1180 }
static struct GNUNET_TIME_Relative delta
Definition: speedup.c:35
uint32_t mid
Unique ID of the message, cycles around, in NBO.
#define GNUNET_NO
Definition: gnunet_common.h:78
#define INT_MAX
#define GNUNET_YES
Definition: gnunet_common.h:77
struct ChannelMessageIdentifier mid
ID of the message (messages up to this point needed before we give this one to the client)...
Here is the caller graph for this function:

◆ GCCH_handle_channel_plaintext_data()

void GCCH_handle_channel_plaintext_data ( struct CadetChannel ch,
const struct GNUNET_CADET_ConnectionTunnelIdentifier cti,
const struct GNUNET_CADET_ChannelAppDataMessage msg 
)

We got payload data for a channel.

Pass it on to the client and send an ACK to the other end (once flow control allows it!)

Parameters
chchannel that got data
ctiidentifier of the connection that delivered the message
msgmessage that was received

We always send if possible in this case. It is guaranteed that the queued MID < received MID

Definition at line 1192 of file gnunet-service-cadet_channel.c.

References CadetChannelClient::c, GNUNET_CADET_LocalData::ccn, CadetChannelClient::ccn, GNUNET_CADET_ClientChannelNumber::channel_of_client, CadetChannelClient::client_ready, CadetChannel::ctn, data_sent_cb(), delta, CadetChannel::dest, CadetChannel::destroy, env, CadetOutOfOrderMessage::env, GCCH_2s(), GCT_send_channel_destroy(), GNUNET_assert, GNUNET_CONTAINER_DLL_insert_sorted, GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA, GNUNET_MQ_discard(), GNUNET_MQ_msg_extra, GNUNET_new, GNUNET_NO, GNUNET_STATISTICS_update(), GNUNET_YES, GSC_2s(), GSC_send_to_client(), CadetChannelClient::head_recv, GNUNET_CADET_ChannelAppDataMessage::header, is_before(), CadetChannel::is_loopback, LOG, CadetChannel::max_pending_messages, CadetOutOfOrderMessage::mid, GNUNET_CADET_ChannelAppDataMessage::mid, ChannelMessageIdentifier::mid, CadetChannel::mid_futures, CadetChannel::mid_recv, CadetChannelClient::num_recv, CadetChannel::out_of_order, CadetChannel::owner, CadetChannel::reliable, send_channel_data_ack(), GNUNET_MessageHeader::size, stats, CadetChannel::t, and CadetChannelClient::tail_recv.

Referenced by handle_plaintext_data().

1196 {
1197  struct GNUNET_MQ_Envelope *env;
1198  struct GNUNET_CADET_LocalData *ld;
1199  struct CadetChannelClient *ccc;
1200  size_t payload_size;
1201  struct CadetOutOfOrderMessage *com;
1202  int duplicate;
1203  uint32_t mid_min;
1204  uint32_t mid_max;
1205  uint32_t mid_msg;
1206  uint32_t delta;
1207 
1209  if ((NULL == ch->owner) && (NULL == ch->dest))
1210  {
1211  /* This client is gone, but we still have messages to send to
1212  the other end (which is why @a ch is not yet dead). However,
1213  we cannot pass messages to our client anymore. */
1215  "Dropping incoming payload on %s as this end is already closed\n",
1216  GCCH_2s(ch));
1217  /* send back DESTROY notification to stop further retransmissions! */
1218  if (GNUNET_YES == ch->destroy)
1219  GCT_send_channel_destroy(ch->t, ch->ctn);
1220  return;
1221  }
1222  payload_size = ntohs(msg->header.size) - sizeof(*msg);
1223  env = GNUNET_MQ_msg_extra(ld,
1224  payload_size,
1226  ld->ccn = (NULL == ch->dest) ? ch->owner->ccn : ch->dest->ccn;
1227  GNUNET_memcpy(&ld[1], &msg[1], payload_size);
1228  ccc = (NULL != ch->owner) ? ch->owner : ch->dest;
1229  if (GNUNET_YES == ccc->client_ready)
1230  {
1231  /*
1232  * We ad-hoc send the message if
1233  * - The channel is out-of-order
1234  * - The channel is reliable and MID matches next expected MID
1235  * - The channel is unreliable and MID is before lowest seen MID
1236  */
1237  if ((GNUNET_YES == ch->out_of_order) ||
1238  ((msg->mid.mid == ch->mid_recv.mid) && (GNUNET_YES == ch->reliable)) ||
1239  ((GNUNET_NO == ch->reliable) &&
1240  (ntohl(msg->mid.mid) >= ntohl(ch->mid_recv.mid)) &&
1241  ((NULL == ccc->head_recv) ||
1242  (ntohl(msg->mid.mid) < ntohl(ccc->head_recv->mid.mid)))))
1243  {
1245  "Giving %u bytes of payload with MID %u from %s to client %s\n",
1246  (unsigned int)payload_size,
1247  ntohl(msg->mid.mid),
1248  GCCH_2s(ch),
1249  GSC_2s(ccc->c));
1250  ccc->client_ready = GNUNET_NO;
1251  GSC_send_to_client(ccc->c, env);
1252  if (GNUNET_NO == ch->out_of_order)
1253  ch->mid_recv.mid = htonl(1 + ntohl(msg->mid.mid));
1254  else
1255  ch->mid_recv.mid = htonl(1 + ntohl(ch->mid_recv.mid));
1256  ch->mid_futures >>= 1;
1257  if ((GNUNET_YES == ch->out_of_order) && (GNUNET_NO == ch->reliable))
1258  {
1259  /* possibly shift by more if we skipped messages */
1260  uint64_t delta = htonl(msg->mid.mid) - 1 - ntohl(ch->mid_recv.mid);
1261 
1262  if (delta > 63)
1263  ch->mid_futures = 0;
1264  else
1265  ch->mid_futures >>= delta;
1266  ch->mid_recv.mid = htonl(1 + ntohl(msg->mid.mid));
1267  }
1269  return;
1270  }
1271  }
1272 
1273  if (GNUNET_YES == ch->reliable)
1274  {
1275  /* check if message ought to be dropped because it is ancient/too distant/duplicate */
1276  mid_min = ntohl(ch->mid_recv.mid);
1277  mid_max = mid_min + ch->max_pending_messages;
1278  mid_msg = ntohl(msg->mid.mid);
1279  if (((uint32_t)(mid_msg - mid_min) > ch->max_pending_messages) ||
1280  ((uint32_t)(mid_max - mid_msg) > ch->max_pending_messages))
1281  {
1283  "%s at %u drops ancient or far-future message %u\n",
1284  GCCH_2s(ch),
1285  (unsigned int)mid_min,
1286  ntohl(msg->mid.mid));
1287 
1289  "# duplicate DATA (ancient or future)",
1290  1,
1291  GNUNET_NO);
1292  GNUNET_MQ_discard(env);
1294  return;
1295  }
1296  /* mark bit for future ACKs */
1297  delta = mid_msg - mid_min - 1; /* overflow/underflow are OK here */
1298  if (delta < 64)
1299  {
1300  if (0 != (ch->mid_futures & (1LLU << delta)))
1301  {
1302  /* Duplicate within the queue, drop also */
1304  "Duplicate payload of %u bytes on %s (mid %u) dropped\n",
1305  (unsigned int)payload_size,
1306  GCCH_2s(ch),
1307  ntohl(msg->mid.mid));
1308  GNUNET_STATISTICS_update(stats, "# duplicate DATA", 1, GNUNET_NO);
1309  GNUNET_MQ_discard(env);
1311  return;
1312  }
1313  ch->mid_futures |= (1LLU << delta);
1315  "Marked bit %llX for mid %u (base: %u); now: %llX\n",
1316  (1LLU << delta),
1317  mid_msg,
1318  mid_min,
1319  ch->mid_futures);
1320  }
1321  }
1322  else /* ! ch->reliable */
1323  {
1324  struct CadetOutOfOrderMessage *next_msg;
1325 
1330  if ((NULL != ccc->head_recv) && (GNUNET_YES == ccc->client_ready))
1331  {
1332  next_msg = ccc->head_recv;
1334  "Giving queued MID %u from %s to client %s\n",
1335  ntohl(next_msg->mid.mid),
1336  GCCH_2s(ch),
1337  GSC_2s(ccc->c));
1338  ccc->client_ready = GNUNET_NO;
1339  GSC_send_to_client(ccc->c, next_msg->env);
1340  ch->mid_recv.mid = htonl(1 + ntohl(next_msg->mid.mid));
1341  ch->mid_futures >>= 1;
1343  GNUNET_CONTAINER_DLL_remove(ccc->head_recv, ccc->tail_recv, next_msg);
1344  ccc->num_recv--;
1345  /* Do not process duplicate MID */
1346  if (msg->mid.mid == next_msg->mid.mid) /* Duplicate */
1347  {
1348  /* Duplicate within the queue, drop */
1350  "Message on %s (mid %u) dropped, duplicate\n",
1351  GCCH_2s(ch),
1352  ntohl(msg->mid.mid));
1353  GNUNET_free(next_msg);
1354  GNUNET_MQ_discard(env);
1355  return;
1356  }
1357  GNUNET_free(next_msg);
1358  }
1359 
1360  if (ntohl(msg->mid.mid) < ntohl(ch->mid_recv.mid)) /* Old */
1361  {
1362  /* Duplicate within the queue, drop */
1364  "Message on %s (mid %u) dropped, old.\n",
1365  GCCH_2s(ch),
1366  ntohl(msg->mid.mid));
1367  GNUNET_MQ_discard(env);
1368  return;
1369  }
1370 
1371  /* Channel is unreliable, so we do not ACK. But we also cannot
1372  allow buffering everything, so check if we have space... */
1373  if (ccc->num_recv >= ch->max_pending_messages)
1374  {
1375  struct CadetOutOfOrderMessage *drop;
1376 
1377  /* Yep, need to drop. Drop the oldest message in
1378  the buffer. */
1380  "Queue full due slow client on %s, dropping oldest message\n",
1381  GCCH_2s(ch));
1383  "# messages dropped due to slow client",
1384  1,
1385  GNUNET_NO);
1386  drop = ccc->head_recv;
1387  GNUNET_assert(NULL != drop);
1389  ccc->num_recv--;
1390  GNUNET_MQ_discard(drop->env);
1391  GNUNET_free(drop);
1392  }
1393  }
1394 
1395  /* Insert message into sorted out-of-order queue */
1396  com = GNUNET_new(struct CadetOutOfOrderMessage);
1397  com->mid = msg->mid;
1398  com->env = env;
1399  duplicate = GNUNET_NO;
1401  is_before,
1402  &duplicate,
1403  ccc->head_recv,
1404  ccc->tail_recv,
1405  com);
1406  ccc->num_recv++;
1407  if (GNUNET_YES == duplicate)
1408  {
1409  /* Duplicate within the queue, drop also (this is not covered by
1410  the case above if "delta" >= 64, which could be the case if
1411  max_pending_messages is also >= 64 or if our client is unready
1412  and we are seeing retransmissions of the message our client is
1413  blocked on. */
1415  "Duplicate payload of %u bytes on %s (mid %u) dropped\n",
1416  (unsigned int)payload_size,
1417  GCCH_2s(ch),
1418  ntohl(msg->mid.mid));
1419  GNUNET_STATISTICS_update(stats, "# duplicate DATA", 1, GNUNET_NO);
1421  ccc->num_recv--;
1422  GNUNET_MQ_discard(com->env);
1423  GNUNET_free(com);
1425  return;
1426  }
1428  "Queued %s payload of %u bytes on %s-%X(%p) (mid %u, need %u first)\n",
1429  (GNUNET_YES == ccc->client_ready) ? "out-of-order" : "client-not-ready",
1430  (unsigned int)payload_size,
1431  GCCH_2s(ch),
1432  ntohl(ccc->ccn.channel_of_client),
1433  ccc,
1434  ntohl(msg->mid.mid),
1435  ntohl(ch->mid_recv.mid));
1436  /* NOTE: this ACK we _could_ skip, as the packet is out-of-order and
1437  the sender may already be transmitting the previous one. Needs
1438  experimental evaluation to see if/when this ACK helps or
1439  hurts. (We might even want another option.) */
1441 }
int out_of_order
Is the tunnel out-of-order?
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
static int is_before(void *cls, struct CadetOutOfOrderMessage *m1, struct CadetOutOfOrderMessage *m2)
Test if element e1 comes before element e2.
static struct GNUNET_STATISTICS_Handle * stats
Handle for statistics.
static struct GNUNET_TIME_Relative delta
Definition: speedup.c:35
uint32_t channel_of_client
Values for channel numbering.
Definition: cadet.h:110
#define GNUNET_CONTAINER_DLL_insert_sorted(TYPE, comparator, comparator_cls, head, tail, element)
Insertion sort of element into DLL from head to tail sorted by comparator.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct CadetChannelClient * owner
Client owner of the tunnel, if any.
uint32_t mid
Unique ID of the message, cycles around, in NBO.
int is_loopback
Is this channel a loopback channel, where the destination is us again?
struct CadetChannelClient * dest
Client destination of the tunnel, if any.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
unsigned int max_pending_messages
Maximum (reliable) messages pending ACK for this channel before we throttle the client.
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_new(type)
Allocate a struct or union of the given type.
List of received out-of-order data messages.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
struct ChannelMessageIdentifier mid_recv
Next MID expected for incoming traffic.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
struct GNUNET_MQ_Envelope * env
The envelope with the payload of the out-of-order message.
unsigned int num_recv
Number of entries currently in head_recv DLL.
void GCT_send_channel_destroy(struct CadetTunnel *t, struct GNUNET_CADET_ChannelTunnelNumber ctn)
Send a DESTROY message via the tunnel.
int reliable
Is the tunnel reliable?
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct...
Definition: gnunet_mq_lib.h:52
struct CadetTunnel * t
Tunnel this channel is in.
#define LOG(level,...)
struct CadetOutOfOrderMessage * tail_recv
Tail DLL of messages received out of order or while client was unready.
struct GNUNET_CADET_ClientChannelNumber ccn
Local tunnel number for this client.
struct GNUNET_CADET_ClientChannelNumber ccn
ID of the channel.
Definition: cadet.h:194
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA.
void GNUNET_MQ_discard(struct GNUNET_MQ_Envelope *mqm)
Discard the message queue message, free all allocated resources.
Definition: mq.c:319
struct GNUNET_CADET_ChannelTunnelNumber ctn
Number identifying this channel in its tunnel.
int client_ready
Can we send data to the client?
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
const char * GCCH_2s(const struct CadetChannel *ch)
Get the static string for identification of the channel.
int destroy
Flag to signal the destruction of the channel.
struct ChannelMessageIdentifier mid
Unique ID of the payload message.
#define GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA
Payload client <-> service.
Client endpoint of a struct CadetChannel.
const char * GSC_2s(struct CadetClient *c)
Return identifier for a client as a string.
struct CadetClient * c
Client handle.
void GSC_send_to_client(struct CadetClient *c, struct GNUNET_MQ_Envelope *env)
Send a message to a client.
static void send_channel_data_ack(struct CadetChannel *ch)
Compute and send the current GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK to the other peer...
#define GNUNET_YES
Definition: gnunet_common.h:77
Message for cadet data traffic.
Definition: cadet.h:185
struct ChannelMessageIdentifier mid
ID of the message (messages up to this point needed before we give this one to the client)...
struct CadetOutOfOrderMessage * head_recv
Head of DLL of messages received out of order or while client was unready.
#define GNUNET_free(ptr)
Wrapper around free.
uint64_t mid_futures
Bitfield of already-received messages past mid_recv.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ data_sent_cb()

static void data_sent_cb ( void *  cls,
const struct GNUNET_CADET_ConnectionTunnelIdentifier cid 
)
static

Function called once the tunnel has sent one of our messages.

If the message is unreliable, simply frees the crm. If the message was reliable, calculate retransmission time and wait for ACK (or retransmit).

Parameters
clsthe struct CadetReliableMessage that was sent
cididentifier of the connection within the tunnel, NULL if transmission failed

Definition at line 1685 of file gnunet-service-cadet_channel.c.

References CadetConnectionMetrics::aged_latency, CadetReliableMessage::ch, cmp_crm_by_next_retry(), CadetReliableMessage::connection_taken, CadetReliableMessage::data_message, CadetReliableMessage::first_transmission_time, GCC_ack_expected(), GCC_get_metrics(), GCC_lookup(), GCCH_2s(), GNUNET_assert, GNUNET_CONTAINER_DLL_insert_sorted, GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_NO, GNUNET_SCHEDULER_add_at(), GNUNET_SCHEDULER_cancel(), GNUNET_STRINGS_relative_time_to_string(), GNUNET_SYSERR, GNUNET_TIME_absolute_get(), GNUNET_TIME_absolute_get_remaining(), GNUNET_TIME_relative_max(), GNUNET_TIME_relative_to_absolute(), GNUNET_TIME_STD_BACKOFF, GNUNET_YES, CadetChannel::head_sent, CadetChannel::is_loopback, LOG, GNUNET_CADET_ChannelAppDataMessage::mid, ChannelMessageIdentifier::mid, MIN_RTT_DELAY, CadetReliableMessage::next_retry, CadetReliableMessage::num_transmissions, CadetChannel::owner, CadetChannel::pending_messages, CadetReliableMessage::qe, GNUNET_TIME_Relative::rel_value_us, CadetChannel::reliable, CadetChannel::retry_data_task, CadetReliableMessage::retry_delay, CadetChannel::retry_time, retry_transmission(), send_ack_to_client(), and CadetChannel::tail_sent.

Referenced by GCCH_handle_channel_plaintext_data(), GCCH_handle_local_data(), and retry_transmission().

1687 {
1688  struct CadetReliableMessage *crm = cls;
1689  struct CadetChannel *ch = crm->ch;
1690 
1692  GNUNET_assert(NULL != crm->qe);
1693  crm->qe = NULL;
1695  if (GNUNET_NO == ch->reliable)
1696  {
1697  GNUNET_free(crm->data_message);
1698  GNUNET_free(crm);
1699  ch->pending_messages--;
1700  send_ack_to_client(ch, (NULL == ch->owner) ? GNUNET_NO : GNUNET_YES);
1701  return;
1702  }
1703  if (NULL == cid)
1704  {
1705  /* There was an error sending. */
1707  }
1708  else if (GNUNET_SYSERR != crm->num_transmissions)
1709  {
1710  /* Increment transmission counter, and possibly store @a cid
1711  if this was the first transmission. */
1712  crm->num_transmissions++;
1713  if (1 == crm->num_transmissions)
1714  {
1716  crm->connection_taken = *cid;
1717  GCC_ack_expected(cid);
1718  }
1719  }
1720  if ((0 == crm->retry_delay.rel_value_us) && (NULL != cid))
1721  {
1722  struct CadetConnection *cc = GCC_lookup(cid);
1723 
1724  if (NULL != cc)
1726  else
1727  crm->retry_delay = ch->retry_time;
1728  }
1732 
1735  NULL,
1736  ch->head_sent,
1737  ch->tail_sent,
1738  crm);
1740  "Message %u sent, next transmission on %s in %s\n",
1741  (unsigned int)ntohl(crm->data_message->mid.mid),
1742  GCCH_2s(ch),
1744  ch->head_sent->next_retry),
1745  GNUNET_YES));
1746  if (NULL == ch->head_sent->qe)
1747  {
1748  if (NULL != ch->retry_data_task)
1752  ch);
1753  }
1754 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
static struct GNUNET_CADET_Channel * ch
Channel handle.
Definition: gnunet-cadet.c:117
struct CadetChannel * ch
Which channel is this message in?
const struct CadetConnectionMetrics * GCC_get_metrics(struct CadetConnection *cc)
Obtain performance metrics from cc.
struct CadetReliableMessage * head_sent
Head of DLL of messages sent and not yet ACK&#39;d.
Info needed to retry a message in case it gets lost.
Low-level connection to a destination.
uint64_t rel_value_us
The actual value.
#define GNUNET_CONTAINER_DLL_insert_sorted(TYPE, comparator, comparator_cls, head, tail, element)
Insertion sort of element into DLL from head to tail sorted by comparator.
#define MIN_RTT_DELAY
How long do we wait at least before retransmitting ever?
struct GNUNET_TIME_Relative GNUNET_TIME_relative_max(struct GNUNET_TIME_Relative t1, struct GNUNET_TIME_Relative t2)
Return the maximum of two relative time values.
Definition: time.c:287
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition: time.c:246
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static void send_ack_to_client(struct CadetChannel *ch, int to_owner)
Send a GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK to the client to solicit more messages.
struct CadetChannelClient * owner
Client owner of the tunnel, if any.
uint32_t mid
Unique ID of the message, cycles around, in NBO.
int is_loopback
Is this channel a loopback channel, where the destination is us again?
struct GNUNET_SCHEDULER_Task * retry_data_task
Task to resend/poll in case no ACK is received.
#define GNUNET_NO
Definition: gnunet_common.h:78
static void retry_transmission(void *cls)
We need to retry a transmission, the last one took too long to be acknowledged.
int reliable
Is the tunnel reliable?
#define LOG(level,...)
struct GNUNET_TIME_Absolute next_retry
How soon should we retry if we fail to get an ACK? Messages in the queue are sorted by this value...
Struct containing all information regarding a channel to a remote client.
struct GNUNET_CADET_ConnectionTunnelIdentifier connection_taken
Identifier of the connection that this message took when it was first transmitted.
struct GNUNET_TIME_Relative retry_time
Counter for exponential backoff.
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
Definition: strings.c:686
struct GNUNET_CADET_ChannelAppDataMessage * data_message
Data message we are trying to send.
struct GNUNET_TIME_Relative aged_latency
Our current best estimate of the latency, based on a weighted average of at least latency_datapoints ...
unsigned int pending_messages
Total (reliable) messages pending ACK for this channel.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
static int cmp_crm_by_next_retry(void *cls, struct CadetReliableMessage *crm1, struct CadetReliableMessage *crm2)
Test if element e1 comes before element e2.
struct GNUNET_TIME_Absolute first_transmission_time
Time when we first successfully transmitted the message (that is, set num_transmissions to 1)...
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
#define GNUNET_TIME_STD_BACKOFF(r)
Perform our standard exponential back-off calculation, starting at 1 ms and then going by a factor of...
int num_transmissions
How often was this message transmitted? GNUNET_SYSERR if there was an error transmitting the message...
const char * GCCH_2s(const struct CadetChannel *ch)
Get the static string for identification of the channel.
struct CadetConnection * GCC_lookup(const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
Lookup a connection by its identifier.
struct CadetReliableMessage * tail_sent
Tail of DLL of messages sent and not yet ACK&#39;d.
struct ChannelMessageIdentifier mid
Unique ID of the payload message.
struct GNUNET_TIME_Relative retry_delay
How long do we wait for an ACK after transmission? Use for the back-off calculation.
struct CadetTunnelQueueEntry * qe
Entry in the tunnels queue for this message, NULL if it has left the tunnel.
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition: time.c:331
void GCC_ack_expected(const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
We sent a message for which we expect to receive an ACK via the connection identified by cti...
#define GNUNET_YES
Definition: gnunet_common.h:77
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_at(struct GNUNET_TIME_Absolute at, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run at the specified time.
Definition: scheduler.c:1214
#define GNUNET_free(ptr)
Wrapper around free.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:956
Here is the call graph for this function:
Here is the caller graph for this function:

◆ retry_transmission()

static void retry_transmission ( void *  cls)
static

We need to retry a transmission, the last one took too long to be acknowledged.

Parameters
clsthe struct CadetChannel where we need to retransmit

Definition at line 1466 of file gnunet-service-cadet_channel.c.

References CadetReliableMessage::ch, CadetReliableMessage::data_message, data_sent_cb(), GCCH_2s(), GCT_send(), GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, CadetChannel::head_sent, GNUNET_CADET_ChannelAppDataMessage::header, LOG, ChannelMessageIdentifier::mid, GNUNET_CADET_ChannelAppDataMessage::mid, CadetReliableMessage::qe, CadetChannel::retry_data_task, and CadetChannel::t.

Referenced by data_sent_cb(), and GCCH_handle_channel_plaintext_data_ack().

1467 {
1468  struct CadetChannel *ch = cls;
1469  struct CadetReliableMessage *crm = ch->head_sent;
1470 
1471  ch->retry_data_task = NULL;
1472  GNUNET_assert(NULL == crm->qe);
1474  "Retrying transmission on %s of message %u\n",
1475  GCCH_2s(ch),
1476  (unsigned int)ntohl(crm->data_message->mid.mid));
1477  crm->qe = GCT_send(ch->t, &crm->data_message->header, &data_sent_cb, crm);
1478  GNUNET_assert(NULL == ch->retry_data_task);
1479 }
static struct GNUNET_CADET_Channel * ch
Channel handle.
Definition: gnunet-cadet.c:117
struct CadetReliableMessage * head_sent
Head of DLL of messages sent and not yet ACK&#39;d.
Info needed to retry a message in case it gets lost.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct CadetTunnelQueueEntry * GCT_send(struct CadetTunnel *t, const struct GNUNET_MessageHeader *message, GCT_SendContinuation cont, void *cont_cls)
Sends an already built message on a tunnel, encrypting it and choosing the best connection if not pro...
uint32_t mid
Unique ID of the message, cycles around, in NBO.
struct GNUNET_SCHEDULER_Task * retry_data_task
Task to resend/poll in case no ACK is received.
struct CadetTunnel * t
Tunnel this channel is in.
#define LOG(level,...)
Struct containing all information regarding a channel to a remote client.
struct GNUNET_CADET_ChannelAppDataMessage * data_message
Data message we are trying to send.
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA.
const char * GCCH_2s(const struct CadetChannel *ch)
Get the static string for identification of the channel.
struct ChannelMessageIdentifier mid
Unique ID of the payload message.
struct CadetTunnelQueueEntry * qe
Entry in the tunnels queue for this message, NULL if it has left the tunnel.
static void data_sent_cb(void *cls, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
Function called once the tunnel has sent one of our messages.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_matching_ack()

static void handle_matching_ack ( struct CadetChannel ch,
const struct GNUNET_CADET_ConnectionTunnelIdentifier cti,
struct CadetReliableMessage crm 
)
static

We got an PLAINTEXT_DATA_ACK for a message in our queue, remove it from the queue and tell our client that it can send more.

Parameters
chthe channel that got the PLAINTEXT_DATA_ACK
ctiidentifier of the connection that delivered the message
crmthe message that got acknowledged

Definition at line 1491 of file gnunet-service-cadet_channel.c.

References CadetReliableMessage::connection_taken, CadetReliableMessage::data_message, CadetReliableMessage::first_transmission_time, GCC_ack_observed(), GCC_latency_observed(), GCCH_2s(), GCT_send_cancel(), GNUNET_assert, GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_memcmp, GNUNET_NO, GNUNET_TIME_absolute_get_duration(), GNUNET_YES, CadetChannel::head_sent, LOG, CadetChannel::max_pending_messages, GNUNET_CADET_ChannelAppDataMessage::mid, ChannelMessageIdentifier::mid, CadetReliableMessage::num_transmissions, CadetChannel::owner, CadetChannel::pending_messages, CadetReliableMessage::qe, send_ack_to_client(), and CadetChannel::tail_sent.

Referenced by GCCH_handle_channel_plaintext_data_ack().

1494 {
1496  ch->pending_messages--;
1499  "Received DATA_ACK on %s for message %u (%u ACKs pending)\n",
1500  GCCH_2s(ch),
1501  (unsigned int)ntohl(crm->data_message->mid.mid),
1502  ch->pending_messages);
1503  if (NULL != crm->qe)
1504  {
1505  GCT_send_cancel(crm->qe);
1506  crm->qe = NULL;
1507  }
1508  if ((1 == crm->num_transmissions) && (NULL != cti))
1509  {
1510  GCC_ack_observed(cti);
1511  if (0 == GNUNET_memcmp(cti, &crm->connection_taken))
1512  {
1515  crm->first_transmission_time));
1516  }
1517  }
1518  GNUNET_free(crm->data_message);
1519  GNUNET_free(crm);
1520  send_ack_to_client(ch, (NULL == ch->owner) ? GNUNET_NO : GNUNET_YES);
1521 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
struct CadetReliableMessage * head_sent
Head of DLL of messages sent and not yet ACK&#39;d.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static void send_ack_to_client(struct CadetChannel *ch, int to_owner)
Send a GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK to the client to solicit more messages.
struct CadetChannelClient * owner
Client owner of the tunnel, if any.
uint32_t mid
Unique ID of the message, cycles around, in NBO.
void GCT_send_cancel(struct CadetTunnelQueueEntry *tq)
Cancel a previously sent message while it&#39;s in the queue.
unsigned int max_pending_messages
Maximum (reliable) messages pending ACK for this channel before we throttle the client.
#define GNUNET_NO
Definition: gnunet_common.h:78
#define LOG(level,...)
struct GNUNET_CADET_ConnectionTunnelIdentifier connection_taken
Identifier of the connection that this message took when it was first transmitted.
void GCC_latency_observed(const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid, struct GNUNET_TIME_Relative latency)
We observed some the given latency on the connection identified by cti.
struct GNUNET_CADET_ChannelAppDataMessage * data_message
Data message we are trying to send.
unsigned int pending_messages
Total (reliable) messages pending ACK for this channel.
struct GNUNET_TIME_Absolute first_transmission_time
Time when we first successfully transmitted the message (that is, set num_transmissions to 1)...
int num_transmissions
How often was this message transmitted? GNUNET_SYSERR if there was an error transmitting the message...
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
const char * GCCH_2s(const struct CadetChannel *ch)
Get the static string for identification of the channel.
struct CadetReliableMessage * tail_sent
Tail of DLL of messages sent and not yet ACK&#39;d.
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_duration(struct GNUNET_TIME_Absolute whence)
Get the duration of an operation as the difference of the current time and the given start time "henc...
Definition: time.c:373
struct ChannelMessageIdentifier mid
Unique ID of the payload message.
struct CadetTunnelQueueEntry * qe
Entry in the tunnels queue for this message, NULL if it has left the tunnel.
void GCC_ack_observed(const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
We observed an ACK for a message that was originally sent via the connection identified by cti...
#define GNUNET_YES
Definition: gnunet_common.h:77
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCCH_handle_channel_plaintext_data_ack()

void GCCH_handle_channel_plaintext_data_ack ( struct CadetChannel ch,
const struct GNUNET_CADET_ConnectionTunnelIdentifier cti,
const struct GNUNET_CADET_ChannelDataAckMessage ack 
)

We got an acknowledgement for payload data for a channel.

Possibly resume transmissions.

Parameters
chchannel that got the ack
ctiidentifier of the connection that delivered the message
ackdetails about what was received

Definition at line 1533 of file gnunet-service-cadet_channel.c.

References CadetReliableMessage::data_message, delta, GNUNET_CADET_ChannelDataAckMessage::futures, GCCH_2s(), GNUNET_break, GNUNET_break_op, GNUNET_ERROR_TYPE_DEBUG, GNUNET_htonll(), GNUNET_NO, GNUNET_SCHEDULER_add_at(), GNUNET_SCHEDULER_cancel(), GNUNET_STATISTICS_update(), GNUNET_YES, handle_matching_ack(), CadetChannel::head_sent, CadetChannel::is_loopback, LOG, CadetChannel::max_pending_messages, ChannelMessageIdentifier::mid, GNUNET_CADET_ChannelAppDataMessage::mid, GNUNET_CADET_ChannelDataAckMessage::mid, CadetReliableMessage::next, CadetReliableMessage::next_retry, CadetReliableMessage::qe, CadetChannel::reliable, CadetChannel::retry_data_task, retry_transmission(), and stats.

Referenced by handle_plaintext_data_ack().

1537 {
1538  struct CadetReliableMessage *crm;
1539  struct CadetReliableMessage *crmn;
1540  int found;
1541  uint32_t mid_base;
1542  uint64_t mid_mask;
1543  unsigned int delta;
1544 
1546  if (GNUNET_NO == ch->reliable)
1547  {
1548  /* not expecting ACKs on unreliable channel, odd */
1549  GNUNET_break_op(0);
1550  return;
1551  }
1552  /* mid_base is the MID of the next message that the
1553  other peer expects (i.e. that is missing!), everything
1554  LOWER (but excluding mid_base itself) was received. */
1555  mid_base = ntohl(ack->mid.mid);
1556  mid_mask = GNUNET_htonll(ack->futures);
1557  found = GNUNET_NO;
1558  for (crm = ch->head_sent; NULL != crm; crm = crmn)
1559  {
1560  crmn = crm->next;
1561  delta = (unsigned int)(ntohl(crm->data_message->mid.mid) - mid_base);
1562  if (delta >= UINT_MAX - ch->max_pending_messages)
1563  {
1564  /* overflow, means crm was a bit in the past, so this ACK counts for it. */
1566  "Got DATA_ACK with base %u satisfying past message %u on %s\n",
1567  (unsigned int)mid_base,
1568  ntohl(crm->data_message->mid.mid),
1569  GCCH_2s(ch));
1570  handle_matching_ack(ch, cti, crm);
1571  found = GNUNET_YES;
1572  continue;
1573  }
1574  delta--;
1575  if (delta >= 64)
1576  continue;
1578  "Testing bit %llX for mid %u (base: %u)\n",
1579  (1LLU << delta),
1580  ntohl(crm->data_message->mid.mid),
1581  mid_base);
1582  if (0 != (mid_mask & (1LLU << delta)))
1583  {
1585  "Got DATA_ACK with mask for %u on %s\n",
1586  ntohl(crm->data_message->mid.mid),
1587  GCCH_2s(ch));
1588  handle_matching_ack(ch, cti, crm);
1589  found = GNUNET_YES;
1590  }
1591  }
1592  if (GNUNET_NO == found)
1593  {
1594  /* ACK for message we already dropped, might have been a
1595  duplicate ACK? Ignore. */
1597  "Duplicate DATA_ACK on %s, ignoring\n",
1598  GCCH_2s(ch));
1599  GNUNET_STATISTICS_update(stats, "# duplicate DATA_ACKs", 1, GNUNET_NO);
1600  return;
1601  }
1602  if (NULL != ch->retry_data_task)
1603  {
1605  ch->retry_data_task = NULL;
1606  }
1607  if ((NULL != ch->head_sent) && (NULL == ch->head_sent->qe))
1610  ch);
1611 }
static struct GNUNET_STATISTICS_Handle * stats
Handle for statistics.
uint64_t futures
Bitfield of already-received newer messages.
struct CadetReliableMessage * head_sent
Head of DLL of messages sent and not yet ACK&#39;d.
Info needed to retry a message in case it gets lost.
static struct GNUNET_TIME_Relative delta
Definition: speedup.c:35
uint32_t mid
Unique ID of the message, cycles around, in NBO.
int is_loopback
Is this channel a loopback channel, where the destination is us again?
struct GNUNET_SCHEDULER_Task * retry_data_task
Task to resend/poll in case no ACK is received.
unsigned int max_pending_messages
Maximum (reliable) messages pending ACK for this channel before we throttle the client.
#define GNUNET_NO
Definition: gnunet_common.h:78
static void retry_transmission(void *cls)
We need to retry a transmission, the last one took too long to be acknowledged.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
int reliable
Is the tunnel reliable?
static void handle_matching_ack(struct CadetChannel *ch, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti, struct CadetReliableMessage *crm)
We got an PLAINTEXT_DATA_ACK for a message in our queue, remove it from the queue and tell our client...
#define LOG(level,...)
struct GNUNET_TIME_Absolute next_retry
How soon should we retry if we fail to get an ACK? Messages in the queue are sorted by this value...
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
struct GNUNET_CADET_ChannelAppDataMessage * data_message
Data message we are trying to send.
struct ChannelMessageIdentifier mid
Next message ID expected.
uint64_t GNUNET_htonll(uint64_t n)
Convert unsigned 64-bit integer to network byte order.
Definition: common_endian.c:35
const char * GCCH_2s(const struct CadetChannel *ch)
Get the static string for identification of the channel.
struct CadetReliableMessage * next
Double linked list, FIFO style.
struct ChannelMessageIdentifier mid
Unique ID of the payload message.
struct CadetTunnelQueueEntry * qe
Entry in the tunnels queue for this message, NULL if it has left the tunnel.
#define GNUNET_YES
Definition: gnunet_common.h:77
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_at(struct GNUNET_TIME_Absolute at, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run at the specified time.
Definition: scheduler.c:1214
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:956
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCCH_handle_remote_destroy()

void GCCH_handle_remote_destroy ( struct CadetChannel ch,
const struct GNUNET_CADET_ConnectionTunnelIdentifier cti 
)

Destroy channel, based on the other peer closing the connection.

Also needs to remove this channel from the tunnel.

Parameters
chchannel to destroy
ctiidentifier of the connection that delivered the message, NULL if we are simulating receiving a destroy due to shutdown

Definition at line 1624 of file gnunet-service-cadet_channel.c.

References CadetChannelClient::c, CadetChannelClient::ccn, channel_destroy(), CadetChannel::dest, CadetChannel::destroy, GCCH_2s(), GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, GNUNET_NO, GNUNET_YES, GSC_handle_remote_channel_destroy(), CadetChannelClient::head_recv, CadetChannel::is_loopback, LOG, and CadetChannel::owner.

Referenced by destroy_remaining_channels(), and handle_plaintext_channel_destroy().

1627 {
1628  struct CadetChannelClient *ccc;
1629 
1632  "Received remote channel DESTROY for %s\n",
1633  GCCH_2s(ch));
1634  if (GNUNET_YES == ch->destroy)
1635  {
1636  /* Local client already gone, this is instant-death. */
1637  channel_destroy(ch);
1638  return;
1639  }
1640  ccc = (NULL != ch->owner) ? ch->owner : ch->dest;
1641  if ((NULL != ccc) && (NULL != ccc->head_recv))
1642  {
1644  "Lost end of transmission due to remote shutdown on %s\n",
1645  GCCH_2s(ch));
1646  /* FIXME: change API to notify client about truncated transmission! */
1647  }
1648  ch->destroy = GNUNET_YES;
1649  if (NULL != ccc)
1650  GSC_handle_remote_channel_destroy(ccc->c, ccc->ccn, ch);
1651  channel_destroy(ch);
1652 }
static void channel_destroy(struct CadetChannel *ch)
Destroy the given channel.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct CadetChannelClient * owner
Client owner of the tunnel, if any.
int is_loopback
Is this channel a loopback channel, where the destination is us again?
struct CadetChannelClient * dest
Client destination of the tunnel, if any.
#define GNUNET_NO
Definition: gnunet_common.h:78
void GSC_handle_remote_channel_destroy(struct CadetClient *c, struct GNUNET_CADET_ClientChannelNumber ccn, struct CadetChannel *ch)
A channel was destroyed by the other peer.
#define LOG(level,...)
struct GNUNET_CADET_ClientChannelNumber ccn
Local tunnel number for this client.
const char * GCCH_2s(const struct CadetChannel *ch)
Get the static string for identification of the channel.
int destroy
Flag to signal the destruction of the channel.
Client endpoint of a struct CadetChannel.
struct CadetClient * c
Client handle.
#define GNUNET_YES
Definition: gnunet_common.h:77
struct CadetOutOfOrderMessage * head_recv
Head of DLL of messages received out of order or while client was unready.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ cmp_crm_by_next_retry()

static int cmp_crm_by_next_retry ( void *  cls,
struct CadetReliableMessage crm1,
struct CadetReliableMessage crm2 
)
static

Test if element e1 comes before element e2.

Parameters
clsclosure, to a flag where we indicate duplicate packets
crm1an element of to sort
crm2another element to sort
Returns
GNUNET_YES if < , otherwise GNUNET_NO

Definition at line 1664 of file gnunet-service-cadet_channel.c.

References GNUNET_TIME_Absolute::abs_value_us, GNUNET_NO, GNUNET_YES, and CadetReliableMessage::next_retry.

Referenced by data_sent_cb().

1667 {
1668  if (crm1->next_retry.abs_value_us < crm2->next_retry.abs_value_us)
1669  return GNUNET_YES;
1670  return GNUNET_NO;
1671 }
#define GNUNET_NO
Definition: gnunet_common.h:78
uint64_t abs_value_us
The actual value.
struct GNUNET_TIME_Absolute next_retry
How soon should we retry if we fail to get an ACK? Messages in the queue are sorted by this value...
#define GNUNET_YES
Definition: gnunet_common.h:77
Here is the caller graph for this function:

◆ GCCH_handle_local_data()

int GCCH_handle_local_data ( struct CadetChannel ch,
struct GNUNET_CADET_ClientChannelNumber  sender_ccn,
const char *  buf,
size_t  buf_len 
)

Handle data given by a client.

Check whether the client is allowed to send in this tunnel, save if channel is reliable and send an ACK to the client if there is still buffer space in the tunnel.

Parameters
chChannel.
sender_ccnccn of the sender
bufpayload to transmit.
buf_lennumber of bytes in buf
Returns
GNUNET_OK if everything goes well, GNUNET_SYSERR in case of an error.

Definition at line 1772 of file gnunet-service-cadet_channel.c.

References CadetChannelClient::c, GNUNET_CADET_LocalData::ccn, CadetChannelClient::ccn, CadetReliableMessage::ch, GNUNET_CADET_ClientChannelNumber::channel_of_client, CadetChannelClient::client_ready, CadetChannel::ctn, GNUNET_CADET_ChannelAppDataMessage::ctn, CadetReliableMessage::data_message, data_sent_cb(), CadetChannel::dest, CadetChannel::destroy, env, CadetOutOfOrderMessage::env, GCCH_2s(), GCT_send(), GNUNET_assert, GNUNET_break, GNUNET_CONTAINER_DLL_insert_tail, GNUNET_ERROR_TYPE_DEBUG, GNUNET_malloc, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA, GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA, GNUNET_MQ_msg_extra, GNUNET_new, GNUNET_NO, GNUNET_OK, GNUNET_SCHEDULER_cancel(), GNUNET_SYSERR, GNUNET_YES, GSC_send_to_client(), CadetChannelClient::head_recv, CadetChannel::head_sent, GNUNET_CADET_ChannelAppDataMessage::header, CadetChannel::is_loopback, LOG, CadetChannel::max_pending_messages, ChannelMessageIdentifier::mid, GNUNET_CADET_ChannelAppDataMessage::mid, CadetChannel::mid_send, CadetChannelClient::num_recv, CadetChannel::owner, CadetChannel::pending_messages, CadetReliableMessage::qe, CadetChannel::retry_data_task, send_ack_to_client(), GNUNET_MessageHeader::size, CadetChannel::t, CadetChannelClient::tail_recv, CadetChannel::tail_sent, and GNUNET_MessageHeader::type.

Referenced by handle_local_data().

1776 {
1777  struct CadetReliableMessage *crm;
1778 
1779  if (ch->pending_messages >= ch->max_pending_messages)
1780  {
1781  GNUNET_break(0); /* Fails: #5370 */
1782  return GNUNET_SYSERR;
1783  }
1784  if (GNUNET_YES == ch->destroy)
1785  {
1786  /* we are going down, drop messages */
1787  return GNUNET_OK;
1788  }
1789  ch->pending_messages++;
1790 
1791  if (GNUNET_YES == ch->is_loopback)
1792  {
1793  struct CadetChannelClient *receiver;
1794  struct GNUNET_MQ_Envelope *env;
1795  struct GNUNET_CADET_LocalData *ld;
1796  int ack_to_owner;
1797 
1798  env =
1800  if ((NULL != ch->owner) &&
1801  (sender_ccn.channel_of_client == ch->owner->ccn.channel_of_client))
1802  {
1803  receiver = ch->dest;
1804  ack_to_owner = GNUNET_YES;
1805  }
1806  else if ((NULL != ch->dest) &&
1807  (sender_ccn.channel_of_client == ch->dest->ccn.channel_of_client))
1808  {
1809  receiver = ch->owner;
1810  ack_to_owner = GNUNET_NO;
1811  }
1812  else
1813  {
1814  GNUNET_break(0);
1815  return GNUNET_SYSERR;
1816  }
1817  GNUNET_assert(NULL != receiver);
1818  ld->ccn = receiver->ccn;
1819  GNUNET_memcpy(&ld[1], buf, buf_len);
1820  if (GNUNET_YES == receiver->client_ready)
1821  {
1822  ch->pending_messages--;
1823  GSC_send_to_client(receiver->c, env);
1824  send_ack_to_client(ch, ack_to_owner);
1825  }
1826  else
1827  {
1828  struct CadetOutOfOrderMessage *oom;
1829 
1830  oom = GNUNET_new(struct CadetOutOfOrderMessage);
1831  oom->env = env;
1833  receiver->tail_recv,
1834  oom);
1835  receiver->num_recv++;
1836  }
1837  return GNUNET_OK;
1838  }
1839 
1840  /* Everything is correct, send the message. */
1841  crm = GNUNET_malloc(sizeof(*crm));
1842  crm->ch = ch;
1843  crm->data_message = GNUNET_malloc(
1844  sizeof(struct GNUNET_CADET_ChannelAppDataMessage) + buf_len);
1845  crm->data_message->header.size =
1846  htons(sizeof(struct GNUNET_CADET_ChannelAppDataMessage) + buf_len);
1847  crm->data_message->header.type =
1849  ch->mid_send.mid = htonl(ntohl(ch->mid_send.mid) + 1);
1850  crm->data_message->mid = ch->mid_send;
1851  crm->data_message->ctn = ch->ctn;
1852  GNUNET_memcpy(&crm->data_message[1], buf, buf_len);
1855  "Sending message %u from local client to %s with %u bytes\n",
1856  ntohl(crm->data_message->mid.mid),
1857  GCCH_2s(ch),
1858  buf_len);
1859  if (NULL != ch->retry_data_task)
1860  {
1862  ch->retry_data_task = NULL;
1863  }
1864  crm->qe = GCT_send(ch->t, &crm->data_message->header, &data_sent_cb, crm);
1865  GNUNET_assert(NULL == ch->retry_data_task);
1866  return GNUNET_OK;
1867 }
static struct GNUNET_CADET_Channel * ch
Channel handle.
Definition: gnunet-cadet.c:117
struct CadetChannel * ch
Which channel is this message in?
struct CadetReliableMessage * head_sent
Head of DLL of messages sent and not yet ACK&#39;d.
Info needed to retry a message in case it gets lost.
uint32_t channel_of_client
Values for channel numbering.
Definition: cadet.h:110
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static void send_ack_to_client(struct CadetChannel *ch, int to_owner)
Send a GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK to the client to solicit more messages.
struct CadetTunnelQueueEntry * GCT_send(struct CadetTunnel *t, const struct GNUNET_MessageHeader *message, GCT_SendContinuation cont, void *cont_cls)
Sends an already built message on a tunnel, encrypting it and choosing the best connection if not pro...
struct CadetChannelClient * owner
Client owner of the tunnel, if any.
uint32_t mid
Unique ID of the message, cycles around, in NBO.
int is_loopback
Is this channel a loopback channel, where the destination is us again?
struct CadetChannelClient * dest
Client destination of the tunnel, if any.
struct GNUNET_SCHEDULER_Task * retry_data_task
Task to resend/poll in case no ACK is received.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
unsigned int max_pending_messages
Maximum (reliable) messages pending ACK for this channel before we throttle the client.
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#define GNUNET_new(type)
Allocate a struct or union of the given type.
List of received out-of-order data messages.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
struct GNUNET_MQ_Envelope * env
The envelope with the payload of the out-of-order message.
unsigned int num_recv
Number of entries currently in head_recv DLL.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA
Payload data (inside an encrypted tunnel).
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct...
Definition: gnunet_mq_lib.h:52
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
struct CadetTunnel * t
Tunnel this channel is in.
#define LOG(level,...)
struct CadetOutOfOrderMessage * tail_recv
Tail DLL of messages received out of order or while client was unready.
struct GNUNET_CADET_ClientChannelNumber ccn
Local tunnel number for this client.
struct GNUNET_CADET_ChannelAppDataMessage * data_message
Data message we are trying to send.
static char buf[2048]
Message for cadet data traffic.
unsigned int pending_messages
Total (reliable) messages pending ACK for this channel.
struct GNUNET_CADET_ClientChannelNumber ccn
ID of the channel.
Definition: cadet.h:194
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA.
struct GNUNET_CADET_ChannelTunnelNumber ctn
Number identifying this channel in its tunnel.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
int client_ready
Can we send data to the client?
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
const char * GCCH_2s(const struct CadetChannel *ch)
Get the static string for identification of the channel.
int destroy
Flag to signal the destruction of the channel.
struct CadetReliableMessage * tail_sent
Tail of DLL of messages sent and not yet ACK&#39;d.
struct ChannelMessageIdentifier mid
Unique ID of the payload message.
#define GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA
Payload client <-> service.
Client endpoint of a struct CadetChannel.
struct CadetClient * c
Client handle.
void GSC_send_to_client(struct CadetClient *c, struct GNUNET_MQ_Envelope *env)
Send a message to a client.
struct GNUNET_CADET_ChannelTunnelNumber ctn
ID of the channel.
struct CadetTunnelQueueEntry * qe
Entry in the tunnels queue for this message, NULL if it has left the tunnel.
static void data_sent_cb(void *cls, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
Function called once the tunnel has sent one of our messages.
#define GNUNET_YES
Definition: gnunet_common.h:77
Message for cadet data traffic.
Definition: cadet.h:185
struct ChannelMessageIdentifier mid_send
Next MID to use for outgoing traffic.
struct CadetOutOfOrderMessage * head_recv
Head of DLL of messages received out of order or while client was unready.
#define GNUNET_malloc(size)
Wrapper around malloc.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:956
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCCH_handle_local_ack()

void GCCH_handle_local_ack ( struct CadetChannel ch,
struct GNUNET_CADET_ClientChannelNumber  client_ccn 
)

Handle ACK from client on local channel.

Means the client is ready for more data, see if we have any for it.

Parameters
chchannel to destroy
client_ccnccn of the client sending the ack

Definition at line 1878 of file gnunet-service-cadet_channel.c.

References CadetChannelClient::c, CadetChannelClient::ccn, channel_destroy(), GNUNET_CADET_ClientChannelNumber::channel_of_client, CadetChannelClient::client_ready, CadetChannel::ctn, CadetChannel::dest, CadetChannel::destroy, CadetOutOfOrderMessage::env, GCCH_2s(), GCT_send_channel_destroy(), GNUNET_assert, GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_NO, GNUNET_YES, GSC_2s(), GSC_send_to_client(), CadetChannelClient::head_recv, CadetChannel::is_loopback, LOG, CadetOutOfOrderMessage::mid, ChannelMessageIdentifier::mid, CadetChannel::mid_futures, CadetChannel::mid_recv, CadetChannelClient::num_recv, CadetChannel::out_of_order, CadetChannel::owner, CadetChannel::reliable, send_ack_to_client(), send_channel_data_ack(), CadetChannel::t, and CadetChannelClient::tail_recv.

Referenced by handle_local_ack().

1880 {
1881  struct CadetChannelClient *ccc;
1882  struct CadetOutOfOrderMessage *com;
1883 
1884  if ((NULL != ch->owner) &&
1885  (ch->owner->ccn.channel_of_client == client_ccn.channel_of_client))
1886  ccc = ch->owner;
1887  else if ((NULL != ch->dest) &&
1888  (ch->dest->ccn.channel_of_client == client_ccn.channel_of_client))
1889  ccc = ch->dest;
1890  else
1891  GNUNET_assert(0);
1892  ccc->client_ready = GNUNET_YES;
1893  com = ccc->head_recv;
1894  if (NULL == com)
1895  {
1897  "Got LOCAL_ACK, %s-%X ready to receive more data, but none pending on %s-%X(%p)!\n",
1898  GSC_2s(ccc->c),
1899  ntohl(client_ccn.channel_of_client),
1900  GCCH_2s(ch),
1901  ntohl(ccc->ccn.channel_of_client),
1902  ccc);
1903  return; /* none pending */
1904  }
1905  if (GNUNET_YES == ch->is_loopback)
1906  {
1907  int to_owner;
1908 
1909  /* Messages are always in-order, just send */
1911  ccc->num_recv--;
1912  GSC_send_to_client(ccc->c, com->env);
1913  /* Notify sender that we can receive more */
1914  if ((NULL != ch->owner) &&
1916  {
1917  to_owner = GNUNET_NO;
1918  }
1919  else
1920  {
1921  GNUNET_assert((NULL != ch->dest) && (ccc->ccn.channel_of_client ==
1922  ch->dest->ccn.channel_of_client));
1923  to_owner = GNUNET_YES;
1924  }
1925  send_ack_to_client(ch, to_owner);
1926  GNUNET_free(com);
1927  return;
1928  }
1929 
1930  if ((com->mid.mid != ch->mid_recv.mid) && (GNUNET_NO == ch->out_of_order) &&
1931  (GNUNET_YES == ch->reliable))
1932  {
1934  "Got LOCAL_ACK, %s-%X ready to receive more data (but next one is out-of-order %u vs. %u)!\n",
1935  GSC_2s(ccc->c),
1936  ntohl(ccc->ccn.channel_of_client),
1937  ntohl(com->mid.mid),
1938  ntohl(ch->mid_recv.mid));
1939  return; /* missing next one in-order */
1940  }
1941 
1943  "Got LOCAL_ACK, giving payload message %u to %s-%X on %s\n",
1944  ntohl(com->mid.mid),
1945  GSC_2s(ccc->c),
1946  ntohl(ccc->ccn.channel_of_client),
1947  GCCH_2s(ch));
1948 
1949  /* all good, pass next message to client */
1951  ccc->num_recv--;
1952  /* FIXME: if unreliable, this is not aggressive
1953  enough, as it would be OK to have lost some! */
1954 
1955  ch->mid_recv.mid = htonl(1 + ntohl(com->mid.mid));
1956  ch->mid_futures >>= 1; /* equivalent to division by 2 */
1957  ccc->client_ready = GNUNET_NO;
1958  GSC_send_to_client(ccc->c, com->env);
1959  GNUNET_free(com);
1961  if (NULL != ccc->head_recv)
1962  return;
1963  if (GNUNET_NO == ch->destroy)
1964  return;
1965  GCT_send_channel_destroy(ch->t, ch->ctn);
1966  channel_destroy(ch);
1967 }
int out_of_order
Is the tunnel out-of-order?
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
static void channel_destroy(struct CadetChannel *ch)
Destroy the given channel.
uint32_t channel_of_client
Values for channel numbering.
Definition: cadet.h:110
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static void send_ack_to_client(struct CadetChannel *ch, int to_owner)
Send a GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK to the client to solicit more messages.
struct CadetChannelClient * owner
Client owner of the tunnel, if any.
uint32_t mid
Unique ID of the message, cycles around, in NBO.
int is_loopback
Is this channel a loopback channel, where the destination is us again?
struct CadetChannelClient * dest
Client destination of the tunnel, if any.
#define GNUNET_NO
Definition: gnunet_common.h:78
List of received out-of-order data messages.
struct ChannelMessageIdentifier mid_recv
Next MID expected for incoming traffic.
struct GNUNET_MQ_Envelope * env
The envelope with the payload of the out-of-order message.
unsigned int num_recv
Number of entries currently in head_recv DLL.
void GCT_send_channel_destroy(struct CadetTunnel *t, struct GNUNET_CADET_ChannelTunnelNumber ctn)
Send a DESTROY message via the tunnel.
int reliable
Is the tunnel reliable?
struct CadetTunnel * t
Tunnel this channel is in.
#define LOG(level,...)
struct CadetOutOfOrderMessage * tail_recv
Tail DLL of messages received out of order or while client was unready.
struct GNUNET_CADET_ClientChannelNumber ccn
Local tunnel number for this client.
struct GNUNET_CADET_ChannelTunnelNumber ctn
Number identifying this channel in its tunnel.
int client_ready
Can we send data to the client?
const char * GCCH_2s(const struct CadetChannel *ch)
Get the static string for identification of the channel.
int destroy
Flag to signal the destruction of the channel.
Client endpoint of a struct CadetChannel.
const char * GSC_2s(struct CadetClient *c)
Return identifier for a client as a string.
struct CadetClient * c
Client handle.
void GSC_send_to_client(struct CadetClient *c, struct GNUNET_MQ_Envelope *env)
Send a message to a client.
static void send_channel_data_ack(struct CadetChannel *ch)
Compute and send the current GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK to the other peer...
#define GNUNET_YES
Definition: gnunet_common.h:77
struct ChannelMessageIdentifier mid
ID of the message (messages up to this point needed before we give this one to the client)...
struct CadetOutOfOrderMessage * head_recv
Head of DLL of messages received out of order or while client was unready.
#define GNUNET_free(ptr)
Wrapper around free.
uint64_t mid_futures
Bitfield of already-received messages past mid_recv.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCCH_debug()

void GCCH_debug ( struct CadetChannel ch,
enum GNUNET_ErrorType  level 
)

Log channel info.

Parameters
chChannel.
levelDebug level to use.

Definition at line 1981 of file gnunet-service-cadet_channel.c.

References CadetChannelClient::c, CadetChannelClient::ccn, GNUNET_CADET_ClientChannelNumber::channel_of_client, CadetChannelClient::client_ready, CadetChannel::ctn, CadetChannel::dest, GCT_2s(), GNUNET_ERROR_TYPE_BULK, GNUNET_get_log_call_status(), GSC_2s(), LOG2, ChannelMessageIdentifier::mid, CadetChannel::mid_futures, CadetChannel::mid_recv, CadetChannel::mid_send, CadetChannel::owner, and CadetChannel::t.

Referenced by debug_channel().

1982 {
1983 #if !defined(GNUNET_CULL_LOGGING)
1984  int do_log;
1985 
1987  "cadet-chn",
1988  __FILE__,
1989  __FUNCTION__,
1990  __LINE__);
1991  if (0 == do_log)
1992  return;
1993 
1994  if (NULL == ch)
1995  {
1996  LOG2(level, "CHN *** DEBUG NULL CHANNEL ***\n");
1997  return;
1998  }
1999  LOG2(level, "CHN %s:%X (%p)\n", GCT_2s(ch->t), ch->ctn, ch);
2000  if (NULL != ch->owner)
2001  {
2002  LOG2(level,
2003  "CHN origin %s ready %s local-id: %u\n",
2004  GSC_2s(ch->owner->c),
2005  ch->owner->client_ready ? "YES" : "NO",
2006  ntohl(ch->owner->ccn.channel_of_client));
2007  }
2008  if (NULL != ch->dest)
2009  {
2010  LOG2(level,
2011  "CHN destination %s ready %s local-id: %u\n",
2012  GSC_2s(ch->dest->c),
2013  ch->dest->client_ready ? "YES" : "NO",
2014  ntohl(ch->dest->ccn.channel_of_client));
2015  }
2016  LOG2(level,
2017  "CHN Message IDs recv: %d (%LLX), send: %d\n",
2018  ntohl(ch->mid_recv.mid),
2019  (unsigned long long)ch->mid_futures,
2020  ntohl(ch->mid_send.mid));
2021 #endif
2022 }
uint32_t channel_of_client
Values for channel numbering.
Definition: cadet.h:110
const char * GCT_2s(const struct CadetTunnel *t)
Get the static string for the peer this tunnel is directed.
struct CadetChannelClient * owner
Client owner of the tunnel, if any.
uint32_t mid
Unique ID of the message, cycles around, in NBO.
struct CadetChannelClient * dest
Client destination of the tunnel, if any.
struct ChannelMessageIdentifier mid_recv
Next MID expected for incoming traffic.
struct CadetTunnel * t
Tunnel this channel is in.
struct GNUNET_CADET_ClientChannelNumber ccn
Local tunnel number for this client.
struct GNUNET_CADET_ChannelTunnelNumber ctn
Number identifying this channel in its tunnel.
int GNUNET_get_log_call_status(int caller_level, const char *comp, const char *file, const char *function, int line)
Decides whether a particular logging call should or should not be allowed to be made.
#define LOG2(level,...)
int client_ready
Can we send data to the client?
const char * GSC_2s(struct CadetClient *c)
Return identifier for a client as a string.
struct CadetClient * c
Client handle.
struct ChannelMessageIdentifier mid_send
Next MID to use for outgoing traffic.
uint64_t mid_futures
Bitfield of already-received messages past mid_recv.
Here is the call graph for this function:
Here is the caller graph for this function: