GNUnet  0.20.0
gnunet-service-cadet_tunnels.c File Reference

Information we track per tunnel. More...

Include dependency graph for gnunet-service-cadet_tunnels.c:

Go to the source code of this file.

Data Structures

struct  CadetTunnelSkippedKey
 Struct to old keys for skipped messages while advancing the Axolotl ratchet. More...
 
struct  CadetTunnelAxolotl
 Axolotl data, according to https://github.com/trevp/axolotl/wiki . More...
 
struct  CadetTunnelQueueEntry
 Struct used to save messages in a non-ready tunnel to send once connected. More...
 
struct  CadetTunnel
 Struct containing all information regarding a tunnel to a peer. More...
 
struct  EvaluationSummary
 Closure for evaluate_connection. More...
 
struct  ChanIterCls
 Closure for iterate_channels_cb. More...
 

Macros

#define LOG(level, ...)   GNUNET_log_from (level, "cadet-tun", __VA_ARGS__)
 
#define MAX_UNVERIFIED_ATTEMPTS   16
 How often do we try to decrypt payload with unverified key material? Used to limit CPU increase upon receiving bogus KX. More...
 
#define IDLE_DESTROY_DELAY
 How long do we wait until tearing down an idle tunnel? More...
 
#define INITIAL_KX_RETRY_DELAY
 How long do we wait initially before retransmitting the KX? TODO: replace by 2 RTT if/once we have connection-level RTT data! More...
 
#define MAX_SKIPPED_KEYS   64
 Maximum number of skipped keys we keep in memory per tunnel. More...
 
#define MAX_KEY_GAP   256
 Maximum number of keys (and thus ratchet steps) we are willing to skip before we decide this is either a bogus packet or a DoS-attempt. More...
 
#define HIGH_BIT   0x8000000
 
#define LOG2(level, ...)
 

Functions

int GCT_alice_or_betty (const struct GNUNET_PeerIdentity *other)
 Am I Alice or Betty (some call her Bob), or talking to myself? More...
 
static void mark_connection_unready (struct CadetTConnection *ct)
 Connection ct is now unready, clear it's ready flag and move it from the ready DLL to the busy DLL. More...
 
const char * GCT_2s (const struct CadetTunnel *t)
 Get the static string for the peer this tunnel is directed. More...
 
static const char * estate2s (enum CadetTunnelEState es)
 Get string description for tunnel encryption state. More...
 
struct CadetPeerGCT_get_destination (struct CadetTunnel *t)
 Return the peer to which this tunnel goes. More...
 
unsigned int GCT_count_channels (struct CadetTunnel *t)
 Returns the number of channels using a tunnel. More...
 
struct CadetChannellookup_channel (struct CadetTunnel *t, struct GNUNET_CADET_ChannelTunnelNumber ctn)
 Lookup a channel by its ctn. More...
 
unsigned int GCT_count_any_connections (const struct CadetTunnel *t)
 Counts the number of connections created for a tunnel, including busy connections. More...
 
static struct CadetTConnectionget_ready_connection (struct CadetTunnel *t)
 Find first connection that is ready in the list of our connections. More...
 
enum CadetTunnelEState GCT_get_estate (struct CadetTunnel *t)
 Get the encryption state of a tunnel. More...
 
static void trigger_transmissions (void *cls)
 Called when either we have a new connection, or a new message in the queue, or some existing connection has transmission capacity. More...
 
static void new_ephemeral (struct CadetTunnelAxolotl *ax)
 Create a new Axolotl ephemeral (ratchet) key. More...
 
static void t_hmac (const void *plaintext, size_t size, uint32_t iv, const struct GNUNET_CRYPTO_SymmetricSessionKey *key, struct GNUNET_ShortHashCode *hmac)
 Calculate HMAC. More...
 
static void t_ax_hmac_hash (const struct GNUNET_CRYPTO_SymmetricSessionKey *key, struct GNUNET_HashCode *hash, const void *source, unsigned int len)
 Perform a HMAC. More...
 
static void t_hmac_derive_key (const struct GNUNET_CRYPTO_SymmetricSessionKey *key, struct GNUNET_CRYPTO_SymmetricSessionKey *out, const void *source, unsigned int len)
 Derive a symmetric encryption key from an HMAC-HASH. More...
 
static void t_ax_encrypt (struct CadetTunnelAxolotl *ax, void *dst, const void *src, size_t size)
 Encrypt data with the axolotl tunnel key. More...
 
static void t_ax_decrypt (struct CadetTunnelAxolotl *ax, void *dst, const void *src, size_t size)
 Decrypt data with the axolotl tunnel key. More...
 
static void t_h_encrypt (struct CadetTunnelAxolotl *ax, struct GNUNET_CADET_TunnelEncryptedMessage *msg)
 Encrypt header with the axolotl header key. More...
 
static void t_h_decrypt (struct CadetTunnelAxolotl *ax, const struct GNUNET_CADET_TunnelEncryptedMessage *src, struct GNUNET_CADET_TunnelEncryptedMessage *dst)
 Decrypt header with the current axolotl header key. More...
 
static void delete_skipped_key (struct CadetTunnelAxolotl *ax, struct CadetTunnelSkippedKey *key)
 Delete a key from the list of skipped keys. More...
 
static ssize_t try_old_ax_keys (struct CadetTunnelAxolotl *ax, void *dst, const struct GNUNET_CADET_TunnelEncryptedMessage *src, size_t size)
 Decrypt and verify data with the appropriate tunnel key and verify that the data has not been altered since it was sent by the remote peer. More...
 
static void store_skipped_key (struct CadetTunnelAxolotl *ax, const struct GNUNET_CRYPTO_SymmetricSessionKey *HKr)
 Delete a key from the list of skipped keys. More...
 
static int store_ax_keys (struct CadetTunnelAxolotl *ax, const struct GNUNET_CRYPTO_SymmetricSessionKey *HKr, uint32_t Np)
 Stage skipped AX keys and calculate the message key. More...
 
static ssize_t t_ax_decrypt_and_validate (struct CadetTunnelAxolotl *ax, void *dst, const struct GNUNET_CADET_TunnelEncryptedMessage *src, size_t size)
 Decrypt and verify data with the appropriate tunnel key and verify that the data has not been altered since it was sent by the remote peer. More...
 
static int notify_tunnel_up_cb (void *cls, uint32_t key, void *value)
 Our tunnel became ready for the first time, notify channels that have been waiting. More...
 
void GCT_change_estate (struct CadetTunnel *t, enum CadetTunnelEState state)
 Change the tunnel encryption state. More...
 
static void send_kx (struct CadetTunnel *t, struct CadetTConnection *ct, struct CadetTunnelAxolotl *ax)
 Send a KX message. More...
 
static void send_kx_auth (struct CadetTunnel *t, struct CadetTConnection *ct, struct CadetTunnelAxolotl *ax, int force_reply)
 Send a KX_AUTH message. More...
 
static void cleanup_ax (struct CadetTunnelAxolotl *ax)
 Cleanup state used by ax. More...
 
static int update_ax_by_kx (struct CadetTunnelAxolotl *ax, const struct GNUNET_PeerIdentity *pid, const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral_key, const struct GNUNET_CRYPTO_EcdhePublicKey *ratchet_key)
 Update our Axolotl key state based on the KX data we received. More...
 
static void retry_kx (void *cls)
 Try to redo the KX or KX_AUTH handshake, if we can. More...
 
void GCT_handle_kx (struct CadetTConnection *ct, const struct GNUNET_CADET_TunnelKeyExchangeMessage *msg)
 Handle KX message that lacks authentication (and which will thus only be considered authenticated after we respond with our own KX_AUTH and finally successfully decrypt the payload). More...
 
void GCT_handle_kx_auth (struct CadetTConnection *ct, const struct GNUNET_CADET_TunnelKeyExchangeAuthMessage *msg)
 Handle KX_AUTH message. More...
 
static struct GNUNET_CADET_ChannelTunnelNumber get_next_free_ctn (struct CadetTunnel *t)
 Compute the next free channel tunnel number for this tunnel. More...
 
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. More...
 
void GCT_connection_lost (struct CadetTConnection *ct)
 We lost a connection, remove it from our list and clean up the connection object itself. More...
 
static void destroy_t_connection (void *cls, struct CadetTConnection *ct)
 Clean up connection ct of a tunnel. More...
 
static void destroy_tunnel (void *cls)
 This tunnel is no longer used, destroy it. More...
 
void GCT_remove_channel (struct CadetTunnel *t, struct CadetChannel *ch, struct GNUNET_CADET_ChannelTunnelNumber ctn)
 Remove a channel from a tunnel. More...
 
static int destroy_remaining_channels (void *cls, uint32_t key, void *value)
 Destroy remaining channels during shutdown. More...
 
void GCT_destroy_tunnel_now (struct CadetTunnel *t)
 Destroys the tunnel t now, without delay. More...
 
static void try_send_normal_payload (struct CadetTunnel *t, struct CadetTConnection *ct)
 Send normal payload from queue in t via connection ct. More...
 
static void connection_ready_cb (void *cls, int is_ready)
 A connection is is_ready for transmission. More...
 
static void evaluate_connection (void *cls, struct CadetTConnection *ct)
 Evaluate a connection, updating our summary information in cls about what kinds of connections we have. More...
 
static int consider_path_cb (void *cls, struct CadetPeerPath *path, unsigned int off)
 Consider using the path p for the tunnel t. More...
 
static void maintain_connections_cb (void *cls)
 Function called to maintain the connections underlying our tunnel. More...
 
void GCT_consider_path (struct CadetTunnel *t, struct CadetPeerPath *p, unsigned int off)
 Consider using the path p for the tunnel t. More...
 
static void handle_plaintext_keepalive (void *cls, const struct GNUNET_MessageHeader *msg)
 We got a keepalive. More...
 
static int check_plaintext_data (void *cls, const struct GNUNET_CADET_ChannelAppDataMessage *msg)
 Check that msg is well-formed. More...
 
static void handle_plaintext_data (void *cls, const struct GNUNET_CADET_ChannelAppDataMessage *msg)
 We received payload data for a channel. More...
 
static void handle_plaintext_data_ack (void *cls, const struct GNUNET_CADET_ChannelDataAckMessage *ack)
 We received an acknowledgement for data we sent on a channel. More...
 
static void handle_plaintext_channel_open (void *cls, const struct GNUNET_CADET_ChannelOpenMessage *copen)
 We have received a request to open a channel to a port from another peer. More...
 
void GCT_send_channel_destroy (struct CadetTunnel *t, struct GNUNET_CADET_ChannelTunnelNumber ctn)
 Send a DESTROY message via the tunnel. More...
 
static void handle_plaintext_channel_open_ack (void *cls, const struct GNUNET_CADET_ChannelOpenAckMessage *cm)
 We have received confirmation from the target peer that the given channel could be established (the port is open). More...
 
static void handle_plaintext_channel_destroy (void *cls, const struct GNUNET_CADET_ChannelDestroyMessage *cm)
 We received a message saying that a channel should be destroyed. More...
 
static int handle_decrypted (void *cls, const struct GNUNET_MessageHeader *msg)
 Handles a message we decrypted, by injecting it into our message queue (which will do the dispatching). More...
 
static void decrypted_error_cb (void *cls, enum GNUNET_MQ_Error error)
 Function called if we had an error processing an incoming decrypted message. More...
 
struct CadetTunnelGCT_create_tunnel (struct CadetPeer *destination)
 Create a tunnel to destination. More...
 
int GCT_add_inbound_connection (struct CadetTunnel *t, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid, struct CadetPeerPath *path)
 Add a connection to the tunnel. More...
 
void GCT_handle_encrypted (struct CadetTConnection *ct, const struct GNUNET_CADET_TunnelEncryptedMessage *msg)
 Handle encrypted message. More...
 
struct CadetTunnelQueueEntryGCT_send (struct CadetTunnel *t, const struct GNUNET_MessageHeader *message, GCT_SendContinuation cont, void *cont_cls, struct GNUNET_CADET_ChannelTunnelNumber *ctn)
 Sends an already built message on a tunnel, encrypting it and choosing the best connection if not provided. More...
 
void GCT_send_cancel (struct CadetTunnelQueueEntry *tq)
 Cancel a previously sent message while it's in the queue. More...
 
void GCT_iterate_connections (struct CadetTunnel *t, GCT_ConnectionIterator iter, void *iter_cls)
 Iterate over all connections of a tunnel. More...
 
static int iterate_channels_cb (void *cls, uint32_t key, void *value)
 Helper function for GCT_iterate_channels. More...
 
void GCT_iterate_channels (struct CadetTunnel *t, GCT_ChannelIterator iter, void *iter_cls)
 Iterate over all channels of a tunnel. More...
 
static int debug_channel (void *cls, uint32_t key, void *value)
 Call GCCH_debug() on a channel. More...
 
void GCT_debug (const struct CadetTunnel *t, enum GNUNET_ErrorType level)
 Log all possible info about the tunnel state. More...
 

Detailed Description

Information we track per tunnel.

Author
Bartlomiej Polot
Christian Grothoff

FIXME:

  • proper connection evaluation during connection management:
    • consider quality (or quality spread?) of current connection set when deciding how often to do maintenance
    • interact with PEER to drive DHT GET/PUT operations based on how much we like our connections

Definition in file gnunet-service-cadet_tunnels.c.

Macro Definition Documentation

◆ LOG

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

Definition at line 45 of file gnunet-service-cadet_tunnels.c.

◆ MAX_UNVERIFIED_ATTEMPTS

#define MAX_UNVERIFIED_ATTEMPTS   16

How often do we try to decrypt payload with unverified key material? Used to limit CPU increase upon receiving bogus KX.

Definition at line 52 of file gnunet-service-cadet_tunnels.c.

◆ IDLE_DESTROY_DELAY

#define IDLE_DESTROY_DELAY
Value:
#define GNUNET_TIME_UNIT_SECONDS
One second.
struct GNUNET_TIME_Relative GNUNET_TIME_relative_multiply(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Multiply relative time by a given factor.
Definition: time.c:484

How long do we wait until tearing down an idle tunnel?

Definition at line 57 of file gnunet-service-cadet_tunnels.c.

◆ INITIAL_KX_RETRY_DELAY

#define INITIAL_KX_RETRY_DELAY
Value:
#define GNUNET_TIME_UNIT_MILLISECONDS
One millisecond.

How long do we wait initially before retransmitting the KX? TODO: replace by 2 RTT if/once we have connection-level RTT data!

Definition at line 64 of file gnunet-service-cadet_tunnels.c.

◆ MAX_SKIPPED_KEYS

#define MAX_SKIPPED_KEYS   64

Maximum number of skipped keys we keep in memory per tunnel.

Definition at line 70 of file gnunet-service-cadet_tunnels.c.

◆ MAX_KEY_GAP

#define MAX_KEY_GAP   256

Maximum number of keys (and thus ratchet steps) we are willing to skip before we decide this is either a bogus packet or a DoS-attempt.

Definition at line 76 of file gnunet-service-cadet_tunnels.c.

◆ HIGH_BIT

#define HIGH_BIT   0x8000000

◆ LOG2

#define LOG2 (   level,
  ... 
)
Value:
GNUNET_log_from_nocheck (level, "cadet-tun", \
__VA_ARGS__)
void GNUNET_log_from_nocheck(enum GNUNET_ErrorType kind, const char *comp, const char *message,...) __attribute__((format(printf
Log function that specifies an alternative component.

Definition at line 3618 of file gnunet-service-cadet_tunnels.c.

Function Documentation

◆ GCT_alice_or_betty()

int GCT_alice_or_betty ( const struct GNUNET_PeerIdentity other)

Am I Alice or Betty (some call her Bob), or talking to myself?

Parameters
otherthe other peer
Returns
GNUNET_YES for Alice, GNUNET_NO for Betty, GNUNET_SYSERR if talking to myself

Definition at line 468 of file gnunet-service-cadet_tunnels.c.

469 {
470  if (0 > GNUNET_memcmp (&my_full_id,
471  other))
472  return GNUNET_YES;
473  else if (0 < GNUNET_memcmp (&my_full_id,
474  other))
475  return GNUNET_NO;
476  else
477  {
478  GNUNET_break_op (0);
479  return GNUNET_SYSERR;
480  }
481 }
struct GNUNET_PeerIdentity my_full_id
Local peer own ID.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.

References GNUNET_break_op, GNUNET_memcmp, GNUNET_NO, GNUNET_SYSERR, GNUNET_YES, and my_full_id.

Referenced by GCT_handle_kx(), send_create(), send_kx(), and update_ax_by_kx().

Here is the caller graph for this function:

◆ mark_connection_unready()

static void mark_connection_unready ( struct CadetTConnection ct)
static

Connection ct is now unready, clear it's ready flag and move it from the ready DLL to the busy DLL.

Parameters
ctconnection to move to unready status

Definition at line 491 of file gnunet-service-cadet_tunnels.c.

492 {
493  struct CadetTunnel *t = ct->t;
494 
496  GNUNET_CONTAINER_DLL_remove (t->connection_ready_head,
497  t->connection_ready_tail,
498  ct);
499  GNUNET_assert (0 < t->num_ready_connections);
500  t->num_ready_connections--;
501  ct->is_ready = GNUNET_NO;
502  GNUNET_CONTAINER_DLL_insert (t->connection_busy_head,
503  t->connection_busy_tail,
504  ct);
505  t->num_busy_connections++;
506 }
static struct GNUNET_SCHEDULER_Task * t
Main task.
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
int is_ready
Is the connection currently ready for transmission?
struct CadetTunnel * t
Tunnel this connection belongs to.
Struct containing all information regarding a tunnel to a peer.

References GNUNET_assert, GNUNET_CONTAINER_DLL_insert, GNUNET_CONTAINER_DLL_remove, GNUNET_NO, GNUNET_YES, CadetTConnection::is_ready, CadetTConnection::t, and t.

Referenced by connection_ready_cb(), send_kx(), send_kx_auth(), and try_send_normal_payload().

Here is the caller graph for this function:

◆ GCT_2s()

const char* GCT_2s ( const struct CadetTunnel t)

Get the static string for the peer this tunnel is directed.

Parameters
tTunnel.
Returns
Static string the destination peer's ID.

Definition at line 517 of file gnunet-service-cadet_tunnels.c.

518 {
519  static char buf[64];
520 
521  if (NULL == t)
522  return "Tunnel(NULL)";
524  sizeof(buf),
525  "Tunnel %s",
526  GNUNET_i2s (GCP_get_id (t->destination)));
527  return buf;
528 }
const struct GNUNET_PeerIdentity * GCP_get_id(struct CadetPeer *cp)
Obtain the peer identity for a struct CadetPeer.
static char buf[2048]
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
int GNUNET_snprintf(char *buf, size_t size, const char *format,...) __attribute__((format(printf
Like snprintf, just aborts if the buffer is of insufficient size.

References buf, GCP_get_id(), GNUNET_i2s(), GNUNET_snprintf(), and t.

Referenced by connection_ready_cb(), consider_path_cb(), destroy_tunnel(), GCC_2s(), GCCH_bind(), GCCH_channel_local_new(), GCCH_debug(), GCP_drop_tunnel(), GCT_add_channel(), GCT_add_inbound_connection(), GCT_change_estate(), GCT_consider_path(), GCT_debug(), GCT_handle_encrypted(), GCT_handle_kx(), GCT_remove_channel(), GCT_send(), handle_plaintext_channel_destroy(), handle_plaintext_channel_open(), handle_plaintext_channel_open_ack(), handle_plaintext_keepalive(), maintain_connections_cb(), retry_kx(), send_keepalive(), send_kx(), send_kx_auth(), try_send_normal_payload(), and update_state().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ estate2s()

static const char* estate2s ( enum CadetTunnelEState  es)
static

Get string description for tunnel encryption state.

Parameters
esTunnel state.
Returns
String representation.

Definition at line 539 of file gnunet-service-cadet_tunnels.c.

540 {
541  static char buf[32];
542 
543  switch (es)
544  {
546  return "CADET_TUNNEL_KEY_UNINITIALIZED";
548  return "CADET_TUNNEL_KEY_AX_RECV";
550  return "CADET_TUNNEL_KEY_AX_SENT";
552  return "CADET_TUNNEL_KEY_AX_SENT_AND_RECV";
554  return "CADET_TUNNEL_KEY_AX_AUTH_SENT";
555  case CADET_TUNNEL_KEY_OK:
556  return "CADET_TUNNEL_KEY_OK";
557  }
559  sizeof(buf),
560  "%u (UNKNOWN STATE)",
561  es);
562  return buf;
563 }
@ CADET_TUNNEL_KEY_AX_AUTH_SENT
KX received and we sent KX_AUTH back, but we got no traffic yet, so we're waiting for either KX_AUTH ...
@ CADET_TUNNEL_KEY_AX_SENT
KX message sent, waiting for other peer's KX_AUTH.
@ CADET_TUNNEL_KEY_UNINITIALIZED
Uninitialized status, we need to send KX.
@ CADET_TUNNEL_KEY_AX_SENT_AND_RECV
KX message sent and received, trying to send back KX_AUTH.
@ CADET_TUNNEL_KEY_OK
Handshake completed: session key available.
@ CADET_TUNNEL_KEY_AX_RECV
KX message received, trying to send back KX_AUTH.

References buf, CADET_TUNNEL_KEY_AX_AUTH_SENT, CADET_TUNNEL_KEY_AX_RECV, CADET_TUNNEL_KEY_AX_SENT, CADET_TUNNEL_KEY_AX_SENT_AND_RECV, CADET_TUNNEL_KEY_OK, CADET_TUNNEL_KEY_UNINITIALIZED, and GNUNET_snprintf().

Referenced by connection_ready_cb(), GCT_change_estate(), GCT_debug(), retry_kx(), and send_kx().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCT_get_destination()

struct CadetPeer* GCT_get_destination ( struct CadetTunnel t)

Return the peer to which this tunnel goes.

Parameters
ta tunnel
Returns
the destination of the tunnel

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

574 {
575  return t->destination;
576 }

References t.

Referenced by GCCH_2s(), GCCH_bind(), GCCH_channel_incoming_new(), and timeout_closed_cb().

Here is the caller graph for this function:

◆ GCT_count_channels()

unsigned int GCT_count_channels ( struct CadetTunnel t)

Returns the number of channels using a tunnel.

Parameters
tTunnel in question.
Returns
Number of channels using the tunnel.

Definition at line 580 of file gnunet-service-cadet_tunnels.c.

581 {
582  return GNUNET_CONTAINER_multihashmap32_size (t->channels);
583 }
unsigned int GNUNET_CONTAINER_multihashmap32_size(const struct GNUNET_CONTAINER_MultiHashMap32 *map)
Get the number of key-value pairs in the map.

References GNUNET_CONTAINER_multihashmap32_size(), and t.

Referenced by connection_ready_cb(), destroy_tunnel(), GCT_destroy_tunnel_now(), GCT_remove_channel(), get_all_tunnels_iterator(), and retry_kx().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ lookup_channel()

struct CadetChannel* lookup_channel ( struct CadetTunnel t,
struct GNUNET_CADET_ChannelTunnelNumber  ctn 
)

Lookup a channel by its ctn.

Parameters
ttunnel to look in
ctnnumber of channel to find
Returns
NULL if channel does not exist

Definition at line 594 of file gnunet-service-cadet_tunnels.c.

596 {
597  return GNUNET_CONTAINER_multihashmap32_get (t->channels,
598  ntohl (ctn.cn));
599 }
void * GNUNET_CONTAINER_multihashmap32_get(const struct GNUNET_CONTAINER_MultiHashMap32 *map, uint32_t key)
Given a key find a value in the map matching the key.
uint32_t cn
Which number does this channel have that uniquely identfies it within its tunnel, in network byte ord...

References GNUNET_CADET_ChannelTunnelNumber::cn, CadetChannel::ctn, GNUNET_CONTAINER_multihashmap32_get(), and t.

Referenced by GCT_send(), handle_plaintext_channel_destroy(), handle_plaintext_channel_open_ack(), handle_plaintext_data(), and handle_plaintext_data_ack().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCT_count_any_connections()

unsigned int GCT_count_any_connections ( const struct CadetTunnel t)

Counts the number of connections created for a tunnel, including busy connections.

Parameters
tTunnel to be counted.
Returns
Number of connections created for the tunnel.

Definition at line 603 of file gnunet-service-cadet_tunnels.c.

604 {
605  return t->num_ready_connections + t->num_busy_connections;
606 }

References t.

Referenced by consider_path_cb(), GCT_debug(), get_all_tunnels_iterator(), and maintain_connections_cb().

Here is the caller graph for this function:

◆ get_ready_connection()

static struct CadetTConnection* get_ready_connection ( struct CadetTunnel t)
static

Find first connection that is ready in the list of our connections.

Picks ready connections round-robin.

Parameters
ttunnel to search
Returns
NULL if we have no connection that is ready

Definition at line 617 of file gnunet-service-cadet_tunnels.c.

618 {
619  struct CadetTConnection *hd = t->connection_ready_head;
620 
621  GNUNET_assert ((NULL == hd) ||
622  (GNUNET_YES == hd->is_ready));
623  return hd;
624 }
Entry in list of connections used by tunnel, with metadata.

Referenced by send_kx(), send_kx_auth(), and trigger_transmissions().

Here is the caller graph for this function:

◆ GCT_get_estate()

enum CadetTunnelEState GCT_get_estate ( struct CadetTunnel t)

Get the encryption state of a tunnel.

Parameters
tTunnel.
Returns
Tunnel's encryption state.

Definition at line 617 of file gnunet-service-cadet_tunnels.c.

636 {
637  return t->estate;
638 }

References GNUNET_assert, GNUNET_YES, CadetTConnection::is_ready, and t.

Referenced by get_all_tunnels_iterator(), handle_connection_create(), send_create(), and send_keepalive().

Here is the caller graph for this function:

◆ trigger_transmissions()

static void trigger_transmissions ( void *  cls)
static

Called when either we have a new connection, or a new message in the queue, or some existing connection has transmission capacity.

Looks at our message queue and if there is a message, picks a connection to send it on.

Parameters
clsthe struct CadetTunnel to process messages on

Definition at line 2491 of file gnunet-service-cadet_tunnels.c.

2492 {
2493  struct CadetTunnel *t = cls;
2494  struct CadetTConnection *ct;
2495 
2496  t->send_task = NULL;
2497  if (NULL == t->tq_head)
2498  return; /* no messages pending right now */
2499  ct = get_ready_connection (t);
2500  if (NULL == ct)
2501  return; /* no connections ready */
2503  ct);
2504 }
static void try_send_normal_payload(struct CadetTunnel *t, struct CadetTConnection *ct)
Send normal payload from queue in t via connection ct.
static struct CadetTConnection * get_ready_connection(struct CadetTunnel *t)
Find first connection that is ready in the list of our connections.

References get_ready_connection(), t, and try_send_normal_payload().

Referenced by GCT_change_estate(), GCT_handle_encrypted(), and GCT_send().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ new_ephemeral()

static void new_ephemeral ( struct CadetTunnelAxolotl ax)
static

Create a new Axolotl ephemeral (ratchet) key.

Parameters
axkey material to update

Definition at line 662 of file gnunet-service-cadet_tunnels.c.

663 {
665  "Creating new ephemeral ratchet key (DHRs)\n");
667 }
#define LOG(level,...)
void GNUNET_CRYPTO_ecdhe_key_create(struct GNUNET_CRYPTO_EcdhePrivateKey *pk)
Create a new private key.
Definition: crypto_ecc.c:436
@ GNUNET_ERROR_TYPE_DEBUG
struct GNUNET_CRYPTO_EcdhePrivateKey DHRs
ECDH Ratchet key (our private key in the current DH).

References CadetTunnelAxolotl::DHRs, GNUNET_CRYPTO_ecdhe_key_create(), GNUNET_ERROR_TYPE_DEBUG, and LOG.

Referenced by GCT_create_tunnel(), and t_ax_encrypt().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ t_hmac()

static void t_hmac ( const void *  plaintext,
size_t  size,
uint32_t  iv,
const struct GNUNET_CRYPTO_SymmetricSessionKey key,
struct GNUNET_ShortHashCode hmac 
)
static

Calculate HMAC.

Parameters
plaintextContent to HMAC.
sizeSize of plaintext.
ivInitialization vector for the message.
keyKey to use.
[out]hmacDestination to store the HMAC.

Definition at line 680 of file gnunet-service-cadet_tunnels.c.

685 {
686  static const char ctx[] = "cadet authentication key";
687  struct GNUNET_CRYPTO_AuthKey auth_key;
688  struct GNUNET_HashCode hash;
689 
691  key,
692  &iv, sizeof(iv),
693  key, sizeof(*key),
694  ctx, sizeof(ctx),
695  NULL);
696  /* Two step: GNUNET_ShortHash is only 256 bits,
697  GNUNET_HashCode is 512, so we truncate. */
698  GNUNET_CRYPTO_hmac (&auth_key,
699  plaintext,
700  size,
701  &hash);
702  GNUNET_memcpy (hmac,
703  &hash,
704  sizeof(*hmac));
705 }
struct GNUNET_HashCode key
The key used in the DHT.
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
void GNUNET_CRYPTO_hmac(const struct GNUNET_CRYPTO_AuthKey *key, const void *plaintext, size_t plaintext_len, struct GNUNET_HashCode *hmac)
Calculate HMAC of a message (RFC 2104)
Definition: crypto_hash.c:330
void GNUNET_CRYPTO_hmac_derive_key(struct GNUNET_CRYPTO_AuthKey *key, const struct GNUNET_CRYPTO_SymmetricSessionKey *rkey, const void *salt, size_t salt_len,...)
Derive an authentication key.
Definition: crypto_hash.c:267
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
static unsigned int size
Size of the "table".
Definition: peer.c:68
type for (message) authentication keys
A 512-bit hashcode.

References ctx, GNUNET_CRYPTO_hmac(), GNUNET_CRYPTO_hmac_derive_key(), GNUNET_memcpy, key, and size.

Referenced by GCT_send(), t_ax_decrypt_and_validate(), and try_old_ax_keys().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ t_ax_hmac_hash()

static void t_ax_hmac_hash ( const struct GNUNET_CRYPTO_SymmetricSessionKey key,
struct GNUNET_HashCode hash,
const void *  source,
unsigned int  len 
)
static

Perform a HMAC.

Parameters
keyKey to use.
[out]hashResulting HMAC.
sourceSource key material (data to HMAC).
lenLength of source.

Definition at line 717 of file gnunet-service-cadet_tunnels.c.

721 {
722  static const char ctx[] = "axolotl HMAC-HASH";
723  struct GNUNET_CRYPTO_AuthKey auth_key;
724 
726  key,
727  ctx, sizeof(ctx),
728  NULL);
729  GNUNET_CRYPTO_hmac (&auth_key,
730  source,
731  len,
732  hash);
733 }
static GstElement * source
Appsrc instance into which we write data for the pipeline.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...

References ctx, GNUNET_CRYPTO_hmac(), GNUNET_CRYPTO_hmac_derive_key(), key, len, and source.

Referenced by t_ax_decrypt_and_validate(), t_ax_encrypt(), and t_hmac_derive_key().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ t_hmac_derive_key()

static void t_hmac_derive_key ( const struct GNUNET_CRYPTO_SymmetricSessionKey key,
struct GNUNET_CRYPTO_SymmetricSessionKey out,
const void *  source,
unsigned int  len 
)
static

Derive a symmetric encryption key from an HMAC-HASH.

Parameters
keyKey to use for the HMAC.
[out]outKey to generate.
sourceSource key material (data to HMAC).
lenLength of source.

Definition at line 745 of file gnunet-service-cadet_tunnels.c.

749 {
750  static const char ctx[] = "axolotl derive key";
751  struct GNUNET_HashCode h;
752 
754  &h,
755  source,
756  len);
757  GNUNET_CRYPTO_kdf (out, sizeof(*out),
758  ctx, sizeof(ctx),
759  &h, sizeof(h),
760  NULL);
761 }
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition: gnunet-arm.c:99
static void t_ax_hmac_hash(const struct GNUNET_CRYPTO_SymmetricSessionKey *key, struct GNUNET_HashCode *hash, const void *source, unsigned int len)
Perform a HMAC.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_kdf(void *result, size_t out_len, const void *xts, size_t xts_len, const void *skm, size_t skm_len,...)
Derive key.
Definition: crypto_kdf.c:70

References ctx, GNUNET_CRYPTO_kdf(), h, key, len, source, and t_ax_hmac_hash().

Referenced by store_skipped_key(), t_ax_decrypt(), and t_ax_encrypt().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ t_ax_encrypt()

static void t_ax_encrypt ( struct CadetTunnelAxolotl ax,
void *  dst,
const void *  src,
size_t  size 
)
static

Encrypt data with the axolotl tunnel key.

Parameters
axkey material to use.
dstDestination with size bytes for the encrypted data.
srcSource of the plaintext. Can overlap with dst, must contain size bytes
sizeSize of the buffers at src and dst

Definition at line 773 of file gnunet-service-cadet_tunnels.c.

777 {
780  size_t out_size;
781 
782  ax->ratchet_counter++;
783  if ((GNUNET_YES == ax->ratchet_allowed) &&
784  ((ratchet_messages <= ax->ratchet_counter) ||
787  {
788  ax->ratchet_flag = GNUNET_YES;
789  }
790  if (GNUNET_YES == ax->ratchet_flag)
791  {
792  /* Advance ratchet */
793  struct GNUNET_CRYPTO_SymmetricSessionKey keys[3];
794  struct GNUNET_HashCode dh;
795  struct GNUNET_HashCode hmac;
796  static const char ctx[] = "axolotl ratchet";
797 
798  new_ephemeral (ax);
799  ax->HKs = ax->NHKs;
800 
801  /* RK, NHKs, CKs = KDF( HMAC-HASH(RK, DH(DHRs, DHRr)) ) */
803  &ax->DHRr,
804  &dh);
805  t_ax_hmac_hash (&ax->RK,
806  &hmac,
807  &dh,
808  sizeof(dh));
809  GNUNET_CRYPTO_kdf (keys, sizeof(keys),
810  ctx, sizeof(ctx),
811  &hmac, sizeof(hmac),
812  NULL);
813  ax->RK = keys[0];
814  ax->NHKs = keys[1];
815  ax->CKs = keys[2];
816 
817  ax->PNs = ax->Ns;
818  ax->Ns = 0;
819  ax->ratchet_flag = GNUNET_NO;
821  ax->ratchet_counter = 0;
824  ratchet_time);
825  }
826 
827  t_hmac_derive_key (&ax->CKs,
828  &MK,
829  "0",
830  1);
832  &MK,
833  NULL, 0,
834  NULL);
835 
836  out_size = GNUNET_CRYPTO_symmetric_encrypt (src,
837  size,
838  &MK,
839  &iv,
840  dst);
841  GNUNET_assert (size == out_size);
842  t_hmac_derive_key (&ax->CKs,
843  &ax->CKs,
844  "1",
845  1);
846 }
struct GNUNET_TIME_Relative ratchet_time
How long until we trigger a ratched advance due to time.
static void new_ephemeral(struct CadetTunnelAxolotl *ax)
Create a new Axolotl ephemeral (ratchet) key.
static void t_hmac_derive_key(const struct GNUNET_CRYPTO_SymmetricSessionKey *key, struct GNUNET_CRYPTO_SymmetricSessionKey *out, const void *source, unsigned int len)
Derive a symmetric encryption key from an HMAC-HASH.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecc_ecdh(const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, const struct GNUNET_CRYPTO_EcdhePublicKey *pub, struct GNUNET_HashCode *key_material)
Derive key material from a public and a private ECC key.
Definition: crypto_ecc.c:714
ssize_t GNUNET_CRYPTO_symmetric_encrypt(const void *block, size_t size, const struct GNUNET_CRYPTO_SymmetricSessionKey *sessionkey, const struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, void *result)
Encrypt a block using a symmetric sessionkey.
void GNUNET_CRYPTO_symmetric_derive_iv(struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, const struct GNUNET_CRYPTO_SymmetricSessionKey *skey, const void *salt, size_t salt_len,...)
Derive an IV.
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:405
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:111
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_add(struct GNUNET_TIME_Absolute start, struct GNUNET_TIME_Relative duration)
Add a given relative duration to the given start time.
Definition: time.c:450
uint32_t PNs
Previous message numbers (# of msgs sent under prev ratchet)
struct GNUNET_CRYPTO_SymmetricSessionKey HKs
32-byte header key (currently used for sending).
struct GNUNET_TIME_Absolute ratchet_expiration
Time when the current ratchet expires and a new one is triggered (if ratchet_allowed is GNUNET_YES).
struct GNUNET_CRYPTO_EcdhePublicKey DHRr
ECDH Ratchet key (other peer's public key in the current DH).
uint32_t Ns
Message number (reset to 0 with each new ratchet, next message to send).
struct GNUNET_CRYPTO_SymmetricSessionKey RK
32-byte root key which gets updated by DH ratchet.
int ratchet_allowed
True (GNUNET_YES) if we have received a message from the other peer that uses the keys from our last ...
int ratchet_flag
True (GNUNET_YES) if we have to send a new ratchet key in next msg.
struct GNUNET_CRYPTO_SymmetricSessionKey CKs
32-byte chain keys (used for forward-secrecy) for sending messages.
unsigned int ratchet_counter
Number of messages received since our last ratchet advance.
struct GNUNET_CRYPTO_SymmetricSessionKey NHKs
32-byte next header key (for sending), used once the ratchet advances.
uint64_t rel_value_us
The actual value.

References CadetTunnelAxolotl::CKs, ctx, CadetTunnelAxolotl::DHRr, CadetTunnelAxolotl::DHRs, GNUNET_assert, GNUNET_CRYPTO_ecc_ecdh(), GNUNET_CRYPTO_kdf(), GNUNET_CRYPTO_symmetric_derive_iv(), GNUNET_CRYPTO_symmetric_encrypt(), GNUNET_NO, GNUNET_TIME_absolute_add(), GNUNET_TIME_absolute_get(), GNUNET_TIME_absolute_get_remaining(), GNUNET_YES, CadetTunnelAxolotl::HKs, new_ephemeral(), CadetTunnelAxolotl::NHKs, CadetTunnelAxolotl::Ns, CadetTunnelAxolotl::PNs, CadetTunnelAxolotl::ratchet_allowed, CadetTunnelAxolotl::ratchet_counter, CadetTunnelAxolotl::ratchet_expiration, CadetTunnelAxolotl::ratchet_flag, ratchet_time, GNUNET_TIME_Relative::rel_value_us, CadetTunnelAxolotl::RK, size, t_ax_hmac_hash(), and t_hmac_derive_key().

Referenced by GCT_send().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ t_ax_decrypt()

static void t_ax_decrypt ( struct CadetTunnelAxolotl ax,
void *  dst,
const void *  src,
size_t  size 
)
static

Decrypt data with the axolotl tunnel key.

Parameters
axkey material to use.
dstDestination for the decrypted data, must contain size bytes.
srcSource of the ciphertext. Can overlap with dst, must contain size bytes.
sizeSize of the src and dst buffers

Definition at line 858 of file gnunet-service-cadet_tunnels.c.

862 {
865  size_t out_size;
866 
867  t_hmac_derive_key (&ax->CKr,
868  &MK,
869  "0",
870  1);
872  &MK,
873  NULL, 0,
874  NULL);
875  GNUNET_assert (size >= sizeof(struct GNUNET_MessageHeader));
876  out_size = GNUNET_CRYPTO_symmetric_decrypt (src,
877  size,
878  &MK,
879  &iv,
880  dst);
881  GNUNET_assert (out_size == size);
882  t_hmac_derive_key (&ax->CKr,
883  &ax->CKr,
884  "1",
885  1);
886 }
ssize_t GNUNET_CRYPTO_symmetric_decrypt(const void *block, size_t size, const struct GNUNET_CRYPTO_SymmetricSessionKey *sessionkey, const struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, void *result)
Decrypt a given block using a symmetric sessionkey.
struct GNUNET_CRYPTO_SymmetricSessionKey CKr
32-byte chain keys (used for forward-secrecy) for receiving messages.
Header for all communications.

References CadetTunnelAxolotl::CKr, GNUNET_assert, GNUNET_CRYPTO_symmetric_decrypt(), GNUNET_CRYPTO_symmetric_derive_iv(), size, and t_hmac_derive_key().

Referenced by t_ax_decrypt_and_validate().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ t_h_encrypt()

static void t_h_encrypt ( struct CadetTunnelAxolotl ax,
struct GNUNET_CADET_TunnelEncryptedMessage msg 
)
static

Encrypt header with the axolotl header key.

Parameters
axkey material to use.
[in,out]msgMessage whose header to encrypt.

Definition at line 896 of file gnunet-service-cadet_tunnels.c.

898 {
900  size_t out_size;
901 
903  &ax->HKs,
904  NULL, 0,
905  NULL);
906  out_size = GNUNET_CRYPTO_symmetric_encrypt (&msg->ax_header,
907  sizeof(struct
909  &ax->HKs,
910  &iv,
911  &msg->ax_header);
912  GNUNET_assert (sizeof(struct GNUNET_CADET_AxHeader) == out_size);
913 }
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
Encrypted axolotl header with numbers that identify which keys in which ratchet are to be used to dec...

References GNUNET_assert, GNUNET_CRYPTO_symmetric_derive_iv(), GNUNET_CRYPTO_symmetric_encrypt(), CadetTunnelAxolotl::HKs, and msg.

Referenced by GCT_send().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ t_h_decrypt()

static void t_h_decrypt ( struct CadetTunnelAxolotl ax,
const struct GNUNET_CADET_TunnelEncryptedMessage src,
struct GNUNET_CADET_TunnelEncryptedMessage dst 
)
static

Decrypt header with the current axolotl header key.

Parameters
axkey material to use.
srcMessage whose header to decrypt.
dstWhere to decrypt header to.

Definition at line 924 of file gnunet-service-cadet_tunnels.c.

927 {
929  size_t out_size;
930 
932  &ax->HKr,
933  NULL, 0,
934  NULL);
935  out_size = GNUNET_CRYPTO_symmetric_decrypt (&src->ax_header.Ns,
936  sizeof(struct
938  &ax->HKr,
939  &iv,
940  &dst->ax_header.Ns);
941  GNUNET_assert (sizeof(struct GNUNET_CADET_AxHeader) == out_size);
942 }
struct GNUNET_CRYPTO_SymmetricSessionKey HKr
32-byte header key (currently used for receiving)
uint32_t Ns
Number of messages sent with the current ratchet key.
struct GNUNET_CADET_AxHeader ax_header
Axolotl-header that specifies which keys to use in which ratchet to decrypt the body that follows.

References GNUNET_CADET_TunnelEncryptedMessage::ax_header, GNUNET_assert, GNUNET_CRYPTO_symmetric_decrypt(), GNUNET_CRYPTO_symmetric_derive_iv(), CadetTunnelAxolotl::HKr, and GNUNET_CADET_AxHeader::Ns.

Referenced by t_ax_decrypt_and_validate().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ delete_skipped_key()

static void delete_skipped_key ( struct CadetTunnelAxolotl ax,
struct CadetTunnelSkippedKey key 
)
static

Delete a key from the list of skipped keys.

Parameters
axkey material to delete key from.
keyKey to delete.

Definition at line 952 of file gnunet-service-cadet_tunnels.c.

954 {
956  ax->skipped_tail,
957  key);
958  GNUNET_free (key);
959  ax->skipped--;
960 }
#define GNUNET_free(ptr)
Wrapper around free.
unsigned int skipped
Number of elements in skipped_head <-> skipped_tail.
struct CadetTunnelSkippedKey * skipped_tail
Skipped messages' keys DLL, tail.
struct CadetTunnelSkippedKey * skipped_head
A (double linked) list of stored message keys and associated header keys for "skipped" messages,...

References GNUNET_CONTAINER_DLL_remove, GNUNET_free, key, CadetTunnelAxolotl::skipped, CadetTunnelAxolotl::skipped_head, and CadetTunnelAxolotl::skipped_tail.

Referenced by cleanup_ax(), store_ax_keys(), and try_old_ax_keys().

Here is the caller graph for this function:

◆ try_old_ax_keys()

static ssize_t try_old_ax_keys ( struct CadetTunnelAxolotl ax,
void *  dst,
const struct GNUNET_CADET_TunnelEncryptedMessage src,
size_t  size 
)
static

Decrypt and verify data with the appropriate tunnel key and verify that the data has not been altered since it was sent by the remote peer.

Parameters
axkey material to use.
dstDestination for the plaintext.
srcSource of the message. Can overlap with dst.
sizeSize of the message.
Returns
Size of the decrypted data, -1 if an error was encountered.

Definition at line 974 of file gnunet-service-cadet_tunnels.c.

978 {
979  struct CadetTunnelSkippedKey *key;
980  struct GNUNET_ShortHashCode *hmac;
982  struct GNUNET_CADET_TunnelEncryptedMessage plaintext_header;
983  struct GNUNET_CRYPTO_SymmetricSessionKey *valid_HK;
984  size_t esize;
985  size_t res;
986  size_t len;
987  unsigned int N;
988 
990  "Trying skipped keys\n");
991  hmac = &plaintext_header.hmac;
992  esize = size - sizeof(struct GNUNET_CADET_TunnelEncryptedMessage);
993 
994  /* Find a correct Header Key */
995  valid_HK = NULL;
996  for (key = ax->skipped_head; NULL != key; key = key->next)
997  {
998  t_hmac (&src->ax_header,
999  sizeof(struct GNUNET_CADET_AxHeader) + esize,
1000  0,
1001  &key->HK,
1002  hmac);
1003  if (0 == GNUNET_memcmp (hmac,
1004  &src->hmac))
1005  {
1006  valid_HK = &key->HK;
1007  break;
1008  }
1009  }
1010  if (NULL == key)
1011  return -1;
1012 
1013  /* Should've been checked in -cadet_connection.c handle_cadet_encrypted. */
1015  len = size - sizeof(struct GNUNET_CADET_TunnelEncryptedMessage);
1016  GNUNET_assert (len >= sizeof(struct GNUNET_MessageHeader));
1017 
1018  /* Decrypt header */
1020  &key->HK,
1021  NULL, 0,
1022  NULL);
1024  sizeof(struct GNUNET_CADET_AxHeader),
1025  &key->HK,
1026  &iv,
1027  &plaintext_header.ax_header.Ns);
1028  GNUNET_assert (sizeof(struct GNUNET_CADET_AxHeader) == res);
1029 
1030  /* Find the correct message key */
1031  N = ntohl (plaintext_header.ax_header.Ns);
1032  while ((NULL != key) &&
1033  (N != key->Kn))
1034  key = key->next;
1035  if ((NULL == key) ||
1036  (0 != GNUNET_memcmp (&key->HK,
1037  valid_HK)))
1038  return -1;
1039 
1040  /* Decrypt payload */
1042  &key->MK,
1043  NULL,
1044  0,
1045  NULL);
1047  len,
1048  &key->MK,
1049  &iv,
1050  dst);
1051  delete_skipped_key (ax,
1052  key);
1053  return res;
1054 }
static int res
static void t_hmac(const void *plaintext, size_t size, uint32_t iv, const struct GNUNET_CRYPTO_SymmetricSessionKey *key, struct GNUNET_ShortHashCode *hmac)
Calculate HMAC.
static void delete_skipped_key(struct CadetTunnelAxolotl *ax, struct CadetTunnelSkippedKey *key)
Delete a key from the list of skipped keys.
#define N
Struct to old keys for skipped messages while advancing the Axolotl ratchet.
Axolotl-encrypted tunnel message with application payload.
struct GNUNET_ShortHashCode hmac
MAC of the encrypted message, used to verify message integrity.
A 256-bit hashcode.

References GNUNET_CADET_TunnelEncryptedMessage::ax_header, delete_skipped_key(), GNUNET_assert, GNUNET_CRYPTO_symmetric_decrypt(), GNUNET_CRYPTO_symmetric_derive_iv(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_memcmp, GNUNET_CADET_TunnelEncryptedMessage::hmac, key, len, LOG, N, GNUNET_CADET_AxHeader::Ns, res, size, CadetTunnelAxolotl::skipped_head, and t_hmac().

Referenced by t_ax_decrypt_and_validate().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ store_skipped_key()

static void store_skipped_key ( struct CadetTunnelAxolotl ax,
const struct GNUNET_CRYPTO_SymmetricSessionKey HKr 
)
static

Delete a key from the list of skipped keys.

Parameters
axkey material to delete from.
HKrHeader Key to use.

Definition at line 1064 of file gnunet-service-cadet_tunnels.c.

1066 {
1067  struct CadetTunnelSkippedKey *key;
1068 
1070  key->timestamp = GNUNET_TIME_absolute_get ();
1071  key->Kn = ax->Nr;
1072  key->HK = ax->HKr;
1073  t_hmac_derive_key (&ax->CKr,
1074  &key->MK,
1075  "0",
1076  1);
1077  t_hmac_derive_key (&ax->CKr,
1078  &ax->CKr,
1079  "1",
1080  1);
1082  ax->skipped_tail,
1083  key);
1084  ax->skipped++;
1085  ax->Nr++;
1086 }
#define GNUNET_new(type)
Allocate a struct or union of the given type.
uint32_t Nr
Message number (reset to 0 with each new ratchet, next message to recv).

References CadetTunnelAxolotl::CKr, GNUNET_CONTAINER_DLL_insert, GNUNET_new, GNUNET_TIME_absolute_get(), CadetTunnelAxolotl::HKr, key, CadetTunnelAxolotl::Nr, CadetTunnelAxolotl::skipped, CadetTunnelAxolotl::skipped_head, CadetTunnelAxolotl::skipped_tail, and t_hmac_derive_key().

Referenced by store_ax_keys().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ store_ax_keys()

static int store_ax_keys ( struct CadetTunnelAxolotl ax,
const struct GNUNET_CRYPTO_SymmetricSessionKey HKr,
uint32_t  Np 
)
static

Stage skipped AX keys and calculate the message key.

Stores each HK and MK for skipped messages.

Parameters
axkey material to use
HKrHeader key.
NpReceived meesage number.
Returns
GNUNET_OK if keys were stored. GNUNET_SYSERR if an error occurred (Np not expected).

Definition at line 1100 of file gnunet-service-cadet_tunnels.c.

1103 {
1104  int gap;
1105 
1106  gap = Np - ax->Nr;
1108  "Storing skipped keys [%u, %u)\n",
1109  ax->Nr,
1110  Np);
1111  if (MAX_KEY_GAP < gap)
1112  {
1113  /* Avoid DoS (forcing peer to do more than #MAX_KEY_GAP HMAC operations) */
1114  /* TODO: start new key exchange on return */
1115  GNUNET_break_op (0);
1117  "Got message %u, expected %u+\n",
1118  Np,
1119  ax->Nr);
1120  return GNUNET_SYSERR;
1121  }
1122  if (0 > gap)
1123  {
1124  /* Delayed message: don't store keys, flag to try old keys. */
1125  return GNUNET_SYSERR;
1126  }
1127 
1128  while (ax->Nr < Np)
1129  store_skipped_key (ax,
1130  HKr);
1131 
1132  while (ax->skipped > MAX_SKIPPED_KEYS)
1133  delete_skipped_key (ax,
1134  ax->skipped_tail);
1135  return GNUNET_OK;
1136 }
#define MAX_KEY_GAP
Maximum number of keys (and thus ratchet steps) we are willing to skip before we decide this is eithe...
static void store_skipped_key(struct CadetTunnelAxolotl *ax, const struct GNUNET_CRYPTO_SymmetricSessionKey *HKr)
Delete a key from the list of skipped keys.
#define MAX_SKIPPED_KEYS
Maximum number of skipped keys we keep in memory per tunnel.
@ GNUNET_OK
@ GNUNET_ERROR_TYPE_WARNING

References delete_skipped_key(), GNUNET_break_op, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, GNUNET_OK, GNUNET_SYSERR, LOG, MAX_KEY_GAP, MAX_SKIPPED_KEYS, CadetTunnelAxolotl::Nr, CadetTunnelAxolotl::skipped, CadetTunnelAxolotl::skipped_tail, and store_skipped_key().

Referenced by t_ax_decrypt_and_validate().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ t_ax_decrypt_and_validate()

static ssize_t t_ax_decrypt_and_validate ( struct CadetTunnelAxolotl ax,
void *  dst,
const struct GNUNET_CADET_TunnelEncryptedMessage src,
size_t  size 
)
static

Decrypt and verify data with the appropriate tunnel key and verify that the data has not been altered since it was sent by the remote peer.

Parameters
axkey material to use
dstDestination for the plaintext.
srcSource of the message. Can overlap with dst.
sizeSize of the message.
Returns
Size of the decrypted data, -1 if an error was encountered.

Definition at line 1150 of file gnunet-service-cadet_tunnels.c.

1155 {
1156  struct GNUNET_ShortHashCode msg_hmac;
1157  struct GNUNET_HashCode hmac;
1158  struct GNUNET_CADET_TunnelEncryptedMessage plaintext_header;
1159  uint32_t Np;
1160  uint32_t PNp;
1161  size_t esize; /* Size of encryped payload */
1162 
1163  esize = size - sizeof(struct GNUNET_CADET_TunnelEncryptedMessage);
1164 
1165  /* Try current HK */
1166  t_hmac (&src->ax_header,
1167  sizeof(struct GNUNET_CADET_AxHeader) + esize,
1168  0, &ax->HKr,
1169  &msg_hmac);
1170  if (0 != GNUNET_memcmp (&msg_hmac,
1171  &src->hmac))
1172  {
1173  static const char ctx[] = "axolotl ratchet";
1174  struct GNUNET_CRYPTO_SymmetricSessionKey keys[3]; /* RKp, NHKp, CKp */
1176  struct GNUNET_HashCode dh;
1177  struct GNUNET_CRYPTO_EcdhePublicKey *DHRp;
1178 
1179  /* Try Next HK */
1180  t_hmac (&src->ax_header,
1181  sizeof(struct GNUNET_CADET_AxHeader) + esize,
1182  0,
1183  &ax->NHKr,
1184  &msg_hmac);
1185  if (0 != GNUNET_memcmp (&msg_hmac,
1186  &src->hmac))
1187  {
1188  /* Try the skipped keys, if that fails, we're out of luck. */
1189  return try_old_ax_keys (ax,
1190  dst,
1191  src,
1192  size);
1193  }
1194  HK = ax->HKr;
1195  ax->HKr = ax->NHKr;
1196  t_h_decrypt (ax,
1197  src,
1198  &plaintext_header);
1199  Np = ntohl (plaintext_header.ax_header.Ns);
1200  PNp = ntohl (plaintext_header.ax_header.PNs);
1201  DHRp = &plaintext_header.ax_header.DHRs;
1202  store_ax_keys (ax,
1203  &HK,
1204  PNp);
1205 
1206  /* RKp, NHKp, CKp = KDF (HMAC-HASH (RK, DH (DHRp, DHRs))) */
1208  DHRp,
1209  &dh);
1210  t_ax_hmac_hash (&ax->RK,
1211  &hmac,
1212  &dh, sizeof(dh));
1213  GNUNET_CRYPTO_kdf (keys, sizeof(keys),
1214  ctx, sizeof(ctx),
1215  &hmac, sizeof(hmac),
1216  NULL);
1217 
1218  /* Commit "purported" keys */
1219  ax->RK = keys[0];
1220  ax->NHKr = keys[1];
1221  ax->CKr = keys[2];
1222  ax->DHRr = *DHRp;
1223  ax->Nr = 0;
1225  }
1226  else
1227  {
1228  t_h_decrypt (ax,
1229  src,
1230  &plaintext_header);
1231  Np = ntohl (plaintext_header.ax_header.Ns);
1232  PNp = ntohl (plaintext_header.ax_header.PNs);
1233  }
1234  if ((Np != ax->Nr) &&
1235  (GNUNET_OK != store_ax_keys (ax,
1236  &ax->HKr,
1237  Np)))
1238  {
1239  /* Try the skipped keys, if that fails, we're out of luck. */
1240  return try_old_ax_keys (ax,
1241  dst,
1242  src,
1243  size);
1244  }
1245 
1246  t_ax_decrypt (ax,
1247  dst,
1248  &src[1],
1249  esize);
1250  ax->Nr = Np + 1;
1251  return esize;
1252 }
static void t_h_decrypt(struct CadetTunnelAxolotl *ax, const struct GNUNET_CADET_TunnelEncryptedMessage *src, struct GNUNET_CADET_TunnelEncryptedMessage *dst)
Decrypt header with the current axolotl header key.
static void t_ax_decrypt(struct CadetTunnelAxolotl *ax, void *dst, const void *src, size_t size)
Decrypt data with the axolotl tunnel key.
static int store_ax_keys(struct CadetTunnelAxolotl *ax, const struct GNUNET_CRYPTO_SymmetricSessionKey *HKr, uint32_t Np)
Stage skipped AX keys and calculate the message key.
static ssize_t try_old_ax_keys(struct CadetTunnelAxolotl *ax, void *dst, const struct GNUNET_CADET_TunnelEncryptedMessage *src, size_t size)
Decrypt and verify data with the appropriate tunnel key and verify that the data has not been altered...
struct GNUNET_CRYPTO_SymmetricSessionKey NHKr
32-byte next header key (for receiving).
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and encr...

References GNUNET_CADET_TunnelEncryptedMessage::ax_header, CadetTunnelAxolotl::CKr, ctx, CadetTunnelAxolotl::DHRr, GNUNET_CADET_AxHeader::DHRs, CadetTunnelAxolotl::DHRs, GNUNET_CRYPTO_ecc_ecdh(), GNUNET_CRYPTO_kdf(), GNUNET_memcmp, GNUNET_OK, GNUNET_YES, CadetTunnelAxolotl::HKr, GNUNET_CADET_TunnelEncryptedMessage::hmac, CadetTunnelAxolotl::NHKr, CadetTunnelAxolotl::Nr, GNUNET_CADET_AxHeader::Ns, GNUNET_CADET_AxHeader::PNs, CadetTunnelAxolotl::ratchet_allowed, CadetTunnelAxolotl::RK, size, store_ax_keys(), t_ax_decrypt(), t_ax_hmac_hash(), t_h_decrypt(), t_hmac(), and try_old_ax_keys().

Referenced by GCT_handle_encrypted().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ notify_tunnel_up_cb()

static int notify_tunnel_up_cb ( void *  cls,
uint32_t  key,
void *  value 
)
static

Our tunnel became ready for the first time, notify channels that have been waiting.

Parameters
clsour tunnel, not used
keyunique ID of the channel, not used
valuethe struct CadetChannel to notify
Returns
GNUNET_OK (continue to iterate)

Definition at line 1265 of file gnunet-service-cadet_tunnels.c.

1268 {
1269  struct CadetChannel *ch = value;
1270 
1271  GCCH_tunnel_up (ch);
1272  return GNUNET_OK;
1273 }
static struct GNUNET_CADET_Channel * ch
Channel handle.
Definition: gnunet-cadet.c:117
static char * value
Value of the record to add/remove.
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 r...
Struct containing all information regarding a channel to a remote client.

References ch, GCCH_tunnel_up(), GNUNET_OK, and value.

Referenced by GCT_change_estate().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCT_change_estate()

void GCT_change_estate ( struct CadetTunnel t,
enum CadetTunnelEState  state 
)

Change the tunnel encryption state.

If the encryption state changes to OK, stop the rekey task.

Parameters
tTunnel whose encryption state to change, or NULL.
stateNew encryption state.

Definition at line 1284 of file gnunet-service-cadet_tunnels.c.

1286 {
1287  enum CadetTunnelEState old = t->estate;
1288 
1289  t->estate = state;
1291  "%s estate changed from %s to %s\n",
1292  GCT_2s (t),
1293  estate2s (old),
1294  estate2s (state));
1295 
1296  if ((CADET_TUNNEL_KEY_OK != old) &&
1297  (CADET_TUNNEL_KEY_OK == t->estate))
1298  {
1299  if (NULL != t->kx_task)
1300  {
1301  GNUNET_SCHEDULER_cancel (t->kx_task);
1302  t->kx_task = NULL;
1303  }
1304  /* notify all channels that have been waiting */
1307  t);
1308  if (NULL != t->send_task)
1309  GNUNET_SCHEDULER_cancel (t->send_task);
1311  t);
1312  }
1313 }
enum State state
current state of profiling
static int notify_tunnel_up_cb(void *cls, uint32_t key, void *value)
Our tunnel became ready for the first time, notify channels that have been waiting.
const char * GCT_2s(const struct CadetTunnel *t)
Get the static string for the peer this tunnel is directed.
static const char * estate2s(enum CadetTunnelEState es)
Get string description for tunnel encryption state.
static void trigger_transmissions(void *cls)
Called when either we have a new connection, or a new message in the queue, or some existing connecti...
CadetTunnelEState
All the encryption states a tunnel can be in.
int GNUNET_CONTAINER_multihashmap32_iterate(struct GNUNET_CONTAINER_MultiHashMap32 *map, GNUNET_CONTAINER_MultiHashMapIterator32Callback it, void *it_cls)
Iterate over all entries in the map.
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:1299
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:975

References CADET_TUNNEL_KEY_OK, estate2s(), GCT_2s(), GNUNET_CONTAINER_multihashmap32_iterate(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_SCHEDULER_add_now(), GNUNET_SCHEDULER_cancel(), LOG, notify_tunnel_up_cb(), state, t, and trigger_transmissions().

Referenced by GCT_add_channel(), GCT_handle_encrypted(), GCT_handle_kx(), handle_connection_create(), send_kx(), and send_kx_auth().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_kx()

static void send_kx ( struct CadetTunnel t,
struct CadetTConnection ct,
struct CadetTunnelAxolotl ax 
)
static

Send a KX message.

Parameters
ttunnel on which to send the KX_AUTH
ctTunnel and connection on which to send the KX_AUTH, NULL if we are to find one that is ready.
axaxolotl key context to use

Definition at line 1325 of file gnunet-service-cadet_tunnels.c.

1328 {
1329  struct CadetConnection *cc;
1330  struct GNUNET_MQ_Envelope *env;
1333 
1334  if (GNUNET_YES != GCT_alice_or_betty (GCP_get_id (t->destination)))
1335  return; /* only Alice may send KX */
1336  if ((NULL == ct) ||
1337  (GNUNET_NO == ct->is_ready))
1338  ct = get_ready_connection (t);
1339  if (NULL == ct)
1340  {
1342  "Wanted to send %s in state %s, but no connection is ready, deferring\n",
1343  GCT_2s (t),
1344  estate2s (t->estate));
1345  t->next_kx_attempt = GNUNET_TIME_absolute_get ();
1346  return;
1347  }
1348  cc = ct->cc;
1349  env = GNUNET_MQ_msg (msg,
1351  flags = GNUNET_CADET_KX_FLAG_FORCE_REPLY; /* always for KX */
1352  msg->flags = htonl (flags);
1353  msg->cid = *GCC_get_id (cc);
1355  &msg->ephemeral_key);
1356 #if DEBUG_KX
1357  msg->ephemeral_key_XXX = ax->kx_0;
1358  msg->private_key_XXX = *my_private_key;
1359 #endif
1361  "Sending KX message to %s with ephemeral %s on CID %s\n",
1362  GCT_2s (t),
1363  GNUNET_e2s (&msg->ephemeral_key),
1364  GNUNET_sh2s (&msg->cid.connection_of_tunnel));
1366  &msg->ratchet_key);
1368  t->kx_retry_delay = GNUNET_TIME_STD_BACKOFF (t->kx_retry_delay);
1369  t->next_kx_attempt = GNUNET_TIME_relative_to_absolute (t->kx_retry_delay);
1370  if (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate)
1373  else if (CADET_TUNNEL_KEY_AX_RECV == t->estate)
1376  GCC_transmit (cc,
1377  env);
1379  "# KX transmitted",
1380  1,
1381  GNUNET_NO);
1382 }
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
GNUNET_CADET_KX_Flags
Flags to be used in GNUNET_CADET_KX.
@ GNUNET_CADET_KX_FLAG_FORCE_REPLY
The peer should reply with its KX details?
struct GNUNET_STATISTICS_Handle * stats
Handle to the statistics service.
struct GNUNET_CRYPTO_EddsaPrivateKey * my_private_key
Own private key.
void GCC_transmit(struct CadetConnection *cc, struct GNUNET_MQ_Envelope *env)
Transmit message msg via connection cc.
const struct GNUNET_CADET_ConnectionTunnelIdentifier * GCC_get_id(struct CadetConnection *cc)
Obtain unique ID for the connection.
static void mark_connection_unready(struct CadetTConnection *ct)
Connection ct is now unready, clear it's ready flag and move it from the ready DLL to the busy DLL.
void GCT_change_estate(struct CadetTunnel *t, enum CadetTunnelEState state)
Change the tunnel encryption state.
int GCT_alice_or_betty(const struct GNUNET_PeerIdentity *other)
Am I Alice or Betty (some call her Bob), or talking to myself?
void GNUNET_CRYPTO_ecdhe_key_get_public(const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, struct GNUNET_CRYPTO_EcdhePublicKey *pub)
Extract the public key for the given private key.
Definition: crypto_ecc.c:214
const char * GNUNET_e2s(const struct GNUNET_CRYPTO_EcdhePublicKey *p)
Convert a public key value to a string (for printing debug messages).
const char * GNUNET_sh2s(const struct GNUNET_ShortHashCode *shc)
Convert a short hash value to a string (for printing debug messages).
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:78
#define GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX
Axolotl key exchange.
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_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:316
#define GNUNET_TIME_STD_BACKOFF(r)
Perform our standard exponential back-off calculation, starting at 1 ms and then going by a factor of...
Low-level connection to a destination.
struct CadetConnection * cc
Connection handle.
struct GNUNET_CRYPTO_EcdhePrivateKey kx_0
ECDH for key exchange (A0 / B0).
Message for a Key eXchange for a tunnel.
uint32_t flags
Flags for the key exchange in NBO, based on enum GNUNET_CADET_KX_Flags.

References CADET_TUNNEL_KEY_AX_RECV, CADET_TUNNEL_KEY_AX_SENT, CADET_TUNNEL_KEY_AX_SENT_AND_RECV, CADET_TUNNEL_KEY_UNINITIALIZED, CadetTConnection::cc, CadetTunnelAxolotl::DHRs, env, estate2s(), GNUNET_CADET_TunnelKeyExchangeMessage::flags, GCC_get_id(), GCC_transmit(), GCP_get_id(), GCT_2s(), GCT_alice_or_betty(), GCT_change_estate(), get_ready_connection(), GNUNET_CADET_KX_FLAG_FORCE_REPLY, GNUNET_CRYPTO_ecdhe_key_get_public(), GNUNET_e2s(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX, GNUNET_MQ_msg, GNUNET_NO, GNUNET_sh2s(), GNUNET_STATISTICS_update(), GNUNET_TIME_absolute_get(), GNUNET_TIME_relative_to_absolute(), GNUNET_TIME_STD_BACKOFF, GNUNET_YES, CadetTConnection::is_ready, CadetTunnelAxolotl::kx_0, LOG, mark_connection_unready(), msg, my_private_key, stats, and t.

Referenced by connection_ready_cb(), GCT_handle_encrypted(), and retry_kx().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_kx_auth()

static void send_kx_auth ( struct CadetTunnel t,
struct CadetTConnection ct,
struct CadetTunnelAxolotl ax,
int  force_reply 
)
static

Send a KX_AUTH message.

Parameters
ttunnel on which to send the KX_AUTH
ctTunnel and connection on which to send the KX_AUTH, NULL if we are to find one that is ready.
axaxolotl key context to use
force_replyForce the other peer to reply with a KX_AUTH message (set if we would like to transmit right now, but cannot)

Definition at line 1396 of file gnunet-service-cadet_tunnels.c.

1400 {
1401  struct CadetConnection *cc;
1402  struct GNUNET_MQ_Envelope *env;
1404  enum GNUNET_CADET_KX_Flags flags;
1405 
1406  if ((NULL == ct) ||
1407  (GNUNET_NO == ct->is_ready))
1408  ct = get_ready_connection (t);
1409  if (NULL == ct)
1410  {
1412  "Wanted to send KX_AUTH on %s, but no connection is ready, deferring\n",
1413  GCT_2s (t));
1414  t->next_kx_attempt = GNUNET_TIME_absolute_get ();
1415  t->kx_auth_requested = GNUNET_YES; /* queue KX_AUTH independent of estate */
1416  return;
1417  }
1418  t->kx_auth_requested = GNUNET_NO; /* clear flag */
1419  cc = ct->cc;
1420  env = GNUNET_MQ_msg (msg,
1422  flags = GNUNET_CADET_KX_FLAG_NONE;
1423  if (GNUNET_YES == force_reply)
1425  msg->kx.flags = htonl (flags);
1426  msg->kx.cid = *GCC_get_id (cc);
1428  &msg->kx.ephemeral_key);
1430  &msg->kx.ratchet_key);
1431 #if DEBUG_KX
1432  msg->kx.ephemeral_key_XXX = ax->kx_0;
1433  msg->kx.private_key_XXX = *my_private_key;
1434  msg->r_ephemeral_key_XXX = ax->last_ephemeral;
1435 #endif
1437  "Sending KX_AUTH message to %s with ephemeral %s on CID %s\n",
1438  GCT_2s (t),
1439  GNUNET_e2s (&msg->kx.ephemeral_key),
1440  GNUNET_sh2s (&msg->kx.cid.connection_of_tunnel));
1441 
1442  /* Compute authenticator (this is the main difference to #send_kx()) */
1443  GNUNET_CRYPTO_hash (&ax->RK,
1444  sizeof(ax->RK),
1445  &msg->auth);
1446  /* Compute when to be triggered again; actual job will
1447  be scheduled via #connection_ready_cb() */
1448  t->kx_retry_delay
1449  = GNUNET_TIME_STD_BACKOFF (t->kx_retry_delay);
1450  t->next_kx_attempt
1451  = GNUNET_TIME_relative_to_absolute (t->kx_retry_delay);
1452 
1453  /* Send via cc, mark it as unready */
1455 
1456  /* Update state machine, unless we are already OK */
1457  if (CADET_TUNNEL_KEY_OK != t->estate)
1460  GCC_transmit (cc,
1461  env);
1463  "# KX_AUTH transmitted",
1464  1,
1465  GNUNET_NO);
1466 }
@ GNUNET_CADET_KX_FLAG_NONE
Should the peer reply with its KX details?
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:41
#define GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX_AUTH
Axolotl key exchange response with authentication.
struct GNUNET_CRYPTO_EcdhePublicKey last_ephemeral
Last ephemeral public key received from the other peer, for duplicate detection.
Message for a Key eXchange for a tunnel, with authentication.

References CADET_TUNNEL_KEY_AX_AUTH_SENT, CADET_TUNNEL_KEY_OK, CadetTConnection::cc, CadetTunnelAxolotl::DHRs, env, GCC_get_id(), GCC_transmit(), GCT_2s(), GCT_change_estate(), get_ready_connection(), GNUNET_CADET_KX_FLAG_FORCE_REPLY, GNUNET_CADET_KX_FLAG_NONE, GNUNET_CRYPTO_ecdhe_key_get_public(), GNUNET_CRYPTO_hash(), GNUNET_e2s(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX_AUTH, GNUNET_MQ_msg, GNUNET_NO, GNUNET_sh2s(), GNUNET_STATISTICS_update(), GNUNET_TIME_absolute_get(), GNUNET_TIME_relative_to_absolute(), GNUNET_TIME_STD_BACKOFF, GNUNET_YES, CadetTConnection::is_ready, CadetTunnelAxolotl::kx_0, CadetTunnelAxolotl::last_ephemeral, LOG, mark_connection_unready(), msg, my_private_key, CadetTunnelAxolotl::RK, stats, and t.

Referenced by connection_ready_cb(), GCT_add_channel(), GCT_handle_encrypted(), GCT_handle_kx(), and retry_kx().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ cleanup_ax()

static void cleanup_ax ( struct CadetTunnelAxolotl ax)
static

Cleanup state used by ax.

Parameters
axstate to free, but not memory of ax itself

Definition at line 1475 of file gnunet-service-cadet_tunnels.c.

1476 {
1477  while (NULL != ax->skipped_head)
1478  delete_skipped_key (ax,
1479  ax->skipped_head);
1480  GNUNET_assert (0 == ax->skipped);
1483 }
void GNUNET_CRYPTO_ecdhe_key_clear(struct GNUNET_CRYPTO_EcdhePrivateKey *pk)
Clear memory that was used to store a private key.
Definition: crypto_ecc.c:415

References delete_skipped_key(), CadetTunnelAxolotl::DHRs, GNUNET_assert, GNUNET_CRYPTO_ecdhe_key_clear(), CadetTunnelAxolotl::kx_0, CadetTunnelAxolotl::skipped, and CadetTunnelAxolotl::skipped_head.

Referenced by destroy_tunnel(), GCT_add_channel(), and GCT_handle_encrypted().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ update_ax_by_kx()

static int update_ax_by_kx ( struct CadetTunnelAxolotl ax,
const struct GNUNET_PeerIdentity pid,
const struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key,
const struct GNUNET_CRYPTO_EcdhePublicKey ratchet_key 
)
static

Update our Axolotl key state based on the KX data we received.

Computes the new chain keys, and root keys, etc, and also checks whether this is a replay of the current chain.

Parameters
[in,out]axchain key state to recompute
pidpeer identity of the other peer
ephemeral_keyephemeral public key of the other peer
ratchet_keysenders next ephemeral public key
Returns
GNUNET_OK on success, GNUNET_NO if the resulting root key is already in ax and thus the KX is useless; GNUNET_SYSERR on hard errors (i.e. pid is my_full_id)

Definition at line 1500 of file gnunet-service-cadet_tunnels.c.

1504 {
1505  struct GNUNET_HashCode key_material[3];
1506  struct GNUNET_CRYPTO_SymmetricSessionKey keys[5];
1507  const char salt[] = "CADET Axolotl salt";
1508  int am_I_alice;
1509 
1510  if (GNUNET_SYSERR == (am_I_alice = GCT_alice_or_betty (pid)))
1511  {
1512  GNUNET_break_op (0);
1513  return GNUNET_SYSERR;
1514  }
1515  if (0 == GNUNET_memcmp (&ax->DHRr,
1516  ratchet_key))
1517  {
1519  "# Ratchet key already known",
1520  1,
1521  GNUNET_NO);
1523  "Ratchet key already known. Ignoring KX.\n");
1524  return GNUNET_NO;
1525  }
1526 
1527  ax->DHRr = *ratchet_key;
1528  ax->last_ephemeral = *ephemeral_key;
1529  /* ECDH A B0 */
1530  if (GNUNET_YES == am_I_alice)
1531  {
1533  ephemeral_key, /* B0 */
1534  &key_material[0]);
1535  }
1536  else
1537  {
1538  GNUNET_CRYPTO_ecdh_eddsa (&ax->kx_0, /* b0 */
1539  &pid->public_key, /* A */
1540  &key_material[0]);
1541  }
1542  /* ECDH A0 B */
1543  if (GNUNET_YES == am_I_alice)
1544  {
1545  GNUNET_CRYPTO_ecdh_eddsa (&ax->kx_0, /* a0 */
1546  &pid->public_key, /* B */
1547  &key_material[1]);
1548  }
1549  else
1550  {
1552  ephemeral_key, /* A0 */
1553  &key_material[1]);
1554  }
1555 
1556  /* ECDH A0 B0 */
1557  GNUNET_CRYPTO_ecc_ecdh (&ax->kx_0, /* a0 or b0 */
1558  ephemeral_key, /* B0 or A0 */
1559  &key_material[2]);
1560  /* KDF */
1561  GNUNET_CRYPTO_kdf (keys, sizeof(keys),
1562  salt, sizeof(salt),
1563  &key_material, sizeof(key_material),
1564  NULL);
1565 
1566  if (0 == memcmp (&ax->RK,
1567  &keys[0],
1568  sizeof(ax->RK)))
1569  {
1571  "Root key already known. Ignoring KX.\n");
1573  "# Root key already known",
1574  1,
1575  GNUNET_NO);
1576  return GNUNET_NO;
1577  }
1578 
1579  ax->RK = keys[0];
1580  if (GNUNET_YES == am_I_alice)
1581  {
1582  ax->HKr = keys[1];
1583  ax->NHKs = keys[2];
1584  ax->NHKr = keys[3];
1585  ax->CKr = keys[4];
1586  ax->ratchet_flag = GNUNET_YES;
1587  }
1588  else
1589  {
1590  ax->HKs = keys[1];
1591  ax->NHKr = keys[2];
1592  ax->NHKs = keys[3];
1593  ax->CKs = keys[4];
1594  ax->ratchet_flag = GNUNET_NO;
1595  ax->ratchet_expiration
1597  ratchet_time);
1598  }
1599  return GNUNET_OK;
1600 }
static struct GNUNET_CRYPTO_PowSalt salt
Salt for PoW calcualations.
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_ecdh(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, const struct GNUNET_CRYPTO_EcdhePublicKey *pub, struct GNUNET_HashCode *key_material)
Derive key material from a ECDH public key and a private EdDSA key.
Definition: crypto_ecc.c:727
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdh_eddsa(const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, const struct GNUNET_CRYPTO_EddsaPublicKey *pub, struct GNUNET_HashCode *key_material)
Derive key material from a EdDSA public key and a private ECDH key.
Definition: crypto_ecc.c:777
struct GNUNET_CRYPTO_EddsaPublicKey public_key

References CadetTunnelAxolotl::CKr, CadetTunnelAxolotl::CKs, CadetTunnelAxolotl::DHRr, GCT_alice_or_betty(), GNUNET_break_op, GNUNET_CRYPTO_ecc_ecdh(), GNUNET_CRYPTO_ecdh_eddsa(), GNUNET_CRYPTO_eddsa_ecdh(), GNUNET_CRYPTO_kdf(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_memcmp, GNUNET_NO, GNUNET_OK, GNUNET_STATISTICS_update(), GNUNET_SYSERR, GNUNET_TIME_absolute_add(), GNUNET_TIME_absolute_get(), GNUNET_YES, CadetTunnelAxolotl::HKr, CadetTunnelAxolotl::HKs, CadetTunnelAxolotl::kx_0, CadetTunnelAxolotl::last_ephemeral, LOG, my_private_key, CadetTunnelAxolotl::NHKr, CadetTunnelAxolotl::NHKs, pid, GNUNET_PeerIdentity::public_key, CadetTunnelAxolotl::ratchet_expiration, CadetTunnelAxolotl::ratchet_flag, ratchet_time, CadetTunnelAxolotl::RK, salt, and stats.

Referenced by GCT_add_channel(), and GCT_handle_kx().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ retry_kx()

static void retry_kx ( void *  cls)
static

Try to redo the KX or KX_AUTH handshake, if we can.

Parameters
clsthe struct CadetTunnel to do KX for.

Definition at line 1609 of file gnunet-service-cadet_tunnels.c.

1610 {
1611  struct CadetTunnel *t = cls;
1612  struct CadetTunnelAxolotl *ax;
1613 
1614  t->kx_task = NULL;
1616  "Trying to make KX progress on %s in state %s\n",
1617  GCT_2s (t),
1618  estate2s (t->estate));
1619  switch (t->estate)
1620  {
1621  case CADET_TUNNEL_KEY_UNINITIALIZED: /* first attempt */
1622  case CADET_TUNNEL_KEY_AX_SENT: /* trying again */
1623  send_kx (t,
1624  NULL,
1625  &t->ax);
1626  break;
1627 
1630  /* We are responding, so only require reply
1631  if WE have a channel waiting. */
1632  if (NULL != t->unverified_ax)
1633  {
1634  /* Send AX_AUTH so we might get this one verified */
1635  ax = t->unverified_ax;
1636  }
1637  else
1638  {
1639  /* How can this be? */
1640  GNUNET_break (0);
1641  ax = &t->ax;
1642  }
1643  send_kx_auth (t,
1644  NULL,
1645  ax,
1646  (0 == GCT_count_channels (t))
1647  ? GNUNET_NO
1648  : GNUNET_YES);
1649  break;
1650 
1652  /* We are responding, so only require reply
1653  if WE have a channel waiting. */
1654  if (NULL != t->unverified_ax)
1655  {
1656  /* Send AX_AUTH so we might get this one verified */
1657  ax = t->unverified_ax;
1658  }
1659  else
1660  {
1661  /* How can this be? */
1662  GNUNET_break (0);
1663  ax = &t->ax;
1664  }
1665  send_kx_auth (t,
1666  NULL,
1667  ax,
1668  (0 == GCT_count_channels (t))
1669  ? GNUNET_NO
1670  : GNUNET_YES);
1671  break;
1672 
1673  case CADET_TUNNEL_KEY_OK:
1674  /* Must have been the *other* peer asking us to
1675  respond with a KX_AUTH. */
1676  if (NULL != t->unverified_ax)
1677  {
1678  /* Sending AX_AUTH in response to AX so we might get this one verified */
1679  ax = t->unverified_ax;
1680  }
1681  else
1682  {
1683  /* Sending AX_AUTH in response to AX_AUTH */
1684  ax = &t->ax;
1685  }
1686  send_kx_auth (t,
1687  NULL,
1688  ax,
1689  GNUNET_NO);
1690  break;
1691  }
1692 }
static void send_kx(struct CadetTunnel *t, struct CadetTConnection *ct, struct CadetTunnelAxolotl *ax)
Send a KX message.
unsigned int GCT_count_channels(struct CadetTunnel *t)
Returns the number of channels using a tunnel.
static void send_kx_auth(struct CadetTunnel *t, struct CadetTConnection *ct, struct CadetTunnelAxolotl *ax, int force_reply)
Send a KX_AUTH message.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
Axolotl data, according to https://github.com/trevp/axolotl/wiki .

References CADET_TUNNEL_KEY_AX_AUTH_SENT, CADET_TUNNEL_KEY_AX_RECV, CADET_TUNNEL_KEY_AX_SENT, CADET_TUNNEL_KEY_AX_SENT_AND_RECV, CADET_TUNNEL_KEY_OK, CADET_TUNNEL_KEY_UNINITIALIZED, estate2s(), GCT_2s(), GCT_count_channels(), GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_NO, GNUNET_YES, LOG, send_kx(), send_kx_auth(), and t.

Referenced by connection_ready_cb(), GCT_add_channel(), and GCT_handle_kx().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCT_handle_kx()

void GCT_handle_kx ( struct CadetTConnection ct,
const struct GNUNET_CADET_TunnelKeyExchangeMessage msg 
)

Handle KX message that lacks authentication (and which will thus only be considered authenticated after we respond with our own KX_AUTH and finally successfully decrypt the payload).

Parameters
ctconnection/tunnel combo that received encrypted message
msgthe key exchange message

Definition at line 1696 of file gnunet-service-cadet_tunnels.c.

1698 {
1699  struct CadetTunnel *t = ct->t;
1700  int ret;
1701 
1703  "# KX received",
1704  1,
1705  GNUNET_NO);
1706  if (GNUNET_YES ==
1707  GCT_alice_or_betty (GCP_get_id (t->destination)))
1708  {
1709  /* Betty/Bob is not allowed to send KX! */
1710  GNUNET_break_op (0);
1711  return;
1712  }
1714  "Received KX message from %s with ephemeral %s from %s on connection %s\n",
1715  GCT_2s (t),
1716  GNUNET_e2s (&msg->ephemeral_key),
1717  GNUNET_i2s (GCP_get_id (t->destination)),
1718  GCC_2s (ct->cc));
1719 #if 1
1720  if ((0 ==
1721  memcmp (&t->ax.DHRr,
1722  &msg->ratchet_key,
1723  sizeof(msg->ratchet_key))) &&
1724  (0 ==
1725  memcmp (&t->ax.last_ephemeral,
1726  &msg->ephemeral_key,
1727  sizeof(msg->ephemeral_key))))
1728 
1729  {
1731  "# Duplicate KX received",
1732  1,
1733  GNUNET_NO);
1734  send_kx_auth (t,
1735  ct,
1736  &t->ax,
1737  GNUNET_NO);
1738  return;
1739  }
1740 #endif
1741  /* We only keep ONE unverified KX around, so if there is an existing one,
1742  clean it up. */
1743  if (NULL != t->unverified_ax)
1744  {
1745  if ((0 ==
1746  memcmp (&t->unverified_ax->DHRr,
1747  &msg->ratchet_key,
1748  sizeof(msg->ratchet_key))) &&
1749  (0 ==
1750  memcmp (&t->unverified_ax->last_ephemeral,
1751  &msg->ephemeral_key,
1752  sizeof(msg->ephemeral_key))))
1753  {
1755  "# Duplicate unverified KX received",
1756  1,
1757  GNUNET_NO);
1758 #if 1
1759  send_kx_auth (t,
1760  ct,
1761  t->unverified_ax,
1762  GNUNET_NO);
1763  return;
1764 #endif
1765  }
1767  "Dropping old unverified KX state.\n");
1769  "# Unverified KX dropped for fresh KX",
1770  1,
1771  GNUNET_NO);
1772  GNUNET_break (NULL == t->unverified_ax->skipped_head);
1773  memset (t->unverified_ax,
1774  0,
1775  sizeof(struct CadetTunnelAxolotl));
1776  }
1777  else
1778  {
1780  "Creating fresh unverified KX for %s\n",
1781  GCT_2s (t));
1783  "# Fresh KX setup",
1784  1,
1785  GNUNET_NO);
1786  t->unverified_ax = GNUNET_new (struct CadetTunnelAxolotl);
1787  }
1788  /* Set as the 'current' RK/DHRr the one we are currently using,
1789  so that the duplicate-detection logic of
1790  #update_ax_by_kx can work. */
1791  t->unverified_ax->RK = t->ax.RK;
1792  t->unverified_ax->DHRr = t->ax.DHRr;
1793  t->unverified_ax->DHRs = t->ax.DHRs;
1794  t->unverified_ax->kx_0 = t->ax.kx_0;
1795  t->unverified_attempts = 0;
1796 
1797  /* Update 'ax' by the new key material */
1798  ret = update_ax_by_kx (t->unverified_ax,
1799  GCP_get_id (t->destination),
1800  &msg->ephemeral_key,
1801  &msg->ratchet_key);
1803  if (GNUNET_OK != ret)
1804  {
1806  "# Useless KX",
1807  1,
1808  GNUNET_NO);
1809  return; /* duplicate KX, nothing to do */
1810  }
1811  /* move ahead in our state machine */
1812  if (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate)
1815  else if (CADET_TUNNEL_KEY_AX_SENT == t->estate)
1818 
1819  /* KX is still not done, try again our end. */
1820  if (CADET_TUNNEL_KEY_OK != t->estate)
1821  {
1822  if (NULL != t->kx_task)
1823  GNUNET_SCHEDULER_cancel (t->kx_task);
1824  t->kx_task
1826  t);
1827  }
1828 }
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
const char * GCC_2s(const struct CadetConnection *cc)
Get a (static) string for a connection.
static void retry_kx(void *cls)
Try to redo the KX or KX_AUTH handshake, if we can.
static int update_ax_by_kx(struct CadetTunnelAxolotl *ax, const struct GNUNET_PeerIdentity *pid, const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral_key, const struct GNUNET_CRYPTO_EcdhePublicKey *ratchet_key)
Update our Axolotl key state based on the KX data we received.

References CADET_TUNNEL_KEY_AX_RECV, CADET_TUNNEL_KEY_AX_SENT, CADET_TUNNEL_KEY_AX_SENT_AND_RECV, CADET_TUNNEL_KEY_OK, CADET_TUNNEL_KEY_UNINITIALIZED, CadetTConnection::cc, GCC_2s(), GCP_get_id(), GCT_2s(), GCT_alice_or_betty(), GCT_change_estate(), GNUNET_break, GNUNET_break_op, GNUNET_e2s(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_new, GNUNET_NO, GNUNET_OK, GNUNET_SCHEDULER_add_now(), GNUNET_SCHEDULER_cancel(), GNUNET_STATISTICS_update(), GNUNET_SYSERR, GNUNET_YES, LOG, msg, ret, retry_kx(), send_kx_auth(), stats, CadetTConnection::t, t, and update_ax_by_kx().

Referenced by GCC_handle_kx().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCT_handle_kx_auth()

void GCT_handle_kx_auth ( struct CadetTConnection ct,
const struct GNUNET_CADET_TunnelKeyExchangeAuthMessage msg 
)

Handle KX_AUTH message.

Parameters
ctconnection/tunnel combo that received encrypted message
msgthe key exchange message

Definition at line 1906 of file gnunet-service-cadet_tunnels.c.

1908 {
1909  struct CadetTunnel *t = ct->t;
1910  struct CadetTunnelAxolotl ax_tmp;
1911  struct GNUNET_HashCode kx_auth;
1912  int ret;
1913 
1915  "# KX_AUTH received",
1916  1,
1917  GNUNET_NO);
1918  if ((CADET_TUNNEL_KEY_UNINITIALIZED == t->estate) ||
1919  (CADET_TUNNEL_KEY_AX_RECV == t->estate))
1920  {
1921  /* Confusing, we got a KX_AUTH before we even send our own
1922  KX. This should not happen. We'll send our own KX ASAP anyway,
1923  so let's ignore this here. */
1924  GNUNET_break_op (0);
1925  return;
1926  }
1928  "Handling KX_AUTH message from %s with ephemeral %s\n",
1929  GCT_2s (t),
1930  GNUNET_e2s (&msg->kx.ephemeral_key));
1931  /* We do everything in ax_tmp until we've checked the authentication
1932  so we don't clobber anything we care about by accident. */
1933  ax_tmp = t->ax;
1934 
1935  /* Update 'ax' by the new key material */
1936  ret = update_ax_by_kx (&ax_tmp,
1937  GCP_get_id (t->destination),
1938  &msg->kx.ephemeral_key,
1939  &msg->kx.ratchet_key);
1940  if (GNUNET_OK != ret)
1941  {
1942  if (GNUNET_NO == ret)
1944  "# redundant KX_AUTH received",
1945  1,
1946  GNUNET_NO);
1947  else
1948  GNUNET_break (0); /* connect to self!? */
1949  return;
1950  }
1951  GNUNET_CRYPTO_hash (&ax_tmp.RK,
1952  sizeof(ax_tmp.RK),
1953  &kx_auth);
1954  if (0 != GNUNET_memcmp (&kx_auth,
1955  &msg->auth))
1956  {
1957  /* This KX_AUTH is not using the latest KX/KX_AUTH data
1958  we transmitted to the sender, refuse it, try KX again. */
1960  "# KX_AUTH not using our last KX received (auth failure)",
1961  1,
1962  GNUNET_NO);
1964  "KX AUTH mismatch!\n");
1965 #if DEBUG_KX
1966  {
1967  struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key;
1968 
1969  GNUNET_CRYPTO_ecdhe_key_get_public (&ax_tmp.kx_0,
1970  &ephemeral_key);
1971  if (0 != GNUNET_memcmp (&ephemeral_key,
1972  &msg->r_ephemeral_key_XXX))
1973  {
1975  "My ephemeral is %s!\n",
1976  GNUNET_e2s (&ephemeral_key));
1978  "Response is for ephemeral %s!\n",
1979  GNUNET_e2s (&msg->r_ephemeral_key_XXX));
1980  }
1981  else
1982  {
1983  test_crypto_bug (&ax_tmp.kx_0,
1984  &msg->kx.ephemeral_key_XXX,
1986  &msg->kx.private_key_XXX);
1987  }
1988  }
1989 #endif
1990  if (NULL == t->kx_task)
1991  t->kx_task
1992  = GNUNET_SCHEDULER_add_at (t->next_kx_attempt,
1993  &retry_kx,
1994  t);
1995  return;
1996  }
1997  /* Yep, we're good. */
1998  t->ax = ax_tmp;
1999  if (NULL != t->unverified_ax)
2000  {
2001  /* We got some "stale" KX before, drop that. */
2002  cleanup_ax (t->unverified_ax);
2003  GNUNET_free (t->unverified_ax);
2004  t->unverified_ax = NULL;
2005  }
2006 
2007  /* move ahead in our state machine */
2008  switch (t->estate)
2009  {
2012  /* Checked above, this is impossible. */
2013  GNUNET_assert (0);
2014  break;
2015 
2016  case CADET_TUNNEL_KEY_AX_SENT: /* This is the normal case */
2017  case CADET_TUNNEL_KEY_AX_SENT_AND_RECV: /* both peers started KX */
2018  case CADET_TUNNEL_KEY_AX_AUTH_SENT: /* both peers now did KX_AUTH */
2021  break;
2022 
2023  case CADET_TUNNEL_KEY_OK:
2024  /* Did not expect another KX_AUTH, but so what, still acceptable.
2025  Nothing to do here. */
2026  break;
2027  }
2028  if (0 != (GNUNET_CADET_KX_FLAG_FORCE_REPLY & ntohl (msg->kx.flags)))
2029  {
2030  send_kx_auth (t,
2031  NULL,
2032  &t->ax,
2033  GNUNET_NO);
2034  }
2035 }
static void cleanup_ax(struct CadetTunnelAxolotl *ax)
Cleanup state used by ax.
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:1249

Referenced by GCC_handle_kx_auth().

Here is the caller graph for this function:

◆ get_next_free_ctn()

static struct GNUNET_CADET_ChannelTunnelNumber get_next_free_ctn ( struct CadetTunnel t)
static

Compute the next free channel tunnel number for this tunnel.

Parameters
tthe tunnel
Returns
unused number that can uniquely identify a channel in the tunnel

Definition at line 1906 of file gnunet-service-cadet_tunnels.c.

2049 {
2050 #define HIGH_BIT 0x8000000
2052  uint32_t ctn;
2053  int cmp;
2054  uint32_t highbit;
2055 
2056  cmp = GNUNET_memcmp (&my_full_id,
2058  if (0 < cmp)
2059  highbit = HIGH_BIT;
2060  else if (0 > cmp)
2061  highbit = 0;
2062  else
2063  GNUNET_assert (0); // loopback must never go here!
2064  ctn = ntohl (t->next_ctn.cn);
2065  while (NULL !=
2067  ctn | highbit))
2068  {
2069  ctn = ((ctn + 1) & (~HIGH_BIT));
2070  }
2071  t->next_ctn.cn = htonl ((ctn + 1) & (~HIGH_BIT));
2072  ret.cn = htonl (ctn | highbit);
2073  return ret;
2074 }
#define HIGH_BIT
struct CadetPeer * GCT_get_destination(struct CadetTunnel *t)
Return the peer to which this tunnel goes.
Number identifying a CADET channel within a tunnel.

◆ GCT_add_channel()

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.

Add a channel to a tunnel.

Otherwise that notification will be done later in notify_tunnel_up_cb().

Parameters
tTunnel.
chChannel
Returns
unique number identifying ch within t

Definition at line 1906 of file gnunet-service-cadet_tunnels.c.

2089 {
2091 
2092  ctn = get_next_free_ctn (t);
2093  if (NULL != t->destroy_task)
2094  {
2095  GNUNET_SCHEDULER_cancel (t->destroy_task);
2096  t->destroy_task = NULL;
2097  }
2100  ntohl (ctn.cn),
2101  ch,
2104  "Adding %s to %s with state %d\n",
2105  GCCH_2s (ch),
2106  GCT_2s (t),
2107  t->estate);
2108  switch (t->estate)
2109  {
2111  /* waiting for connection to start KX */
2112  break;
2113 
2117  /* we're currently waiting for KX to complete */
2118  break;
2119 
2121  /* waiting for OTHER peer to send us data,
2122  we might need to prompt more aggressively! */
2123  if (NULL == t->kx_task)
2124  t->kx_task
2125  = GNUNET_SCHEDULER_add_at (t->next_kx_attempt,
2126  &retry_kx,
2127  t);
2128  break;
2129 
2130  case CADET_TUNNEL_KEY_OK:
2131  /* We are ready. Tell the new channel that we are up. */
2132  GCCH_tunnel_up (ch);
2133  break;
2134  }
2135  return ctn;
2136 }
const char * GCCH_2s(const struct CadetChannel *ch)
Get the static string for identification of the channel.
static struct GNUNET_CADET_ChannelTunnelNumber get_next_free_ctn(struct CadetTunnel *t)
Compute the next free channel tunnel number for this tunnel.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap32_put(struct GNUNET_CONTAINER_MultiHashMap32 *map, uint32_t key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY
There must only be one value per key; storing a value should fail if a value under the same key alrea...

References CADET_TUNNEL_KEY_AX_AUTH_SENT, CADET_TUNNEL_KEY_AX_RECV, CADET_TUNNEL_KEY_AX_SENT, CADET_TUNNEL_KEY_AX_SENT_AND_RECV, CADET_TUNNEL_KEY_OK, CADET_TUNNEL_KEY_UNINITIALIZED, cleanup_ax(), GCP_get_id(), GCT_2s(), GCT_change_estate(), GNUNET_assert, GNUNET_break, GNUNET_break_op, GNUNET_CADET_KX_FLAG_FORCE_REPLY, GNUNET_CRYPTO_ecdhe_key_get_public(), GNUNET_CRYPTO_hash(), GNUNET_e2s(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_memcmp, GNUNET_NO, GNUNET_OK, GNUNET_SCHEDULER_add_at(), GNUNET_STATISTICS_update(), CadetTunnelAxolotl::kx_0, LOG, msg, my_private_key, ret, retry_kx(), CadetTunnelAxolotl::RK, send_kx_auth(), stats, CadetTConnection::t, t, and update_ax_by_kx().

Referenced by GCCH_channel_local_new().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCT_connection_lost()

void GCT_connection_lost ( struct CadetTConnection ct)

We lost a connection, remove it from our list and clean up the connection object itself.

Parameters
ctbinding of connection to tunnel of the connection that was lost.

Definition at line 2146 of file gnunet-service-cadet_tunnels.c.

2147 {
2148  struct CadetTunnel *t = ct->t;
2149 
2150  if (GNUNET_YES == ct->is_ready)
2151  {
2152  GNUNET_CONTAINER_DLL_remove (t->connection_ready_head,
2153  t->connection_ready_tail,
2154  ct);
2155  t->num_ready_connections--;
2156  }
2157  else
2158  {
2159  GNUNET_CONTAINER_DLL_remove (t->connection_busy_head,
2160  t->connection_busy_tail,
2161  ct);
2162  t->num_busy_connections--;
2163  }
2164  GNUNET_free (ct);
2165 }

References GNUNET_CONTAINER_DLL_remove, GNUNET_free, GNUNET_YES, CadetTConnection::is_ready, CadetTConnection::t, and t.

Referenced by destroy_t_connection(), GCC_create_inbound(), and GCC_destroy_without_core().

Here is the caller graph for this function:

◆ destroy_t_connection()

static void destroy_t_connection ( void *  cls,
struct CadetTConnection ct 
)
static

Clean up connection ct of a tunnel.

Parameters
clsthe struct CadetTunnel
ctconnection to clean up

Definition at line 2175 of file gnunet-service-cadet_tunnels.c.

2177 {
2178  struct CadetTunnel *t = cls;
2179  struct CadetConnection *cc = ct->cc;
2180 
2181  GNUNET_assert (ct->t == t);
2184 }
void GCC_destroy_without_tunnel(struct CadetConnection *cc)
Destroy a connection, called if the tunnel association with the connection was already broken,...
void GCT_connection_lost(struct CadetTConnection *ct)
We lost a connection, remove it from our list and clean up the connection object itself.
struct CadetTConnection * ct
Which tunnel is using this connection?

References CadetTConnection::cc, CadetConnection::ct, GCC_destroy_without_tunnel(), GCT_connection_lost(), GNUNET_assert, CadetTConnection::t, and t.

Referenced by destroy_tunnel(), and maintain_connections_cb().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ destroy_tunnel()

static void destroy_tunnel ( void *  cls)
static

This tunnel is no longer used, destroy it.

Parameters
clsthe idle tunnel

Definition at line 2193 of file gnunet-service-cadet_tunnels.c.

2194 {
2195  struct CadetTunnel *t = cls;
2196  struct CadetTunnelQueueEntry *tq;
2197 
2198  t->destroy_task = NULL;
2200  "Destroying idle %s\n",
2201  GCT_2s (t));
2205  t);
2206  GNUNET_assert (NULL == t->connection_ready_head);
2207  GNUNET_assert (NULL == t->connection_busy_head);
2208  while (NULL != (tq = t->tq_head))
2209  {
2210  if (NULL != tq->cont)
2211  tq->cont (tq->cont_cls,
2212  NULL);
2213  GCT_send_cancel (tq);
2214  }
2215  GCP_drop_tunnel (t->destination,
2216  t);
2218  if (NULL != t->maintain_connections_task)
2219  {
2220  GNUNET_SCHEDULER_cancel (t->maintain_connections_task);
2221  t->maintain_connections_task = NULL;
2222  }
2223  if (NULL != t->send_task)
2224  {
2225  GNUNET_SCHEDULER_cancel (t->send_task);
2226  t->send_task = NULL;
2227  }
2228  if (NULL != t->kx_task)
2229  {
2230  GNUNET_SCHEDULER_cancel (t->kx_task);
2231  t->kx_task = NULL;
2232  }
2233  GNUNET_MST_destroy (t->mst);
2234  GNUNET_MQ_destroy (t->mq);
2235  if (NULL != t->unverified_ax)
2236  {
2237  cleanup_ax (t->unverified_ax);
2238  GNUNET_free (t->unverified_ax);
2239  }
2240  cleanup_ax (&t->ax);
2241  GNUNET_assert (NULL == t->destroy_task);
2242  GNUNET_free (t);
2243 }
void GCP_drop_tunnel(struct CadetPeer *cp, struct CadetTunnel *t)
The tunnel to the given peer no longer exists, remove it from our data structures,...
void GCT_send_cancel(struct CadetTunnelQueueEntry *tq)
Cancel a previously sent message while it's in the queue.
void GCT_iterate_connections(struct CadetTunnel *t, GCT_ConnectionIterator iter, void *iter_cls)
Iterate over all connections of a tunnel.
static void destroy_t_connection(void *cls, struct CadetTConnection *ct)
Clean up connection ct of a tunnel.
void GNUNET_CONTAINER_multihashmap32_destroy(struct GNUNET_CONTAINER_MultiHashMap32 *map)
Destroy a 32-bit key hash map.
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition: mq.c:683
void GNUNET_MST_destroy(struct GNUNET_MessageStreamTokenizer *mst)
Destroys a tokenizer.
Definition: mst.c:404
Struct used to save messages in a non-ready tunnel to send once connected.
GCT_SendContinuation cont
Continuation to call once sent (on the channel layer).
void * cont_cls
Closure for cont.

References cleanup_ax(), CadetTunnelQueueEntry::cont, CadetTunnelQueueEntry::cont_cls, destroy_t_connection(), GCP_drop_tunnel(), GCT_2s(), GCT_count_channels(), GCT_iterate_connections(), GCT_send_cancel(), GNUNET_assert, GNUNET_CONTAINER_multihashmap32_destroy(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_MQ_destroy(), GNUNET_MST_destroy(), GNUNET_SCHEDULER_cancel(), LOG, and t.

Referenced by callback_room_connect(), connection_ready_cb(), enter_srv_room_at(), GCT_destroy_tunnel_now(), GCT_remove_channel(), and iterate_destroy_tunnels().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCT_remove_channel()

void GCT_remove_channel ( struct CadetTunnel t,
struct CadetChannel ch,
struct GNUNET_CADET_ChannelTunnelNumber  ctn 
)

Remove a channel from a tunnel.

Parameters
tTunnel.
chChannel
ctnunique number identifying ch within t

Definition at line 2254 of file gnunet-service-cadet_tunnels.c.

2257 {
2259  "Removing %s from %s\n",
2260  GCCH_2s (ch),
2261  GCT_2s (t));
2264  ntohl (ctn.cn),
2265  ch));
2266  if ((0 ==
2267  GCT_count_channels (t)) &&
2268  (NULL == t->destroy_task))
2269  {
2270  t->destroy_task
2272  &destroy_tunnel,
2273  t);
2274  }
2275 }
#define IDLE_DESTROY_DELAY
How long do we wait until tearing down an idle tunnel?
static void destroy_tunnel(void *cls)
This tunnel is no longer used, destroy it.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap32_remove(struct GNUNET_CONTAINER_MultiHashMap32 *map, uint32_t key, const void *value)
Remove the given key-value pair from the map.
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:1272

References ch, GNUNET_CADET_ChannelTunnelNumber::cn, destroy_tunnel(), GCCH_2s(), GCT_2s(), GCT_count_channels(), GNUNET_assert, GNUNET_CONTAINER_multihashmap32_remove(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_SCHEDULER_add_delayed(), GNUNET_YES, IDLE_DESTROY_DELAY, LOG, and t.

Referenced by channel_destroy().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ destroy_remaining_channels()

static int destroy_remaining_channels ( void *  cls,
uint32_t  key,
void *  value 
)
static

Destroy remaining channels during shutdown.

Parameters
clsthe struct CadetTunnel of the channel
keykey of the channel
valuethe struct CadetChannel
Returns
GNUNET_OK (continue to iterate)

Definition at line 2287 of file gnunet-service-cadet_tunnels.c.

2290 {
2291  struct CadetChannel *ch = value;
2292 
2294  NULL);
2295  return GNUNET_OK;
2296 }
void GCCH_handle_remote_destroy(struct CadetChannel *ch, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti)
Destroy channel, based on the other peer closing the connection.

References ch, GCCH_handle_remote_destroy(), GNUNET_OK, and value.

Referenced by GCT_destroy_tunnel_now().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCT_destroy_tunnel_now()

void GCT_destroy_tunnel_now ( struct CadetTunnel t)

Destroys the tunnel t now, without delay.

Used during shutdown.

Parameters
ttunnel to destroy

Definition at line 2305 of file gnunet-service-cadet_tunnels.c.

2306 {
2310  t);
2311  GNUNET_assert (0 ==
2312  GCT_count_channels (t));
2313  if (NULL != t->destroy_task)
2314  {
2315  GNUNET_SCHEDULER_cancel (t->destroy_task);
2316  t->destroy_task = NULL;
2317  }
2318  destroy_tunnel (t);
2319 }
int shutting_down
Signal that shutdown is happening: prevent recovery measures.
static int destroy_remaining_channels(void *cls, uint32_t key, void *value)
Destroy remaining channels during shutdown.

References destroy_remaining_channels(), destroy_tunnel(), GCT_count_channels(), GNUNET_assert, GNUNET_CONTAINER_multihashmap32_iterate(), GNUNET_SCHEDULER_cancel(), GNUNET_YES, shutting_down, and t.

Referenced by destroy_tunnels_now().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ try_send_normal_payload()

static void try_send_normal_payload ( struct CadetTunnel t,
struct CadetTConnection ct 
)
static

Send normal payload from queue in t via connection ct.

Does nothing if our payload queue is empty.

Parameters
ttunnel to send data from
ctconnection to use for transmission (is ready)

Definition at line 2330 of file gnunet-service-cadet_tunnels.c.

2332 {
2333  struct CadetTunnelQueueEntry *tq;
2334 
2336  tq = t->tq_head;
2337  if (NULL == tq)
2338  {
2339  /* no messages pending right now */
2341  "Not sending payload of %s on ready %s (nothing pending)\n",
2342  GCT_2s (t),
2343  GCC_2s (ct->cc));
2344  return;
2345  }
2346  /* ready to send message 'tq' on tunnel 'ct' */
2347  GNUNET_assert (t == tq->t);
2348  GNUNET_CONTAINER_DLL_remove (t->tq_head,
2349  t->tq_tail,
2350  tq);
2351  if (NULL != tq->cid)
2352  *tq->cid = *GCC_get_id (ct->cc);
2355  "Sending payload of %s on %s\n",
2356  GCT_2s (t),
2357  GCC_2s (ct->cc));
2358  GCC_transmit (ct->cc,
2359  tq->env);
2360  if (NULL != tq->cont)
2361  tq->cont (tq->cont_cls,
2362  GCC_get_id (ct->cc));
2363  GNUNET_free (tq);
2364 }
struct GNUNET_MQ_Envelope * env
Envelope of message to send follows.
struct GNUNET_CADET_ConnectionTunnelIdentifier * cid
Where to put the connection identifier into the payload of the message in env once we have it?
struct CadetTunnel * t
Tunnel these messages belong in.

References CadetTConnection::cc, CadetTunnelQueueEntry::cid, CadetTunnelQueueEntry::cont, CadetTunnelQueueEntry::cont_cls, CadetTunnelQueueEntry::env, GCC_2s(), GCC_get_id(), GCC_transmit(), GCT_2s(), GNUNET_assert, GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_YES, CadetTConnection::is_ready, LOG, mark_connection_unready(), CadetTunnelQueueEntry::t, and t.

Referenced by connection_ready_cb(), and trigger_transmissions().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ connection_ready_cb()

static void connection_ready_cb ( void *  cls,
int  is_ready 
)
static

A connection is is_ready for transmission.

Looks at our message queue and if there is a message, sends it out via the connection.

Parameters
clsthe struct CadetTConnection that is is_ready
is_readyGNUNET_YES if connection are now ready, GNUNET_NO if connection are no longer ready

Definition at line 2376 of file gnunet-service-cadet_tunnels.c.

2378 {
2379  struct CadetTConnection *ct = cls;
2380  struct CadetTunnel *t = ct->t;
2381 
2382  if (GNUNET_NO == is_ready)
2383  {
2385  "%s no longer ready for %s\n",
2386  GCC_2s (ct->cc),
2387  GCT_2s (t));
2389  return;
2390  }
2391  GNUNET_assert (GNUNET_NO == ct->is_ready);
2392  GNUNET_CONTAINER_DLL_remove (t->connection_busy_head,
2393  t->connection_busy_tail,
2394  ct);
2395  GNUNET_assert (0 < t->num_busy_connections);
2396  t->num_busy_connections--;
2397  ct->is_ready = GNUNET_YES;
2398  GNUNET_CONTAINER_DLL_insert_tail (t->connection_ready_head,
2399  t->connection_ready_tail,
2400  ct);
2401  t->num_ready_connections++;
2402 
2404  "%s now ready for %s in state %s\n",
2405  GCC_2s (ct->cc),
2406  GCT_2s (t),
2407  estate2s (t->estate));
2408  switch (t->estate)
2409  {
2412  "Do not begin KX for %s if WE have no channels waiting. Retrying after %llu\n",
2413  GCT_2s (t),
2414  (unsigned long long) GNUNET_TIME_absolute_get_remaining (
2415  t->next_kx_attempt).rel_value_us);
2416  /* Do not begin KX if WE have no channels waiting! */
2418  t->next_kx_attempt).rel_value_us)
2419  return; /* wait for timeout before retrying */
2420  /* We are uninitialized, just transmit immediately,
2421  without undue delay. */
2422 
2424  "Why for %s \n",
2425  GCT_2s (t));
2426 
2427  if (NULL != t->kx_task)
2428  {
2429  GNUNET_SCHEDULER_cancel (t->kx_task);
2430  t->kx_task = NULL;
2431  }
2432  send_kx (t,
2433  ct,
2434  &t->ax);
2435  if ((0 ==
2436  GCT_count_channels (t)) &&
2437  (NULL == t->destroy_task))
2438  {
2439  t->destroy_task
2441  &destroy_tunnel,
2442  t);
2443  }
2444  break;
2445 
2450  /* we're currently waiting for KX to complete, schedule job */
2451  if (NULL == t->kx_task)
2452  t->kx_task
2453  = GNUNET_SCHEDULER_add_at (t->next_kx_attempt,
2454  &retry_kx,
2455  t);
2456  break;
2457 
2458  case CADET_TUNNEL_KEY_OK:
2459  if (GNUNET_YES == t->kx_auth_requested)
2460  {
2462  t->next_kx_attempt).rel_value_us)
2463  return; /* wait for timeout */
2464  if (NULL != t->kx_task)
2465  {
2466  GNUNET_SCHEDULER_cancel (t->kx_task);
2467  t->kx_task = NULL;
2468  }
2469  send_kx_auth (t,
2470  ct,
2471  &t->ax,
2472  GNUNET_NO);
2473  return;
2474  }
2476  ct);
2477  break;
2478  }
2479 }
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.

References CADET_TUNNEL_KEY_AX_AUTH_SENT, CADET_TUNNEL_KEY_AX_RECV, CADET_TUNNEL_KEY_AX_SENT, CADET_TUNNEL_KEY_AX_SENT_AND_RECV, CADET_TUNNEL_KEY_OK, CADET_TUNNEL_KEY_UNINITIALIZED, CadetTConnection::cc, destroy_tunnel(), estate2s(), GCC_2s(), GCT_2s(), GCT_count_channels(), GNUNET_assert, GNUNET_CONTAINER_DLL_insert_tail, GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_DEBUG, GNUNET_NO, GNUNET_SCHEDULER_add_at(), GNUNET_SCHEDULER_add_delayed(), GNUNET_SCHEDULER_cancel(), GNUNET_TIME_absolute_get_remaining(), GNUNET_YES, IDLE_DESTROY_DELAY, CadetTConnection::is_ready, LOG, mark_connection_unready(), GNUNET_TIME_Relative::rel_value_us, retry_kx(), send_kx(), send_kx_auth(), CadetTConnection::t, t, and try_send_normal_payload().

Referenced by consider_path_cb(), and GCT_add_inbound_connection().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ evaluate_connection()

static void evaluate_connection ( void *  cls,
struct CadetTConnection ct 
)
static

Evaluate a connection, updating our summary information in cls about what kinds of connections we have.

Parameters
clsthe struct EvaluationSummary * to update
cta connection to include in the summary

Definition at line 2564 of file gnunet-service-cadet_tunnels.c.

2566 {
2567  struct EvaluationSummary *es = cls;
2568  struct CadetConnection *cc = ct->cc;
2569  unsigned int ct_length;
2570  struct CadetPeerPath *ps;
2571  const struct CadetConnectionMetrics *metrics;
2572  GNUNET_CONTAINER_HeapCostType ct_desirability;
2573  struct GNUNET_TIME_Relative uptime;
2574  struct GNUNET_TIME_Relative last_use;
2575  double score;
2576  double success_rate;
2577 
2578  ps = GCC_get_path (cc,
2579  &ct_length);
2581  "Evaluating path %s of existing %s\n",
2582  GCPP_2s (ps),
2583  GCC_2s (cc));
2584  if (ps == es->path)
2585  {
2587  "Ignoring duplicate path %s.\n",
2588  GCPP_2s (es->path));
2589  es->duplicate = GNUNET_YES;
2590  return;
2591  }
2592  if (NULL != es->path)
2593  {
2594  int duplicate = GNUNET_YES;
2595 
2596  for (unsigned int i = 0; i < ct_length; i++)
2597  {
2598  GNUNET_assert (GCPP_get_length (es->path) > i);
2599  if (GCPP_get_peer_at_offset (es->path,
2600  i) !=
2602  i))
2603  {
2604  duplicate = GNUNET_NO;
2605  break;
2606  }
2607  }
2608  if (GNUNET_YES == duplicate)
2609  {
2611  "Ignoring overlapping path %s.\n",
2612  GCPP_2s (es->path));
2613  es->duplicate = GNUNET_YES;
2614  return;
2615  }
2616  else
2617  {
2619  "Known path %s differs from proposed path\n",
2620  GCPP_2s (ps));
2621  }
2622  }
2623 
2624  ct_desirability = GCPP_get_desirability (ps);
2625  metrics = GCC_get_metrics (cc);
2626  uptime = GNUNET_TIME_absolute_get_duration (metrics->age);
2627  last_use = GNUNET_TIME_absolute_get_duration (metrics->last_use);
2628  /* We add 1.0 here to avoid division by zero. */
2629  success_rate = (metrics->num_acked_transmissions + 1.0)
2630  / (metrics->num_successes + 1.0);
2631  score
2632  = ct_desirability
2633  + 100.0 / (1.0 + ct_length) /* longer paths = better */
2634  + sqrt (uptime.rel_value_us / 60000000LL) /* larger uptime = better */
2635  - last_use.rel_value_us / 1000L; /* longer idle = worse */
2636  score *= success_rate; /* weigh overall by success rate */
2637 
2638  if ((NULL == es->worst) ||
2639  (score < es->worst_score))
2640  {
2641  es->worst = ct;
2642  es->worst_score = score;
2643  }
2644  es->min_length = GNUNET_MIN (es->min_length,
2645  ct_length);
2646  es->max_length = GNUNET_MAX (es->max_length,
2647  ct_length);
2648  es->min_desire = GNUNET_MIN (es->min_desire,
2649  ct_desirability);
2650  es->max_desire = GNUNET_MAX (es->max_desire,
2651  ct_desirability);
2652 }
const struct CadetConnectionMetrics * GCC_get_metrics(struct CadetConnection *cc)
Obtain performance metrics from cc.
struct CadetPeerPath * GCC_get_path(struct CadetConnection *cc, unsigned int *off)
Obtain the path used by this connection.
struct CadetPeer * GCPP_get_peer_at_offset(struct CadetPeerPath *path, unsigned int off)
Obtain the peer at offset off in path.
const char * GCPP_2s(struct CadetPeerPath *path)
Convert a path to a human-readable string.
unsigned int GCPP_get_length(struct CadetPeerPath *path)
Return the length of the path.
GNUNET_CONTAINER_HeapCostType GCPP_get_desirability(const struct CadetPeerPath *path)
Return how much we like keeping the path.
uint64_t GNUNET_CONTAINER_HeapCostType
Cost by which elements in a heap can be ordered.
#define GNUNET_MAX(a, b)
#define GNUNET_MIN(a, b)
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:436
Performance metrics for a connection.
unsigned long long num_acked_transmissions
How many packets that ought to generate an ACK did we send via this connection?
struct GNUNET_TIME_Absolute age
When was this connection first established? (by us sending or receiving the CREATE_ACK for the first ...
unsigned long long num_successes
Number of packets that were sent via this connection did actually receive an ACK? (Note: ACKs may be ...
struct GNUNET_TIME_Absolute last_use
When was this connection last used? (by us sending or receiving a PAYLOAD message on it)
Information regarding a possible path to reach a peer.
Closure for evaluate_connection.
unsigned int max_length
Maximum length of any of our connections, 0 if we have none.
int duplicate
Set to GNUNET_YES if we have a connection over path already.
GNUNET_CONTAINER_HeapCostType min_desire
Minimum desirability of any of our connections, UINT64_MAX if we have none.
struct CadetTConnection * worst
Connection deemed the "worst" so far encountered by evaluate_connection, NULL if we did not yet encou...
unsigned int min_length
Minimum length of any of our connections, UINT_MAX if we have none.
GNUNET_CONTAINER_HeapCostType max_desire
Maximum desirability of any of our connections, 0 if we have none.
double worst_score
Numeric score of worst, only set if worst is non-NULL.
struct CadetPeerPath * path
Path we are comparing against for evaluate_connection, can be NULL.
Time for relative time used by GNUnet, in microseconds.

References CadetConnectionMetrics::age, CadetTConnection::cc, CadetConnection::ct, EvaluationSummary::duplicate, GCC_2s(), GCC_get_metrics(), GCC_get_path(), GCPP_2s(), GCPP_get_desirability(), GCPP_get_length(), GCPP_get_peer_at_offset(), GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_MAX, GNUNET_MIN, GNUNET_NO, GNUNET_TIME_absolute_get_duration(), GNUNET_YES, CadetConnectionMetrics::last_use, LOG, EvaluationSummary::max_desire, EvaluationSummary::max_length, EvaluationSummary::min_desire, EvaluationSummary::min_length, CadetConnectionMetrics::num_acked_transmissions, CadetConnectionMetrics::num_successes, EvaluationSummary::path, GNUNET_TIME_Relative::rel_value_us, EvaluationSummary::worst, and EvaluationSummary::worst_score.

Referenced by consider_path_cb(), and maintain_connections_cb().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ consider_path_cb()

static int consider_path_cb ( void *  cls,
struct CadetPeerPath path,
unsigned int  off 
)
static

Consider using the path p for the tunnel t.

The tunnel destination is at offset off in path p.

Parameters
clsour tunnel
patha path to our destination
offoffset of the destination on path path
Returns
GNUNET_YES (should keep iterating)

Definition at line 2665 of file gnunet-service-cadet_tunnels.c.

2668 {
2669  struct CadetTunnel *t = cls;
2670  struct EvaluationSummary es;
2671  struct CadetTConnection *ct;
2672 
2673  GNUNET_assert (off < GCPP_get_length (path));
2675  off) == t->destination);
2676  es.min_length = UINT_MAX;
2677  es.max_length = 0;
2678  es.max_desire = 0;
2679  es.min_desire = UINT64_MAX;
2680  es.path = path;
2681  es.duplicate = GNUNET_NO;
2682  es.worst = NULL;
2683 
2684  /* Compute evaluation summary over existing connections. */
2686  "Evaluating proposed path %s for target %s\n",
2687  GCPP_2s (path),
2688  GCT_2s (t));
2689  /* FIXME: suspect this does not ACTUALLY iterate
2690  over all existing paths, otherwise dup detection
2691  should work!!! */
2694  &es);
2695  if (GNUNET_YES == es.duplicate)
2696  return GNUNET_YES;
2697 
2698  /* FIXME: not sure we should really just count
2699  'num_connections' here, as they may all have
2700  consistently failed to connect. */
2701 
2702  /* We iterate by increasing path length; if we have enough paths and
2703  this one is more than twice as long than what we are currently
2704  using, then ignore all of these super-long ones! */
2706  (es.min_length * 2 < off) &&
2707  (es.max_length < off))
2708  {
2710  "Ignoring paths of length %u, they are way too long.\n",
2711  es.min_length * 2);
2712  return GNUNET_NO;
2713  }
2714  /* If we have enough paths and this one looks no better, ignore it. */
2716  (es.min_length < GCPP_get_length (path)) &&
2717  (es.min_desire > GCPP_get_desirability (path)) &&
2718  (es.max_length < off))
2719  {
2721  "Ignoring path (%u/%llu) to %s, got something better already.\n",
2722  GCPP_get_length (path),
2723  (unsigned long long) GCPP_get_desirability (path),
2724  GCP_2s (t->destination));
2725  return GNUNET_YES;
2726  }
2727 
2728  /* Path is interesting (better by some metric, or we don't have
2729  enough paths yet). */
2730  ct = GNUNET_new (struct CadetTConnection);
2732  ct->t = t;
2733  ct->cc = GCC_create (t->destination,
2734  path,
2735  off,
2736  ct,
2738  ct);
2739 
2740  /* FIXME: schedule job to kill connection (and path?) if it takes
2741  too long to get ready! (And track performance data on how long
2742  other connections took with the tunnel!)
2743  => Note: to be done within 'connection'-logic! */
2744  GNUNET_CONTAINER_DLL_insert (t->connection_busy_head,
2745  t->connection_busy_tail,
2746  ct);
2747  t->num_busy_connections++;
2749  "Found interesting path %s for %s, created %s\n",
2750  GCPP_2s (path),
2751  GCT_2s (t),
2752  GCC_2s (ct->cc));
2753  return GNUNET_YES;
2754 }
struct CadetConnection * GCC_create(struct CadetPeer *destination, struct CadetPeerPath *path, unsigned int off, struct CadetTConnection *ct, GCC_ReadyCallback ready_cb, void *ready_cb_cls)
Create a connection to destination via path and notify cb whenever we are ready for more data.
const char * GCP_2s(const struct CadetPeer *cp)
Get the static string for a peer ID.
unsigned int GCT_count_any_connections(const struct CadetTunnel *t)
Counts the number of connections created for a tunnel, including busy connections.
static void connection_ready_cb(void *cls, int is_ready)
A connection is is_ready for transmission.
static void evaluate_connection(void *cls, struct CadetTConnection *ct)
Evaluate a connection, updating our summary information in cls about what kinds of connections we hav...
#define DESIRED_CONNECTIONS_PER_TUNNEL
How many connections would we like to have per tunnel?
struct GNUNET_TIME_Absolute created
Creation time, to keep oldest connection alive.

References CadetTConnection::cc, connection_ready_cb(), CadetTConnection::created, DESIRED_CONNECTIONS_PER_TUNNEL, EvaluationSummary::duplicate, evaluate_connection(), GCC_2s(), GCC_create(), GCP_2s(), GCPP_2s(), GCPP_get_desirability(), GCPP_get_length(), GCPP_get_peer_at_offset(), GCT_2s(), GCT_count_any_connections(), GCT_iterate_connections(), GNUNET_assert, GNUNET_CONTAINER_DLL_insert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_new, GNUNET_NO, GNUNET_TIME_absolute_get(), GNUNET_YES, LOG, EvaluationSummary::max_desire, EvaluationSummary::max_length, EvaluationSummary::min_desire, EvaluationSummary::min_length, EvaluationSummary::path, CadetTConnection::t, t, and EvaluationSummary::worst.

Referenced by GCT_consider_path(), and maintain_connections_cb().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ maintain_connections_cb()

static void maintain_connections_cb ( void *  cls)
static

Function called to maintain the connections underlying our tunnel.

Tries to maintain (incl. tear down) connections for the tunnel, and if there is a significant change, may trigger transmissions.

Basically, needs to check if there are connections that perform badly, and if so eventually kill them and trigger a replacement. The strategy is to open one more connection than DESIRED_CONNECTIONS_PER_TUNNEL, and then periodically kick out the least-performing one, and then inquire for new ones.

Parameters
clsthe struct CadetTunnel

Definition at line 2771 of file gnunet-service-cadet_tunnels.c.

2772 {
2773  struct CadetTunnel *t = cls;
2774  struct GNUNET_TIME_Relative delay;
2775  struct EvaluationSummary es;
2776 
2777  t->maintain_connections_task = NULL;
2779  "Performing connection maintenance for %s.\n",
2780  GCT_2s (t));
2781 
2782  es.min_length = UINT_MAX;
2783  es.max_length = 0;
2784  es.max_desire = 0;
2785  es.min_desire = UINT64_MAX;
2786  es.path = NULL;
2787  es.worst = NULL;
2788  es.duplicate = GNUNET_NO;
2791  &es);
2792  if ((NULL != es.worst) &&
2794  {
2795  /* Clear out worst-performing connection 'es.worst'. */
2797  es.worst);
2798  }
2799 
2800  /* Consider additional paths */
2801  (void) GCP_iterate_paths (t->destination,
2803  t);
2804 
2805  /* FIXME: calculate when to try again based on how well we are doing;
2806  in particular, if we have to few connections, we might be able
2807  to do without this (as PATHS should tell us whenever a new path
2808  is available instantly; however, need to make sure this job is
2809  restarted after that happens).
2810  Furthermore, if the paths we do know are in a reasonably narrow
2811  quality band and are plentyful, we might also consider us stabilized
2812  and then reduce the frequency accordingly. */delay = GNUNET_TIME_UNIT_MINUTES;
2813  t->maintain_connections_task
2816  t);
2817 }
static struct GNUNET_TIME_Relative delay
When should dkg communication start?
unsigned int GCP_iterate_paths(struct CadetPeer *cp, GCP_PathIterator callback, void *callback_cls)
Iterate over the paths to a peer.
static int consider_path_cb(void *cls, struct CadetPeerPath *path, unsigned int off)
Consider using the path p for the tunnel t.
static void maintain_connections_cb(void *cls)
Function called to maintain the connections underlying our tunnel.
#define GNUNET_TIME_UNIT_MINUTES
One minute.

References consider_path_cb(), delay, DESIRED_CONNECTIONS_PER_TUNNEL, destroy_t_connection(), EvaluationSummary::duplicate, evaluate_connection(), GCP_iterate_paths(), GCT_2s(), GCT_count_any_connections(), GCT_iterate_connections(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_NO, GNUNET_SCHEDULER_add_delayed(), GNUNET_TIME_UNIT_MINUTES, LOG, EvaluationSummary::max_desire, EvaluationSummary::max_length, EvaluationSummary::min_desire, EvaluationSummary::min_length, EvaluationSummary::path, t, and EvaluationSummary::worst.

Referenced by GCT_create_tunnel().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCT_consider_path()

void GCT_consider_path ( struct CadetTunnel t,
struct CadetPeerPath p,
unsigned int  off 
)

Consider using the path p for the tunnel t.

The tunnel destination is at offset off in path p.

Parameters
tour tunnel
pa path to our destination
offoffset of the destination on path path

Definition at line 2821 of file gnunet-service-cadet_tunnels.c.

2824 {
2826  "Considering %s for %s (offset %u)\n",
2827  GCPP_2s (p),
2828  GCT_2s (t),
2829  off);
2830  (void) consider_path_cb (t,
2831  p,
2832  off);
2833 }
static struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-uri.c:38

References consider_path_cb(), GCPP_2s(), GCT_2s(), GNUNET_ERROR_TYPE_DEBUG, LOG, p, and t.

Referenced by GCP_path_entry_add(), and GCP_set_mq().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_plaintext_keepalive()

static void handle_plaintext_keepalive ( void *  cls,
const struct GNUNET_MessageHeader msg 
)
static

We got a keepalive.

Track in statistics.

Parameters
clsthe struct CadetTunnel for which we decrypted the message
msgthe message we received on the tunnel

Definition at line 2843 of file gnunet-service-cadet_tunnels.c.

2845 {
2846  struct CadetTunnel *t = cls;
2847 
2849  "Received KEEPALIVE on %s\n",
2850  GCT_2s (t));
2852  "# keepalives received",
2853  1,
2854  GNUNET_NO);
2855 }

References GCT_2s(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_NO, GNUNET_STATISTICS_update(), LOG, stats, and t.

Here is the call graph for this function:

◆ check_plaintext_data()

static int check_plaintext_data ( void *  cls,
const struct GNUNET_CADET_ChannelAppDataMessage msg 
)
static

Check that msg is well-formed.

Parameters
clsthe struct CadetTunnel for which we decrypted the message
msgthe message we received on the tunnel
Returns
GNUNET_OK (any variable-size payload goes)

Definition at line 2866 of file gnunet-service-cadet_tunnels.c.

2868 {
2869  return GNUNET_OK;
2870 }

References GNUNET_OK.

◆ handle_plaintext_data()

static void handle_plaintext_data ( void *  cls,
const struct GNUNET_CADET_ChannelAppDataMessage msg 
)
static

We received payload data for a channel.

Locate the channel and process the data, or return an error if the channel is unknown.

Parameters
clsthe struct CadetTunnel for which we decrypted the message
msgthe message we received on the tunnel

Definition at line 2881 of file gnunet-service-cadet_tunnels.c.

2883 {
2884  struct CadetTunnel *t = cls;
2885  struct CadetChannel *ch;
2886 
2887  ch = lookup_channel (t,
2888  msg->ctn);
2889  if (NULL == ch)
2890  {
2891  /* We don't know about such a channel, might have been destroyed on our
2892  end in the meantime, or never existed. Send back a DESTROY. */
2894  "Received %u bytes of application data for unknown channel %u, sending DESTROY\n",
2895  (unsigned int) (ntohs (msg->header.size) - sizeof(*msg)),
2896  ntohl (msg->ctn.cn));
2898  msg->ctn);
2899  return;
2900  }
2902  GCC_get_id (t->current_ct->cc),
2903  msg);
2904 }
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.
void GCT_send_channel_destroy(struct CadetTunnel *t, struct GNUNET_CADET_ChannelTunnelNumber ctn)
Send a DESTROY message via the tunnel.
struct CadetChannel * lookup_channel(struct CadetTunnel *t, struct GNUNET_CADET_ChannelTunnelNumber ctn)
Lookup a channel by its ctn.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.

References ch, GCC_get_id(), GCCH_handle_channel_plaintext_data(), GCT_send_channel_destroy(), GNUNET_ERROR_TYPE_DEBUG, LOG, lookup_channel(), msg, GNUNET_MessageHeader::size, and t.

Here is the call graph for this function:

◆ handle_plaintext_data_ack()

static void handle_plaintext_data_ack ( void *  cls,
const struct GNUNET_CADET_ChannelDataAckMessage ack 
)
static

We received an acknowledgement for data we sent on a channel.

Locate the channel and process it, or return an error if the channel is unknown.

Parameters
clsthe struct CadetTunnel for which we decrypted the message
ackthe message we received on the tunnel

Definition at line 2916 of file gnunet-service-cadet_tunnels.c.

2918 {
2919  struct CadetTunnel *t = cls;
2920  struct CadetChannel *ch;
2921 
2922  ch = lookup_channel (t,
2923  ack->ctn);
2924  if (NULL == ch)
2925  {
2926  /* We don't know about such a channel, might have been destroyed on our
2927  end in the meantime, or never existed. Send back a DESTROY. */
2929  "Received DATA_ACK for unknown channel %u, sending DESTROY\n",
2930  ntohl (ack->ctn.cn));
2932  ack->ctn);
2933  return;
2934  }
2936  GCC_get_id (t->current_ct->cc),
2937  ack);
2938 }
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.
struct GNUNET_CADET_ChannelTunnelNumber ctn
ID of the channel.

References ch, GNUNET_CADET_ChannelTunnelNumber::cn, GNUNET_CADET_ChannelDataAckMessage::ctn, GCC_get_id(), GCCH_handle_channel_plaintext_data_ack(), GCT_send_channel_destroy(), GNUNET_ERROR_TYPE_DEBUG, LOG, lookup_channel(), and t.

Here is the call graph for this function:

◆ handle_plaintext_channel_open()

static void handle_plaintext_channel_open ( void *  cls,
const struct GNUNET_CADET_ChannelOpenMessage copen 
)
static

We have received a request to open a channel to a port from another peer.

Creates the incoming channel.

Parameters
clsthe struct CadetTunnel for which we decrypted the message
copenthe message we received on the tunnel

Definition at line 2949 of file gnunet-service-cadet_tunnels.c.

2952 {
2953  struct CadetTunnel *t = cls;
2954  struct CadetChannel *ch;
2955 
2957  ntohl (copen->ctn.cn));
2958  if (NULL != ch)
2959  {
2961  "Received duplicate channel CHANNEL_OPEN on h_port %s from %s (%s), resending ACK\n",
2962  GNUNET_h2s (&copen->h_port),
2963  GCT_2s (t),
2964  GCCH_2s (ch));
2966  GCC_get_id (t->current_ct->cc));
2967  return;
2968  }
2970  "Received CHANNEL_OPEN on h_port %s from %s\n",
2971  GNUNET_h2s (&copen->h_port),
2972  GCT_2s (t));
2974  copen->ctn,
2975  &copen->h_port,
2976  ntohl (copen->opt));
2977  if (NULL != t->destroy_task)
2978  {
2979  GNUNET_SCHEDULER_cancel (t->destroy_task);
2980  t->destroy_task = NULL;
2981  }
2984  ntohl (copen->ctn.cn),
2985  ch,
2987 }
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.
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.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
struct GNUNET_HashCode h_port
Hash of destination port and listener.
struct GNUNET_CADET_ChannelTunnelNumber ctn
ID of the channel within the tunnel.
uint32_t opt
Channel options.

References ch, GNUNET_CADET_ChannelTunnelNumber::cn, GNUNET_CADET_ChannelOpenMessage::ctn, GCC_get_id(), GCCH_2s(), GCCH_channel_incoming_new(), GCCH_handle_duplicate_open(), GCT_2s(), GNUNET_assert, GNUNET_CONTAINER_multihashmap32_get(), GNUNET_CONTAINER_multihashmap32_put(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY, GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_OK, GNUNET_SCHEDULER_cancel(), GNUNET_CADET_ChannelOpenMessage::h_port, LOG, GNUNET_CADET_ChannelOpenMessage::opt, and t.

Here is the call graph for this function:

◆ GCT_send_channel_destroy()

void GCT_send_channel_destroy ( struct CadetTunnel t,
struct GNUNET_CADET_ChannelTunnelNumber  ctn 
)

Send a DESTROY message via the tunnel.

Parameters
tthe tunnel to transmit over
ctnID of the channel to destroy

Definition at line 2997 of file gnunet-service-cadet_tunnels.c.

2999 {
3001 
3003  "Sending DESTROY message for channel ID %u\n",
3004  ntohl (ctn.cn));
3005  msg.header.size = htons (sizeof(msg));
3007  msg.reserved = htonl (0);
3008  msg.ctn = ctn;
3009  GCT_send (t,
3010  &msg.header,
3011  NULL,
3012  NULL,
3013  &ctn);
3014 }
struct CadetTunnelQueueEntry * GCT_send(struct CadetTunnel *t, const struct GNUNET_MessageHeader *message, GCT_SendContinuation cont, void *cont_cls, struct GNUNET_CADET_ChannelTunnelNumber *ctn)
Sends an already built message on a tunnel, encrypting it and choosing the best connection if not pro...
#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY
Ask the cadet service to destroy a channel.
Message to destroy a channel of type GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY.
struct GNUNET_CADET_ChannelTunnelNumber ctn
ID of the channel.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.

References GNUNET_CADET_ChannelTunnelNumber::cn, GNUNET_CADET_ChannelDestroyMessage::ctn, GCT_send(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY, LOG, msg, GNUNET_MessageHeader::size, t, and GNUNET_MessageHeader::type.

Referenced by GCCH_channel_local_destroy(), GCCH_handle_channel_plaintext_data(), GCCH_handle_local_ack(), handle_plaintext_channel_open_ack(), handle_plaintext_data(), and handle_plaintext_data_ack().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_plaintext_channel_open_ack()

static void handle_plaintext_channel_open_ack ( void *  cls,
const struct GNUNET_CADET_ChannelOpenAckMessage cm 
)
static

We have received confirmation from the target peer that the given channel could be established (the port is open).

Tell the client.

Parameters
clsthe struct CadetTunnel for which we decrypted the message
cmthe message we received on the tunnel

Definition at line 3026 of file gnunet-service-cadet_tunnels.c.

3029 {
3030  struct CadetTunnel *t = cls;
3031  struct CadetChannel *ch;
3032 
3033  ch = lookup_channel (t,
3034  cm->ctn);
3035  if (NULL == ch)
3036  {
3037  /* We don't know about such a channel, might have been destroyed on our
3038  end in the meantime, or never existed. Send back a DESTROY. */
3040  "Received channel OPEN_ACK for unknown channel %u, sending DESTROY\n",
3041  ntohl (cm->ctn.cn));
3043  cm->ctn);
3044  return;
3045  }
3047  "Received channel OPEN_ACK on channel %s from %s\n",
3048  GCCH_2s (ch),
3049  GCT_2s (t));
3051  GCC_get_id (t->current_ct->cc),
3052  &cm->port);
3053 }
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).
struct GNUNET_HashCode port
Port number of the channel, used to prove to the initiator that the receiver knows the port.
struct GNUNET_CADET_ChannelTunnelNumber ctn
ID of the channel.

References ch, GNUNET_CADET_ChannelTunnelNumber::cn, GNUNET_CADET_ChannelOpenAckMessage::ctn, GCC_get_id(), GCCH_2s(), GCCH_handle_channel_open_ack(), GCT_2s(), GCT_send_channel_destroy(), GNUNET_ERROR_TYPE_DEBUG, LOG, lookup_channel(), GNUNET_CADET_ChannelOpenAckMessage::port, and t.

Here is the call graph for this function:

◆ handle_plaintext_channel_destroy()

static void handle_plaintext_channel_destroy ( void *  cls,
const struct GNUNET_CADET_ChannelDestroyMessage cm 
)
static

We received a message saying that a channel should be destroyed.

Pass it on to the correct channel.

Parameters
clsthe struct CadetTunnel for which we decrypted the message
cmthe message we received on the tunnel

Definition at line 3064 of file gnunet-service-cadet_tunnels.c.

3067 {
3068  struct CadetTunnel *t = cls;
3069  struct CadetChannel *ch;
3070 
3071  ch = lookup_channel (t,
3072  cm->ctn);
3073  if (NULL == ch)
3074  {
3075  /* We don't know about such a channel, might have been destroyed on our
3076  end in the meantime, or never existed. */
3078  "Received channel DESTROY for unknown channel %u. Ignoring.\n",
3079  ntohl (cm->ctn.cn));
3080  return;
3081  }
3083  "Received channel DESTROY on %s from %s\n",
3084  GCCH_2s (ch),
3085  GCT_2s (t));
3087  GCC_get_id (t->current_ct->cc));
3088 }

References ch, GNUNET_CADET_ChannelTunnelNumber::cn, GNUNET_CADET_ChannelDestroyMessage::ctn, GCC_get_id(), GCCH_2s(), GCCH_handle_remote_destroy(), GCT_2s(), GNUNET_ERROR_TYPE_DEBUG, LOG, lookup_channel(), and t.

Here is the call graph for this function:

◆ handle_decrypted()

static int handle_decrypted ( void *  cls,
const struct GNUNET_MessageHeader msg 
)
static

Handles a message we decrypted, by injecting it into our message queue (which will do the dispatching).

Parameters
clsthe struct CadetTunnel that got the message
msgthe message
Returns
GNUNET_OK on success (always) GNUNET_NO to stop further processing (no error) GNUNET_SYSERR to stop further processing with error

Definition at line 3102 of file gnunet-service-cadet_tunnels.c.

3104 {
3105  struct CadetTunnel *t = cls;
3106 
3107  GNUNET_assert (NULL != t->current_ct);
3109  msg);
3110  return GNUNET_OK;
3111 }
void GNUNET_MQ_inject_message(struct GNUNET_MQ_Handle *mq, const struct GNUNET_MessageHeader *mh)
Call the message message handler that was registered for the type of the given message in the given m...
Definition: mq.c:187

References GNUNET_assert, GNUNET_MQ_inject_message(), GNUNET_OK, msg, and t.

Referenced by GCT_create_tunnel().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ decrypted_error_cb()

static void decrypted_error_cb ( void *  cls,
enum GNUNET_MQ_Error  error 
)
static

Function called if we had an error processing an incoming decrypted message.

Parameters
clsthe struct CadetTunnel
errorerror code

Definition at line 3122 of file gnunet-service-cadet_tunnels.c.

3124 {
3125  GNUNET_break_op (0);
3126 }

References GNUNET_break_op.

Referenced by GCT_create_tunnel().

Here is the caller graph for this function:

◆ GCT_create_tunnel()

struct CadetTunnel* GCT_create_tunnel ( struct CadetPeer destination)

Create a tunnel to destination.

Must only be called from within GCP_get_tunnel().

Parameters
destinationwhere to create the tunnel to
Returns
new tunnel to destination

Definition at line 3137 of file gnunet-service-cadet_tunnels.c.

3138 {
3139  struct CadetTunnel *t = GNUNET_new (struct CadetTunnel);
3140  struct GNUNET_MQ_MessageHandler handlers[] = {
3141  GNUNET_MQ_hd_fixed_size (plaintext_keepalive,
3143  struct GNUNET_MessageHeader,
3144  t),
3145  GNUNET_MQ_hd_var_size (plaintext_data,
3148  t),
3149  GNUNET_MQ_hd_fixed_size (plaintext_data_ack,
3152  t),
3153  GNUNET_MQ_hd_fixed_size (plaintext_channel_open,
3156  t),
3157  GNUNET_MQ_hd_fixed_size (plaintext_channel_open_ack,
3160  t),
3161  GNUNET_MQ_hd_fixed_size (plaintext_channel_destroy,
3164  t),
3166  };
3167 
3168  t->kx_retry_delay = INITIAL_KX_RETRY_DELAY;
3169  new_ephemeral (&t->ax);
3170  GNUNET_CRYPTO_ecdhe_key_create (&t->ax.kx_0);
3171  t->destination = destination;
3172  t->channels = GNUNET_CONTAINER_multihashmap32_create (8);
3173  t->maintain_connections_task
3175  t);
3176  t->mq = GNUNET_MQ_queue_for_callbacks (NULL,
3177  NULL,
3178  NULL,
3179  NULL,
3180  handlers,
3182  t);
3184  t);
3185  return t;
3186 }
static struct GNUNET_CADET_MessageHandler handlers[]
Handlers, for diverse services.
static int handle_decrypted(void *cls, const struct GNUNET_MessageHeader *msg)
Handles a message we decrypted, by injecting it into our message queue (which will do the dispatching...
static void decrypted_error_cb(void *cls, enum GNUNET_MQ_Error error)
Function called if we had an error processing an incoming decrypted message.
#define INITIAL_KX_RETRY_DELAY
How long do we wait initially before retransmitting the KX? TODO: replace by 2 RTT if/once we have co...
struct GNUNET_CONTAINER_MultiHashMap32 * GNUNET_CONTAINER_multihashmap32_create(unsigned int len)
Create a 32-bit key multi hash map.
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
struct GNUNET_MQ_Handle * GNUNET_MQ_queue_for_callbacks(GNUNET_MQ_SendImpl send, GNUNET_MQ_DestroyImpl destroy, GNUNET_MQ_CancelImpl cancel, void *impl_state, const struct GNUNET_MQ_MessageHandler *handlers, GNUNET_MQ_ErrorHandler error_handler, void *cls)
Create a message queue for the specified handlers.
Definition: mq.c:465
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN
Ask the cadet service to create a new channel.
#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK
Confirm payload data end-to-end.
#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA
Payload data (inside an encrypted tunnel).
#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_KEEPALIVE
Announce connection is still alive (direction sensitive).
#define GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK
Confirm the creation of a channel.
struct GNUNET_MessageStreamTokenizer * GNUNET_MST_create(GNUNET_MessageTokenizerCallback cb, void *cb_cls)
Create a message stream tokenizer.
Definition: mst.c:86
Message for cadet data traffic.
Message to acknowledge end-to-end data.
Message to acknowledge opening a channel of type GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK.
Message to create a Channel.
Message handler for a specific message type.

References decrypted_error_cb(), GNUNET_CONTAINER_multihashmap32_create(), GNUNET_CRYPTO_ecdhe_key_create(), GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA, GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK, GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY, GNUNET_MESSAGE_TYPE_CADET_CHANNEL_KEEPALIVE, GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN, GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK, GNUNET_MQ_handler_end, GNUNET_MQ_hd_fixed_size, GNUNET_MQ_hd_var_size, GNUNET_MQ_queue_for_callbacks(), GNUNET_MST_create(), GNUNET_new, GNUNET_SCHEDULER_add_now(), handle_decrypted(), handlers, INITIAL_KX_RETRY_DELAY, maintain_connections_cb(), new_ephemeral(), and t.

Referenced by GCP_get_tunnel().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCT_add_inbound_connection()

int GCT_add_inbound_connection ( struct CadetTunnel t,
const struct GNUNET_CADET_ConnectionTunnelIdentifier cid,
struct CadetPeerPath path 
)

Add a connection to the tunnel.

Parameters
ta tunnel
cidconnection identifier to use for the connection
pathpath to use for the connection
Returns
GNUNET_OK on success, GNUNET_SYSERR on failure (duplicate connection)

Definition at line 3190 of file gnunet-service-cadet_tunnels.c.

3194 {
3195  struct CadetTConnection *ct;
3196 
3197  ct = GNUNET_new (struct CadetTConnection);
3199  ct->t = t;
3200  ct->cc = GCC_create_inbound (t->destination,
3201  path,
3202  ct,
3203  cid,
3205  ct);
3206  if (NULL == ct->cc)
3207  {
3209  "%s refused inbound %s (duplicate)\n",
3210  GCT_2s (t),
3211  GCC_2s (ct->cc));
3212  GNUNET_free (ct);
3213  return GNUNET_SYSERR;
3214  }
3215  /* FIXME: schedule job to kill connection (and path?) if it takes
3216  too long to get ready! (And track performance data on how long
3217  other connections took with the tunnel!)
3218  => Note: to be done within 'connection'-logic! */
3219  GNUNET_CONTAINER_DLL_insert (t->connection_busy_head,
3220  t->connection_busy_tail,
3221  ct);
3222  t->num_busy_connections++;
3224  "%s has new %s\n",
3225  GCT_2s (t),
3226  GCC_2s (ct->cc));
3227  return GNUNET_OK;
3228 }
struct CadetConnection * GCC_create_inbound(struct CadetPeer *destination, struct CadetPeerPath *path, struct CadetTConnection *ct, const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid, GCC_ReadyCallback ready_cb, void *ready_cb_cls)
Create a connection to destination via path and notify cb whenever we are ready for more data.

References CadetTConnection::cc, connection_ready_cb(), CadetTConnection::created, GCC_2s(), GCC_create_inbound(), GCT_2s(), GNUNET_CONTAINER_DLL_insert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_new, GNUNET_OK, GNUNET_SYSERR, GNUNET_TIME_absolute_get(), LOG, CadetTConnection::t, and t.

Referenced by handle_connection_create().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCT_handle_encrypted()

void GCT_handle_encrypted ( struct CadetTConnection ct,
const struct GNUNET_CADET_TunnelEncryptedMessage msg 
)

Handle encrypted message.

Parameters
ctconnection/tunnel combo that received encrypted message
msgthe encrypted message to decrypt

Definition at line 3238 of file gnunet-service-cadet_tunnels.c.

3240 {
3241  struct CadetTunnel *t = ct->t;
3242  uint16_t size = ntohs (msg->header.size);
3243  char cbuf[size] GNUNET_ALIGN;
3244  ssize_t decrypted_size;
3245 
3247  "%s received %u bytes of encrypted data in state %d\n",
3248  GCT_2s (t),
3249  (unsigned int) size,
3250  t->estate);
3251 
3252  switch (t->estate)
3253  {
3256  /* We did not even SEND our KX, how can the other peer
3257  send us encrypted data? Must have been that we went
3258  down and the other peer still things we are up.
3259  Let's send it KX back. */
3261  "# received encrypted without any KX",
3262  1,
3263  GNUNET_NO);
3264  if (NULL != t->kx_task)
3265  {
3266  GNUNET_SCHEDULER_cancel (t->kx_task);
3267  t->kx_task = NULL;
3268  }
3269  send_kx (t,
3270  ct,
3271  &t->ax);
3272  return;
3273 
3275  /* We send KX, and other peer send KX to us at the same time.
3276  Neither KX is AUTH'ed, so let's try KX_AUTH this time. */
3278  "# received encrypted without KX_AUTH",
3279  1,
3280  GNUNET_NO);
3281  if (NULL != t->kx_task)
3282  {
3283  GNUNET_SCHEDULER_cancel (t->kx_task);
3284  t->kx_task = NULL;
3285  }
3286  send_kx_auth (t,
3287  ct,
3288  &t->ax,
3289  GNUNET_YES);
3290  return;
3291 
3293  /* We did not get the KX of the other peer, but that
3294  might have been lost. Send our KX again immediately. */
3296  "# received encrypted without KX",
3297  1,
3298  GNUNET_NO);
3299  if (NULL != t->kx_task)
3300  {
3301  GNUNET_SCHEDULER_cancel (t->kx_task);
3302  t->kx_task = NULL;
3303  }
3304  send_kx (t,
3305  ct,
3306  &t->ax);
3307  return;
3308 
3310  /* Great, first payload, we might graduate to OK! */
3311  case CADET_TUNNEL_KEY_OK:
3312  /* We are up and running, all good. */
3313  break;
3314  }
3315 
3316  decrypted_size = -1;
3317  if (CADET_TUNNEL_KEY_OK == t->estate)
3318  {
3319  /* We have well-established key material available,
3320  try that. (This is the common case.) */
3321  decrypted_size = t_ax_decrypt_and_validate (&t->ax,
3322  cbuf,
3323  msg,
3324  size);
3325  }
3326 
3327  if ((-1 == decrypted_size) &&
3328  (NULL != t->unverified_ax))
3329  {
3330  /* We have un-authenticated KX material available. We should try
3331  this as a back-up option, in case the sender crashed and
3332  switched keys. */
3333  decrypted_size = t_ax_decrypt_and_validate (t->unverified_ax,
3334  cbuf,
3335  msg,
3336  size);
3337  if (-1 != decrypted_size)
3338  {
3339  /* It worked! Treat this as authentication of the AX data! */
3340  cleanup_ax (&t->ax);
3341  t->ax = *t->unverified_ax;
3342  GNUNET_free (t->unverified_ax);
3343  t->unverified_ax = NULL;
3344  }
3345  if (CADET_TUNNEL_KEY_AX_AUTH_SENT == t->estate)
3346  {
3347  /* First time it worked, move tunnel into production! */
3350  if (NULL != t->send_task)
3351  GNUNET_SCHEDULER_cancel (t->send_task);
3353  t);
3354  }
3355  }
3356  if (NULL != t->unverified_ax)
3357  {
3358  /* We had unverified KX material that was useless; so increment
3359  counter and eventually move to ignore it. Note that we even do
3360  this increment if we successfully decrypted with the old KX
3361  material and thus didn't even both with the new one. This is
3362  the ideal case, as a malicious injection of bogus KX data
3363  basically only causes us to increment a counter a few times. */t->unverified_attempts++;
3365  "Failed to decrypt message with unverified KX data %u times\n",
3366  t->unverified_attempts);
3367  if (t->unverified_attempts > MAX_UNVERIFIED_ATTEMPTS)
3368  {
3369  cleanup_ax (t->unverified_ax);
3370  GNUNET_free (t->unverified_ax);
3371  t->unverified_ax = NULL;
3372  }
3373  }
3374 
3375  if (-1 == decrypted_size)
3376  {
3377  /* Decryption failed for good, complain. */
3379  "%s failed to decrypt and validate encrypted data, retrying KX\n",
3380  GCT_2s (t));
3382  "# unable to decrypt",
3383  1,
3384  GNUNET_NO);
3385  if (NULL != t->kx_task)
3386  {
3387  GNUNET_SCHEDULER_cancel (t->kx_task);
3388  t->kx_task = NULL;
3389  }
3390  send_kx (t,
3391  ct,
3392  &t->ax);
3393  return;
3394  }
3396  "# decrypted bytes",
3397  decrypted_size,
3398  GNUNET_NO);
3399 
3400  /* The MST will ultimately call #handle_decrypted() on each message. */
3401  t->current_ct = ct;
3403  GNUNET_MST_from_buffer (t->mst,
3404  cbuf,
3405  decrypted_size,
3406  GNUNET_YES,
3407  GNUNET_NO));
3408  t->current_ct = NULL;
3409 }
#define MAX_UNVERIFIED_ATTEMPTS
How often do we try to decrypt payload with unverified key material? Used to limit CPU increase upon ...
static ssize_t t_ax_decrypt_and_validate(struct CadetTunnelAxolotl *ax, void *dst, const struct GNUNET_CADET_TunnelEncryptedMessage *src, size_t size)
Decrypt and verify data with the appropriate tunnel key and verify that the data has not been altered...
#define GNUNET_ALIGN
gcc-ism to force alignment; we use this to align char-arrays that may then be cast to 'struct's.
enum GNUNET_GenericReturnValue GNUNET_MST_from_buffer(struct GNUNET_MessageStreamTokenizer *mst, const char *buf, size_t size, int purge, int one_shot)
Add incoming data to the receive buffer and call the callback for all complete messages.
Definition: mst.c:101

References CADET_TUNNEL_KEY_AX_AUTH_SENT, CADET_TUNNEL_KEY_AX_RECV, CADET_TUNNEL_KEY_AX_SENT, CADET_TUNNEL_KEY_AX_SENT_AND_RECV, CADET_TUNNEL_KEY_OK, CADET_TUNNEL_KEY_UNINITIALIZED, cleanup_ax(), GCT_2s(), GCT_change_estate(), GNUNET_ALIGN, GNUNET_break_op, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_MST_from_buffer(), GNUNET_NO, GNUNET_OK, GNUNET_SCHEDULER_add_now(), GNUNET_SCHEDULER_cancel(), GNUNET_STATISTICS_update(), GNUNET_YES, LOG, MAX_UNVERIFIED_ATTEMPTS, msg, send_kx(), send_kx_auth(), GNUNET_MessageHeader::size, size, stats, CadetTConnection::t, t, t_ax_decrypt_and_validate(), and trigger_transmissions().

Referenced by GCC_handle_encrypted().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCT_send()

struct CadetTunnelQueueEntry* GCT_send ( struct CadetTunnel t,
const struct GNUNET_MessageHeader message,
GCT_SendContinuation  cont,
void *  cont_cls,
struct GNUNET_CADET_ChannelTunnelNumber ctn 
)

Sends an already built message on a tunnel, encrypting it and choosing the best connection if not provided.

Parameters
messageMessage to send. Function modifies it.
tTunnel on which this message is transmitted.
contContinuation to call once message is really sent.
cont_clsClosure for cont.
Returns
Handle to cancel message.

Definition at line 3413 of file gnunet-service-cadet_tunnels.c.

3418 {
3419  struct CadetTunnelQueueEntry *tq;
3420  uint16_t payload_size;
3421  struct GNUNET_MQ_Envelope *env;
3422  struct GNUNET_CADET_TunnelEncryptedMessage *ax_msg;
3423  struct CadetChannel *ch;
3424 
3425  if (NULL != ctn)
3426  {
3427  ch = lookup_channel (t,
3428  *ctn);
3429  if ((NULL != ch) && GCCH_is_type_to_drop (ch, message))
3430  {
3431  GNUNET_break (0);
3432  return NULL;
3433  }
3434  }
3435 
3436  if (CADET_TUNNEL_KEY_OK != t->estate)
3437  {
3438  GNUNET_break (0);
3439  return NULL;
3440  }
3441  payload_size = ntohs (message->size);
3443  "Encrypting %u bytes for %s\n",
3444  (unsigned int) payload_size,
3445  GCT_2s (t));
3446  env = GNUNET_MQ_msg_extra (ax_msg,
3447  payload_size,
3449  t_ax_encrypt (&t->ax,
3450  &ax_msg[1],
3451  message,
3452  payload_size);
3454  "# encrypted bytes",
3455  payload_size,
3456  GNUNET_NO);
3457  ax_msg->ax_header.Ns = htonl (t->ax.Ns++);
3458  ax_msg->ax_header.PNs = htonl (t->ax.PNs);
3459  /* FIXME: we should do this once, not once per message;
3460  this is a point multiplication, and DHRs does not
3461  change all the time. */
3463  &ax_msg->ax_header.DHRs);
3464  t_h_encrypt (&t->ax,
3465  ax_msg);
3466  t_hmac (&ax_msg->ax_header,
3467  sizeof(struct GNUNET_CADET_AxHeader) + payload_size,
3468  0,
3469  &t->ax.HKs,
3470  &ax_msg->hmac);
3471 
3472  tq = GNUNET_malloc (sizeof(*tq));
3473  tq->t = t;
3474  tq->env = env;
3475  tq->cid = &ax_msg->cid; /* will initialize 'ax_msg->cid' once we know the connection */
3476  tq->cont = cont;
3477  tq->cont_cls = cont_cls;
3479  t->tq_tail,
3480  tq);
3481  if (NULL != t->send_task)
3482  GNUNET_SCHEDULER_cancel (t->send_task);
3483  t->send_task
3485  t);
3486  return tq;
3487 }
int GCCH_is_type_to_drop(struct CadetChannel *ch, const struct GNUNET_MessageHeader *message)
Check if type of message is the one to drop.
static void t_h_encrypt(struct CadetTunnelAxolotl *ax, struct GNUNET_CADET_TunnelEncryptedMessage *msg)
Encrypt header with the axolotl header key.
static void t_ax_encrypt(struct CadetTunnelAxolotl *ax, void *dst, const void *src, size_t size)
Encrypt data with the axolotl tunnel key.
#define GNUNET_malloc(size)
Wrapper around malloc.
#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:63
#define GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED
Axolotl encrypted data.
struct GNUNET_CADET_ChannelTunnelNumber ctn
Number identifying this channel in its tunnel.
uint32_t PNs
Number of messages sent with the previous ratchet key.
struct GNUNET_CRYPTO_EcdhePublicKey DHRs
Current ratchet key.
struct GNUNET_CADET_ConnectionTunnelIdentifier cid
ID of the connection.

References GNUNET_CADET_TunnelEncryptedMessage::ax_header, CADET_TUNNEL_KEY_OK, ch, GNUNET_CADET_TunnelEncryptedMessage::cid, CadetTunnelQueueEntry::cid, CadetTunnelQueueEntry::cont, CadetTunnelQueueEntry::cont_cls, CadetChannel::ctn, GNUNET_CADET_AxHeader::DHRs, env, CadetTunnelQueueEntry::env, GCCH_is_type_to_drop(), GCT_2s(), GNUNET_break, GNUNET_CONTAINER_DLL_insert_tail, GNUNET_CRYPTO_ecdhe_key_get_public(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_malloc, GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED, GNUNET_MQ_msg_extra, GNUNET_NO, GNUNET_SCHEDULER_add_now(), GNUNET_SCHEDULER_cancel(), GNUNET_STATISTICS_update(), GNUNET_CADET_TunnelEncryptedMessage::hmac, LOG, lookup_channel(), GNUNET_CADET_AxHeader::Ns, GNUNET_CADET_AxHeader::PNs, GNUNET_MessageHeader::size, stats, CadetTunnelQueueEntry::t, t, t_ax_encrypt(), t_h_encrypt(), t_hmac(), and trigger_transmissions().

Referenced by GCCH_handle_local_data(), GCT_send_channel_destroy(), retry_transmission(), send_channel_data_ack(), send_channel_open(), send_keepalive(), and send_open_ack().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCT_send_cancel()

void GCT_send_cancel ( struct CadetTunnelQueueEntry q)

Cancel a previously sent message while it's in the queue.

ONLY can be called before the continuation given to the send function is called. Once the continuation is called, the message is no longer in the queue!

Parameters
qHandle to the queue entry to cancel.

Definition at line 3491 of file gnunet-service-cadet_tunnels.c.

3492 {
3493  struct CadetTunnel *t = tq->t;
3494 
3495  GNUNET_CONTAINER_DLL_remove (t->tq_head,
3496  t->tq_tail,
3497  tq);
3498  GNUNET_MQ_discard (tq->env);
3499  GNUNET_free (tq);
3500 }
void GNUNET_MQ_discard(struct GNUNET_MQ_Envelope *mqm)
Discard the message queue message, free all allocated resources.
Definition: mq.c:285

References CadetTunnelQueueEntry::env, GNUNET_CONTAINER_DLL_remove, GNUNET_free, GNUNET_MQ_discard(), CadetTunnelQueueEntry::t, and t.

Referenced by channel_destroy(), destroy_tunnel(), GCC_destroy(), handle_matching_ack(), send_channel_data_ack(), send_channel_open(), and send_open_ack().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCT_iterate_connections()

void GCT_iterate_connections ( struct CadetTunnel t,
GCT_ConnectionIterator  iter,
void *  iter_cls 
)

Iterate over all connections of a tunnel.

Parameters
tTunnel whose connections to iterate.
iterIterator.
iter_clsClosure for iter.

Definition at line 3511 of file gnunet-service-cadet_tunnels.c.

3514 {
3515  struct CadetTConnection *n;
3516 
3517  for (struct CadetTConnection *ct = t->connection_ready_head;
3518  NULL != ct;
3519  ct = n)
3520  {
3521  n = ct->next;
3522  iter (iter_cls,
3523  ct);
3524  }
3525  for (struct CadetTConnection *ct = t->connection_busy_head;
3526  NULL != ct;
3527  ct = n)
3528  {
3529  n = ct->next;
3530  iter (iter_cls,
3531  ct);
3532  }
3533 }
struct CadetTConnection * next
Next in DLL.

References CadetTConnection::next, and t.

Referenced by consider_path_cb(), destroy_tunnel(), and maintain_connections_cb().

Here is the caller graph for this function:

◆ iterate_channels_cb()

static int iterate_channels_cb ( void *  cls,
uint32_t  key,
void *  value 
)
static

Helper function for GCT_iterate_channels.

Parameters
clsthe struct ChanIterCls
keyunused
valuea struct CadetChannel
Returns
GNUNET_OK

Definition at line 3562 of file gnunet-service-cadet_tunnels.c.

3565 {
3566  struct ChanIterCls *ctx = cls;
3567  struct CadetChannel *ch = value;
3568 
3569  ctx->iter (ctx->iter_cls,
3570  ch);
3571  return GNUNET_OK;
3572 }
Closure for iterate_channels_cb.

References ch, ctx, GNUNET_OK, and value.

Referenced by GCT_iterate_channels().

Here is the caller graph for this function:

◆ GCT_iterate_channels()

void GCT_iterate_channels ( struct CadetTunnel t,
GCT_ChannelIterator  iter,
void *  iter_cls 
)

Iterate over all channels of a tunnel.

Parameters
tTunnel whose channels to iterate.
iterIterator.
iter_clsClosure for iter.

Definition at line 3583 of file gnunet-service-cadet_tunnels.c.

3586 {
3587  struct ChanIterCls ctx;
3588 
3589  ctx.iter = iter;
3590  ctx.iter_cls = iter_cls;
3593  &ctx);
3594 }
static int iterate_channels_cb(void *cls, uint32_t key, void *value)
Helper function for GCT_iterate_channels.
void * iter_cls
Closure for iter.
GCT_ChannelIterator iter
Function to call.

References ctx, GNUNET_CONTAINER_multihashmap32_iterate(), ChanIterCls::iter, ChanIterCls::iter_cls, iterate_channels_cb(), and t.

Here is the call graph for this function:

◆ debug_channel()

static int debug_channel ( void *  cls,
uint32_t  key,
void *  value 
)
static

Call GCCH_debug() on a channel.

Parameters
clspoints to the log level to use
keyunused
valuethe struct CadetChannel to dump
Returns
GNUNET_OK (continue iteration)

Definition at line 3606 of file gnunet-service-cadet_tunnels.c.

3609 {
3610  const enum GNUNET_ErrorType *level = cls;
3611  struct CadetChannel *ch = value;
3612 
3613  GCCH_debug (ch, *level);
3614  return GNUNET_OK;
3615 }
void GCCH_debug(struct CadetChannel *ch, enum GNUNET_ErrorType level)
Log channel info.
GNUNET_ErrorType
Types of errors.

References ch, GCCH_debug(), GNUNET_OK, and value.

Referenced by GCT_debug().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GCT_debug()

void GCT_debug ( const struct CadetTunnel t,
enum GNUNET_ErrorType  level 
)

Log all possible info about the tunnel state.

Parameters
tTunnel to debug.
levelDebug level to use.

Definition at line 3629 of file gnunet-service-cadet_tunnels.c.

3631 {
3632 #if ! defined(GNUNET_CULL_LOGGING)
3633  struct CadetTConnection *iter_c;
3634  int do_log;
3635 
3637  "cadet-tun",
3638  __FILE__, __FUNCTION__, __LINE__);
3639  if (0 == do_log)
3640  return;
3641 
3642  LOG2 (level,
3643  "TTT TUNNEL TOWARDS %s in estate %s tq_len: %u #cons: %u\n",
3644  GCT_2s (t),
3645  estate2s (t->estate),
3646  t->tq_len,
3648  LOG2 (level,
3649  "TTT channels:\n");
3651  &debug_channel,
3652  &level);
3653  LOG2 (level,
3654  "TTT connections:\n");
3655  for (iter_c = t->connection_ready_head; NULL != iter_c; iter_c = iter_c->next)
3656  GCC_debug (iter_c->cc,
3657  level);
3658  for (iter_c = t->connection_busy_head; NULL != iter_c; iter_c = iter_c->next)
3659  GCC_debug (iter_c->cc,
3660  level);
3661 
3662  LOG2 (level,
3663  "TTT TUNNEL END\n");
3664 #endif
3665 }
void GCC_debug(struct CadetConnection *cc, enum GNUNET_ErrorType level)
Log connection info.
static int debug_channel(void *cls, uint32_t key, void *value)
Call GCCH_debug() on a channel.
#define LOG2(level,...)
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.
@ GNUNET_ERROR_TYPE_BULK

References CadetTConnection::cc, debug_channel(), estate2s(), GCC_debug(), GCT_2s(), GCT_count_any_connections(), GNUNET_CONTAINER_multihashmap32_iterate(), GNUNET_ERROR_TYPE_BULK, GNUNET_get_log_call_status(), LOG2, CadetTConnection::next, and t.

Here is the call graph for this function: