GNUnet  0.10.x
Functions
gnunet-service-cadet_channel.h File Reference

GNUnet CADET service with encryption. More...

#include "gnunet-service-cadet.h"
#include "gnunet-service-cadet_peer.h"
#include "cadet_protocol.h"
Include dependency graph for gnunet-service-cadet_channel.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

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...
 
const char * GCCH_2s (const struct CadetChannel *ch)
 Get the static string for identification of the channel. More...
 
void GCCH_debug (struct CadetChannel *ch, enum GNUNET_ErrorType level)
 Log channel info. More...
 
struct GNUNET_CADET_ChannelTunnelNumber GCCH_get_id (const struct CadetChannel *ch)
 Get the channel's public ID. More...
 
struct CadetChannelGCCH_channel_local_new (struct CadetClient *owner, struct GNUNET_CADET_ClientChannelNumber owner_id, struct CadetPeer *destination, const struct GNUNET_HashCode *port, uint32_t options)
 Create a new channel. 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...
 
void GCCH_channel_local_destroy (struct CadetChannel *ch, struct CadetClient *c, struct GNUNET_CADET_ClientChannelNumber ccn)
 Destroy locally created channel. 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_incoming_new (struct CadetTunnel *t, struct GNUNET_CADET_ChannelTunnelNumber chid, const struct GNUNET_HashCode *h_port, uint32_t options)
 Create a new channel based on a request coming in over the network. 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...
 
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...
 
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_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...
 
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...
 
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...
 

Detailed Description

GNUnet CADET service with encryption.

Author
Bartlomiej Polot
Christian Grothoff

Definition in file gnunet-service-cadet_channel.h.

Function Documentation

◆ 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 423 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().

426 {
427  struct GNUNET_HashContext *hc;
428 
431  port,
432  sizeof (*port));
434  listener,
435  sizeof (*listener));
437  h_port);
439  "Calculated port hash %s\n",
440  GNUNET_h2s (h_port));
441 }
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:446
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:472
void GNUNET_CRYPTO_hash_context_finish(struct GNUNET_HashContext *hc, struct GNUNET_HashCode *r_hash)
Finish the hash computation.
Definition: crypto_hash.c:489
Here is the call graph for this function:
Here is the caller graph for this function:

◆ 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 395 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().

396 {
397  static char buf[128];
398 
399  GNUNET_snprintf (buf,
400  sizeof (buf),
401  "Channel %s:%s ctn:%X(%X/%X)",
402  (GNUNET_YES == ch->is_loopback)
403  ? "loopback"
405  GNUNET_h2s (&ch->port),
406  ch->ctn,
407  (NULL == ch->owner) ? 0 : ntohl (ch->owner->ccn.channel_of_client),
408  (NULL == ch->dest) ? 0 : ntohl (ch->dest->ccn.channel_of_client));
409  return buf;
410 }
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:111
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:80
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_debug()

void GCCH_debug ( struct CadetChannel ch,
enum GNUNET_ErrorType  level 
)

Log channel info.

Parameters
chChannel.
levelDebug level to use.

Definition at line 2129 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().

2131 {
2132 #if !defined(GNUNET_CULL_LOGGING)
2133  int do_log;
2134 
2136  "cadet-chn",
2137  __FILE__, __FUNCTION__, __LINE__);
2138  if (0 == do_log)
2139  return;
2140 
2141  if (NULL == ch)
2142  {
2143  LOG2 (level, "CHN *** DEBUG NULL CHANNEL ***\n");
2144  return;
2145  }
2146  LOG2 (level,
2147  "CHN %s:%X (%p)\n",
2148  GCT_2s (ch->t),
2149  ch->ctn,
2150  ch);
2151  if (NULL != ch->owner)
2152  {
2153  LOG2 (level,
2154  "CHN origin %s ready %s local-id: %u\n",
2155  GSC_2s (ch->owner->c),
2156  ch->owner->client_ready ? "YES" : "NO",
2157  ntohl (ch->owner->ccn.channel_of_client));
2158  }
2159  if (NULL != ch->dest)
2160  {
2161  LOG2 (level,
2162  "CHN destination %s ready %s local-id: %u\n",
2163  GSC_2s (ch->dest->c),
2164  ch->dest->client_ready ? "YES" : "NO",
2165  ntohl (ch->dest->ccn.channel_of_client));
2166  }
2167  LOG2 (level,
2168  "CHN Message IDs recv: %d (%LLX), send: %d\n",
2169  ntohl (ch->mid_recv.mid),
2170  (unsigned long long) ch->mid_futures,
2171  ntohl (ch->mid_send.mid));
2172 #endif
2173 }
uint32_t channel_of_client
Values for channel numbering.
Definition: cadet.h:111
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:

◆ 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 452 of file gnunet-service-cadet_channel.c.

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

453 {
454  return ch->ctn;
455 }
struct GNUNET_CADET_ChannelTunnelNumber ctn
Number identifying this channel in its tunnel.

◆ 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
owner_idlocal chid 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
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 657 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_CADET_OPTION_NOBUFFER, GNUNET_CADET_OPTION_OUT_OF_ORDER, GNUNET_CADET_OPTION_RELIABLE, 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().

662 {
663  struct CadetChannel *ch;
664  struct CadetChannelClient *ccco;
665 
666  ccco = GNUNET_new (struct CadetChannelClient);
667  ccco->c = owner;
668  ccco->ccn = ccn;
669  ccco->client_ready = GNUNET_YES;
670 
671  ch = GNUNET_new (struct CadetChannel);
672  ch->mid_recv.mid = htonl (1); /* The OPEN_ACK counts as message 0! */
676  ch->max_pending_messages = (ch->nobuffer) ? 1 : 4; /* FIXME: 4!? Do not hardcode! */
677  ch->owner = ccco;
678  ch->port = *port;
679  GCCH_hash_port (&ch->h_port,
680  port,
681  GCP_get_id (destination));
682  if (0 == GNUNET_memcmp (&my_full_id,
683  GCP_get_id (destination)))
684  {
685  struct OpenPort *op;
686 
687  ch->is_loopback = GNUNET_YES;
689  &ch->h_port);
690  if (NULL == op)
691  {
692  /* port closed, wait for it to possibly open */
695  &ch->h_port,
696  ch,
699  "Created loose incoming loopback channel to port %s\n",
700  GNUNET_h2s (&ch->port));
701  }
702  else
703  {
704  GCCH_bind (ch,
705  op->c,
706  &op->port);
707  }
708  }
709  else
710  {
711  ch->t = GCP_get_tunnel (destination,
712  GNUNET_YES);
714  ch->ctn = GCT_add_channel (ch->t,
715  ch);
716  }
718  "# channels",
719  1,
720  GNUNET_NO);
722  "Created channel to port %s at peer %s for %s using %s\n",
723  GNUNET_h2s (port),
724  GCP_2s (destination),
725  GSC_2s (owner),
726  (GNUNET_YES == ch->is_loopback) ? "loopback" : GCT_2s (ch->t));
727  return ch;
728 }
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.
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.
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?
Enable channel reliability, lost messages will be retransmitted.
#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:81
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...
Enable out of order delivery of messages.
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:79
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:80
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.
Disable buffering on intermediate nodes (for minimum latency).
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_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
portport number c is listening on

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 981 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_CADET_OPTION_NOBUFFER, GNUNET_CADET_OPTION_OUT_OF_ORDER, GNUNET_CADET_OPTION_RELIABLE, 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, CadetChannel::nobuffer, options, CadetChannel::out_of_order, port, CadetChannel::port, CadetChannel::reliable, 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().

984 {
985  uint32_t options;
986  struct CadetChannelClient *cccd;
987 
989  "Binding %s from %s to port %s of %s\n",
990  GCCH_2s (ch),
991  GCT_2s (ch->t),
992  GNUNET_h2s (&ch->port),
993  GSC_2s (c));
994  if (NULL != ch->retry_control_task)
995  {
996  /* there might be a timeout task here */
998  ch->retry_control_task = NULL;
999  }
1000  options = 0;
1001  if (ch->nobuffer)
1002  options |= GNUNET_CADET_OPTION_NOBUFFER;
1003  if (ch->reliable)
1004  options |= GNUNET_CADET_OPTION_RELIABLE;
1005  if (ch->out_of_order)
1007  cccd = GNUNET_new (struct CadetChannelClient);
1008  GNUNET_assert (NULL == ch->dest);
1009  ch->dest = cccd;
1010  ch->port = *port;
1011  cccd->c = c;
1012  cccd->client_ready = GNUNET_YES;
1013  cccd->ccn = GSC_bind (c,
1014  ch,
1015  (GNUNET_YES == ch->is_loopback)
1016  ? GCP_get (&my_full_id,
1017  GNUNET_YES)
1018  : GCT_get_destination (ch->t),
1019  port,
1020  options);
1021  GNUNET_assert (ntohl (cccd->ccn.channel_of_client) <
1023  ch->mid_recv.mid = htonl (1); /* The OPEN counts as message 0! */
1024  if (GNUNET_YES == ch->is_loopback)
1025  {
1028  NULL,
1029  port);
1030  }
1031  else
1032  {
1033  /* notify other peer that we accepted the connection */
1034  ch->state = CADET_CHANNEL_READY;
1035  ch->retry_control_task
1037  ch);
1038  }
1039  /* give client it's initial supply of ACKs */
1040  GNUNET_assert (ntohl (cccd->ccn.channel_of_client) <
1042  for (unsigned int i=0;i<ch->max_pending_messages;i++)
1043  send_ack_to_client (ch,
1044  GNUNET_NO);
1045 }
int out_of_order
Is the tunnel out-of-order?
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:111
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.
Enable channel reliability, lost messages will be retransmitted.
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:81
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.
int reliable
Is the tunnel reliable?
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:1273
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
Enable out of order delivery of messages.
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:79
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:80
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.
Disable buffering on intermediate nodes (for minimum latency).
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:965
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_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 1080 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().

1083 {
1085  "%s asks for destruction of %s\n",
1086  GSC_2s (c),
1087  GCCH_2s (ch));
1088  GNUNET_assert (NULL != c);
1089  if ( (NULL != ch->owner) &&
1090  (c == ch->owner->c) &&
1092  {
1093  free_channel_client (ch->owner);
1094  ch->owner = NULL;
1095  }
1096  else if ( (NULL != ch->dest) &&
1097  (c == ch->dest->c) &&
1099  {
1100  free_channel_client (ch->dest);
1101  ch->dest = NULL;
1102  }
1103  else
1104  {
1105  GNUNET_assert (0);
1106  }
1107 
1108  if (GNUNET_YES == ch->destroy)
1109  {
1110  /* other end already destroyed, with the local client gone, no need
1111  to finish transmissions, just destroy immediately. */
1112  channel_destroy (ch);
1113  return;
1114  }
1115  if ( (NULL != ch->head_sent) &&
1116  ( (NULL != ch->owner) ||
1117  (NULL != ch->dest) ) )
1118  {
1119  /* Wait for other end to destroy us as well,
1120  and otherwise allow send queue to be transmitted first */
1121  ch->destroy = GNUNET_YES;
1122  return;
1123  }
1124  if ( (GNUNET_YES == ch->is_loopback) &&
1125  ( (NULL != ch->owner) ||
1126  (NULL != ch->dest) ) )
1127  {
1128  if (NULL != ch->retry_control_task)
1130  ch->retry_control_task
1132  ch);
1133  return;
1134  }
1135  if (GNUNET_NO == ch->is_loopback)
1136  {
1137  /* If the we ever sent the CHANNEL_CREATE, we need to send a destroy message. */
1138  switch (ch->state)
1139  {
1140  case CADET_CHANNEL_NEW:
1141  /* We gave up on a channel that we created as a client to a remote
1142  target, but that never went anywhere. Nothing to do here. */
1143  break;
1144  case CADET_CHANNEL_LOOSE:
1145  break;
1146  default:
1148  ch->ctn);
1149  }
1150  }
1151  /* Nothing left to do, just finish destruction */
1152  channel_destroy (ch);
1153 }
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:111
#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:81
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:1273
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:80
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:965
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 634 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().

635 {
636  GNUNET_assert (NULL == ch->retry_control_task);
638  "Tunnel up, sending CHANNEL_OPEN on %s now\n",
639  GCCH_2s (ch));
642  ch);
643 }
#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:1273
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_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
chididentifier of this channel in the tunnel
originpeer to who initiated the channel
h_porthash of desired local port
optionsoptions for the channel
Returns
handle to the new channel
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 761 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_CADET_OPTION_NOBUFFER, GNUNET_CADET_OPTION_OUT_OF_ORDER, GNUNET_CADET_OPTION_RELIABLE, 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(), 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().

765 {
766  struct CadetChannel *ch;
767  struct OpenPort *op;
768 
769  ch = GNUNET_new (struct CadetChannel);
770  ch->h_port = *h_port;
771  ch->t = t;
772  ch->ctn = ctn;
777  ch->max_pending_messages = (ch->nobuffer) ? 1 : 4; /* FIXME: 4!? Do not hardcode! */
779  "# channels",
780  1,
781  GNUNET_NO);
782 
784  h_port);
785  if (NULL == op)
786  {
787  /* port closed, wait for it to possibly open */
790  &ch->h_port,
791  ch,
793  GNUNET_assert (NULL == ch->retry_control_task);
797  ch);
799  "Created loose incoming channel to port %s from peer %s\n",
800  GNUNET_h2s (&ch->port),
801  GCP_2s (GCT_get_destination (ch->t)));
802  }
803  else
804  {
805  GCCH_bind (ch,
806  op->c,
807  &op->port);
808  }
810  "# channels",
811  1,
812  GNUNET_NO);
813  return ch;
814 }
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.
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
Enable channel reliability, lost messages will be retransmitted.
#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:81
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:1246
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&#39;re waiting for the port to be opened.
struct GNUNET_TIME_Relative retry_time
Counter for exponential backoff.
struct GNUNET_HashCode port
Port number.
Enable out of order delivery of messages.
#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&#39;ed port of the channel with initiator and destination PID.
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.
Disable buffering on intermediate nodes (for minimum latency).
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 907 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().

909 {
910  if (NULL == ch->dest)
911  {
913  "Ignoring duplicate CHANNEL_OPEN on %s: port is closed\n",
914  GCCH_2s (ch));
915  return;
916  }
917  if (NULL != ch->retry_control_task)
918  {
920  "Ignoring duplicate CHANNEL_OPEN on %s: control message is pending\n",
921  GCCH_2s (ch));
922  return;
923  }
925  "Retransmitting CHANNEL_OPEN_ACK on %s\n",
926  GCCH_2s (ch));
929  ch);
930 }
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:1273
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:

◆ 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.

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

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 1267 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().

1270 {
1271  struct GNUNET_MQ_Envelope *env;
1272  struct GNUNET_CADET_LocalData *ld;
1273  struct CadetChannelClient *ccc;
1274  size_t payload_size;
1275  struct CadetOutOfOrderMessage *com;
1276  int duplicate;
1277  uint32_t mid_min;
1278  uint32_t mid_max;
1279  uint32_t mid_msg;
1280  uint32_t delta;
1281 
1283  if ( (NULL == ch->owner) &&
1284  (NULL == ch->dest) )
1285  {
1286  /* This client is gone, but we still have messages to send to
1287  the other end (which is why @a ch is not yet dead). However,
1288  we cannot pass messages to our client anymore. */
1290  "Dropping incoming payload on %s as this end is already closed\n",
1291  GCCH_2s (ch));
1292  /* send back DESTROY notification to stop further retransmissions! */
1293  if (GNUNET_YES == ch->destroy)
1295  ch->ctn);
1296  return;
1297  }
1298  payload_size = ntohs (msg->header.size) - sizeof (*msg);
1299  env = GNUNET_MQ_msg_extra (ld,
1300  payload_size,
1302  ld->ccn = (NULL == ch->dest) ? ch->owner->ccn : ch->dest->ccn;
1303  GNUNET_memcpy (&ld[1],
1304  &msg[1],
1305  payload_size);
1306  ccc = (NULL != ch->owner) ? ch->owner : ch->dest;
1307  if (GNUNET_YES == ccc->client_ready)
1308  {
1309  /*
1310  * We ad-hoc send the message if
1311  * - The channel is out-of-order
1312  * - The channel is reliable and MID matches next expected MID
1313  * - The channel is unreliable and MID is before lowest seen MID
1314  */
1315  if ( (GNUNET_YES == ch->out_of_order) ||
1316  ((msg->mid.mid == ch->mid_recv.mid) &&
1317  (GNUNET_YES == ch->reliable)) ||
1318  ((GNUNET_NO == ch->reliable) &&
1319  (ntohl (msg->mid.mid) >= ntohl (ch->mid_recv.mid)) &&
1320  ((NULL == ccc->head_recv) ||
1321  (ntohl (msg->mid.mid) < ntohl (ccc->head_recv->mid.mid)))) )
1322  {
1324  "Giving %u bytes of payload with MID %u from %s to client %s\n",
1325  (unsigned int) payload_size,
1326  ntohl (msg->mid.mid),
1327  GCCH_2s (ch),
1328  GSC_2s (ccc->c));
1329  ccc->client_ready = GNUNET_NO;
1330  GSC_send_to_client (ccc->c,
1331  env);
1332  if (GNUNET_NO == ch->out_of_order)
1333  ch->mid_recv.mid = htonl (1 + ntohl (msg->mid.mid));
1334  else
1335  ch->mid_recv.mid = htonl (1 + ntohl (ch->mid_recv.mid));
1336  ch->mid_futures >>= 1;
1337  if ( (GNUNET_YES == ch->out_of_order) &&
1338  (GNUNET_NO == ch->reliable) )
1339  {
1340  /* possibly shift by more if we skipped messages */
1341  uint64_t delta = htonl (msg->mid.mid) - 1 - ntohl (ch->mid_recv.mid);
1342 
1343  if (delta > 63)
1344  ch->mid_futures = 0;
1345  else
1346  ch->mid_futures >>= delta;
1347  ch->mid_recv.mid = htonl (1 + ntohl (msg->mid.mid));
1348  }
1349  send_channel_data_ack (ch);
1350  return;
1351  }
1352  }
1353 
1354  if (GNUNET_YES == ch->reliable)
1355  {
1356  /* check if message ought to be dropped because it is ancient/too distant/duplicate */
1357  mid_min = ntohl (ch->mid_recv.mid);
1358  mid_max = mid_min + ch->max_pending_messages;
1359  mid_msg = ntohl (msg->mid.mid);
1360  if ( ( (uint32_t) (mid_msg - mid_min) > ch->max_pending_messages) ||
1361  ( (uint32_t) (mid_max - mid_msg) > ch->max_pending_messages) )
1362  {
1364  "%s at %u drops ancient or far-future message %u\n",
1365  GCCH_2s (ch),
1366  (unsigned int) mid_min,
1367  ntohl (msg->mid.mid));
1368 
1370  "# duplicate DATA (ancient or future)",
1371  1,
1372  GNUNET_NO);
1373  GNUNET_MQ_discard (env);
1374  send_channel_data_ack (ch);
1375  return;
1376  }
1377  /* mark bit for future ACKs */
1378  delta = mid_msg - mid_min - 1; /* overflow/underflow are OK here */
1379  if (delta < 64)
1380  {
1381  if (0 != (ch->mid_futures & (1LLU << delta)))
1382  {
1383  /* Duplicate within the queue, drop also */
1385  "Duplicate payload of %u bytes on %s (mid %u) dropped\n",
1386  (unsigned int) payload_size,
1387  GCCH_2s (ch),
1388  ntohl (msg->mid.mid));
1390  "# duplicate DATA",
1391  1,
1392  GNUNET_NO);
1393  GNUNET_MQ_discard (env);
1394  send_channel_data_ack (ch);
1395  return;
1396  }
1397  ch->mid_futures |= (1LLU << delta);
1399  "Marked bit %llX for mid %u (base: %u); now: %llX\n",
1400  (1LLU << delta),
1401  mid_msg,
1402  mid_min,
1403  ch->mid_futures);
1404  }
1405  }
1406  else /* ! ch->reliable */
1407  {
1408  struct CadetOutOfOrderMessage *next_msg;
1409 
1414  if ((NULL != ccc->head_recv) &&
1415  (GNUNET_YES == ccc->client_ready))
1416  {
1417  next_msg = ccc->head_recv;
1419  "Giving queued MID %u from %s to client %s\n",
1420  ntohl (next_msg->mid.mid),
1421  GCCH_2s (ch),
1422  GSC_2s (ccc->c));
1423  ccc->client_ready = GNUNET_NO;
1424  GSC_send_to_client (ccc->c,
1425  next_msg->env);
1426  ch->mid_recv.mid = htonl (1 + ntohl (next_msg->mid.mid));
1427  ch->mid_futures >>= 1;
1428  send_channel_data_ack (ch);
1430  ccc->tail_recv,
1431  next_msg);
1432  ccc->num_recv--;
1433  /* Do not process duplicate MID */
1434  if (msg->mid.mid == next_msg->mid.mid) /* Duplicate */
1435  {
1436  /* Duplicate within the queue, drop */
1438  "Message on %s (mid %u) dropped, duplicate\n",
1439  GCCH_2s (ch),
1440  ntohl (msg->mid.mid));
1441  GNUNET_free (next_msg);
1442  GNUNET_MQ_discard (env);
1443  return;
1444  }
1445  GNUNET_free (next_msg);
1446  }
1447 
1448  if (ntohl (msg->mid.mid) < ntohl (ch->mid_recv.mid)) /* Old */
1449  {
1450  /* Duplicate within the queue, drop */
1452  "Message on %s (mid %u) dropped, old.\n",
1453  GCCH_2s (ch),
1454  ntohl (msg->mid.mid));
1455  GNUNET_MQ_discard (env);
1456  return;
1457  }
1458 
1459  /* Channel is unreliable, so we do not ACK. But we also cannot
1460  allow buffering everything, so check if we have space... */
1461  if (ccc->num_recv >= ch->max_pending_messages)
1462  {
1463  struct CadetOutOfOrderMessage *drop;
1464 
1465  /* Yep, need to drop. Drop the oldest message in
1466  the buffer. */
1468  "Queue full due slow client on %s, dropping oldest message\n",
1469  GCCH_2s (ch));
1471  "# messages dropped due to slow client",
1472  1,
1473  GNUNET_NO);
1474  drop = ccc->head_recv;
1475  GNUNET_assert (NULL != drop);
1477  ccc->tail_recv,
1478  drop);
1479  ccc->num_recv--;
1480  GNUNET_MQ_discard (drop->env);
1481  GNUNET_free (drop);
1482  }
1483  }
1484 
1485  /* Insert message into sorted out-of-order queue */
1486  com = GNUNET_new (struct CadetOutOfOrderMessage);
1487  com->mid = msg->mid;
1488  com->env = env;
1489  duplicate = GNUNET_NO;
1491  is_before,
1492  &duplicate,
1493  ccc->head_recv,
1494  ccc->tail_recv,
1495  com);
1496  ccc->num_recv++;
1497  if (GNUNET_YES == duplicate)
1498  {
1499  /* Duplicate within the queue, drop also (this is not covered by
1500  the case above if "delta" >= 64, which could be the case if
1501  max_pending_messages is also >= 64 or if our client is unready
1502  and we are seeing retransmissions of the message our client is
1503  blocked on. */
1505  "Duplicate payload of %u bytes on %s (mid %u) dropped\n",
1506  (unsigned int) payload_size,
1507  GCCH_2s (ch),
1508  ntohl (msg->mid.mid));
1510  "# duplicate DATA",
1511  1,
1512  GNUNET_NO);
1514  ccc->tail_recv,
1515  com);
1516  ccc->num_recv--;
1517  GNUNET_MQ_discard (com->env);
1518  GNUNET_free (com);
1519  send_channel_data_ack (ch);
1520  return;
1521  }
1523  "Queued %s payload of %u bytes on %s-%X(%p) (mid %u, need %u first)\n",
1524  (GNUNET_YES == ccc->client_ready)
1525  ? "out-of-order"
1526  : "client-not-ready",
1527  (unsigned int) payload_size,
1528  GCCH_2s (ch),
1529  ntohl (ccc->ccn.channel_of_client),
1530  ccc,
1531  ntohl (msg->mid.mid),
1532  ntohl (ch->mid_recv.mid));
1533  /* NOTE: this ACK we _could_ skip, as the packet is out-of-order and
1534  the sender may already be transmitting the previous one. Needs
1535  experimental evaluation to see if/when this ACK helps or
1536  hurts. (We might even want another option.) */
1537  send_channel_data_ack (ch);
1538 }
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:111
#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.
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:81
#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 GNUNET_memcpy(dst, src, n)
#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:199
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:321
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:80
Message for cadet data traffic.
Definition: cadet.h:189
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_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 1639 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().

1642 {
1643  struct CadetReliableMessage *crm;
1644  struct CadetReliableMessage *crmn;
1645  int found;
1646  uint32_t mid_base;
1647  uint64_t mid_mask;
1648  unsigned int delta;
1649 
1651  if (GNUNET_NO == ch->reliable)
1652  {
1653  /* not expecting ACKs on unreliable channel, odd */
1654  GNUNET_break_op (0);
1655  return;
1656  }
1657  /* mid_base is the MID of the next message that the
1658  other peer expects (i.e. that is missing!), everything
1659  LOWER (but excluding mid_base itself) was received. */
1660  mid_base = ntohl (ack->mid.mid);
1661  mid_mask = GNUNET_htonll (ack->futures);
1662  found = GNUNET_NO;
1663  for (crm = ch->head_sent;
1664  NULL != crm;
1665  crm = crmn)
1666  {
1667  crmn = crm->next;
1668  delta = (unsigned int) (ntohl (crm->data_message->mid.mid) - mid_base);
1669  if (delta >= UINT_MAX - ch->max_pending_messages)
1670  {
1671  /* overflow, means crm was a bit in the past, so this ACK counts for it. */
1673  "Got DATA_ACK with base %u satisfying past message %u on %s\n",
1674  (unsigned int) mid_base,
1675  ntohl (crm->data_message->mid.mid),
1676  GCCH_2s (ch));
1677  handle_matching_ack (ch,
1678  cti,
1679  crm);
1680  found = GNUNET_YES;
1681  continue;
1682  }
1683  delta--;
1684  if (delta >= 64)
1685  continue;
1687  "Testing bit %llX for mid %u (base: %u)\n",
1688  (1LLU << delta),
1689  ntohl (crm->data_message->mid.mid),
1690  mid_base);
1691  if (0 != (mid_mask & (1LLU << delta)))
1692  {
1694  "Got DATA_ACK with mask for %u on %s\n",
1695  ntohl (crm->data_message->mid.mid),
1696  GCCH_2s (ch));
1697  handle_matching_ack (ch,
1698  cti,
1699  crm);
1700  found = GNUNET_YES;
1701  }
1702  }
1703  if (GNUNET_NO == found)
1704  {
1705  /* ACK for message we already dropped, might have been a
1706  duplicate ACK? Ignore. */
1708  "Duplicate DATA_ACK on %s, ignoring\n",
1709  GCCH_2s (ch));
1711  "# duplicate DATA_ACKs",
1712  1,
1713  GNUNET_NO);
1714  return;
1715  }
1716  if (NULL != ch->retry_data_task)
1717  {
1719  ch->retry_data_task = NULL;
1720  }
1721  if ( (NULL != ch->head_sent) &&
1722  (NULL == ch->head_sent->qe) )
1723  ch->retry_data_task
1726  ch);
1727 }
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:81
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:80
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:1223
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:965
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).

Begin transmissions.

Parameters
chchannel to destroy
ctiidentifier of the connection that delivered the message, NULL if the ACK was inferred because we got payload or are on loopback
portport number (needed to verify receiver knows the port)

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 1166 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().

1169 {
1170  switch (ch->state)
1171  {
1172  case CADET_CHANNEL_NEW:
1173  /* this should be impossible */
1174  GNUNET_break (0);
1175  break;
1176  case CADET_CHANNEL_LOOSE:
1177  /* This makes no sense. */
1178  GNUNET_break_op (0);
1179  break;
1181  if (NULL == ch->owner)
1182  {
1183  /* We're not the owner, wrong direction! */
1184  GNUNET_break_op (0);
1185  return;
1186  }
1187  if (0 != GNUNET_memcmp (&ch->port,
1188  port))
1189  {
1190  /* Other peer failed to provide the right port,
1191  refuse connection. */
1192  GNUNET_break_op (0);
1193  return;
1194  }
1196  "Received CHANNEL_OPEN_ACK for waiting %s, entering READY state\n",
1197  GCCH_2s (ch));
1198  if (NULL != ch->retry_control_task) /* can be NULL if ch->is_loopback */
1199  {
1201  ch->retry_control_task = NULL;
1202  }
1203  ch->state = CADET_CHANNEL_READY;
1204  /* On first connect, send client as many ACKs as we allow messages
1205  to be buffered! */
1206  for (unsigned int i=0;i<ch->max_pending_messages;i++)
1207  send_ack_to_client (ch,
1208  GNUNET_YES);
1209  break;
1210  case CADET_CHANNEL_READY:
1211  /* duplicate ACK, maybe we retried the CREATE. Ignore. */
1213  "Received duplicate channel OPEN_ACK for %s\n",
1214  GCCH_2s (ch));
1216  "# duplicate CREATE_ACKs",
1217  1,
1218  GNUNET_NO);
1219  break;
1220  }
1221 }
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:81
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:80
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:965
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_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.

FIXME: need to make it possible to defer destruction until we have received all messages up to the destroy, and right now the destroy message (and this API) fails to give is the information we need!

FIXME: also need to know if the other peer got a destroy from us before!

Parameters
chchannel to destroy
ctiidentifier of the connection that delivered the message, NULL during shutdown

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 1740 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().

1742 {
1743  struct CadetChannelClient *ccc;
1744 
1747  "Received remote channel DESTROY for %s\n",
1748  GCCH_2s (ch));
1749  if (GNUNET_YES == ch->destroy)
1750  {
1751  /* Local client already gone, this is instant-death. */
1752  channel_destroy (ch);
1753  return;
1754  }
1755  ccc = (NULL != ch->owner) ? ch->owner : ch->dest;
1756  if ( (NULL != ccc) &&
1757  (NULL != ccc->head_recv) )
1758  {
1760  "Lost end of transmission due to remote shutdown on %s\n",
1761  GCCH_2s (ch));
1762  /* FIXME: change API to notify client about truncated transmission! */
1763  }
1764  ch->destroy = GNUNET_YES;
1765  if (NULL != ccc)
1767  ccc->ccn,
1768  ch);
1769  channel_destroy (ch);
1770 }
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:81
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:80
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:

◆ 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 1898 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().

1902 {
1903  struct CadetReliableMessage *crm;
1904 
1905  if (ch->pending_messages >= ch->max_pending_messages)
1906  {
1907  GNUNET_break (0); /* Fails: #5370 */
1908  return GNUNET_SYSERR;
1909  }
1910  if (GNUNET_YES == ch->destroy)
1911  {
1912  /* we are going down, drop messages */
1913  return GNUNET_OK;
1914  }
1915  ch->pending_messages++;
1916 
1917  if (GNUNET_YES == ch->is_loopback)
1918  {
1919  struct CadetChannelClient *receiver;
1920  struct GNUNET_MQ_Envelope *env;
1921  struct GNUNET_CADET_LocalData *ld;
1922  int ack_to_owner;
1923 
1924  env = GNUNET_MQ_msg_extra (ld,
1925  buf_len,
1927  if ( (NULL != ch->owner) &&
1928  (sender_ccn.channel_of_client ==
1929  ch->owner->ccn.channel_of_client) )
1930  {
1931  receiver = ch->dest;
1932  ack_to_owner = GNUNET_YES;
1933  }
1934  else if ( (NULL != ch->dest) &&
1935  (sender_ccn.channel_of_client ==
1936  ch->dest->ccn.channel_of_client) )
1937  {
1938  receiver = ch->owner;
1939  ack_to_owner = GNUNET_NO;
1940  }
1941  else
1942  {
1943  GNUNET_break (0);
1944  return GNUNET_SYSERR;
1945  }
1946  GNUNET_assert (NULL != receiver);
1947  ld->ccn = receiver->ccn;
1948  GNUNET_memcpy (&ld[1],
1949  buf,
1950  buf_len);
1951  if (GNUNET_YES == receiver->client_ready)
1952  {
1953  ch->pending_messages--;
1954  GSC_send_to_client (receiver->c,
1955  env);
1956  send_ack_to_client (ch,
1957  ack_to_owner);
1958  }
1959  else
1960  {
1961  struct CadetOutOfOrderMessage *oom;
1962 
1963  oom = GNUNET_new (struct CadetOutOfOrderMessage);
1964  oom->env = env;
1966  receiver->tail_recv,
1967  oom);
1968  receiver->num_recv++;
1969  }
1970  return GNUNET_OK;
1971  }
1972 
1973  /* Everything is correct, send the message. */
1974  crm = GNUNET_malloc (sizeof (*crm));
1975  crm->ch = ch;
1977  + buf_len);
1978  crm->data_message->header.size = htons (sizeof (struct GNUNET_CADET_ChannelAppDataMessage) + buf_len);
1980  ch->mid_send.mid = htonl (ntohl (ch->mid_send.mid) + 1);
1981  crm->data_message->mid = ch->mid_send;
1982  crm->data_message->ctn = ch->ctn;
1983  GNUNET_memcpy (&crm->data_message[1],
1984  buf,
1985  buf_len);
1987  ch->tail_sent,
1988  crm);
1990  "Sending message %u from local client to %s with %u bytes\n",
1991  ntohl (crm->data_message->mid.mid),
1992  GCCH_2s (ch),
1993  buf_len);
1994  if (NULL != ch->retry_data_task)
1995  {
1997  ch->retry_data_task = NULL;
1998  }
1999  crm->qe = GCT_send (ch->t,
2000  &crm->data_message->header,
2001  &data_sent_cb,
2002  crm);
2003  GNUNET_assert (NULL == ch->retry_data_task);
2004  return GNUNET_OK;
2005 }
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:111
#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.
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:81
#define GNUNET_OK
Named constants for return values.
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 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 GNUNET_memcpy(dst, src, n)
#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:199
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:79
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:80
Message for cadet data traffic.
Definition: cadet.h:189
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:965
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.

Parameters
chchannel to destroy
client_ccnccn of the client sending the ack

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 2016 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().

2018 {
2019  struct CadetChannelClient *ccc;
2020  struct CadetOutOfOrderMessage *com;
2021 
2022  if ( (NULL != ch->owner) &&
2023  (ch->owner->ccn.channel_of_client == client_ccn.channel_of_client) )
2024  ccc = ch->owner;
2025  else if ( (NULL != ch->dest) &&
2026  (ch->dest->ccn.channel_of_client == client_ccn.channel_of_client) )
2027  ccc = ch->dest;
2028  else
2029  GNUNET_assert (0);
2030  ccc->client_ready = GNUNET_YES;
2031  com = ccc->head_recv;
2032  if (NULL == com)
2033  {
2035  "Got LOCAL_ACK, %s-%X ready to receive more data, but none pending on %s-%X(%p)!\n",
2036  GSC_2s (ccc->c),
2037  ntohl (client_ccn.channel_of_client),
2038  GCCH_2s (ch),
2039  ntohl (ccc->ccn.channel_of_client),
2040  ccc);
2041  return; /* none pending */
2042  }
2043  if (GNUNET_YES == ch->is_loopback)
2044  {
2045  int to_owner;
2046 
2047  /* Messages are always in-order, just send */
2049  ccc->tail_recv,
2050  com);
2051  ccc->num_recv--;
2052  GSC_send_to_client (ccc->c,
2053  com->env);
2054  /* Notify sender that we can receive more */
2055  if ( (NULL != ch->owner) &&
2056  (ccc->ccn.channel_of_client ==
2057  ch->owner->ccn.channel_of_client) )
2058  {
2059  to_owner = GNUNET_NO;
2060  }
2061  else
2062  {
2063  GNUNET_assert ( (NULL != ch->dest) &&
2064  (ccc->ccn.channel_of_client ==
2065  ch->dest->ccn.channel_of_client) );
2066  to_owner = GNUNET_YES;
2067  }
2068  send_ack_to_client (ch,
2069  to_owner);
2070  GNUNET_free (com);
2071  return;
2072  }
2073 
2074  if ( (com->mid.mid != ch->mid_recv.mid) &&
2075  (GNUNET_NO == ch->out_of_order) &&
2076  (GNUNET_YES == ch->reliable) )
2077  {
2079  "Got LOCAL_ACK, %s-%X ready to receive more data (but next one is out-of-order %u vs. %u)!\n",
2080  GSC_2s (ccc->c),
2081  ntohl (ccc->ccn.channel_of_client),
2082  ntohl (com->mid.mid),
2083  ntohl (ch->mid_recv.mid));
2084  return; /* missing next one in-order */
2085  }
2086 
2088  "Got LOCAL_ACK, giving payload message %u to %s-%X on %s\n",
2089  ntohl (com->mid.mid),
2090  GSC_2s (ccc->c),
2091  ntohl (ccc->ccn.channel_of_client),
2092  GCCH_2s (ch));
2093 
2094  /* all good, pass next message to client */
2096  ccc->tail_recv,
2097  com);
2098  ccc->num_recv--;
2099  /* FIXME: if unreliable, this is not aggressive
2100  enough, as it would be OK to have lost some! */
2101 
2102  ch->mid_recv.mid = htonl (1 + ntohl (com->mid.mid));
2103  ch->mid_futures >>= 1; /* equivalent to division by 2 */
2104  ccc->client_ready = GNUNET_NO;
2105  GSC_send_to_client (ccc->c,
2106  com->env);
2107  GNUNET_free (com);
2108  send_channel_data_ack (ch);
2109  if (NULL != ccc->head_recv)
2110  return;
2111  if (GNUNET_NO == ch->destroy)
2112  return;
2114  ch->ctn);
2115  channel_destroy (ch);
2116 }
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:111
#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:81
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:80
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: