GNUnet 0.22.1
gnunet-communicator-udp.c File Reference

Transport plugin using UDP. More...

#include "platform.h"
#include "gnunet_common.h"
#include "gnunet_util_lib.h"
#include "gnunet_protocols.h"
#include "gnunet_signatures.h"
#include "gnunet_constants.h"
#include "gnunet_nat_service.h"
#include "gnunet_statistics_service.h"
#include "gnunet_transport_application_service.h"
#include "gnunet_transport_communication_service.h"
Include dependency graph for gnunet-communicator-udp.c:

Go to the source code of this file.

Data Structures

struct  UdpHandshakeSignature
 Signature we use to verify that the ephemeral key was really chosen by the specified sender. More...
 
struct  InitialKX
 "Plaintext" header at beginning of KX message. More...
 
struct  UDPConfirmation
 Encrypted continuation of UDP initial handshake, followed by message header with payload. More...
 
struct  UDPAck
 UDP key acknowledgement. More...
 
struct  UdpBroadcastSignature
 Signature we use to verify that the broadcast was really made by the peer that claims to have made it. More...
 
struct  UDPBroadcast
 Broadcast by peer in LAN announcing its presence. More...
 
struct  UDPBox
 UDP message box. More...
 
struct  UDPRekey
 Plaintext of a rekey payload in a UDPBox. More...
 
struct  KeyCacheEntry
 Pre-generated "kid" code (key and IV identification code) to quickly derive master key for a struct UDPBox. More...
 
struct  SharedSecret
 Shared secret we generated for a particular sender or receiver. More...
 
struct  SenderAddress
 Information we track per sender address we have recently been in contact with (we decrypt messages from the sender). More...
 
struct  ReceiverAddress
 Information we track per receiving address we have recently been in contact with (encryption to receiver). More...
 
struct  BroadcastInterface
 Interface we broadcast our presence on. More...
 
struct  SearchContext
 Closure for #find_sender_by_address() More...
 
struct  AckInfo
 

Macros

#define DEFAULT_REKEY_TIME_INTERVAL   GNUNET_TIME_UNIT_DAYS
 How often do we rekey based on time (at least) More...
 
#define PROTO_QUEUE_TIMEOUT   GNUNET_TIME_UNIT_MINUTES
 How long do we wait until we must have received the initial KX? More...
 
#define BROADCAST_FREQUENCY   GNUNET_TIME_UNIT_MINUTES
 How often do we broadcast our presence on the LAN? More...
 
#define INTERFACE_SCAN_FREQUENCY    GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)
 How often do we scan for changes to our network interfaces? More...
 
#define ADDRESS_VALIDITY_PERIOD   GNUNET_TIME_UNIT_HOURS
 How long do we believe our addresses to remain up (before the other peer should revalidate). More...
 
#define WORKING_QUEUE_INTERVALL    GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MICROSECONDS,1)
 
#define AES_KEY_SIZE   (256 / 8)
 AES key size. More...
 
#define AES_IV_SIZE   (96 / 8)
 AES (GCM) IV size. More...
 
#define GCM_TAG_SIZE   (128 / 8)
 Size of the GCM tag. More...
 
#define GENERATE_AT_ONCE   64
 
#define KCN_THRESHOLD   96
 If we fall below this number of available KCNs, we generate additional ACKs until we reach KCN_TARGET. More...
 
#define KCN_TARGET   128
 How many KCNs do we keep around after we hit the KCN_THRESHOLD? Should be larger than KCN_THRESHOLD so we do not generate just one ACK at the time. More...
 
#define MAX_SQN_DELTA   160
 What is the maximum delta between KCN sequence numbers that we allow. More...
 
#define MAX_SECRETS   256
 How many shared master secrets do we keep around at most per sender? Should be large enough so that we generally have a chance of sending an ACK before the sender already rotated out the master secret. More...
 
#define DEFAULT_REKEY_MAX_BYTES   (1024LLU * 1024 * 1024 * 4LLU)
 Default value for how often we do rekey based on number of bytes transmitted? (additionally randomized). More...
 
#define COMMUNICATOR_ADDRESS_PREFIX   "udp"
 Address prefix used by the communicator. More...
 
#define COMMUNICATOR_CONFIG_SECTION   "communicator-udp"
 Configuration section used by the communicator. More...
 

Functions

static void eddsa_priv_to_hpke_key (struct GNUNET_CRYPTO_EddsaPrivateKey *edpk, struct GNUNET_CRYPTO_EcdhePrivateKey *pk)
 
static void eddsa_pub_to_hpke_key (struct GNUNET_CRYPTO_EddsaPublicKey *edpk, struct GNUNET_CRYPTO_EcdhePublicKey *pk)
 
static void bi_destroy (struct BroadcastInterface *bi)
 An interface went away, stop broadcasting on it. More...
 
static int secret_destroy (struct SharedSecret *ss)
 Destroy ss and associated key cache entries. More...
 
static void receiver_destroy (struct ReceiverAddress *receiver)
 Destroys a receiving state due to timeout or shutdown. More...
 
static void kce_destroy (struct KeyCacheEntry *kce)
 Free memory used by key cache entry. More...
 
static void get_kid (const struct GNUNET_ShortHashCode *msec, uint32_t serial, struct GNUNET_ShortHashCode *kid)
 Compute kid. More...
 
static void kce_generate (struct SharedSecret *ss, uint32_t seq)
 Setup key cache entry for sequence number seq and shared secret ss. More...
 
static void sender_destroy (struct SenderAddress *sender)
 Functions with this signature are called whenever we need to close a sender's state due to timeout. More...
 
static void get_iv_key (const struct GNUNET_ShortHashCode *msec, uint32_t serial, char key[(256/8)], char iv[(96/8)])
 Compute key and iv. More...
 
static void reschedule_sender_timeout (struct SenderAddress *sender)
 Increment sender timeout due to activity. More...
 
static void reschedule_receiver_timeout (struct ReceiverAddress *receiver)
 Increment receiver timeout due to activity. More...
 
static void check_timeouts (void *cls)
 Task run to check #receiver_heap and #sender_heap for timeouts. More...
 
static void calculate_cmac (struct SharedSecret *ss)
 Calculate cmac from master in ss. More...
 
static void pass_plaintext_to_core (struct SenderAddress *sender, const void *plaintext, size_t plaintext_len)
 We received plaintext_len bytes of plaintext from a sender. More...
 
static void setup_cipher (const struct GNUNET_ShortHashCode *msec, uint32_t serial, gcry_cipher_hd_t *cipher)
 Setup cipher based on shared secret msec and serial number serial. More...
 
static int try_decrypt (const struct SharedSecret *ss, const uint8_t *tag, uint32_t serial, const char *in_buf, size_t in_buf_size, char *out_buf)
 Try to decrypt buf using shared secret ss and key/iv derived using serial. More...
 
static struct SharedSecretsetup_shared_secret_dec (const struct GNUNET_CRYPTO_HpkeEncapsulation *ephemeral)
 Setup shared secret for decryption. More...
 
static struct SharedSecretsetup_initial_shared_secret_dec (const struct GNUNET_CRYPTO_HpkeEncapsulation *c)
 Setup shared secret for decryption for initial handshake. More...
 
static struct SharedSecretsetup_shared_secret_ephemeral (struct GNUNET_CRYPTO_HpkeEncapsulation *ephemeral, struct ReceiverAddress *receiver)
 Setup new shared secret for encryption using KEM. More...
 
static struct SharedSecretsetup_initial_shared_secret_ephemeral (struct GNUNET_CRYPTO_HpkeEncapsulation *c, struct ReceiverAddress *receiver)
 Setup new shared secret for encryption using KEM for initial handshake. More...
 
static void setup_receiver_mq (struct ReceiverAddress *receiver)
 Setup the MQ for the receiver. More...
 
static unsigned int purge_secrets (struct SharedSecret *ss_list_tail)
 Best effort try to purge some secrets. More...
 
static void add_acks (struct SharedSecret *ss, int acks_to_add)
 
static int handle_ack (void *cls, const struct GNUNET_HashCode *key, void *value)
 We received an ACK for pid. More...
 
static void consider_ss_ack (struct SharedSecret *ss)
 We established a shared secret with a sender. More...
 
static void kce_generate_cb (void *cls)
 
static void try_handle_plaintext (struct SenderAddress *sender, const void *buf, size_t buf_size)
 Test if we have received a valid message in plaintext. More...
 
static void decrypt_box (const struct UDPBox *box, size_t box_len, struct KeyCacheEntry *kce)
 We received a box with matching kce. More...
 
static struct SenderAddresssetup_sender (const struct GNUNET_PeerIdentity *target, const struct sockaddr *address, socklen_t address_len)
 Create sender address for target. More...
 
static int verify_confirmation (const struct GNUNET_CRYPTO_HpkeEncapsulation *enc, const struct UDPConfirmation *uc)
 Check signature from uc against ephemeral. More...
 
static char * sockaddr_to_udpaddr_string (const struct sockaddr *address, socklen_t address_len)
 Converts address to the address string format used by this communicator in HELLOs. More...
 
static struct GNUNET_NETWORK_Handleget_socket (struct ReceiverAddress *receiver)
 
static struct sockaddr * udp_address_to_sockaddr (const char *bindto, sa_family_t family, socklen_t *sock_len)
 Convert UDP bind specification to a struct sockaddr * More...
 
static void sock_read (void *cls)
 Socket read task. More...
 
static enum GNUNET_GenericReturnValue create_receiver (const struct GNUNET_PeerIdentity *peer, const char *address, struct GNUNET_NETWORK_Handle *udp_sock)
 
static void do_pad (gcry_cipher_hd_t out_cipher, char *dgram, size_t pad_size)
 Pad dgram by pad_size using out_cipher. More...
 
static void send_msg_with_kx (const struct GNUNET_MessageHeader *msg, struct ReceiverAddress *receiver, struct GNUNET_MQ_Handle *mq)
 
static void mq_send_kx (struct GNUNET_MQ_Handle *mq, const struct GNUNET_MessageHeader *msg, void *impl_state)
 Signature of functions implementing the sending functionality of a message queue. More...
 
static void create_rekey (struct ReceiverAddress *receiver, struct SharedSecret *ss, struct UDPRekey *rekey)
 
static void mq_send_d (struct GNUNET_MQ_Handle *mq, const struct GNUNET_MessageHeader *msg, void *impl_state)
 Signature of functions implementing the sending functionality of a message queue. More...
 
static void mq_destroy_d (struct GNUNET_MQ_Handle *mq, void *impl_state)
 Signature of functions implementing the destruction of a message queue. More...
 
static void mq_destroy_kx (struct GNUNET_MQ_Handle *mq, void *impl_state)
 Signature of functions implementing the destruction of a message queue. More...
 
static void mq_cancel (struct GNUNET_MQ_Handle *mq, void *impl_state)
 Implementation function that cancels the currently sent message. More...
 
static void mq_error (void *cls, enum GNUNET_MQ_Error error)
 Generic error handler, called with the appropriate error code and the same closure specified at the creation of the message queue. More...
 
static int mq_init (void *cls, const struct GNUNET_PeerIdentity *peer, const char *address)
 Function called by the transport service to initialize a message queue given address information about another peer. More...
 
static int get_receiver_delete_it (void *cls, const struct GNUNET_HashCode *target, void *value)
 Iterator over all receivers to clean up. More...
 
static int get_sender_delete_it (void *cls, const struct GNUNET_HashCode *target, void *value)
 Iterator over all senders to clean up. More...
 
static void do_shutdown (void *cls)
 Shutdown the UNIX communicator. More...
 
static int handle_ack_by_sender (void *cls, const struct GNUNET_HashCode *key, void *value)
 
static void enc_notify_cb (void *cls, const struct GNUNET_PeerIdentity *sender, const struct GNUNET_MessageHeader *msg)
 Function called when the transport service has received a backchannel message for this communicator (!) via a different return path. More...
 
static void nat_address_cb (void *cls, void **app_ctx, int add_remove, enum GNUNET_NAT_AddressClass ac, const struct sockaddr *addr, socklen_t addrlen)
 Signature of the callback passed to GNUNET_NAT_register() for a function to call whenever our set of 'valid' addresses changes. More...
 
static void ifc_broadcast (void *cls)
 Broadcast our presence on one of our interfaces. More...
 
static int iface_proc (void *cls, const char *name, int isDefault, const struct sockaddr *addr, const struct sockaddr *broadcast_addr, const struct sockaddr *netmask, socklen_t addrlen)
 Callback function invoked for each interface found. More...
 
static void do_broadcast (void *cls)
 Scan interfaces to broadcast our presence on the LAN. More...
 
static void try_connection_reversal (void *cls, const struct sockaddr *addr, socklen_t addrlen)
 
static void udp_socket_notify (struct GNUNET_UdpSocketInfo *sock_info)
 
static void start_burst (const char *addr, struct GNUNET_TIME_Relative rtt, struct GNUNET_PeerIdentity *pid)
 
static struct GNUNET_NETWORK_Handlecreate_udp_socket (const char *bindto, sa_family_t family, struct sockaddr **out, socklen_t *out_len)
 
static void shutdown_run (struct sockaddr *addrs[2])
 
static void run (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c)
 

Variables

static struct GNUNET_TIME_Relative rekey_interval
 The rekey interval. More...
 
static unsigned long long rekey_max_bytes
 How often we do rekey based on number of bytes transmitted. More...
 
static struct GNUNET_CONTAINER_MultiShortmapkey_cache
 Cache of pre-generated key IDs. More...
 
static struct GNUNET_SCHEDULER_Taskread_v4_task
 ID of read IPv4 task. More...
 
static struct GNUNET_SCHEDULER_Taskread_v6_task
 ID of read IPv6 task. More...
 
static struct GNUNET_SCHEDULER_Tasktimeout_task
 ID of timeout task. More...
 
static struct GNUNET_SCHEDULER_Taskbroadcast_task
 ID of master broadcast task. More...
 
static struct GNUNET_STATISTICS_Handlestats
 For logging statistics. More...
 
static struct GNUNET_TRANSPORT_CommunicatorHandlech
 Our environment. More...
 
static struct GNUNET_CONTAINER_MultiHashMapreceivers
 Receivers (map from peer identity to struct ReceiverAddress) More...
 
static struct GNUNET_CONTAINER_MultiHashMapsenders
 Senders (map from peer identity to struct SenderAddress) More...
 
static struct GNUNET_CONTAINER_Heapsenders_heap
 Expiration heap for senders (contains struct SenderAddress) More...
 
static struct GNUNET_CONTAINER_Heapreceivers_heap
 Expiration heap for receivers (contains struct ReceiverAddress) More...
 
static struct BroadcastInterfacebi_head
 Broadcast interface tasks. More...
 
static struct BroadcastInterfacebi_tail
 Broadcast interface tasks. More...
 
static struct GNUNET_NETWORK_Handledefault_v4_sock
 Our IPv4 socket. More...
 
static struct GNUNET_NETWORK_Handledefault_v6_sock
 Our IPv6 socket. More...
 
static struct GNUNET_PeerIdentity my_identity
 Our public key. More...
 
static struct GNUNET_CRYPTO_EddsaPrivateKeymy_private_key
 Our private key. More...
 
static struct GNUNET_CRYPTO_EcdhePrivateKey my_x25519_private_key
 Our private key for HPKE. More...
 
static const struct GNUNET_CONFIGURATION_Handlecfg
 Our configuration. More...
 
static struct GNUNET_TRANSPORT_ApplicationHandleah
 Our handle to report addresses for validation to TRANSPORT. More...
 
static struct GNUNET_NT_InterfaceScanneris
 Network scanner to determine network types. More...
 
static struct GNUNET_NAT_Handlenat
 Connection to NAT service. More...
 
static uint16_t my_port
 Port number to which we are actually bound. More...
 
char * my_ipv4
 Our ipv4 address. More...
 
static int disable_v6
 IPv6 disabled or not. More...
 
static struct GNUNET_SCHEDULER_Taskburst_task
 

Detailed Description

Transport plugin using UDP.

Author
Christian Grothoff

TODO:

  • consider imposing transmission limits in the absence of ACKs; or: maybe this should be done at TNG service level? (at least the receiver might want to enforce limits on KX/DH operations per sender in here) (#5552)
  • overall, we should look more into flow control support (either in backchannel, or general solution in TNG service)
  • handle addresses discovered from broadcasts (#5551) (think: what was the story again on address validation? where is the API for that!?!)
  • support DNS names in BINDTO option (#5528)
  • support NAT connection reversal method (#5529)
  • support other UDP-specific NAT traversal methods (#)

Definition in file gnunet-communicator-udp.c.

Macro Definition Documentation

◆ DEFAULT_REKEY_TIME_INTERVAL

#define DEFAULT_REKEY_TIME_INTERVAL   GNUNET_TIME_UNIT_DAYS

How often do we rekey based on time (at least)

Definition at line 54 of file gnunet-communicator-udp.c.

◆ PROTO_QUEUE_TIMEOUT

#define PROTO_QUEUE_TIMEOUT   GNUNET_TIME_UNIT_MINUTES

How long do we wait until we must have received the initial KX?

Definition at line 59 of file gnunet-communicator-udp.c.

◆ BROADCAST_FREQUENCY

#define BROADCAST_FREQUENCY   GNUNET_TIME_UNIT_MINUTES

How often do we broadcast our presence on the LAN?

Definition at line 64 of file gnunet-communicator-udp.c.

◆ INTERFACE_SCAN_FREQUENCY

#define INTERFACE_SCAN_FREQUENCY    GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)

How often do we scan for changes to our network interfaces?

Definition at line 69 of file gnunet-communicator-udp.c.

◆ ADDRESS_VALIDITY_PERIOD

#define ADDRESS_VALIDITY_PERIOD   GNUNET_TIME_UNIT_HOURS

How long do we believe our addresses to remain up (before the other peer should revalidate).

Definition at line 76 of file gnunet-communicator-udp.c.

◆ WORKING_QUEUE_INTERVALL

#define WORKING_QUEUE_INTERVALL    GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MICROSECONDS,1)

Definition at line 78 of file gnunet-communicator-udp.c.

◆ AES_KEY_SIZE

#define AES_KEY_SIZE   (256 / 8)

AES key size.

Definition at line 84 of file gnunet-communicator-udp.c.

◆ AES_IV_SIZE

#define AES_IV_SIZE   (96 / 8)

AES (GCM) IV size.

Definition at line 89 of file gnunet-communicator-udp.c.

◆ GCM_TAG_SIZE

#define GCM_TAG_SIZE   (128 / 8)

Size of the GCM tag.

Definition at line 94 of file gnunet-communicator-udp.c.

◆ GENERATE_AT_ONCE

#define GENERATE_AT_ONCE   64

Definition at line 96 of file gnunet-communicator-udp.c.

◆ KCN_THRESHOLD

#define KCN_THRESHOLD   96

If we fall below this number of available KCNs, we generate additional ACKs until we reach KCN_TARGET.

Should be large enough that we don't generate ACKs all the time and still have enough time for the ACK to arrive before the sender runs out. So really this should ideally be based on the RTT.

Definition at line 107 of file gnunet-communicator-udp.c.

◆ KCN_TARGET

#define KCN_TARGET   128

How many KCNs do we keep around after we hit the KCN_THRESHOLD? Should be larger than KCN_THRESHOLD so we do not generate just one ACK at the time.

Definition at line 115 of file gnunet-communicator-udp.c.

◆ MAX_SQN_DELTA

#define MAX_SQN_DELTA   160

What is the maximum delta between KCN sequence numbers that we allow.

Used to expire 'ancient' KCNs that likely were dropped by the network. Must be larger than KCN_TARGET (otherwise we generate new KCNs all the time), but not too large (otherwise packet loss may cause sender to fall back to KX needlessly when sender runs out of ACK'ed KCNs due to losses).

Definition at line 126 of file gnunet-communicator-udp.c.

◆ MAX_SECRETS

#define MAX_SECRETS   256

How many shared master secrets do we keep around at most per sender? Should be large enough so that we generally have a chance of sending an ACK before the sender already rotated out the master secret.

Generally values around KCN_TARGET make sense. Might make sense to adapt to RTT if we had a good measurement...

Definition at line 137 of file gnunet-communicator-udp.c.

◆ DEFAULT_REKEY_MAX_BYTES

#define DEFAULT_REKEY_MAX_BYTES   (1024LLU * 1024 * 1024 * 4LLU)

Default value for how often we do rekey based on number of bytes transmitted? (additionally randomized).

Definition at line 143 of file gnunet-communicator-udp.c.

◆ COMMUNICATOR_ADDRESS_PREFIX

#define COMMUNICATOR_ADDRESS_PREFIX   "udp"

Address prefix used by the communicator.

Definition at line 149 of file gnunet-communicator-udp.c.

◆ COMMUNICATOR_CONFIG_SECTION

#define COMMUNICATOR_CONFIG_SECTION   "communicator-udp"

Configuration section used by the communicator.

Definition at line 154 of file gnunet-communicator-udp.c.

Function Documentation

◆ eddsa_priv_to_hpke_key()

static void eddsa_priv_to_hpke_key ( struct GNUNET_CRYPTO_EddsaPrivateKey edpk,
struct GNUNET_CRYPTO_EcdhePrivateKey pk 
)
static

Definition at line 893 of file gnunet-communicator-udp.c.

895{
897 key.type = htonl (GNUNET_PUBLIC_KEY_TYPE_EDDSA);
898 key.eddsa_key = *edpk;
900}
struct GNUNET_HashCode key
The key used in the DHT.
struct GNUNET_CRYPTO_PrivateKey pk
Private key from command line option, or NULL.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hpke_sk_to_x25519(const struct GNUNET_CRYPTO_PrivateKey *sk, struct GNUNET_CRYPTO_EcdhePrivateKey *x25519)
Convert a GNUnet identity key to a key sutiable for HPKE (X25519)
Definition: crypto_hpke.c:1013
@ GNUNET_PUBLIC_KEY_TYPE_EDDSA
EDDSA identity.
A private key for an identity as per LSD0001.

References GNUNET_CRYPTO_hpke_sk_to_x25519(), GNUNET_PUBLIC_KEY_TYPE_EDDSA, key, and pk.

Referenced by run().

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

◆ eddsa_pub_to_hpke_key()

static void eddsa_pub_to_hpke_key ( struct GNUNET_CRYPTO_EddsaPublicKey edpk,
struct GNUNET_CRYPTO_EcdhePublicKey pk 
)
static

Definition at line 904 of file gnunet-communicator-udp.c.

906{
908 key.type = htonl (GNUNET_PUBLIC_KEY_TYPE_EDDSA);
909 key.eddsa_key = *edpk;
911}
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hpke_pk_to_x25519(const struct GNUNET_CRYPTO_PublicKey *pk, struct GNUNET_CRYPTO_EcdhePublicKey *x25519)
Convert a GNUnet identity key to a key sutiable for HPKE (X25519)
Definition: crypto_hpke.c:989
An identity key as per LSD0001.

References GNUNET_CRYPTO_hpke_pk_to_x25519(), GNUNET_PUBLIC_KEY_TYPE_EDDSA, key, and pk.

Referenced by create_receiver().

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

◆ bi_destroy()

static void bi_destroy ( struct BroadcastInterface bi)
static

An interface went away, stop broadcasting on it.

Parameters
bientity to close down

Definition at line 920 of file gnunet-communicator-udp.c.

921{
922 if (AF_INET6 == bi->sa->sa_family)
923 {
924 /* Leave the multicast group */
926 IPPROTO_IPV6,
927 IPV6_LEAVE_GROUP,
928 &bi->mcreq,
929 sizeof(bi->mcreq)))
930 {
932 }
933 }
936 GNUNET_free (bi->sa);
937 GNUNET_free (bi->ba);
938 GNUNET_free (bi);
939}
static struct BroadcastInterface * bi_tail
Broadcast interface tasks.
static struct BroadcastInterface * bi_head
Broadcast interface tasks.
static struct GNUNET_NETWORK_Handle * default_v6_sock
Our IPv6 socket.
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
@ GNUNET_OK
#define GNUNET_log_strerror(level, cmd)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
@ GNUNET_ERROR_TYPE_WARNING
#define GNUNET_free(ptr)
Wrapper around free.
int GNUNET_NETWORK_socket_setsockopt(struct GNUNET_NETWORK_Handle *fd, int level, int option_name, const void *option_value, socklen_t option_len)
Set socket option.
Definition: network.c:806
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:979
struct ipv6_mreq mcreq
If this is an IPv6 interface, this is the request we use to join/leave the group.
struct sockaddr * ba
Broadcast address to use on the interface.
struct GNUNET_SCHEDULER_Task * broadcast_task
Task for this broadcast interface.
struct sockaddr * sa
Sender's address of the interface.

References BroadcastInterface::ba, bi_head, bi_tail, BroadcastInterface::broadcast_task, default_v6_sock, GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_log_strerror, GNUNET_NETWORK_socket_setsockopt(), GNUNET_OK, GNUNET_SCHEDULER_cancel(), BroadcastInterface::mcreq, and BroadcastInterface::sa.

Referenced by do_broadcast(), and do_shutdown().

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

◆ secret_destroy()

static int secret_destroy ( struct SharedSecret ss)
static

Destroy ss and associated key cache entries.

Parameters
ssshared secret to destroy
withoutKceIf GNUNET_YES shared secrets with kce will not be destroyed.

Definition at line 1085 of file gnunet-communicator-udp.c.

1086{
1087 struct SenderAddress *sender;
1088 struct ReceiverAddress *receiver;
1089 struct KeyCacheEntry *kce;
1090
1092 "secret %s destroy %u\n",
1093 GNUNET_sh2s (&ss->master),
1095 if (NULL != (sender = ss->sender))
1096 {
1097 GNUNET_CONTAINER_DLL_remove (sender->ss_head, sender->ss_tail, ss);
1098 sender->num_secrets--;
1100 "%u sender->num_secrets %u allowed %u used, %u available\n",
1102 sender->acks_available);
1104 if (NULL != ss->sender->kce_task)
1105 {
1107 ss->sender->kce_task = NULL;
1108 }
1109 }
1110 if (NULL != (receiver = ss->receiver))
1111 {
1112 GNUNET_CONTAINER_DLL_remove (receiver->ss_head, receiver->ss_tail, ss);
1113 receiver->num_secrets--;
1114 receiver->acks_available -= (ss->sequence_allowed - ss->sequence_used);
1116 "%u receiver->num_secrets\n",
1117 receiver->num_secrets);
1118 }
1119 while (NULL != (kce = ss->kce_head))
1120 kce_destroy (kce);
1121 GNUNET_STATISTICS_update (stats, "# Secrets active", -1, GNUNET_NO);
1123 "# KIDs active",
1125 GNUNET_NO);
1126 GNUNET_free (ss);
1127 return GNUNET_YES;
1128}
static void kce_destroy(struct KeyCacheEntry *kce)
Free memory used by key cache entry.
static struct GNUNET_STATISTICS_Handle * stats
For logging statistics.
static struct GNUNET_CONTAINER_MultiShortmap * key_cache
Cache of pre-generated key IDs.
unsigned int GNUNET_CONTAINER_multishortmap_size(const struct GNUNET_CONTAINER_MultiShortmap *map)
Get the number of key-value pairs in the map.
#define GNUNET_log(kind,...)
@ GNUNET_YES
@ GNUNET_NO
const char * GNUNET_sh2s(const struct GNUNET_ShortHashCode *shc)
Convert a short hash value to a string (for printing debug messages).
@ GNUNET_ERROR_TYPE_DEBUG
void GNUNET_STATISTICS_set(struct GNUNET_STATISTICS_Handle *handle, const char *name, uint64_t value, int make_persistent)
Set statistic value for the peer.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
void receiver(void *cls, const void *buf, size_t available, const struct sockaddr *addr, socklen_t addrlen, int errCode)
Callback to read from the SOCKS5 proxy.
Definition: socks.c:330
Pre-generated "kid" code (key and IV identification code) to quickly derive master key for a struct U...
struct SharedSecret * ss
Corresponding shared secret.
Information we track per receiving address we have recently been in contact with (encryption to recei...
Information we track per sender address we have recently been in contact with (we decrypt messages fr...
unsigned int acks_available
Number of BOX keys from ACKs we have currently available for this sender.
unsigned int num_secrets
Length of the DLL at ss_head.
struct GNUNET_SCHEDULER_Task * kce_task
ID of kce working queue task.
struct SharedSecret * ss_head
Shared secrets we used with target, first used is head.
struct SharedSecret * ss_tail
Shared secrets we used with target, last used is tail.
uint32_t sequence_allowed
Up to which sequence number did the other peer allow us to use this key, or up to which number did we...
uint32_t sequence_used
Up to which sequence number did we use this master already? (for encrypting only)
struct SenderAddress * sender
Sender we use this shared secret with, or NULL.
struct KeyCacheEntry * kce_head
Kept in a DLL, sorted by sequence number.
struct ReceiverAddress * receiver
Receiver we use this shared secret with, or NULL.
struct GNUNET_ShortHashCode master
Master shared secret.

References SenderAddress::acks_available, GNUNET_CONTAINER_DLL_remove, GNUNET_CONTAINER_multishortmap_size(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_log, GNUNET_NO, GNUNET_SCHEDULER_cancel(), GNUNET_sh2s(), GNUNET_STATISTICS_set(), GNUNET_STATISTICS_update(), GNUNET_YES, kce_destroy(), SharedSecret::kce_head, SenderAddress::kce_task, key_cache, SharedSecret::master, SenderAddress::num_secrets, receiver(), SharedSecret::receiver, SharedSecret::sender, SharedSecret::sequence_allowed, SharedSecret::sequence_used, KeyCacheEntry::ss, SenderAddress::ss_head, SenderAddress::ss_tail, and stats.

Referenced by decrypt_box(), mq_send_d(), purge_secrets(), receiver_destroy(), send_msg_with_kx(), sender_destroy(), sock_read(), and try_handle_plaintext().

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

◆ receiver_destroy()

static void receiver_destroy ( struct ReceiverAddress receiver)
static

Destroys a receiving state due to timeout or shutdown.

Parameters
receiverentity to close down

Definition at line 951 of file gnunet-communicator-udp.c.

952{
953 struct SharedSecret *ss;
954 receiver->receiver_destroy_called = GNUNET_YES;
955
957 "Disconnecting receiver for peer `%s'\n",
958 GNUNET_i2s (&receiver->target));
959 if (NULL != receiver->kx_qh)
960 {
962 receiver->kx_qh = NULL;
963 receiver->kx_mq = NULL;
964 }
965 if (NULL != receiver->d_qh)
966 {
968 receiver->d_qh = NULL;
969 }
970 else if (NULL != receiver->d_mq)
971 {
973 receiver->d_mq = NULL;
974 }
975 if (NULL != receiver->udp_sock)
976 {
979 receiver->udp_sock = NULL;
980 }
983 &receiver->key,
984 receiver));
987 "# receivers active",
989 GNUNET_NO);
990 while (NULL != (ss = receiver->ss_head))
991 {
992 secret_destroy (ss);
993 }
994 GNUNET_free (receiver->address);
995 GNUNET_free (receiver->foreign_addr);
997}
static int secret_destroy(struct SharedSecret *ss)
Destroy ss and associated key cache entries.
static struct GNUNET_CONTAINER_MultiHashMap * receivers
Receivers (map from peer identity to struct ReceiverAddress)
void GNUNET_TRANSPORT_communicator_mq_del(struct GNUNET_TRANSPORT_QueueHandle *qh)
Notify transport service that an MQ became unavailable due to a disconnect or timeout.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_remove(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, const void *value)
Remove the given key-value pair from the map.
unsigned int GNUNET_CONTAINER_multihashmap_size(const struct GNUNET_CONTAINER_MultiHashMap *map)
Get the number of key-value pairs in the map.
void * GNUNET_CONTAINER_heap_remove_node(struct GNUNET_CONTAINER_HeapNode *node)
Removes a node from the heap.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition: mq.c:700
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:508
Shared secret we generated for a particular sender or receiver.

References GNUNET_assert, GNUNET_break, GNUNET_CONTAINER_heap_remove_node(), GNUNET_CONTAINER_multihashmap_remove(), GNUNET_CONTAINER_multihashmap_size(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_i2s(), GNUNET_log, GNUNET_MQ_destroy(), GNUNET_NETWORK_socket_close(), GNUNET_NO, GNUNET_OK, GNUNET_STATISTICS_set(), GNUNET_TRANSPORT_communicator_mq_del(), GNUNET_YES, receiver(), receivers, secret_destroy(), and stats.

Referenced by check_timeouts(), get_receiver_delete_it(), mq_destroy_d(), mq_destroy_kx(), mq_error(), mq_send_d(), and send_msg_with_kx().

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

◆ kce_destroy()

static void kce_destroy ( struct KeyCacheEntry kce)
static

Free memory used by key cache entry.

Parameters
kcethe key cache entry

Definition at line 1006 of file gnunet-communicator-udp.c.

1007{
1008 struct SharedSecret *ss = kce->ss;
1009
1010 ss->active_kce_count--;
1013 &kce->kid,
1014 kce));
1015 GNUNET_free (kce);
1016}
int GNUNET_CONTAINER_multishortmap_remove(struct GNUNET_CONTAINER_MultiShortmap *map, const struct GNUNET_ShortHashCode *key, const void *value)
Remove the given key-value pair from the map.
struct GNUNET_ShortHashCode kid
Key and IV identification code.
struct KeyCacheEntry * kce_tail
Kept in a DLL, sorted by sequence number.
unsigned int active_kce_count
Number of active KCN entries.

References SharedSecret::active_kce_count, GNUNET_assert, GNUNET_CONTAINER_DLL_remove, GNUNET_CONTAINER_multishortmap_remove(), GNUNET_free, GNUNET_YES, SharedSecret::kce_head, SharedSecret::kce_tail, key_cache, KeyCacheEntry::kid, and KeyCacheEntry::ss.

Referenced by consider_ss_ack(), decrypt_box(), and secret_destroy().

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

◆ get_kid()

static void get_kid ( const struct GNUNET_ShortHashCode msec,
uint32_t  serial,
struct GNUNET_ShortHashCode kid 
)
static

Compute kid.

Parameters
msecmaster secret for HMAC calculation
serialnumber for the smac calculation
[out]kidwhere to write the key ID

Definition at line 1027 of file gnunet-communicator-udp.c.

1030{
1031 uint32_t sid = htonl (serial);
1032 struct GNUNET_ShortHashCode prk;
1034 &sid, sizeof (sid),
1035 msec, sizeof (*msec));
1036
1038 sizeof(*kid),
1039 &prk,
1040 "gnunet-communicator-udp-kid",
1041 strlen ("gnunet-communicator-udp-kid"),
1042 NULL,
1043 0);
1044}
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hkdf_extract(struct GNUNET_ShortHashCode *prk, const void *salt, size_t salt_len, const void *ikm, size_t ikm_len)
HKDF-Extract using SHA256.
Definition: crypto_hkdf.c:224
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hkdf_expand(void *result, size_t out_len, const struct GNUNET_ShortHashCode *prk,...)
HKDF-Expand using SHA256.
Definition: crypto_hkdf.c:156
A 256-bit hashcode.

References GNUNET_CRYPTO_hkdf_expand(), and GNUNET_CRYPTO_hkdf_extract().

Referenced by kce_generate(), and mq_send_d().

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

◆ kce_generate()

static void kce_generate ( struct SharedSecret ss,
uint32_t  seq 
)
static

Setup key cache entry for sequence number seq and shared secret ss.

Parameters
ssshared secret
seqsequence number for the key cache entry

Definition at line 1054 of file gnunet-communicator-udp.c.

1055{
1056 struct KeyCacheEntry *kce;
1057
1058 GNUNET_assert (0 < seq);
1059 kce = GNUNET_new (struct KeyCacheEntry);
1060 kce->ss = ss;
1061 kce->sequence_number = seq;
1062 get_kid (&ss->master, seq, &kce->kid);
1067 key_cache,
1068 &kce->kid,
1069 kce,
1072 "# KIDs active",
1074 GNUNET_NO);
1075}
static void get_kid(const struct GNUNET_ShortHashCode *msec, uint32_t serial, struct GNUNET_ShortHashCode *kid)
Compute kid.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multishortmap_put(struct GNUNET_CONTAINER_MultiShortmap *map, const struct GNUNET_ShortHashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE
Allow multiple values with the same key.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
uint32_t sequence_number
Sequence number used to derive this entry from master key.

References SenderAddress::acks_available, SharedSecret::active_kce_count, get_kid(), GNUNET_assert, GNUNET_CONTAINER_DLL_insert, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE, GNUNET_CONTAINER_multishortmap_put(), GNUNET_CONTAINER_multishortmap_size(), GNUNET_new, GNUNET_NO, GNUNET_STATISTICS_set(), SharedSecret::kce_head, SharedSecret::kce_tail, key_cache, KeyCacheEntry::kid, SharedSecret::master, SharedSecret::sender, KeyCacheEntry::sequence_number, KeyCacheEntry::ss, and stats.

Referenced by kce_generate_cb().

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

◆ sender_destroy()

static void sender_destroy ( struct SenderAddress sender)
static

Functions with this signature are called whenever we need to close a sender's state due to timeout.

Parameters
senderentity to close down

Definition at line 1138 of file gnunet-communicator-udp.c.

1139{
1140 struct SharedSecret *ss;
1143 GNUNET_YES ==
1147 "# senders active",
1149 GNUNET_NO);
1150 while (NULL != (ss = sender->ss_head))
1151 {
1152 secret_destroy (ss);
1153 }
1156}
static struct GNUNET_CONTAINER_MultiHashMap * senders
Senders (map from peer identity to struct SenderAddress)
struct GNUNET_CONTAINER_HeapNode * hn
Entry in sender expiration heap.
struct sockaddr * address
Address of the other peer.
struct GNUNET_HashCode key
The address key for this entry.
int sender_destroy_called
sender_destroy already called on sender.

References SenderAddress::address, GNUNET_assert, GNUNET_CONTAINER_heap_remove_node(), GNUNET_CONTAINER_multihashmap_remove(), GNUNET_CONTAINER_multihashmap_size(), GNUNET_free, GNUNET_NO, GNUNET_STATISTICS_set(), GNUNET_YES, SenderAddress::hn, SenderAddress::key, secret_destroy(), SharedSecret::sender, SenderAddress::sender_destroy_called, senders, SenderAddress::ss_head, and stats.

Referenced by check_timeouts(), and get_sender_delete_it().

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

◆ get_iv_key()

static void get_iv_key ( const struct GNUNET_ShortHashCode msec,
uint32_t  serial,
char  key[(256/8)],
char  iv[(96/8)] 
)
static

Compute key and iv.

Parameters
msecmaster secret for calculation
serialnumber for the smac calculation
[out]keywhere to write the decryption key
[out]ivwhere to write the IV

Definition at line 1168 of file gnunet-communicator-udp.c.

1172{
1173 uint32_t sid = htonl (serial);
1174
1177 msec,
1178 "gnunet-communicator-udp-key",
1179 strlen ("gnunet-communicator-udp-key"),
1180 &sid, sizeof (sid),
1181 NULL,
1182 0);
1185 msec,
1186 "gnunet-communicator-udp-iv",
1187 strlen ("gnunet-communicator-udp-iv"),
1188 &sid, sizeof (sid),
1189 NULL,
1190 0);
1191}
#define AES_KEY_SIZE
AES key size.
#define AES_IV_SIZE
AES (GCM) IV size.

References AES_IV_SIZE, AES_KEY_SIZE, GNUNET_CRYPTO_hkdf_expand(), and key.

Referenced by setup_cipher().

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

◆ reschedule_sender_timeout()

static void reschedule_sender_timeout ( struct SenderAddress sender)
static

Increment sender timeout due to activity.

Parameters
senderaddress for which the timeout should be rescheduled

Definition at line 1200 of file gnunet-communicator-udp.c.

1201{
1202 sender->timeout =
1205}
#define GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT
After how long do we consider a connection to a peer dead if we don't receive messages from the peer?
void GNUNET_CONTAINER_heap_update_cost(struct GNUNET_CONTAINER_HeapNode *node, GNUNET_CONTAINER_HeapCostType new_cost)
Updates the cost of any node in the tree.
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
uint64_t abs_value_us
The actual value.
struct GNUNET_TIME_Absolute timeout
Timeout for this sender.

References GNUNET_TIME_Absolute::abs_value_us, GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, GNUNET_CONTAINER_heap_update_cost(), GNUNET_TIME_relative_to_absolute(), SenderAddress::hn, SharedSecret::sender, and SenderAddress::timeout.

Referenced by setup_sender().

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

◆ reschedule_receiver_timeout()

static void reschedule_receiver_timeout ( struct ReceiverAddress receiver)
static

Increment receiver timeout due to activity.

Parameters
receiveraddress for which the timeout should be rescheduled

Definition at line 1214 of file gnunet-communicator-udp.c.

References GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, GNUNET_CONTAINER_heap_update_cost(), GNUNET_TIME_relative_to_absolute(), and receiver().

Referenced by mq_send_d(), and send_msg_with_kx().

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

◆ check_timeouts()

static void check_timeouts ( void *  cls)
static

Task run to check #receiver_heap and #sender_heap for timeouts.

Parameters
clsunused, NULL

Definition at line 1229 of file gnunet-communicator-udp.c.

1230{
1231 struct GNUNET_TIME_Relative st;
1232 struct GNUNET_TIME_Relative rt;
1233 struct GNUNET_TIME_Relative delay;
1234 struct ReceiverAddress *receiver;
1235 struct SenderAddress *sender;
1236
1237 (void) cls;
1238 timeout_task = NULL;
1241 {
1243 if (0 != rt.rel_value_us)
1244 break;
1246 "Receiver timed out\n");
1248 }
1250 while (NULL != (sender = GNUNET_CONTAINER_heap_peek (senders_heap)))
1251 {
1252 if (GNUNET_YES != sender->sender_destroy_called)
1253 {
1255 if (0 != st.rel_value_us)
1256 break;
1257 sender_destroy (sender);
1258 }
1259 }
1260 delay = GNUNET_TIME_relative_min (rt, st);
1261 if (delay.rel_value_us < GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
1263}
static struct GNUNET_CONTAINER_Heap * senders_heap
Expiration heap for senders (contains struct SenderAddress)
static void sender_destroy(struct SenderAddress *sender)
Functions with this signature are called whenever we need to close a sender's state due to timeout.
static void receiver_destroy(struct ReceiverAddress *receiver)
Destroys a receiving state due to timeout or shutdown.
static struct GNUNET_CONTAINER_Heap * receivers_heap
Expiration heap for receivers (contains struct ReceiverAddress)
static void check_timeouts(void *cls)
Task run to check #receiver_heap and #sender_heap for timeouts.
static struct GNUNET_SCHEDULER_Task * timeout_task
ID of timeout task.
static struct GNUNET_SCHEDULER_Task * st
The shutdown task.
void * GNUNET_CONTAINER_heap_peek(const struct GNUNET_CONTAINER_Heap *heap)
Get element stored at the root of heap.
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:1276
struct GNUNET_TIME_Relative GNUNET_TIME_relative_min(struct GNUNET_TIME_Relative t1, struct GNUNET_TIME_Relative t2)
Return the minimum of two relative time values.
Definition: time.c:344
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
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:406
Time for relative time used by GNUnet, in microseconds.

References check_timeouts(), GNUNET_CONTAINER_heap_peek(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_SCHEDULER_add_delayed(), GNUNET_TIME_absolute_get_remaining(), GNUNET_TIME_relative_min(), GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_YES, receiver(), receiver_destroy(), receivers_heap, GNUNET_TIME_Relative::rel_value_us, sender_destroy(), SenderAddress::sender_destroy_called, senders_heap, st, SenderAddress::timeout, and timeout_task.

Referenced by check_timeouts(), create_receiver(), and setup_sender().

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

◆ calculate_cmac()

static void calculate_cmac ( struct SharedSecret ss)
static

Calculate cmac from master in ss.

Parameters
[in,out]ssdata structure to complete

Definition at line 1272 of file gnunet-communicator-udp.c.

1273{
1275 sizeof(ss->cmac),
1276 &ss->master,
1277 "gnunet-communicator-udp-cmac",
1278 strlen ("gnunet-communicator-udp-cmac"),
1279 NULL,
1280 0);
1281}
struct GNUNET_HashCode cmac
CMAC is used to identify master in ACKs.

References SharedSecret::cmac, GNUNET_CRYPTO_hkdf_expand(), and SharedSecret::master.

Referenced by setup_initial_shared_secret_dec(), setup_initial_shared_secret_ephemeral(), setup_shared_secret_dec(), setup_shared_secret_ephemeral(), and sock_read().

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

◆ pass_plaintext_to_core()

static void pass_plaintext_to_core ( struct SenderAddress sender,
const void *  plaintext,
size_t  plaintext_len 
)
static

We received plaintext_len bytes of plaintext from a sender.

Pass it on to CORE.

Parameters
queuethe queue that received the plaintext
plaintextthe plaintext that was received
plaintext_lennumber of bytes of plaintext received

Definition at line 1293 of file gnunet-communicator-udp.c.

1296{
1297 const struct GNUNET_MessageHeader *hdr = plaintext;
1298 const char *pos = plaintext;
1299
1300 while (ntohs (hdr->size) <= plaintext_len)
1301 {
1303 "# bytes given to core",
1304 ntohs (hdr->size),
1305 GNUNET_NO);
1307 "Giving %u bytes to TNG\n", ntohs (hdr->size));
1310 &sender->target,
1311 hdr,
1313 NULL /* no flow control possible */
1314 ,
1315 NULL));
1316 /* move on to next message, if any */
1317 plaintext_len -= ntohs (hdr->size);
1318 if (plaintext_len < sizeof(*hdr))
1319 break;
1320 pos += ntohs (hdr->size);
1321 hdr = (const struct GNUNET_MessageHeader *) pos;
1322 // TODO for now..., we do not actually sen >1msg or have a way of telling
1323 // if we are done
1324 break;
1325 }
1327 "# bytes padding discarded",
1328 plaintext_len,
1329 GNUNET_NO);
1330}
#define ADDRESS_VALIDITY_PERIOD
How long do we believe our addresses to remain up (before the other peer should revalidate).
static struct GNUNET_TRANSPORT_CommunicatorHandle * ch
Our environment.
int GNUNET_TRANSPORT_communicator_receive(struct GNUNET_TRANSPORT_CommunicatorHandle *handle, const struct GNUNET_PeerIdentity *sender, const struct GNUNET_MessageHeader *msg, struct GNUNET_TIME_Relative expected_addr_validity, GNUNET_TRANSPORT_MessageCompletedCallback cb, void *cb_cls)
Notify transport service that the communicator has received a message.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
@ GNUNET_SYSERR
Header for all communications.
struct GNUNET_PeerIdentity target
To whom are we talking to.

References ADDRESS_VALIDITY_PERIOD, ch, GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_NO, GNUNET_STATISTICS_update(), GNUNET_SYSERR, GNUNET_TRANSPORT_communicator_receive(), GNUNET_MessageHeader::size, stats, and SenderAddress::target.

Referenced by try_handle_plaintext().

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

◆ setup_cipher()

static void setup_cipher ( const struct GNUNET_ShortHashCode msec,
uint32_t  serial,
gcry_cipher_hd_t *  cipher 
)
static

Setup cipher based on shared secret msec and serial number serial.

Parameters
msecmaster shared secret
serialserial number of cipher to set up
cipher[out]cipher to initialize

Definition at line 1342 of file gnunet-communicator-udp.c.

1345{
1346 char key[AES_KEY_SIZE];
1347 char iv[AES_IV_SIZE];
1348 int rc;
1349
1350 GNUNET_assert (0 ==
1351 gcry_cipher_open (cipher,
1352 GCRY_CIPHER_AES256 /* low level: go for speed */
1353 ,
1354 GCRY_CIPHER_MODE_GCM,
1355 0 /* flags */));
1356 get_iv_key (msec, serial, key, iv);
1357 rc = gcry_cipher_setkey (*cipher, key, sizeof(key));
1358 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
1359 rc = gcry_cipher_setiv (*cipher, iv, sizeof(iv));
1360 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
1361}
static void get_iv_key(const struct GNUNET_ShortHashCode *msec, uint32_t serial, char key[(256/8)], char iv[(96/8)])
Compute key and iv.

References AES_IV_SIZE, AES_KEY_SIZE, get_iv_key(), GNUNET_assert, and key.

Referenced by mq_send_d(), send_msg_with_kx(), and try_decrypt().

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

◆ try_decrypt()

static int try_decrypt ( const struct SharedSecret ss,
const uint8_t *  tag,
uint32_t  serial,
const char *  in_buf,
size_t  in_buf_size,
char *  out_buf 
)
static

Try to decrypt buf using shared secret ss and key/iv derived using serial.

Parameters
ssshared secret
tagGCM authentication tag
serialserial number to use
in_bufinput buffer to decrypt
in_buf_sizenumber of bytes in in_buf and available in out_buf
out_bufwhere to write the result
Returns
GNUNET_OK on success

Definition at line 1377 of file gnunet-communicator-udp.c.

1383{
1384 gcry_cipher_hd_t cipher;
1385
1386 setup_cipher (&ss->master, serial, &cipher);
1388 0 ==
1389 gcry_cipher_decrypt (cipher, out_buf, in_buf_size, in_buf, in_buf_size));
1390 if (0 != gcry_cipher_checktag (cipher, tag, GCM_TAG_SIZE))
1391 {
1392 gcry_cipher_close (cipher);
1394 "# AEAD authentication failures",
1395 1,
1396 GNUNET_NO);
1397 return GNUNET_SYSERR;
1398 }
1399 gcry_cipher_close (cipher);
1400 return GNUNET_OK;
1401}
#define GCM_TAG_SIZE
Size of the GCM tag.
static void setup_cipher(const struct GNUNET_ShortHashCode *msec, uint32_t serial, gcry_cipher_hd_t *cipher)
Setup cipher based on shared secret msec and serial number serial.

References GCM_TAG_SIZE, GNUNET_assert, GNUNET_NO, GNUNET_OK, GNUNET_STATISTICS_update(), GNUNET_SYSERR, SharedSecret::master, setup_cipher(), and stats.

Referenced by decrypt_box(), and sock_read().

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

◆ setup_shared_secret_dec()

static struct SharedSecret * setup_shared_secret_dec ( const struct GNUNET_CRYPTO_HpkeEncapsulation ephemeral)
static

Setup shared secret for decryption.

Parameters
ephemeralephemeral key we received from the other peer
Returns
new shared secret

Definition at line 1411 of file gnunet-communicator-udp.c.

1413{
1414 struct SharedSecret *ss;
1415
1416 ss = GNUNET_new (struct SharedSecret);
1418 calculate_cmac (ss);
1419 return ss;
1420}
static void calculate_cmac(struct SharedSecret *ss)
Calculate cmac from master in ss.
static struct GNUNET_CRYPTO_EddsaPrivateKey * my_private_key
Our private key.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_kem_decaps(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, const struct GNUNET_CRYPTO_HpkeEncapsulation *c, struct GNUNET_ShortHashCode *prk)
Decapsulate a key for a private EdDSA key.
Definition: crypto_hpke.c:407

References calculate_cmac(), GNUNET_CRYPTO_eddsa_kem_decaps(), GNUNET_new, SharedSecret::master, and my_private_key.

Referenced by try_handle_plaintext().

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

◆ setup_initial_shared_secret_dec()

static struct SharedSecret * setup_initial_shared_secret_dec ( const struct GNUNET_CRYPTO_HpkeEncapsulation c)
static

Setup shared secret for decryption for initial handshake.

Parameters
representativeof ephemeral key we received from the other peer
Returns
new shared secret

Definition at line 1430 of file gnunet-communicator-udp.c.

1432{
1433 struct SharedSecret *ss;
1434
1435 ss = GNUNET_new (struct SharedSecret);
1437 &ss->master);
1439 "New receiver SS master: %s\n", GNUNET_sh2s (&ss->master));
1440 calculate_cmac (ss);
1441 return ss;
1442}
static struct GNUNET_CRYPTO_EcdhePrivateKey my_x25519_private_key
Our private key for HPKE.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hpke_elligator_kem_decaps(const struct GNUNET_CRYPTO_EcdhePrivateKey *skR, const struct GNUNET_CRYPTO_HpkeEncapsulation *c, struct GNUNET_ShortHashCode *shared_secret)
Carries out ecdh decapsulation with own private key and the representative of the received public key...
Definition: crypto_hpke.c:470

References calculate_cmac(), GNUNET_CRYPTO_hpke_elligator_kem_decaps(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_new, GNUNET_sh2s(), SharedSecret::master, and my_x25519_private_key.

Referenced by sock_read().

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

◆ setup_shared_secret_ephemeral()

static struct SharedSecret * setup_shared_secret_ephemeral ( struct GNUNET_CRYPTO_HpkeEncapsulation ephemeral,
struct ReceiverAddress receiver 
)
static

Setup new shared secret for encryption using KEM.

Parameters
[out]ephemeralephemeral key to be sent to other peer (encapsulated key from KEM)
[in,out]receiverqueue to initialize encryption key for
Returns
new shared secret

Definition at line 1453 of file gnunet-communicator-udp.c.

1456{
1457 struct SharedSecret *ss;
1458
1459 ss = GNUNET_new (struct SharedSecret);
1460 GNUNET_CRYPTO_eddsa_kem_encaps (&receiver->target.public_key, ephemeral,
1461 &ss->master);
1462 calculate_cmac (ss);
1463 ss->receiver = receiver;
1464 GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss);
1465 receiver->num_secrets++;
1466 GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
1467 return ss;
1468}
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_kem_encaps(const struct GNUNET_CRYPTO_EddsaPublicKey *pub, struct GNUNET_CRYPTO_HpkeEncapsulation *c, struct GNUNET_ShortHashCode *prk)
Encapsulate key material for a EdDSA public key.
Definition: crypto_hpke.c:312

References calculate_cmac(), GNUNET_CONTAINER_DLL_insert, GNUNET_CRYPTO_eddsa_kem_encaps(), GNUNET_new, GNUNET_NO, GNUNET_STATISTICS_update(), SharedSecret::master, receiver(), SharedSecret::receiver, and stats.

Referenced by create_rekey().

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

◆ setup_initial_shared_secret_ephemeral()

static struct SharedSecret * setup_initial_shared_secret_ephemeral ( struct GNUNET_CRYPTO_HpkeEncapsulation c,
struct ReceiverAddress receiver 
)
static

Setup new shared secret for encryption using KEM for initial handshake.

Parameters
[out]representativeof ephemeral key to be sent to other peer (encapsulated key from KEM)
[in,out]receiverqueue to initialize encryption key for
Returns
new shared secret

Definition at line 1479 of file gnunet-communicator-udp.c.

1482{
1483 struct SharedSecret *ss;
1484
1485 ss = GNUNET_new (struct SharedSecret);
1487 c, &ss->master);
1489 "New sender SS master: %s\n", GNUNET_sh2s (&ss->master));
1490 calculate_cmac (ss);
1491 ss->receiver = receiver;
1492 GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss);
1493 receiver->num_secrets++;
1494 GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
1495 return ss;
1496}
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hpke_elligator_kem_encaps(const struct GNUNET_CRYPTO_EcdhePublicKey *pkR, struct GNUNET_CRYPTO_HpkeEncapsulation *c, struct GNUNET_ShortHashCode *shared_secret)
Carries out ecdh encapsulation with given public key and the private key from a freshly created ephem...
Definition: crypto_hpke.c:449

References calculate_cmac(), GNUNET_CONTAINER_DLL_insert, GNUNET_CRYPTO_hpke_elligator_kem_encaps(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_new, GNUNET_NO, GNUNET_sh2s(), GNUNET_STATISTICS_update(), SharedSecret::master, receiver(), SharedSecret::receiver, and stats.

Referenced by send_msg_with_kx().

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

◆ setup_receiver_mq()

static void setup_receiver_mq ( struct ReceiverAddress receiver)
static

Setup the MQ for the receiver.

If a queue exists, the existing one is destroyed. Then the MTU is recalculated and a fresh queue is initialized.

Parameters
receiverreceiver to setup MQ for

Definition at line 2999 of file gnunet-communicator-udp.c.

3000{
3001 size_t base_mtu;
3002
3003 switch (receiver->address->sa_family)
3004 {
3005 case AF_INET:
3006 base_mtu = 1480 /* Ethernet MTU, 1500 - Ethernet header - VLAN tag */
3007 - sizeof(struct GNUNET_TUN_IPv4Header) /* 20 */
3008 - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */;
3009 break;
3010
3011 case AF_INET6:
3012 base_mtu = 1280 /* Minimum MTU required by IPv6 */
3013 - sizeof(struct GNUNET_TUN_IPv6Header) /* 40 */
3014 - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */;
3015 break;
3016
3017 default:
3018 GNUNET_assert (0);
3019 break;
3020 }
3021 /* MTU based on full KX messages */
3022 receiver->kx_mtu = base_mtu - sizeof(struct InitialKX) /* 48 */
3023 - sizeof(struct UDPConfirmation); /* 104 */
3024 /* MTU based on BOXed messages */
3025 receiver->d_mtu = base_mtu - sizeof(struct UDPBox);
3026
3028 "Setting up MQs and QHs\n");
3029 /* => Effective MTU for CORE will range from 1080 (IPv6 + KX) to
3030 1404 (IPv4 + Box) bytes, depending on circumstances... */
3031 if (NULL == receiver->kx_mq)
3034 &mq_cancel,
3035 receiver,
3036 NULL,
3037 &mq_error,
3038 receiver);
3039 if (NULL == receiver->d_mq)
3041 &mq_destroy_d,
3042 &mq_cancel,
3043 receiver,
3044 NULL,
3045 &mq_error,
3046 receiver);
3047
3048 receiver->kx_qh =
3050 &receiver->target,
3051 receiver->foreign_addr,
3052 receiver->kx_mtu,
3054 0, /* Priority */
3055 receiver->nt,
3057 receiver->kx_mq);
3058}
static void mq_destroy_d(struct GNUNET_MQ_Handle *mq, void *impl_state)
Signature of functions implementing the destruction of a message queue.
static void mq_send_kx(struct GNUNET_MQ_Handle *mq, const struct GNUNET_MessageHeader *msg, void *impl_state)
Signature of functions implementing the sending functionality of a message queue.
static void mq_destroy_kx(struct GNUNET_MQ_Handle *mq, void *impl_state)
Signature of functions implementing the destruction of a message queue.
static void mq_send_d(struct GNUNET_MQ_Handle *mq, const struct GNUNET_MessageHeader *msg, void *impl_state)
Signature of functions implementing the sending functionality of a message queue.
static void mq_cancel(struct GNUNET_MQ_Handle *mq, void *impl_state)
Implementation function that cancels the currently sent message.
static void mq_error(void *cls, enum GNUNET_MQ_Error error)
Generic error handler, called with the appropriate error code and the same closure specified at the c...
#define GNUNET_TRANSPORT_QUEUE_LENGTH_UNLIMITED
Queue length.
struct GNUNET_TRANSPORT_QueueHandle * GNUNET_TRANSPORT_communicator_mq_add(struct GNUNET_TRANSPORT_CommunicatorHandle *ch, const struct GNUNET_PeerIdentity *peer, const char *address, uint32_t mtu, uint64_t q_len, uint32_t priority, enum GNUNET_NetworkType nt, enum GNUNET_TRANSPORT_ConnectionStatus cs, struct GNUNET_MQ_Handle *mq)
Notify transport service that a MQ became available due to an "inbound" connection or because the com...
@ GNUNET_TRANSPORT_CS_OUTBOUND
this is an outbound connection (transport initiated)
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:482
Standard IPv4 header.
Standard IPv6 header.
UDP packet header.
"Plaintext" header at beginning of KX message.
UDP message box.
Encrypted continuation of UDP initial handshake, followed by message header with payload.

References ch, GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_MQ_queue_for_callbacks(), GNUNET_TRANSPORT_communicator_mq_add(), GNUNET_TRANSPORT_CS_OUTBOUND, GNUNET_TRANSPORT_QUEUE_LENGTH_UNLIMITED, mq_cancel(), mq_destroy_d(), mq_destroy_kx(), mq_error(), mq_send_d(), mq_send_kx(), and receiver().

Referenced by create_receiver().

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

◆ purge_secrets()

static unsigned int purge_secrets ( struct SharedSecret ss_list_tail)
static

Best effort try to purge some secrets.

Ideally those, not ACKed.

Parameters
ss_list_tailthe oldest secret in the list of interest.
Returns
number of deleted secrets.

Definition at line 1518 of file gnunet-communicator-udp.c.

1519{
1520 struct SharedSecret *pos;
1521 struct SharedSecret *ss_to_purge;
1522 unsigned int deleted = 0;
1523
1525 "Purging secrets.\n");
1526 pos = ss_list_tail;
1527 while (NULL != pos)
1528 {
1529 ss_to_purge = pos;
1530 pos = pos->prev;
1531
1532 // FIXME we may also want to purge old unacked.
1533 if (rekey_max_bytes <= ss_to_purge->bytes_sent)
1534 {
1535 secret_destroy (ss_to_purge);
1536 deleted++;
1537 }
1538 }
1540 "Finished purging all, deleted %u.\n", deleted);
1541 return deleted;
1542}
size_t bytes_sent
Bytes sent with this shared secret.
struct SharedSecret * prev
Kept in a DLL.

References SharedSecret::bytes_sent, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, SharedSecret::prev, and secret_destroy().

Referenced by mq_send_d(), send_msg_with_kx(), sock_read(), and try_handle_plaintext().

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

◆ add_acks()

static void add_acks ( struct SharedSecret ss,
int  acks_to_add 
)
static

Definition at line 1546 of file gnunet-communicator-udp.c.

1547{
1548
1549 struct ReceiverAddress *receiver = ss->receiver;
1550
1551 GNUNET_assert (NULL != ss);
1552 GNUNET_assert (NULL != receiver);
1553
1554 if (NULL == receiver->d_qh)
1555 {
1556 receiver->d_qh =
1558 &receiver->target,
1559 receiver->foreign_addr,
1560 receiver->d_mtu,
1561 acks_to_add,
1562 1, /* Priority */
1563 receiver->nt,
1565 receiver->d_mq);
1566 }
1567 else
1568 {
1570 receiver->d_qh,
1571 acks_to_add,
1572 1);
1573 }
1574
1576 "Tell transport we have %u more acks!\n",
1577 acks_to_add);
1578
1579 // Until here for alternative 1
1580
1581 /* move ss to head to avoid discarding it anytime soon! */
1582
1583 // GNUNET_CONTAINER_DLL_remove (receiver->ss_head, receiver->ss_tail, ss);
1584 // GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss);
1585}
void GNUNET_TRANSPORT_communicator_mq_update(struct GNUNET_TRANSPORT_CommunicatorHandle *ch, const struct GNUNET_TRANSPORT_QueueHandle *u_qh, uint64_t q_len, uint32_t priority)
Notify transport service that an MQ was updated.

References ch, GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_TRANSPORT_communicator_mq_add(), GNUNET_TRANSPORT_communicator_mq_update(), GNUNET_TRANSPORT_CS_OUTBOUND, receiver(), and SharedSecret::receiver.

Referenced by handle_ack().

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

◆ handle_ack()

static int handle_ack ( void *  cls,
const struct GNUNET_HashCode key,
void *  value 
)
static

We received an ACK for pid.

Check if it is for the receiver in value and if so, handle it and return GNUNET_NO. Otherwise, return GNUNET_YES.

Parameters
clsa const struct UDPAck
pidpeer the ACK is from
valuea struct ReceiverAddress
Returns
GNUNET_YES to continue to iterate

Definition at line 1599 of file gnunet-communicator-udp.c.

1600{
1601 const struct UDPAck *ack = cls;
1602 struct ReceiverAddress *receiver = value;
1603 uint32_t acks_to_add;
1604 uint32_t allowed;
1605
1607 "in handle ack with cmac %s\n",
1608 GNUNET_h2s (&ack->cmac));
1609
1610 (void) key;
1611 for (struct SharedSecret *ss = receiver->ss_head; NULL != ss; ss = ss->next)
1612 {
1613 if (0 == memcmp (&ack->cmac, &ss->cmac, sizeof(struct GNUNET_HashCode)))
1614 {
1615
1617 "Found matching cmac\n");
1618
1619 allowed = ntohl (ack->sequence_ack);
1620
1621 if (allowed <= ss->sequence_allowed)
1622 {
1624 "Ignoring ack, not giving us increased window\n.");
1625 return GNUNET_NO;
1626 }
1627 acks_to_add = (allowed - ss->sequence_allowed);
1628 GNUNET_assert (0 != acks_to_add);
1629 receiver->acks_available += (allowed - ss->sequence_allowed);
1630 ss->sequence_allowed = allowed;
1631 add_acks (ss, acks_to_add);
1633 "New sequence allows until %u (+%u). Acks available to us: %u. For secret %s\n",
1634 allowed,
1635 acks_to_add,
1636 receiver->acks_available,
1637 GNUNET_sh2s (&ss->master));
1638 return GNUNET_NO;
1639 }
1640 }
1642 "Matching cmac not found for ack!\n");
1643 return GNUNET_YES;
1644}
static void add_acks(struct SharedSecret *ss, int acks_to_add)
static char * value
Value of the record to add/remove.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
A 512-bit hashcode.
UDP key acknowledgement.
uint32_t sequence_ack
Sequence acknowledgement limit.
struct GNUNET_HashCode cmac
CMAC of the base key being acknowledged.

References add_acks(), UDPAck::cmac, GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_log, GNUNET_NO, GNUNET_sh2s(), GNUNET_YES, key, receiver(), UDPAck::sequence_ack, and value.

Referenced by handle_ack_by_sender(), and try_handle_plaintext().

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

◆ consider_ss_ack()

static void consider_ss_ack ( struct SharedSecret ss)
static

We established a shared secret with a sender.

We should try to send the sender an struct UDPAck at the next opportunity to allow the sender to use ss longer (assuming we did not yet already recently).

Parameters
ssshared secret to generate ACKs for

Definition at line 1656 of file gnunet-communicator-udp.c.

1657{
1658 struct UDPAck ack;
1659 GNUNET_assert (NULL != ss->sender);
1661 "Considering SS UDPAck %s\n",
1662 GNUNET_i2s_full (&ss->sender->target));
1663
1665 "Sender has %u acks available.\n",
1666 ss->sender->acks_available);
1667 /* drop ancient KeyCacheEntries */
1668 while ((NULL != ss->kce_head) &&
1669 (MAX_SQN_DELTA <
1671 kce_destroy (ss->kce_tail);
1672
1673
1674 ack.header.type = htons (GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK);
1675 ack.header.size = htons (sizeof(ack));
1676 ack.sequence_ack = htonl (ss->sequence_allowed);
1677 ack.cmac = ss->cmac;
1679 "Notifying transport with UDPAck %s, sequence %u and master %s\n",
1681 ss->sequence_allowed,
1682 GNUNET_sh2s (&(ss->master)));
1684 &ss->sender->target,
1686 &ack.header);
1687}
#define COMMUNICATOR_ADDRESS_PREFIX
Address prefix used by the communicator.
#define MAX_SQN_DELTA
What is the maximum delta between KCN sequence numbers that we allow.
void GNUNET_TRANSPORT_communicator_notify(struct GNUNET_TRANSPORT_CommunicatorHandle *ch, const struct GNUNET_PeerIdentity *pid, const char *comm, const struct GNUNET_MessageHeader *header)
The communicator asks the transport service to route a message via a different path to another commun...
const char * GNUNET_i2s_full(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK
UDP KX acknowledgement.

References SenderAddress::acks_available, ch, UDPAck::cmac, SharedSecret::cmac, COMMUNICATOR_ADDRESS_PREFIX, GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s_full(), GNUNET_log, GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK, GNUNET_sh2s(), GNUNET_TRANSPORT_communicator_notify(), UDPAck::header, kce_destroy(), SharedSecret::kce_head, SharedSecret::kce_tail, SharedSecret::master, MAX_SQN_DELTA, SharedSecret::sender, UDPAck::sequence_ack, SharedSecret::sequence_allowed, KeyCacheEntry::sequence_number, GNUNET_MessageHeader::size, SenderAddress::target, and GNUNET_MessageHeader::type.

Referenced by kce_generate_cb().

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

◆ kce_generate_cb()

static void kce_generate_cb ( void *  cls)
static

As long as we loose over 30% of max acks in reschedule, We keep generating acks for this ss.

Definition at line 1691 of file gnunet-communicator-udp.c.

1692{
1693 struct SharedSecret *ss = cls;
1694 ss->sender->kce_task = NULL;
1695
1697 "Precomputing %u keys for master %s\n",
1699 GNUNET_sh2s (&ss->master));
1700 if ((ss->override_available_acks != GNUNET_YES) &&
1701 (KCN_TARGET < ss->sender->acks_available))
1702 return;
1703 for (int i = 0; i < GENERATE_AT_ONCE; i++)
1704 kce_generate (ss, ++ss->sequence_allowed);
1705
1710 if (KCN_TARGET > ss->sender->acks_available)
1711 {
1715 ss);
1716 return;
1717 }
1719 "We have enough keys (ACKs: %u).\n", ss->sender->acks_available);
1723 consider_ss_ack (ss);
1724}
#define WORKING_QUEUE_INTERVALL
static void kce_generate(struct SharedSecret *ss, uint32_t seq)
Setup key cache entry for sequence number seq and shared secret ss.
#define GENERATE_AT_ONCE
static void kce_generate_cb(void *cls)
#define KCN_TARGET
How many KCNs do we keep around after we hit the KCN_THRESHOLD? Should be larger than KCN_THRESHOLD s...
static void consider_ss_ack(struct SharedSecret *ss)
We established a shared secret with a sender.
int kce_send_ack_on_finish
When KCE finishes, send ACK if GNUNET_YES.
int kce_task_finished
Is the kce_task finished?
int override_available_acks
Also precompute keys despite sufficient acks (for rekey)

References SenderAddress::acks_available, consider_ss_ack(), GENERATE_AT_ONCE, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_NO, GNUNET_SCHEDULER_add_delayed(), GNUNET_sh2s(), GNUNET_YES, kce_generate(), kce_generate_cb(), SenderAddress::kce_send_ack_on_finish, SenderAddress::kce_task, SenderAddress::kce_task_finished, KCN_TARGET, SharedSecret::master, SharedSecret::override_available_acks, SharedSecret::sender, SharedSecret::sequence_allowed, and WORKING_QUEUE_INTERVALL.

Referenced by decrypt_box(), kce_generate_cb(), sock_read(), and try_handle_plaintext().

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

◆ try_handle_plaintext()

static void try_handle_plaintext ( struct SenderAddress sender,
const void *  buf,
size_t  buf_size 
)
static

Test if we have received a valid message in plaintext.

If so, handle it.

Parameters
senderpeer to process inbound plaintext for
bufbuffer we received
buf_sizenumber of bytes in buf

Definition at line 1736 of file gnunet-communicator-udp.c.

1739{
1740 const struct GNUNET_MessageHeader *hdr;
1741 const struct UDPAck *ack;
1742 const struct UDPRekey *rekey;
1743 struct SharedSecret *ss_rekey;
1744 const char *buf_pos = buf;
1745 size_t bytes_remaining = buf_size;
1746 uint16_t type;
1747
1748 hdr = (struct GNUNET_MessageHeader*) buf_pos;
1749 if (sizeof(*hdr) > bytes_remaining)
1750 {
1751 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Plaintext too short, dropping...\n");
1752 return; /* no data left */
1753 }
1755 "try_handle_plaintext of size %llu (%u %lu) and type %u\n",
1756 (unsigned long long) bytes_remaining,
1757 ntohs (hdr->size),
1758 sizeof(*hdr),
1759 ntohs (hdr->type));
1760 if (ntohs (hdr->size) > bytes_remaining)
1761 return; /* buffer too short for indicated message length */
1762 type = ntohs (hdr->type);
1763 switch (type)
1764 {
1766 rekey = (struct UDPRekey*) buf_pos;
1767 ss_rekey = setup_shared_secret_dec (&rekey->ephemeral);
1768 ss_rekey->sender = sender;
1769 GNUNET_CONTAINER_DLL_insert (sender->ss_head, sender->ss_tail, ss_rekey);
1770 sender->num_secrets++;
1772 "Received rekey secret with cmac %s\n",
1773 GNUNET_h2s (&(ss_rekey->cmac)));
1775 "Received secret with master %s.\n",
1776 GNUNET_sh2s (&(ss_rekey->master)));
1778 "We have %u sequence_allowed.\n",
1779 ss_rekey->sequence_allowed);
1781 "We have a sender %p\n",
1782 ss_rekey->sender);
1784 "We have %u acks available.\n",
1785 ss_rekey->sender->acks_available);
1787 "# rekeying successful",
1788 1,
1789 GNUNET_NO);
1792 // FIXME
1793 kce_generate_cb (ss_rekey);
1794 /* ss_rekey->sender->kce_task = GNUNET_SCHEDULER_add_delayed (
1795 WORKING_QUEUE_INTERVALL,
1796 kce_generate_cb,
1797 ss_rekey);*/
1798 // FIXME: Theoretically, this could be an Ack
1799 buf_pos += ntohs (hdr->size);
1800 bytes_remaining -= ntohs (hdr->size);
1801 pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
1802 if (0 == purge_secrets (sender->ss_tail))
1803 {
1804 // No secret purged. Delete oldest.
1805 if (sender->num_secrets > MAX_SECRETS)
1806 {
1807 secret_destroy (sender->ss_tail);
1808 }
1809 }
1810 break;
1812 /* lookup master secret by 'cmac', then update sequence_max */
1813 ack = (struct UDPAck*) buf_pos;
1815 &sender->key,
1816 &handle_ack,
1817 (void *) ack);
1818 /* There could be more messages after the ACK, handle those as well */
1819 buf_pos += ntohs (hdr->size);
1820 bytes_remaining -= ntohs (hdr->size);
1821 pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
1822 break;
1823
1825 /* skip padding */
1826 break;
1827
1828 default:
1829 pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
1830 }
1831 return;
1832}
static int handle_ack(void *cls, const struct GNUNET_HashCode *key, void *value)
We received an ACK for pid.
static void pass_plaintext_to_core(struct SenderAddress *sender, const void *plaintext, size_t plaintext_len)
We received plaintext_len bytes of plaintext from a sender.
static struct SharedSecret * setup_shared_secret_dec(const struct GNUNET_CRYPTO_HpkeEncapsulation *ephemeral)
Setup shared secret for decryption.
#define MAX_SECRETS
How many shared master secrets do we keep around at most per sender? Should be large enough so that w...
static unsigned int purge_secrets(struct SharedSecret *ss_list_tail)
Best effort try to purge some secrets.
static uint32_t type
Type string converted to DNS type value.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_get_multiple(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, GNUNET_CONTAINER_MultiHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map that match a particular key.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
#define GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_REKEY
UDP Rekey.
#define GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_PAD
UDP communicator padding.
Plaintext of a rekey payload in a UDPBox.
struct GNUNET_CRYPTO_HpkeEncapsulation ephemeral
Ephemeral key to rekey with.

References SenderAddress::acks_available, SharedSecret::cmac, UDPRekey::ephemeral, GNUNET_CONTAINER_DLL_insert, GNUNET_CONTAINER_multihashmap_get_multiple(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_log, GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK, GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_PAD, GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_REKEY, GNUNET_NO, GNUNET_sh2s(), GNUNET_STATISTICS_update(), GNUNET_YES, handle_ack(), kce_generate_cb(), SenderAddress::kce_send_ack_on_finish, SenderAddress::key, SharedSecret::master, MAX_SECRETS, SenderAddress::num_secrets, SharedSecret::override_available_acks, pass_plaintext_to_core(), purge_secrets(), receivers, secret_destroy(), SharedSecret::sender, SharedSecret::sequence_allowed, setup_shared_secret_dec(), GNUNET_MessageHeader::size, SenderAddress::ss_head, SenderAddress::ss_tail, stats, type, and GNUNET_MessageHeader::type.

Referenced by decrypt_box(), and sock_read().

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

◆ decrypt_box()

static void decrypt_box ( const struct UDPBox box,
size_t  box_len,
struct KeyCacheEntry kce 
)
static

We received a box with matching kce.

Decrypt and process it.

Parameters
boxthe data we received
box_lennumber of bytes in box
kcekey index to decrypt box

Definition at line 1843 of file gnunet-communicator-udp.c.

1846{
1847 struct SharedSecret *ss = kce->ss;
1848 struct SharedSecret *ss_c = ss->sender->ss_tail;
1849 struct SharedSecret *ss_tmp;
1850 int ss_destroyed = 0;
1851 char out_buf[box_len - sizeof(*box)];
1852
1853 GNUNET_assert (NULL != ss->sender);
1854 if (GNUNET_OK != try_decrypt (ss,
1855 box->gcm_tag,
1856 kce->sequence_number,
1857 (const char *) &box[1],
1858 sizeof(out_buf),
1859 out_buf))
1860 {
1861 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed decryption.\n");
1863 "# Decryption failures with valid KCE",
1864 1,
1865 GNUNET_NO);
1866 kce_destroy (kce);
1867 ss->sender->acks_available--;
1868 return;
1869 }
1870 kce_destroy (kce);
1871 kce = NULL;
1872 ss->bytes_sent += box_len;
1873 ss->sender->acks_available--;
1874 ss->sequence_used++;
1876 "# bytes decrypted with BOX",
1877 sizeof(out_buf),
1878 GNUNET_NO);
1880 "# messages decrypted with BOX",
1881 1,
1882 GNUNET_NO);
1884 "decrypted UDPBox with kid %s\n",
1885 GNUNET_sh2s (&box->kid));
1886 try_handle_plaintext (ss->sender, out_buf, sizeof(out_buf));
1887
1888 while (NULL != ss_c)
1889 {
1890 if (ss_c->bytes_sent >= rekey_max_bytes)
1891 {
1893 "Removing SS because rekey bytes reached.\n");
1894 ss_tmp = ss_c->prev;
1895 if (ss == ss_c)
1896 ss_destroyed = 1;
1897 secret_destroy (ss_c);
1898 ss_c = ss_tmp;
1899 continue;
1900 }
1901 ss_c = ss_c->prev;
1902 }
1903 if (1 == ss_destroyed)
1904 return;
1906 "Sender has %u ack left.\n",
1907 ss->sender->acks_available);
1908 if ((KCN_THRESHOLD > ss->sender->acks_available) &&
1909 (NULL == ss->sender->kce_task) &&
1911 {
1913 "Sender has %u ack left which is under threshold.\n",
1914 ss->sender->acks_available);
1918 ss);
1919 }
1920}
static int try_decrypt(const struct SharedSecret *ss, const uint8_t *tag, uint32_t serial, const char *in_buf, size_t in_buf_size, char *out_buf)
Try to decrypt buf using shared secret ss and key/iv derived using serial.
static void try_handle_plaintext(struct SenderAddress *sender, const void *buf, size_t buf_size)
Test if we have received a valid message in plaintext.
#define KCN_THRESHOLD
If we fall below this number of available KCNs, we generate additional ACKs until we reach KCN_TARGET...
static unsigned long long rekey_max_bytes
How often we do rekey based on number of bytes transmitted.
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:1303
uint8_t gcm_tag[(128/8)]
128-bit authentication tag for the following encrypted message, from GCM.

References SenderAddress::acks_available, SharedSecret::bytes_sent, UDPBox::gcm_tag, GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_NO, GNUNET_OK, GNUNET_SCHEDULER_add_now(), GNUNET_sh2s(), GNUNET_STATISTICS_update(), GNUNET_YES, kce_destroy(), kce_generate_cb(), SenderAddress::kce_send_ack_on_finish, SenderAddress::kce_task, SenderAddress::kce_task_finished, KCN_THRESHOLD, UDPBox::kid, SharedSecret::prev, rekey_max_bytes, secret_destroy(), SharedSecret::sender, KeyCacheEntry::sequence_number, SharedSecret::sequence_used, KeyCacheEntry::ss, SenderAddress::ss_tail, stats, try_decrypt(), and try_handle_plaintext().

Referenced by sock_read().

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

◆ setup_sender()

static struct SenderAddress * setup_sender ( const struct GNUNET_PeerIdentity target,
const struct sockaddr *  address,
socklen_t  address_len 
)
static

Create sender address for target.

Note that we might already have one, so a fresh one is only allocated if one does not yet exist for address.

Parameters
targetpeer to generate address for
addresstarget address
address_lennumber of bytes in address
Returns
data structure to keep track of key material for decrypting data from target

Definition at line 1957 of file gnunet-communicator-udp.c.

1960{
1961 struct SenderAddress *sender;
1962 struct GNUNET_HashContext *hsh;
1963 struct GNUNET_HashCode sender_key;
1964
1966 GNUNET_CRYPTO_hash_context_read (hsh, address, address_len);
1967 GNUNET_CRYPTO_hash_context_read (hsh, target, sizeof(*target));
1968 GNUNET_CRYPTO_hash_context_finish (hsh, &sender_key);
1969
1970 sender = GNUNET_CONTAINER_multihashmap_get (senders, &sender_key);
1971 if (NULL != sender)
1972 {
1974 return sender;
1975 }
1976 sender = GNUNET_new (struct SenderAddress);
1977 sender->key = sender_key;
1978 sender->target = *target;
1979 sender->address = GNUNET_memdup (address, address_len);
1980 sender->address_len = address_len;
1982 senders,
1983 &sender->key,
1984 sender,
1987 "# senders active",
1989 GNUNET_NO);
1990 sender->timeout =
1993 sender,
1994 sender->timeout.abs_value_us);
1995 sender->nt = GNUNET_NT_scanner_get_type (is, address, address_len);
1996 if (NULL == timeout_task)
1998 return sender;
1999}
static struct GNUNET_NT_InterfaceScanner * is
Network scanner to determine network types.
static void reschedule_sender_timeout(struct SenderAddress *sender)
Increment sender timeout due to activity.
static char * address
GNS address for this phone.
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
struct GNUNET_CONTAINER_HeapNode * GNUNET_CONTAINER_heap_insert(struct GNUNET_CONTAINER_Heap *heap, void *element, GNUNET_CONTAINER_HeapCostType cost)
Inserts a new element into the heap.
void GNUNET_CRYPTO_hash_context_read(struct GNUNET_HashContext *hc, const void *buf, size_t size)
Add data to be hashed.
Definition: crypto_hash.c:366
void GNUNET_CRYPTO_hash_context_finish(struct GNUNET_HashContext *hc, struct GNUNET_HashCode *r_hash)
Finish the hash computation.
Definition: crypto_hash.c:390
struct GNUNET_HashContext * GNUNET_CRYPTO_hash_context_start(void)
Start incremental hashing operation.
Definition: crypto_hash.c:350
#define GNUNET_memdup(buf, size)
Allocate and initialize a block of memory.
enum GNUNET_NetworkType GNUNET_NT_scanner_get_type(struct GNUNET_NT_InterfaceScanner *is, const struct sockaddr *addr, socklen_t addrlen)
Returns where the address is located: loopback, LAN or WAN.
Definition: nt.c:309
socklen_t address_len
Length of the address.
enum GNUNET_NetworkType nt
Which network type does this queue use?

References GNUNET_TIME_Absolute::abs_value_us, address, SenderAddress::address, SenderAddress::address_len, check_timeouts(), GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, GNUNET_CONTAINER_heap_insert(), GNUNET_CONTAINER_multihashmap_get(), GNUNET_CONTAINER_multihashmap_put(), GNUNET_CONTAINER_multihashmap_size(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE, GNUNET_CRYPTO_hash_context_finish(), GNUNET_CRYPTO_hash_context_read(), GNUNET_CRYPTO_hash_context_start(), GNUNET_memdup, GNUNET_new, GNUNET_NO, GNUNET_NT_scanner_get_type(), GNUNET_SCHEDULER_add_now(), GNUNET_STATISTICS_set(), GNUNET_TIME_relative_to_absolute(), SenderAddress::hn, is, SenderAddress::key, SenderAddress::nt, receivers, reschedule_sender_timeout(), senders, senders_heap, stats, SenderAddress::target, SenderAddress::timeout, and timeout_task.

Referenced by sock_read().

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

◆ verify_confirmation()

static int verify_confirmation ( const struct GNUNET_CRYPTO_HpkeEncapsulation enc,
const struct UDPConfirmation uc 
)
static

Check signature from uc against ephemeral.

Parameters
ephemeralkey that is signed
ucsignature of claimant
Returns
GNUNET_OK if signature is valid

Definition at line 2010 of file gnunet-communicator-udp.c.

2012{
2013 struct UdpHandshakeSignature uhs;
2014
2015 uhs.purpose.purpose = htonl (
2017 uhs.purpose.size = htonl (sizeof(uhs));
2018 uhs.sender = uc->sender;
2019 uhs.receiver = my_identity;
2020 uhs.enc = *enc;
2021 uhs.monotonic_time = uc->monotonic_time;
2024 &uhs,
2025 &uc->sender_sig,
2026 &uc->sender.public_key);
2027}
static struct GNUNET_PeerIdentity my_identity
Our public key.
static OpusEncoder * enc
OPUS encoder.
static struct GNUNET_FS_UnindexContext * uc
#define GNUNET_CRYPTO_eddsa_verify(purp, ps, sig, pub)
Verify EdDSA signature.
#define GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_HANDSHAKE
Signature used by UDP communicator handshake.
uint32_t purpose
What does this signature vouch for? This must contain a GNUNET_SIGNATURE_PURPOSE_XXX constant (from g...
Signature we use to verify that the ephemeral key was really chosen by the specified sender.
struct GNUNET_CRYPTO_EccSignaturePurpose purpose
Purpose must be GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_HANDSHAKE.

References enc, UdpHandshakeSignature::enc, GNUNET_CRYPTO_eddsa_verify, GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_HANDSHAKE, UdpHandshakeSignature::monotonic_time, my_identity, GNUNET_CRYPTO_EccSignaturePurpose::purpose, UdpHandshakeSignature::purpose, UdpHandshakeSignature::receiver, UdpHandshakeSignature::sender, GNUNET_CRYPTO_EccSignaturePurpose::size, and uc.

Referenced by sock_read().

Here is the caller graph for this function:

◆ sockaddr_to_udpaddr_string()

static char * sockaddr_to_udpaddr_string ( const struct sockaddr *  address,
socklen_t  address_len 
)
static

Converts address to the address string format used by this communicator in HELLOs.

Parameters
addressthe address to convert, must be AF_INET or AF_INET6.
address_lennumber of bytes in address
Returns
string representation of address

Definition at line 2039 of file gnunet-communicator-udp.c.

2041{
2042 char *ret;
2043
2044 switch (address->sa_family)
2045 {
2046 case AF_INET:
2048 "%s-%s",
2050 GNUNET_a2s (address, address_len));
2051 break;
2052
2053 case AF_INET6:
2055 "%s-%s",
2057 GNUNET_a2s (address, address_len));
2058 break;
2059
2060 default:
2061 GNUNET_assert (0);
2062 }
2063 return ret;
2064}
static int ret
Final status code.
Definition: gnunet-arm.c:93
const char * GNUNET_a2s(const struct sockaddr *addr, socklen_t addrlen)
Convert a "struct sockaddr*" (IPv4 or IPv6 address) to a string (for printing debug messages).
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.

References address, COMMUNICATOR_ADDRESS_PREFIX, GNUNET_a2s(), GNUNET_asprintf(), GNUNET_assert, and ret.

Referenced by create_receiver(), sock_read(), and udp_socket_notify().

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

◆ get_socket()

static struct GNUNET_NETWORK_Handle * get_socket ( struct ReceiverAddress receiver)
static

Definition at line 2068 of file gnunet-communicator-udp.c.

2069{
2071
2072 if (NULL == receiver->udp_sock)
2073 {
2074 if (AF_INET6 == receiver->address->sa_family)
2076 else
2078 }
2079 else
2080 udp_sock = receiver->udp_sock;
2081
2082 return udp_sock;
2083}
static struct GNUNET_NETWORK_Handle * udp_sock
Our socket.
static struct GNUNET_NETWORK_Handle * default_v4_sock
Our IPv4 socket.
handle to a socket
Definition: network.c:53

References default_v4_sock, default_v6_sock, receiver(), and udp_sock.

Referenced by mq_send_d(), and send_msg_with_kx().

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

◆ udp_address_to_sockaddr()

static struct sockaddr * udp_address_to_sockaddr ( const char *  bindto,
sa_family_t  family,
socklen_t *  sock_len 
)
static

Convert UDP bind specification to a struct sockaddr *

Parameters
bindtobind specification to convert
familyaddress family to enforce
[out]sock_lenset to the length of the address
Returns
converted bindto specification

Definition at line 2095 of file gnunet-communicator-udp.c.

2098{
2099 struct sockaddr *in;
2100 unsigned int port;
2101 char dummy[2];
2102 char *colon;
2103 char *cp;
2104
2105 if (1 == sscanf (bindto, "%u%1s", &port, dummy))
2106 {
2107 /* interpreting value as just a PORT number */
2108 if (port > UINT16_MAX)
2109 {
2111 "BINDTO specification `%s' invalid: value too large for port\n",
2112 bindto);
2113 return NULL;
2114 }
2115 if ((AF_INET == family) || (GNUNET_YES == disable_v6))
2116 {
2117 struct sockaddr_in *i4;
2118
2119 i4 = GNUNET_malloc (sizeof(struct sockaddr_in));
2120 i4->sin_family = AF_INET;
2121 i4->sin_port = htons ((uint16_t) port);
2122 *sock_len = sizeof(struct sockaddr_in);
2123 in = (struct sockaddr *) i4;
2124 }
2125 else
2126 {
2127 struct sockaddr_in6 *i6;
2128
2129 i6 = GNUNET_malloc (sizeof(struct sockaddr_in6));
2130 i6->sin6_family = AF_INET6;
2131 i6->sin6_port = htons ((uint16_t) port);
2132 *sock_len = sizeof(struct sockaddr_in6);
2133 in = (struct sockaddr *) i6;
2134 }
2135 return in;
2136 }
2137 cp = GNUNET_strdup (bindto);
2138 colon = strrchr (cp, ':');
2139 if (NULL != colon)
2140 {
2141 /* interpret value after colon as port */
2142 *colon = '\0';
2143 colon++;
2144 if (1 == sscanf (colon, "%u%1s", &port, dummy))
2145 {
2146 /* interpreting value as just a PORT number */
2147 if (port > UINT16_MAX)
2148 {
2150 "BINDTO specification `%s' invalid: value too large for port\n",
2151 bindto);
2152 GNUNET_free (cp);
2153 return NULL;
2154 }
2155 }
2156 else
2157 {
2158 GNUNET_log (
2160 "BINDTO specification `%s' invalid: last ':' not followed by number\n",
2161 bindto);
2162 GNUNET_free (cp);
2163 return NULL;
2164 }
2165 }
2166 else
2167 {
2168 /* interpret missing port as 0, aka pick any free one */
2169 port = 0;
2170 }
2171 if (AF_INET6 != family)
2172 {
2173 /* try IPv4 */
2174 struct sockaddr_in v4;
2175
2176 memset (&v4, 0, sizeof(v4));
2177 if (1 == inet_pton (AF_INET, cp, &v4.sin_addr))
2178 {
2179 v4.sin_family = AF_INET;
2180 v4.sin_port = htons ((uint16_t) port);
2181#if HAVE_SOCKADDR_IN_SIN_LEN
2182 v4.sin_len = sizeof(struct sockaddr_in);
2183#endif
2184 in = GNUNET_memdup (&v4, sizeof(struct sockaddr_in));
2185 *sock_len = sizeof(struct sockaddr_in);
2186 GNUNET_free (cp);
2187 return in;
2188 }
2189 }
2190 if (AF_INET != family)
2191 {
2192 /* try IPv6 */
2193 struct sockaddr_in6 v6;
2194 const char *start;
2195
2196 memset (&v6, 0, sizeof(v6));
2197 start = cp;
2198 if (('[' == *cp) && (']' == cp[strlen (cp) - 1]))
2199 {
2200 start++; /* skip over '[' */
2201 cp[strlen (cp) - 1] = '\0'; /* eat ']' */
2202 }
2203 if (1 == inet_pton (AF_INET6, start, &v6.sin6_addr))
2204 {
2205 v6.sin6_family = AF_INET6;
2206 v6.sin6_port = htons ((uint16_t) port);
2207#if HAVE_SOCKADDR_IN_SIN_LEN
2208 v6.sin6_len = sizeof(struct sockaddr_in6);
2209#endif
2210 in = GNUNET_memdup (&v6, sizeof(v6));
2211 *sock_len = sizeof(v6);
2212 GNUNET_free (cp);
2213 return in;
2214 }
2215 }
2216 /* #5528 FIXME (feature!): maybe also try getnameinfo()? */
2217 GNUNET_free (cp);
2218 return NULL;
2219}
static int start
Set if we are to start default services (including ARM).
Definition: gnunet-arm.c:38
static uint16_t port
Port number.
Definition: gnunet-bcd.c:146
static int disable_v6
IPv6 disabled or not.
static struct in_addr dummy
Target "dummy" address of the packet we pretend to respond to.
@ GNUNET_ERROR_TYPE_ERROR
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_malloc(size)
Wrapper around malloc.

References disable_v6, dummy, GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_log, GNUNET_malloc, GNUNET_memdup, GNUNET_strdup, GNUNET_YES, port, and start.

Referenced by create_receiver(), and create_udp_socket().

Here is the caller graph for this function:

◆ sock_read()

static void sock_read ( void *  cls)
static

Socket read task.

Parameters
clsNULL

Definition at line 2335 of file gnunet-communicator-udp.c.

2336{
2337 struct sockaddr_storage sa;
2338 struct sockaddr_in *addr_verify;
2339 socklen_t salen = sizeof(sa);
2340 char buf[UINT16_MAX];
2341 ssize_t rcvd;
2342
2343 struct GNUNET_NETWORK_Handle *udp_sock = cls;
2344
2347 udp_sock,
2348 &sock_read,
2349 udp_sock);
2352 udp_sock,
2353 &sock_read,
2354 udp_sock);
2355 while (1)
2356 {
2358 buf,
2359 sizeof(buf),
2360 (struct sockaddr *) &sa,
2361 &salen);
2362 if (-1 == rcvd)
2363 {
2364 struct sockaddr *addr = (struct sockaddr*) &sa;
2365
2366 if (EAGAIN == errno)
2367 break; // We are done reading data
2369 "Failed to recv from %s family %d failed sock %p\n",
2370 GNUNET_a2s ((struct sockaddr*) &sa,
2371 sizeof (*addr)),
2372 addr->sa_family,
2373 udp_sock);
2375 return;
2376 }
2378 "Read %llu bytes\n",
2379 (unsigned long long) rcvd);
2380 if (0 == rcvd)
2381 {
2382 GNUNET_break_op (0);
2384 "Read 0 bytes from UDP socket\n");
2385 return;
2386 }
2387
2388 /* first, see if it is a GNUNET_BurstMessage */
2389 if (rcvd == sizeof (struct GNUNET_BurstMessage))
2390 {
2391 struct GNUNET_BurstMessage *bm = (struct GNUNET_BurstMessage *) buf;
2392 struct sockaddr *addr = (struct sockaddr*) &sa;
2393 char *address = sockaddr_to_udpaddr_string (addr, sizeof (*addr));
2394
2395 GNUNET_assert (0 == bm->local_port);
2397 "Received a burst message for default port\n");
2398 create_receiver (&bm->peer,
2399 address,
2400 NULL);
2401 if (AF_INET6 == addr->sa_family)
2403 else
2407 return;
2408 }
2409 /* second, see if it is a UDPBox */
2410 if (rcvd > sizeof(struct UDPBox))
2411 {
2412 const struct UDPBox *box;
2413 struct KeyCacheEntry *kce;
2414
2415 box = (const struct UDPBox *) buf;
2417 if (NULL != kce)
2418 {
2420 "Found KCE with kid %s\n",
2421 GNUNET_sh2s (&box->kid));
2422 decrypt_box (box, (size_t) rcvd, kce);
2423 continue;
2424 }
2425 }
2426
2427 /* next, check if it is a broadcast */
2428 if (sizeof(struct UDPBroadcast) == rcvd)
2429 {
2430 const struct UDPBroadcast *ub;
2431 struct UdpBroadcastSignature uhs;
2432 struct GNUNET_PeerIdentity sender;
2433
2434 addr_verify = GNUNET_memdup (&sa, salen);
2435 addr_verify->sin_port = 0;
2437 "received UDPBroadcast from %s\n",
2438 GNUNET_a2s ((const struct sockaddr *) addr_verify, salen));
2439 ub = (const struct UDPBroadcast *) buf;
2440 uhs.purpose.purpose = htonl (
2442 uhs.purpose.size = htonl (sizeof(uhs));
2443 uhs.sender = ub->sender;
2444 sender = ub->sender;
2445 if (0 == memcmp (&sender, &my_identity, sizeof (struct
2447 {
2449 "Received our own broadcast\n");
2450 GNUNET_free (addr_verify);
2451 continue;
2452 }
2454 "checking UDPBroadcastSignature for %s\n",
2455 GNUNET_i2s (&sender));
2456 GNUNET_CRYPTO_hash ((struct sockaddr *) addr_verify, salen,
2457 &uhs.h_address);
2458 if (GNUNET_OK ==
2461 &uhs,
2462 &ub->sender_sig,
2463 &ub->sender.public_key))
2464 {
2465 char *addr_s;
2467
2468 addr_s =
2469 sockaddr_to_udpaddr_string ((const struct sockaddr *) &sa, salen);
2470 GNUNET_STATISTICS_update (stats, "# broadcasts received", 1, GNUNET_NO);
2471 /* use our own mechanism to determine network type */
2472 nt =
2473 GNUNET_NT_scanner_get_type (is, (const struct sockaddr *) &sa, salen);
2475 "validating address %s received from UDPBroadcast\n",
2476 GNUNET_i2s (&sender));
2478 GNUNET_free (addr_s);
2479 GNUNET_free (addr_verify);
2480 continue;
2481 }
2482 else
2483 {
2485 "VerifyingPeer %s is verifying UDPBroadcast\n",
2488 "Verifying UDPBroadcast from %s failed\n",
2489 GNUNET_i2s (&ub->sender));
2490 }
2491 GNUNET_free (addr_verify);
2492 /* continue with KX, mostly for statistics... */
2493 }
2494
2495
2496 /* finally, test if it is a KX */
2497 if (rcvd < sizeof(struct UDPConfirmation) + sizeof(struct InitialKX))
2498 {
2500 "# messages dropped (no kid, too small for KX)",
2501 1,
2502 GNUNET_NO);
2503 continue;
2504 }
2506 "Got KX\n");
2507 {
2508 const struct InitialKX *kx;
2509 struct SharedSecret *ss;
2510 char pbuf[rcvd - sizeof(struct InitialKX)];
2511 const struct UDPConfirmation *uc;
2512 struct SenderAddress *sender;
2513
2514 kx = (const struct InitialKX *) buf;
2517 "Before DEC\n");
2518
2519 if (GNUNET_OK != try_decrypt (ss,
2520 kx->gcm_tag,
2521 0,
2522 &buf[sizeof(*kx)],
2523 sizeof(pbuf),
2524 pbuf))
2525 {
2527 "Unable to decrypt tag, dropping...\n");
2528 GNUNET_free (ss);
2530 stats,
2531 "# messages dropped (no kid, AEAD decryption failed)",
2532 1,
2533 GNUNET_NO);
2534 continue;
2535 }
2537 "Before VERIFY\n");
2538
2539 uc = (const struct UDPConfirmation *) pbuf;
2540
2541 if (GNUNET_OK != verify_confirmation (&kx->enc, uc)) // TODO: need ephemeral instead of representative
2542 {
2543 GNUNET_break_op (0);
2544 GNUNET_free (ss);
2546 "# messages dropped (sender signature invalid)",
2547 1,
2548 GNUNET_NO);
2549 continue;
2550 }
2552 "Before SETUP_SENDER\n");
2553
2554 calculate_cmac (ss);
2555 sender = setup_sender (&uc->sender, (const struct sockaddr *) &sa, salen);
2556 ss->sender = sender;
2557 GNUNET_CONTAINER_DLL_insert (sender->ss_head, sender->ss_tail, ss);
2558 if ((KCN_THRESHOLD > ss->sender->acks_available) &&
2559 (NULL == ss->sender->kce_task) &&
2561 {
2562 // TODO This task must be per sender! FIXME: This is a nice todo, but I do not know what must be done here to fix.
2566 ss);
2567 }
2568 sender->num_secrets++;
2569 GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
2571 "# messages decrypted without BOX",
2572 1,
2573 GNUNET_NO);
2574 try_handle_plaintext (sender, &uc[1], sizeof(pbuf) - sizeof(*uc));
2575 if (0 == purge_secrets (sender->ss_tail))
2576 {
2577 // No secret purged. Delete oldest.
2578 if (sender->num_secrets > MAX_SECRETS)
2579 {
2580 secret_destroy (sender->ss_tail);
2581 }
2582 }
2583 }
2584 }
2585}
static struct GNUNET_SCHEDULER_Task * read_v6_task
ID of read IPv6 task.
static struct GNUNET_SCHEDULER_Task * read_v4_task
ID of read IPv4 task.
static int verify_confirmation(const struct GNUNET_CRYPTO_HpkeEncapsulation *enc, const struct UDPConfirmation *uc)
Check signature from uc against ephemeral.
static struct SenderAddress * setup_sender(const struct GNUNET_PeerIdentity *target, const struct sockaddr *address, socklen_t address_len)
Create sender address for target.
static void sock_read(void *cls)
Socket read task.
static struct SharedSecret * setup_initial_shared_secret_dec(const struct GNUNET_CRYPTO_HpkeEncapsulation *c)
Setup shared secret for decryption for initial handshake.
static struct GNUNET_TRANSPORT_ApplicationHandle * ah
Our handle to report addresses for validation to TRANSPORT.
static char * sockaddr_to_udpaddr_string(const struct sockaddr *address, socklen_t address_len)
Converts address to the address string format used by this communicator in HELLOs.
static enum GNUNET_GenericReturnValue create_receiver(const struct GNUNET_PeerIdentity *peer, const char *address, struct GNUNET_NETWORK_Handle *udp_sock)
static void decrypt_box(const struct UDPBox *box, size_t box_len, struct KeyCacheEntry *kce)
We received a box with matching kce.
static struct GNUNET_NAT_AUTO_Test * nt
Handle to a NAT test operation.
void GNUNET_TRANSPORT_communicator_burst_finished(struct GNUNET_TRANSPORT_CommunicatorHandle *ch)
The communicator tells the transport service that it finished the burst.
void GNUNET_TRANSPORT_application_validate(struct GNUNET_TRANSPORT_ApplicationHandle *ch, const struct GNUNET_PeerIdentity *peer, enum GNUNET_NetworkType nt, const char *addr)
An application (or a communicator) has received a HELLO (or other address data of another peer) and w...
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
void * GNUNET_CONTAINER_multishortmap_get(const struct GNUNET_CONTAINER_MultiShortmap *map, const struct GNUNET_ShortHashCode *key)
Given a key find a value in the map matching the key.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
void GNUNET_stop_burst(struct GNUNET_NETWORK_Handle *do_not_touch)
Method to stop all sockets we established to the other peer.
Definition: nat.c:564
ssize_t GNUNET_NETWORK_socket_recvfrom(const struct GNUNET_NETWORK_Handle *desc, void *buffer, size_t length, struct sockaddr *src_addr, socklen_t *addrlen)
Read data from a socket (always non-blocking).
Definition: network.c:688
GNUNET_NetworkType
Types of networks (with separate quotas) we support.
Definition: gnunet_nt_lib.h:44
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_read_net(struct GNUNET_TIME_Relative delay, struct GNUNET_NETWORK_Handle *rfd, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay or when the specified file descriptor is ready f...
Definition: scheduler.c:1510
#define GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_BROADCAST
Signature used by UDP broadcasts.
Message send during burst mode.
struct GNUNET_PeerIdentity peer
The peer who send the msg.
unsigned int local_port
The local port the message was send from.
The identity of the host (wraps the signing key of the peer).
struct GNUNET_CRYPTO_EddsaPublicKey public_key
uint8_t gcm_tag[(128/8)]
HMAC for the following encrypted message, using GCM.
struct GNUNET_CRYPTO_HpkeEncapsulation enc
Representative of ephemeral key for KX.
struct GNUNET_ShortHashCode kid
Key and IV identification code.
Broadcast by peer in LAN announcing its presence.
struct GNUNET_CRYPTO_EddsaSignature sender_sig
Sender's signature of type GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_BROADCAST.
struct GNUNET_PeerIdentity sender
Sender's peer identity.
struct GNUNET_PeerIdentity sender
Sender's identity.
Signature we use to verify that the broadcast was really made by the peer that claims to have made it...

References SenderAddress::acks_available, address, ah, calculate_cmac(), ch, create_receiver(), decrypt_box(), default_v4_sock, default_v6_sock, InitialKX::enc, InitialKX::gcm_tag, GNUNET_a2s(), GNUNET_assert, GNUNET_break_op, GNUNET_CONTAINER_DLL_insert, GNUNET_CONTAINER_multishortmap_get(), GNUNET_CRYPTO_eddsa_verify, GNUNET_CRYPTO_hash(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_i2s(), GNUNET_log, GNUNET_log_strerror, GNUNET_memdup, GNUNET_NETWORK_socket_recvfrom(), GNUNET_NO, GNUNET_NT_scanner_get_type(), GNUNET_OK, GNUNET_SCHEDULER_add_now(), GNUNET_SCHEDULER_add_read_net(), GNUNET_sh2s(), GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_BROADCAST, GNUNET_STATISTICS_update(), GNUNET_stop_burst(), GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_TRANSPORT_application_validate(), GNUNET_TRANSPORT_communicator_burst_finished(), GNUNET_YES, UdpBroadcastSignature::h_address, is, kce_generate_cb(), SenderAddress::kce_send_ack_on_finish, SenderAddress::kce_task, SenderAddress::kce_task_finished, KCN_THRESHOLD, key_cache, UDPBox::kid, GNUNET_BurstMessage::local_port, MAX_SECRETS, my_identity, nt, GNUNET_BurstMessage::peer, GNUNET_PeerIdentity::public_key, purge_secrets(), GNUNET_CRYPTO_EccSignaturePurpose::purpose, UdpBroadcastSignature::purpose, read_v4_task, read_v6_task, secret_destroy(), UDPConfirmation::sender, UdpBroadcastSignature::sender, UDPBroadcast::sender, SharedSecret::sender, UDPBroadcast::sender_sig, setup_initial_shared_secret_dec(), setup_sender(), GNUNET_CRYPTO_EccSignaturePurpose::size, sock_read(), sockaddr_to_udpaddr_string(), stats, try_decrypt(), try_handle_plaintext(), uc, udp_sock, and verify_confirmation().

Referenced by create_receiver(), run(), and sock_read().

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

◆ create_receiver()

static enum GNUNET_GenericReturnValue create_receiver ( const struct GNUNET_PeerIdentity peer,
const char *  address,
struct GNUNET_NETWORK_Handle udp_sock 
)
static

Definition at line 2227 of file gnunet-communicator-udp.c.

2230{
2231 struct GNUNET_HashContext *hsh;
2232 struct ReceiverAddress *receiver;
2233 struct GNUNET_HashCode receiver_key;
2234 const char *path;
2235 struct sockaddr *in;
2236 socklen_t in_len;
2237
2238 if (0 != strncmp (address,
2240 strlen (COMMUNICATOR_ADDRESS_PREFIX "-")))
2241 {
2242 GNUNET_break_op (0);
2243 return GNUNET_SYSERR;
2244 }
2245 path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")];
2246 in = udp_address_to_sockaddr (path, AF_UNSPEC, &in_len);
2247
2248 if (NULL == in)
2249 {
2251 "Failed to setup UDP socket address\n");
2252 return GNUNET_SYSERR;
2253 }
2254 if ((AF_INET6 == in->sa_family) &&
2256 {
2258 "IPv6 disabled, skipping %s\n", address);
2259 GNUNET_free (in);
2260 return GNUNET_SYSERR;
2261 }
2262 else if (AF_INET == in->sa_family)
2263 {
2264 struct sockaddr_in *sin = (struct sockaddr_in *) in;
2265 if (0 == sin->sin_port)
2266 {
2267 GNUNET_free (in);
2268 return GNUNET_NO;
2269 }
2270 }
2271
2273 GNUNET_CRYPTO_hash_context_read (hsh, in, in_len);
2274 GNUNET_CRYPTO_hash_context_read (hsh, peer, sizeof(*peer));
2275 GNUNET_CRYPTO_hash_context_finish (hsh, &receiver_key);
2276
2278 if (NULL != receiver)
2279 {
2281 "receiver %s already exist or is being connected to\n",
2282 address);
2283 return GNUNET_NO;
2284 }
2285
2287 receiver->udp_sock = udp_sock;
2288 receiver->key = receiver_key;
2289 receiver->address = in;
2290 receiver->address_len = in_len;
2291 receiver->target = *peer;
2292 eddsa_pub_to_hpke_key (&receiver->target.public_key,
2293 &receiver->target_hpke_key);
2294 receiver->nt = GNUNET_NT_scanner_get_type (is, in, in_len);
2296 receivers,
2297 &receiver->key,
2298 receiver,
2301 "Added %s to receivers with address %s and sock %p\n",
2302 GNUNET_i2s_full (&receiver->target),
2303 address,
2304 udp_sock);
2305 receiver->timeout =
2308 receiver,
2309 receiver->timeout.abs_value_us);
2311 "# receivers active",
2313 GNUNET_NO);
2314 receiver->foreign_addr =
2315 sockaddr_to_udpaddr_string (receiver->address, receiver->address_len);
2316 if (NULL != udp_sock)
2319 udp_sock,
2320 &sock_read,
2321 udp_sock);
2323 if (NULL == timeout_task)
2325 return GNUNET_OK;
2326}
static void setup_receiver_mq(struct ReceiverAddress *receiver)
Setup the MQ for the receiver.
static struct sockaddr * udp_address_to_sockaddr(const char *bindto, sa_family_t family, socklen_t *sock_len)
Convert UDP bind specification to a struct sockaddr *
static void eddsa_pub_to_hpke_key(struct GNUNET_CRYPTO_EddsaPublicKey *edpk, struct GNUNET_CRYPTO_EcdhePublicKey *pk)

References address, check_timeouts(), COMMUNICATOR_ADDRESS_PREFIX, disable_v6, eddsa_pub_to_hpke_key(), GNUNET_break_op, GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, GNUNET_CONTAINER_heap_insert(), GNUNET_CONTAINER_multihashmap_get(), GNUNET_CONTAINER_multihashmap_put(), GNUNET_CONTAINER_multihashmap_size(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE, GNUNET_CRYPTO_hash_context_finish(), GNUNET_CRYPTO_hash_context_read(), GNUNET_CRYPTO_hash_context_start(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_i2s_full(), GNUNET_log, GNUNET_new, GNUNET_NO, GNUNET_NT_scanner_get_type(), GNUNET_OK, GNUNET_SCHEDULER_add_now(), GNUNET_SCHEDULER_add_read_net(), GNUNET_STATISTICS_set(), GNUNET_SYSERR, GNUNET_TIME_relative_to_absolute(), GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_YES, is, receiver(), receivers, receivers_heap, setup_receiver_mq(), sock_read(), sockaddr_to_udpaddr_string(), stats, timeout_task, udp_address_to_sockaddr(), and udp_sock.

Referenced by mq_init(), sock_read(), and udp_socket_notify().

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

◆ do_pad()

static void do_pad ( gcry_cipher_hd_t  out_cipher,
char *  dgram,
size_t  pad_size 
)
static

Pad dgram by pad_size using out_cipher.

Parameters
out_ciphercipher to use
dgramdatagram to pad
pad_sizenumber of bytes of padding to append

Definition at line 2596 of file gnunet-communicator-udp.c.

2597{
2598 char pad[pad_size];
2599
2601 if (sizeof(pad) > sizeof(struct GNUNET_MessageHeader))
2602 {
2603 struct GNUNET_MessageHeader hdr =
2604 { .size = htons (sizeof(pad)),
2606
2607 memcpy (pad, &hdr, sizeof(hdr));
2608 }
2610 0 ==
2611 gcry_cipher_encrypt (out_cipher, dgram, sizeof(pad), pad, sizeof(pad)));
2612}
void GNUNET_CRYPTO_random_block(enum GNUNET_CRYPTO_Quality mode, void *buffer, size_t length)
Fill block with a random values.
@ GNUNET_CRYPTO_QUALITY_WEAK
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).

References GNUNET_assert, GNUNET_CRYPTO_QUALITY_WEAK, GNUNET_CRYPTO_random_block(), GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_PAD, and GNUNET_MessageHeader::size.

Referenced by mq_send_d(), and send_msg_with_kx().

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

◆ send_msg_with_kx()

static void send_msg_with_kx ( const struct GNUNET_MessageHeader msg,
struct ReceiverAddress receiver,
struct GNUNET_MQ_Handle mq 
)
static

Definition at line 2616 of file gnunet-communicator-udp.c.

2619{
2620 uint16_t msize = ntohs (msg->size);
2621 struct UdpHandshakeSignature uhs;
2622 struct UDPConfirmation uc;
2623 struct InitialKX kx;
2624 char dgram[receiver->kx_mtu + sizeof(uc) + sizeof(kx)];
2625 size_t dpos;
2626 gcry_cipher_hd_t out_cipher;
2627 struct SharedSecret *ss;
2628
2629 if (msize > receiver->kx_mtu)
2630 {
2631 GNUNET_break (0);
2632 if (GNUNET_YES != receiver->receiver_destroy_called)
2634 return;
2635 }
2637
2638 /* setup key material */
2640
2641 if (0 == purge_secrets (receiver->ss_tail))
2642 {
2643 // No secret purged. Delete oldest.
2644 if (receiver->num_secrets > MAX_SECRETS)
2645 {
2646 secret_destroy (receiver->ss_tail);
2647 }
2648 }
2649
2650 setup_cipher (&ss->master, 0, &out_cipher);
2651 /* compute 'uc' */
2652 uc.sender = my_identity;
2653 uc.monotonic_time =
2655 uhs.purpose.purpose = htonl (
2657 uhs.purpose.size = htonl (sizeof(uhs));
2658 uhs.sender = my_identity;
2659 uhs.receiver = receiver->target;
2660 uhs.monotonic_time = uc.monotonic_time;
2662 &uhs,
2663 &uc.sender_sig);
2664 /* Leave space for kx */
2665 dpos = sizeof(kx);
2666 /* Append encrypted uc to dgram */
2667 GNUNET_assert (0 == gcry_cipher_encrypt (out_cipher,
2668 &dgram[dpos],
2669 sizeof(uc),
2670 &uc,
2671 sizeof(uc)));
2672 dpos += sizeof(uc);
2673 /* Append encrypted payload to dgram */
2675 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], msize, msg, msize));
2676 dpos += msize;
2677 do_pad (out_cipher, &dgram[dpos], sizeof(dgram) - dpos);
2678 /* Datagram starts with kx */
2679 kx.enc = uhs.enc;
2681 0 == gcry_cipher_gettag (out_cipher, kx.gcm_tag, sizeof(kx.gcm_tag)));
2682 gcry_cipher_close (out_cipher);
2683 memcpy (dgram, &kx, sizeof(kx));
2685 dgram,
2686 sizeof(dgram),
2687 receiver->address,
2688 receiver->address_len))
2689 {
2692 "Sending KX with payload size %u to %s family %d failed sock %p\n",
2693 msize,
2694 GNUNET_a2s (receiver->address,
2695 receiver->address_len),
2696 receiver->address->sa_family,
2700 return;
2701 }
2703 "Sending KX with payload size %u to %s with socket %p\n",
2704 msize,
2705 GNUNET_a2s (receiver->address,
2706 receiver->address_len),
2709}
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
static struct SharedSecret * setup_initial_shared_secret_ephemeral(struct GNUNET_CRYPTO_HpkeEncapsulation *c, struct ReceiverAddress *receiver)
Setup new shared secret for encryption using KEM for initial handshake.
static const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
static void reschedule_receiver_timeout(struct ReceiverAddress *receiver)
Increment receiver timeout due to activity.
static void do_pad(gcry_cipher_hd_t out_cipher, char *dgram, size_t pad_size)
Pad dgram by pad_size using out_cipher.
static struct GNUNET_NETWORK_Handle * get_socket(struct ReceiverAddress *receiver)
#define GNUNET_CRYPTO_eddsa_sign(priv, ps, sig)
EdDSA sign a given block.
void GNUNET_MQ_impl_send_continue(struct GNUNET_MQ_Handle *mq)
Call the send implementation for the next queued message, if any.
Definition: mq.c:437
ssize_t GNUNET_NETWORK_socket_sendto(const struct GNUNET_NETWORK_Handle *desc, const void *message, size_t length, const struct sockaddr *dest_addr, socklen_t dest_len)
Send data to a particular destination (always non-blocking).
Definition: network.c:772
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get_monotonic(const struct GNUNET_CONFIGURATION_Handle *cfg)
Obtain the current time and make sure it is monotonically increasing.
Definition: time.c:862
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:640

References cfg, do_pad(), UdpHandshakeSignature::enc, InitialKX::enc, InitialKX::gcm_tag, get_socket(), GNUNET_a2s(), GNUNET_assert, GNUNET_break, GNUNET_CRYPTO_eddsa_sign, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_WARNING, GNUNET_log, GNUNET_log_strerror, GNUNET_MQ_impl_send_continue(), GNUNET_NETWORK_socket_sendto(), GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_HANDSHAKE, GNUNET_TIME_absolute_get_monotonic(), GNUNET_TIME_absolute_hton(), GNUNET_YES, SharedSecret::master, MAX_SECRETS, UdpHandshakeSignature::monotonic_time, mq, msg, my_identity, my_private_key, purge_secrets(), GNUNET_CRYPTO_EccSignaturePurpose::purpose, UdpHandshakeSignature::purpose, receiver(), UdpHandshakeSignature::receiver, receiver_destroy(), reschedule_receiver_timeout(), secret_destroy(), UdpHandshakeSignature::sender, setup_cipher(), setup_initial_shared_secret_ephemeral(), GNUNET_MessageHeader::size, GNUNET_CRYPTO_EccSignaturePurpose::size, and uc.

Referenced by mq_send_d(), and mq_send_kx().

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

◆ mq_send_kx()

static void mq_send_kx ( struct GNUNET_MQ_Handle mq,
const struct GNUNET_MessageHeader msg,
void *  impl_state 
)
static

Signature of functions implementing the sending functionality of a message queue.

Parameters
mqthe message queue
msgthe message to send
impl_stateour struct ReceiverAddress

Definition at line 2721 of file gnunet-communicator-udp.c.

2724{
2725 struct ReceiverAddress *receiver = impl_state;
2726
2727 GNUNET_assert (mq == receiver->kx_mq);
2729}
static void send_msg_with_kx(const struct GNUNET_MessageHeader *msg, struct ReceiverAddress *receiver, struct GNUNET_MQ_Handle *mq)

References GNUNET_assert, mq, msg, receiver(), and send_msg_with_kx().

Referenced by setup_receiver_mq().

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

◆ create_rekey()

static void create_rekey ( struct ReceiverAddress receiver,
struct SharedSecret ss,
struct UDPRekey rekey 
)
static

Definition at line 2733 of file gnunet-communicator-udp.c.

2735{
2736 struct SharedSecret *ss_rekey;
2737
2739 /* setup key material */
2740 ss_rekey = setup_shared_secret_ephemeral (&rekey->ephemeral,
2741 receiver);
2742 ss_rekey->sequence_allowed = 0;
2744 "Setup secret with k = %s\n",
2745 GNUNET_sh2s (&ss_rekey->master));
2747 "Setup secret with H(k) = %s\n",
2748 GNUNET_h2s (&(ss_rekey->cmac)));
2749
2750 /* Append encrypted payload to dgram */
2752 rekey->header.size = htons (sizeof (struct UDPRekey));
2753}
static struct SharedSecret * setup_shared_secret_ephemeral(struct GNUNET_CRYPTO_HpkeEncapsulation *ephemeral, struct ReceiverAddress *receiver)
Setup new shared secret for encryption using KEM.
int rekey_initiated
rekey initiated for this secret?
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_REKEY.

References SharedSecret::cmac, UDPRekey::ephemeral, GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_log, GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_REKEY, GNUNET_sh2s(), GNUNET_YES, UDPRekey::header, SharedSecret::master, receiver(), SharedSecret::rekey_initiated, SharedSecret::sequence_allowed, setup_shared_secret_ephemeral(), GNUNET_MessageHeader::size, and GNUNET_MessageHeader::type.

Referenced by mq_send_d().

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

◆ mq_send_d()

static void mq_send_d ( struct GNUNET_MQ_Handle mq,
const struct GNUNET_MessageHeader msg,
void *  impl_state 
)
static

Signature of functions implementing the sending functionality of a message queue.

Parameters
mqthe message queue
msgthe message to send
impl_stateour struct ReceiverAddress

Definition at line 2765 of file gnunet-communicator-udp.c.

2768{
2769 struct ReceiverAddress *receiver = impl_state;
2770 struct UDPRekey rekey;
2771 struct SharedSecret *ss;
2772 int inject_rekey = GNUNET_NO;
2773 uint16_t msize = ntohs (msg->size);
2774
2775 GNUNET_assert (mq == receiver->d_mq);
2776 if ((msize > receiver->d_mtu) ||
2777 (0 == receiver->acks_available))
2778 {
2780 "msize: %u, mtu: %llu, acks: %u\n",
2781 (unsigned int) msize,
2782 (unsigned long long) receiver->d_mtu,
2783 receiver->acks_available);
2784
2785 GNUNET_break (0);
2786 if (GNUNET_YES != receiver->receiver_destroy_called)
2788 return;
2789 }
2791
2792 if (receiver->num_secrets > MAX_SECRETS)
2793 {
2794 if ((0 == purge_secrets (receiver->ss_tail)) &&
2795 (NULL != receiver->ss_tail))
2796 {
2797 // No secret purged. Delete oldest.
2798 secret_destroy (receiver->ss_tail);
2799 }
2800 }
2801 /* begin "BOX" encryption method, scan for ACKs from tail! */
2802 ss = receiver->ss_tail;
2803 while (NULL != ss)
2804 {
2805 size_t payload_len = sizeof(struct UDPBox) + receiver->d_mtu;
2807 "Considering SS %s sequence used: %u sequence allowed: %u bytes sent: %lu.\n",
2808 GNUNET_sh2s (&ss->master), ss->sequence_used,
2809 ss->sequence_allowed, ss->bytes_sent);
2810 if (ss->sequence_used >= ss->sequence_allowed)
2811 {
2812 // GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2813 // "Skipping ss because no acks to use.\n");
2814 ss = ss->prev;
2815 continue;
2816 }
2817 if (ss->bytes_sent >= rekey_max_bytes)
2818 {
2819 struct SharedSecret *ss_tmp;
2821 "Skipping ss because rekey bytes reached.\n");
2822 // FIXME cleanup ss with too many bytes sent!
2823 ss_tmp = ss->prev;
2824 secret_destroy (ss);
2825 ss = ss_tmp;
2826 continue;
2827 }
2828 if (ss->bytes_sent > rekey_max_bytes * 0.7)
2829 {
2830 if (ss->rekey_initiated == GNUNET_NO)
2831 {
2833 "Injecting rekey for ss with byte sent %lu\n",
2834 (unsigned long) ss->bytes_sent);
2835 create_rekey (receiver, ss, &rekey);
2837 payload_len += sizeof (rekey);
2839 }
2840 }
2841 if (0 < ss->sequence_used)
2843 "Trying to send UDPBox with shared secrect %s sequence_used %u and ss->sequence_allowed %u\n",
2844 GNUNET_sh2s (&ss->master),
2845 ss->sequence_used,
2846 ss->sequence_allowed);
2847 {
2848 char dgram[payload_len];
2849 struct UDPBox *box;
2850 gcry_cipher_hd_t out_cipher;
2851 size_t dpos;
2852
2853 box = (struct UDPBox *) dgram;
2854 ss->sequence_used++;
2855 get_kid (&ss->master, ss->sequence_used, &box->kid);
2856 setup_cipher (&ss->master, ss->sequence_used, &out_cipher);
2857 /* Append encrypted payload to dgram */
2858 dpos = sizeof(struct UDPBox);
2859 if (GNUNET_YES == inject_rekey)
2860 {
2862 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], sizeof (rekey),
2863 &rekey, sizeof (rekey)));
2864 dpos += sizeof (rekey);
2865 }
2867 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], msize, msg, msize));
2868 dpos += msize;
2869 do_pad (out_cipher, &dgram[dpos], sizeof(dgram) - dpos);
2870 GNUNET_assert (0 == gcry_cipher_gettag (out_cipher,
2871 box->gcm_tag,
2872 sizeof(box->gcm_tag)));
2873 gcry_cipher_close (out_cipher);
2874
2876 dgram,
2877 payload_len, // FIXME why always send sizeof dgram?
2878 receiver->address,
2879 receiver->address_len))
2880 {
2883 "Sending UDPBox to %s family %d failed sock %p failed\n",
2884 GNUNET_a2s (receiver->address,
2885 receiver->address_len),
2886 receiver->address->sa_family,
2889 return;
2890 }
2892 "Sending UDPBox with payload size %u, %u acks left, %lu bytes sent with socket %p\n",
2893 msize,
2894 receiver->acks_available,
2895 (unsigned long) ss->bytes_sent,
2897 ss->bytes_sent += sizeof (dgram);
2898 receiver->acks_available--;
2900 return;
2901 }
2902 }
2904 "No suitable ss found, sending as KX...\n");
2906}
static void inject_rekey(struct Queue *queue)
Inject a struct TCPRekey message into the queue's plaintext buffer.
static void create_rekey(struct ReceiverAddress *receiver, struct SharedSecret *ss, struct UDPRekey *rekey)

References SharedSecret::bytes_sent, create_rekey(), do_pad(), UDPBox::gcm_tag, get_kid(), get_socket(), GNUNET_a2s(), GNUNET_assert, GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_WARNING, GNUNET_log, GNUNET_log_strerror, GNUNET_MQ_impl_send_continue(), GNUNET_NETWORK_socket_sendto(), GNUNET_NO, GNUNET_sh2s(), GNUNET_YES, inject_rekey(), UDPBox::kid, SharedSecret::master, MAX_SECRETS, mq, msg, SharedSecret::prev, purge_secrets(), receiver(), receiver_destroy(), SharedSecret::rekey_initiated, rekey_max_bytes, reschedule_receiver_timeout(), secret_destroy(), send_msg_with_kx(), SharedSecret::sequence_allowed, SharedSecret::sequence_used, setup_cipher(), and GNUNET_MessageHeader::size.

Referenced by setup_receiver_mq().

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

◆ mq_destroy_d()

static void mq_destroy_d ( struct GNUNET_MQ_Handle mq,
void *  impl_state 
)
static

Signature of functions implementing the destruction of a message queue.

Implementations must not free mq, but should take care of impl_state.

Parameters
mqthe message queue to destroy
impl_stateour struct ReceiverAddress

Definition at line 2918 of file gnunet-communicator-udp.c.

2919{
2920 struct ReceiverAddress *receiver = impl_state;
2922 "Default MQ destroyed\n");
2923 if (mq == receiver->d_mq)
2924 {
2925 receiver->d_mq = NULL;
2926 if (GNUNET_YES != receiver->receiver_destroy_called)
2928 }
2929}

References GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_YES, mq, receiver(), and receiver_destroy().

Referenced by setup_receiver_mq().

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

◆ mq_destroy_kx()

static void mq_destroy_kx ( struct GNUNET_MQ_Handle mq,
void *  impl_state 
)
static

Signature of functions implementing the destruction of a message queue.

Implementations must not free mq, but should take care of impl_state.

Parameters
mqthe message queue to destroy
impl_stateour struct ReceiverAddress

Definition at line 2941 of file gnunet-communicator-udp.c.

2942{
2943 struct ReceiverAddress *receiver = impl_state;
2945 "KX MQ destroyed\n");
2946 if (mq == receiver->kx_mq)
2947 {
2948 receiver->kx_mq = NULL;
2949 if (GNUNET_YES != receiver->receiver_destroy_called)
2951 }
2952}

References GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_YES, mq, receiver(), and receiver_destroy().

Referenced by setup_receiver_mq().

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

◆ mq_cancel()

static void mq_cancel ( struct GNUNET_MQ_Handle mq,
void *  impl_state 
)
static

Implementation function that cancels the currently sent message.

Parameters
mqmessage queue
impl_stateour struct RecvierAddress

Definition at line 2962 of file gnunet-communicator-udp.c.

2963{
2964 /* Cancellation is impossible with UDP; bail */
2965 GNUNET_assert (0);
2966}

References GNUNET_assert.

Referenced by setup_receiver_mq().

Here is the caller graph for this function:

◆ mq_error()

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

Generic error handler, called with the appropriate error code and the same closure specified at the creation of the message queue.

Not every message queue implementation supports an error handler.

Parameters
clsour struct ReceiverAddress
errorerror code

Definition at line 2979 of file gnunet-communicator-udp.c.

2980{
2981 struct ReceiverAddress *receiver = cls;
2982
2984 "MQ error in queue to %s: %d\n",
2985 GNUNET_i2s (&receiver->target),
2986 (int) error);
2988}

References GNUNET_ERROR_TYPE_ERROR, GNUNET_i2s(), GNUNET_log, receiver(), and receiver_destroy().

Referenced by setup_receiver_mq().

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

◆ mq_init()

static int mq_init ( void *  cls,
const struct GNUNET_PeerIdentity peer,
const char *  address 
)
static

Function called by the transport service to initialize a message queue given address information about another peer.

If and when the communication channel is established, the communicator must call GNUNET_TRANSPORT_communicator_mq_add() to notify the service that the channel is now up. It is the responsibility of the communicator to manage sane retries and timeouts for any peer/address combination provided by the transport service. Timeouts and retries do not need to be signalled to the transport service.

Parameters
clsclosure
peeridentity of the other peer
addresswhere to send the message, human-readable communicator-specific format, 0-terminated, UTF-8
Returns
GNUNET_OK on success, GNUNET_SYSERR if the provided address is invalid

Definition at line 3080 of file gnunet-communicator-udp.c.

3081{
3082 (void) cls;
3084 "create receiver for mq_init\n");
3085 return create_receiver (peer,
3086 address,
3087 NULL);
3088}

References address, create_receiver(), GNUNET_ERROR_TYPE_DEBUG, and GNUNET_log.

Referenced by run().

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

◆ get_receiver_delete_it()

static int get_receiver_delete_it ( void *  cls,
const struct GNUNET_HashCode target,
void *  value 
)
static

Iterator over all receivers to clean up.

Parameters
clsNULL
targetunused
valuethe queue to destroy
Returns
GNUNET_OK to continue to iterate

Definition at line 3100 of file gnunet-communicator-udp.c.

3103{
3104 struct ReceiverAddress *receiver = value;
3105
3106 (void) cls;
3107 (void) target;
3109 return GNUNET_OK;
3110}
struct GNUNET_PeerIdentity target
To whom are we talking to.

References GNUNET_OK, receiver(), receiver_destroy(), ReceiverAddress::target, and value.

Referenced by do_shutdown().

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

◆ get_sender_delete_it()

static int get_sender_delete_it ( void *  cls,
const struct GNUNET_HashCode target,
void *  value 
)
static

Iterator over all senders to clean up.

Parameters
clsNULL
targetunused
valuethe queue to destroy
Returns
GNUNET_OK to continue to iterate

Definition at line 3122 of file gnunet-communicator-udp.c.

3125{
3126 struct SenderAddress *sender = value;
3127
3128 (void) cls;
3129 (void) target;
3130
3131
3132 sender_destroy (sender);
3133 return GNUNET_OK;
3134}

References GNUNET_OK, sender_destroy(), SenderAddress::target, and value.

Referenced by do_shutdown().

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

◆ do_shutdown()

static void do_shutdown ( void *  cls)
static

Shutdown the UNIX communicator.

Parameters
clsNULL (always)

Definition at line 3143 of file gnunet-communicator-udp.c.

3144{
3146 "do_shutdown\n");
3147 GNUNET_stop_burst (NULL);
3148 if (NULL != nat)
3149 {
3151 nat = NULL;
3152 }
3153 while (NULL != bi_head)
3155 if (NULL != broadcast_task)
3156 {
3158 broadcast_task = NULL;
3159 }
3160 if (NULL != timeout_task)
3161 {
3163 timeout_task = NULL;
3164 }
3165 if (NULL != read_v6_task)
3166 {
3168 read_v6_task = NULL;
3169 }
3170 if (NULL != read_v4_task)
3171 {
3173 read_v4_task = NULL;
3174 }
3175 if (NULL != default_v6_sock)
3176 {
3179 default_v6_sock = NULL;
3180 }
3181 if (NULL != default_v4_sock)
3182 {
3185 default_v4_sock = NULL;
3186 }
3189 NULL);
3193 NULL);
3198 if (NULL != timeout_task)
3199 {
3201 timeout_task = NULL;
3202 }
3203 if (NULL != ch)
3204 {
3206 ch = NULL;
3207 }
3208 if (NULL != ah)
3209 {
3211 ah = NULL;
3212 }
3213 if (NULL != stats)
3214 {
3216 stats = NULL;
3217 }
3218 if (NULL != my_private_key)
3219 {
3221 my_private_key = NULL;
3222 }
3223 if (NULL != is)
3224 {
3226 is = NULL;
3227 }
3229 "do_shutdown finished\n");
3230}
static int get_receiver_delete_it(void *cls, const struct GNUNET_HashCode *target, void *value)
Iterator over all receivers to clean up.
static struct GNUNET_SCHEDULER_Task * broadcast_task
ID of master broadcast task.
static int get_sender_delete_it(void *cls, const struct GNUNET_HashCode *target, void *value)
Iterator over all senders to clean up.
static struct GNUNET_NAT_Handle * nat
Connection to NAT service.
static void bi_destroy(struct BroadcastInterface *bi)
An interface went away, stop broadcasting on it.
void GNUNET_TRANSPORT_application_done(struct GNUNET_TRANSPORT_ApplicationHandle *ch)
Shutdown TRANSPORT application client.
void GNUNET_TRANSPORT_communicator_disconnect(struct GNUNET_TRANSPORT_CommunicatorHandle *ch)
Disconnect from the transport service.
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MultiHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
void GNUNET_CONTAINER_multishortmap_destroy(struct GNUNET_CONTAINER_MultiShortmap *map)
Destroy a hash map.
void GNUNET_CONTAINER_heap_destroy(struct GNUNET_CONTAINER_Heap *heap)
Destroys the heap.
void GNUNET_NAT_unregister(struct GNUNET_NAT_Handle *nh)
Stop port redirection and public IP address detection for the given handle.
Definition: nat_api.c:703
void GNUNET_NT_scanner_done(struct GNUNET_NT_InterfaceScanner *is)
Terminate interface scanner.
Definition: nt.c:428
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).

References ah, bi_destroy(), bi_head, broadcast_task, ch, default_v4_sock, default_v6_sock, get_receiver_delete_it(), get_sender_delete_it(), GNUNET_break, GNUNET_CONTAINER_heap_destroy(), GNUNET_CONTAINER_multihashmap_destroy(), GNUNET_CONTAINER_multihashmap_iterate(), GNUNET_CONTAINER_multishortmap_destroy(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_log, GNUNET_NAT_unregister(), GNUNET_NETWORK_socket_close(), GNUNET_NT_scanner_done(), GNUNET_OK, GNUNET_SCHEDULER_cancel(), GNUNET_STATISTICS_destroy(), GNUNET_stop_burst(), GNUNET_TRANSPORT_application_done(), GNUNET_TRANSPORT_communicator_disconnect(), GNUNET_YES, is, key_cache, my_private_key, nat, read_v4_task, read_v6_task, receivers, receivers_heap, senders, senders_heap, stats, and timeout_task.

Referenced by run().

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

◆ handle_ack_by_sender()

static int handle_ack_by_sender ( void *  cls,
const struct GNUNET_HashCode key,
void *  value 
)
static

Definition at line 3241 of file gnunet-communicator-udp.c.

3242{
3243 struct ReceiverAddress *receiver = value;
3244 struct AckInfo *ai = cls;
3245
3246 if (0 != GNUNET_memcmp (ai->sender, &receiver->target))
3247 {
3248 return GNUNET_YES;
3249 }
3250 handle_ack ((void*) ai->ack, key, receiver);
3251 return GNUNET_YES;
3252}
static struct GNUNET_TRANSPORT_AddressIdentifier * ai
Handle to the operation that publishes our address.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.

References ai, GNUNET_memcmp, GNUNET_YES, handle_ack(), key, receiver(), and value.

Referenced by enc_notify_cb().

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

◆ enc_notify_cb()

static void enc_notify_cb ( void *  cls,
const struct GNUNET_PeerIdentity sender,
const struct GNUNET_MessageHeader msg 
)
static

Function called when the transport service has received a backchannel message for this communicator (!) via a different return path.

Should be an acknowledgement.

Parameters
clsclosure, NULL
senderwhich peer sent the notification
msgpayload

Definition at line 3265 of file gnunet-communicator-udp.c.

3268{
3269 struct AckInfo ai;
3270
3271 (void) cls;
3273 "Storing UDPAck received from backchannel from %s\n",
3276 (ntohs (msg->size) != sizeof(struct UDPAck)))
3277 {
3278 GNUNET_break_op (0);
3279 return;
3280 }
3281 ai.ack = (const struct UDPAck *) msg;
3282 ai.sender = sender;
3285 &ai);
3286}
static int handle_ack_by_sender(void *cls, const struct GNUNET_HashCode *key, void *value)
const struct GNUNET_PeerIdentity * sender

References ai, GNUNET_break_op, GNUNET_CONTAINER_multihashmap_iterate(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s_full(), GNUNET_log, GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK, handle_ack_by_sender(), msg, receivers, AckInfo::sender, GNUNET_MessageHeader::size, and GNUNET_MessageHeader::type.

Referenced by run().

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

◆ nat_address_cb()

static void nat_address_cb ( void *  cls,
void **  app_ctx,
int  add_remove,
enum GNUNET_NAT_AddressClass  ac,
const struct sockaddr *  addr,
socklen_t  addrlen 
)
static

Signature of the callback passed to GNUNET_NAT_register() for a function to call whenever our set of 'valid' addresses changes.

Parameters
clsclosure
app_ctx[in,out]location where the app can store stuff on add and retrieve it on remove
add_removeGNUNET_YES to add a new public IP address, GNUNET_NO to remove a previous (now invalid) one
acaddress class the address belongs to
addreither the previous or the new public IP address
addrlenactual length of the addr

Definition at line 3303 of file gnunet-communicator-udp.c.

3309{
3310 char *my_addr;
3312
3313 if (GNUNET_YES == add_remove)
3314 {
3316
3317 GNUNET_asprintf (&my_addr,
3318 "%s-%s",
3320 GNUNET_a2s (addr, addrlen));
3321 nt = GNUNET_NT_scanner_get_type (is, addr, addrlen);
3322 ai =
3324 my_addr,
3325 nt,
3327 GNUNET_free (my_addr);
3328 *app_ctx = ai;
3329 }
3330 else
3331 {
3332 ai = *app_ctx;
3334 *app_ctx = NULL;
3335 }
3336}
void GNUNET_TRANSPORT_communicator_address_remove(struct GNUNET_TRANSPORT_AddressIdentifier *ai)
Notify transport service about an address that this communicator no longer provides for this peer.
struct GNUNET_TRANSPORT_AddressIdentifier * GNUNET_TRANSPORT_communicator_address_add(struct GNUNET_TRANSPORT_CommunicatorHandle *ch, const char *address, enum GNUNET_NetworkType nt, struct GNUNET_TIME_Relative expiration)
Notify transport service about an address that this communicator provides for this peer.
Internal representation of an address a communicator is currently providing for the transport service...

References ai, ch, COMMUNICATOR_ADDRESS_PREFIX, GNUNET_a2s(), GNUNET_asprintf(), GNUNET_free, GNUNET_NT_scanner_get_type(), GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_TRANSPORT_communicator_address_add(), GNUNET_TRANSPORT_communicator_address_remove(), GNUNET_YES, is, and nt.

Referenced by run().

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

◆ ifc_broadcast()

static void ifc_broadcast ( void *  cls)
static

Broadcast our presence on one of our interfaces.

Parameters
clsa struct BroadcastInterface

Definition at line 3345 of file gnunet-communicator-udp.c.

3346{
3347 struct BroadcastInterface *bi = cls;
3348 struct GNUNET_TIME_Relative delay;
3349
3350 delay = BROADCAST_FREQUENCY;
3351 delay.rel_value_us =
3353 bi->broadcast_task =
3355
3356 switch (bi->sa->sa_family)
3357 {
3358 case AF_INET: {
3359 static int yes = 1;
3360 static int no = 0;
3361 ssize_t sent;
3362
3363 if (GNUNET_OK !=
3365 SOL_SOCKET,
3366 SO_BROADCAST,
3367 &yes,
3368 sizeof(int)))
3370 "setsockopt");
3372 "creating UDPBroadcast from %s\n",
3373 GNUNET_i2s (&(bi->bcm.sender)));
3375 "sending UDPBroadcast to add %s\n",
3376 GNUNET_a2s (bi->ba, bi->salen));
3378 &bi->bcm,
3379 sizeof(bi->bcm),
3380 bi->ba,
3381 bi->salen);
3382 if (-1 == sent)
3384 "sendto");
3386 SOL_SOCKET,
3387 SO_BROADCAST,
3388 &no,
3389 sizeof(int)))
3391 "setsockopt");
3392 break;
3393 }
3394
3395 case AF_INET6: {
3396 ssize_t sent;
3397 struct sockaddr_in6 dst;
3398
3399 dst.sin6_family = AF_INET6;
3400 dst.sin6_port = htons (my_port);
3401 dst.sin6_addr = bi->mcreq.ipv6mr_multiaddr;
3402 dst.sin6_scope_id = ((struct sockaddr_in6 *) bi->ba)->sin6_scope_id;
3403
3405 "sending UDPBroadcast\n");
3407 &bi->bcm,
3408 sizeof(bi->bcm),
3409 (const struct sockaddr *) &dst,
3410 sizeof(dst));
3411 if (-1 == sent)
3413 break;
3414 }
3415
3416 default:
3417 GNUNET_break (0);
3418 break;
3419 }
3420}
static uint16_t my_port
Port number to which we are actually bound.
static void ifc_broadcast(void *cls)
Broadcast our presence on one of our interfaces.
#define BROADCAST_FREQUENCY
How often do we broadcast our presence on the LAN?
uint64_t GNUNET_CRYPTO_random_u64(enum GNUNET_CRYPTO_Quality mode, uint64_t max)
Generate a random unsigned 64-bit value.
Interface we broadcast our presence on.
socklen_t salen
Number of bytes in sa.
struct UDPBroadcast bcm
Message we broadcast on this interface.

References BroadcastInterface::ba, BroadcastInterface::bcm, BROADCAST_FREQUENCY, BroadcastInterface::broadcast_task, default_v4_sock, default_v6_sock, GNUNET_a2s(), GNUNET_break, GNUNET_CRYPTO_QUALITY_WEAK, GNUNET_CRYPTO_random_u64(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, GNUNET_i2s(), GNUNET_log, GNUNET_log_strerror, GNUNET_NETWORK_socket_sendto(), GNUNET_NETWORK_socket_setsockopt(), GNUNET_OK, GNUNET_SCHEDULER_add_delayed(), ifc_broadcast(), BroadcastInterface::mcreq, my_port, GNUNET_TIME_Relative::rel_value_us, BroadcastInterface::sa, BroadcastInterface::salen, and UDPBroadcast::sender.

Referenced by iface_proc(), and ifc_broadcast().

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

◆ iface_proc()

static int iface_proc ( void *  cls,
const char *  name,
int  isDefault,
const struct sockaddr *  addr,
const struct sockaddr *  broadcast_addr,
const struct sockaddr *  netmask,
socklen_t  addrlen 
)
static

Callback function invoked for each interface found.

Activates/deactivates broadcast interfaces.

Parameters
clsNULL
namename of the interface (can be NULL for unknown)
isDefaultis this presumably the default interface
addraddress of this interface (can be NULL for unknown or unassigned)
broadcast_addrthe broadcast address (can be NULL for unknown or unassigned)
netmaskthe network mask (can be NULL for unknown or unassigned)
addrlenlength of the address
Returns
GNUNET_OK to continue iteration, GNUNET_SYSERR to abort

Definition at line 3438 of file gnunet-communicator-udp.c.

3445{
3446 struct BroadcastInterface *bi;
3447 enum GNUNET_NetworkType network;
3448 struct UdpBroadcastSignature ubs;
3449
3450 (void) cls;
3451 (void) netmask;
3452 if (NULL == addr)
3453 return GNUNET_YES; /* need to know our address! */
3454 network = GNUNET_NT_scanner_get_type (is, addr, addrlen);
3455 if (GNUNET_NT_LOOPBACK == network)
3456 {
3457 /* Broadcasting on loopback does not make sense */
3458 return GNUNET_YES;
3459 }
3460 for (bi = bi_head; NULL != bi; bi = bi->next)
3461 {
3462 if ((bi->salen == addrlen) && (0 == memcmp (addr, bi->sa, addrlen)))
3463 {
3464 bi->found = GNUNET_YES;
3465 return GNUNET_OK;
3466 }
3467 }
3468
3469 if ((AF_INET6 == addr->sa_family) && (NULL == broadcast_addr))
3470 return GNUNET_OK; /* broadcast_addr is required for IPv6! */
3471 if ((AF_INET6 == addr->sa_family) && (NULL != default_v6_sock))
3472 return GNUNET_OK; /* not using IPv6 */
3473
3474 bi = GNUNET_new (struct BroadcastInterface);
3475 bi->sa = GNUNET_memdup (addr,
3476 addrlen);
3477 if ( (NULL != broadcast_addr) &&
3478 (addrlen == sizeof (struct sockaddr_in)) )
3479 {
3480 struct sockaddr_in *ba;
3481
3482 ba = GNUNET_memdup (broadcast_addr,
3483 addrlen);
3484 ba->sin_port = htons (2086); /* always GNUnet port, ignore configuration! */
3485 bi->ba = (struct sockaddr *) ba;
3486 }
3487 bi->salen = addrlen;
3488 bi->found = GNUNET_YES;
3489 bi->bcm.sender = my_identity;
3490 ubs.purpose.purpose = htonl (
3492 ubs.purpose.size = htonl (sizeof(ubs));
3493 ubs.sender = my_identity;
3495 "creating UDPBroadcastSignature for %s\n",
3496 GNUNET_a2s (addr, addrlen));
3497 GNUNET_CRYPTO_hash (addr, addrlen, &ubs.h_address);
3499 &ubs,
3500 &bi->bcm.sender_sig);
3501 if (NULL != bi->ba)
3502 {
3505 }
3506 if ((AF_INET6 == addr->sa_family) && (NULL != broadcast_addr))
3507 {
3508 /* Create IPv6 multicast request */
3509 const struct sockaddr_in6 *s6 =
3510 (const struct sockaddr_in6 *) broadcast_addr;
3511
3513 1 == inet_pton (AF_INET6, "FF05::13B", &bi->mcreq.ipv6mr_multiaddr));
3514
3515 /* http://tools.ietf.org/html/rfc2553#section-5.2:
3516 *
3517 * IPV6_JOIN_GROUP
3518 *
3519 * Join a multicast group on a specified local interface. If the
3520 * interface index is specified as 0, the kernel chooses the local
3521 * interface. For example, some kernels look up the multicast
3522 * group in the normal IPv6 routing table and using the resulting
3523 * interface; we do this for each interface, so no need to use
3524 * zero (anymore...).
3525 */
3526 bi->mcreq.ipv6mr_interface = s6->sin6_scope_id;
3527
3528 /* Join the multicast group */
3530 IPPROTO_IPV6,
3531 IPV6_JOIN_GROUP,
3532 &bi->mcreq,
3533 sizeof(bi->mcreq)))
3534 {
3536 }
3537 }
3538 return GNUNET_OK;
3539}
@ GNUNET_NT_LOOPBACK
Loopback (same host).
Definition: gnunet_nt_lib.h:53
struct BroadcastInterface * next
Kept in a DLL.
int found
Was this interface found in the last iface_proc() scan?

References BroadcastInterface::ba, BroadcastInterface::bcm, bi_head, bi_tail, BroadcastInterface::broadcast_task, default_v6_sock, BroadcastInterface::found, GNUNET_a2s(), GNUNET_assert, GNUNET_CONTAINER_DLL_insert, GNUNET_CRYPTO_eddsa_sign, GNUNET_CRYPTO_hash(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, GNUNET_log, GNUNET_log_strerror, GNUNET_memdup, GNUNET_NETWORK_socket_setsockopt(), GNUNET_new, GNUNET_NT_LOOPBACK, GNUNET_NT_scanner_get_type(), GNUNET_OK, GNUNET_SCHEDULER_add_now(), GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_BROADCAST, GNUNET_YES, UdpBroadcastSignature::h_address, ifc_broadcast(), is, BroadcastInterface::mcreq, my_identity, my_private_key, BroadcastInterface::next, GNUNET_CRYPTO_EccSignaturePurpose::purpose, UdpBroadcastSignature::purpose, BroadcastInterface::sa, BroadcastInterface::salen, UdpBroadcastSignature::sender, UDPBroadcast::sender, UDPBroadcast::sender_sig, and GNUNET_CRYPTO_EccSignaturePurpose::size.

Referenced by do_broadcast().

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

◆ do_broadcast()

static void do_broadcast ( void *  cls)
static

Scan interfaces to broadcast our presence on the LAN.

Parameters
clsNULL, unused

Definition at line 3548 of file gnunet-communicator-udp.c.

3549{
3550 struct BroadcastInterface *bin;
3551
3552 (void) cls;
3553 for (struct BroadcastInterface *bi = bi_head; NULL != bi; bi = bi->next)
3554 bi->found = GNUNET_NO;
3556 for (struct BroadcastInterface *bi = bi_head; NULL != bi; bi = bin)
3557 {
3558 bin = bi->next;
3559 if (GNUNET_NO == bi->found)
3560 bi_destroy (bi);
3561 }
3563 &do_broadcast,
3564 NULL);
3565}
static void do_broadcast(void *cls)
Scan interfaces to broadcast our presence on the LAN.
#define INTERFACE_SCAN_FREQUENCY
How often do we scan for changes to our network interfaces?
static int iface_proc(void *cls, const char *name, int isDefault, const struct sockaddr *addr, const struct sockaddr *broadcast_addr, const struct sockaddr *netmask, socklen_t addrlen)
Callback function invoked for each interface found.
void GNUNET_OS_network_interfaces_list(GNUNET_OS_NetworkInterfaceProcessor proc, void *proc_cls)
Enumerate all network interfaces.
Definition: os_network.c:397

References bi_destroy(), bi_head, broadcast_task, do_broadcast(), BroadcastInterface::found, GNUNET_NO, GNUNET_OS_network_interfaces_list(), GNUNET_SCHEDULER_add_delayed(), iface_proc(), INTERFACE_SCAN_FREQUENCY, and BroadcastInterface::next.

Referenced by do_broadcast(), and run().

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

◆ try_connection_reversal()

static void try_connection_reversal ( void *  cls,
const struct sockaddr *  addr,
socklen_t  addrlen 
)
static

Definition at line 3569 of file gnunet-communicator-udp.c.

3572{
3573 /* FIXME: support reversal: #5529 */
3575 "No connection reversal implemented!\n");
3576}
@ GNUNET_ERROR_TYPE_INFO

References GNUNET_ERROR_TYPE_INFO, and GNUNET_log.

Referenced by run().

Here is the caller graph for this function:

◆ udp_socket_notify()

static void udp_socket_notify ( struct GNUNET_UdpSocketInfo sock_info)
static

Definition at line 3580 of file gnunet-communicator-udp.c.

3581{
3583 sizeof (*sock_info->actual_address
3584 ));
3585 create_receiver (sock_info->pid,
3586 address,
3587 default_v4_sock == sock_info->udp_sock ||
3588 default_v6_sock == sock_info->udp_sock ?
3589 NULL : sock_info->udp_sock);
3591 GNUNET_free (sock_info);
3592}
struct sockaddr * actual_address
The address of the other peer we received a burst message from.
struct GNUNET_NETWORK_Handle * udp_sock
struct GNUNET_PeerIdentity * pid
The peer we like to connect to.

References GNUNET_UdpSocketInfo::actual_address, address, ch, create_receiver(), default_v4_sock, default_v6_sock, GNUNET_free, GNUNET_TRANSPORT_communicator_burst_finished(), GNUNET_UdpSocketInfo::pid, sockaddr_to_udpaddr_string(), and GNUNET_UdpSocketInfo::udp_sock.

Referenced by start_burst().

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

◆ start_burst()

static void start_burst ( const char *  addr,
struct GNUNET_TIME_Relative  rtt,
struct GNUNET_PeerIdentity pid 
)
static

Definition at line 3596 of file gnunet-communicator-udp.c.

3599{
3600 struct GNUNET_UdpSocketInfo *sock_info;
3601
3603 "Communicator was called to start burst to address %s from %s\n",
3604 addr,
3605 my_ipv4);
3606
3607 GNUNET_stop_burst (NULL);
3608
3609 sock_info = GNUNET_new (struct GNUNET_UdpSocketInfo);
3610 sock_info->pid = GNUNET_new (struct GNUNET_PeerIdentity);
3611 sock_info->address = GNUNET_strdup (addr);
3612 sock_info->bind_address = my_ipv4;
3613 sock_info->has_port = GNUNET_YES;
3614 sock_info->udp_sock = default_v4_sock;
3615 sock_info->rtt = rtt;
3616 GNUNET_memcpy (sock_info->pid, pid, sizeof (struct GNUNET_PeerIdentity));
3617 sock_info->std_port = my_port;
3619 "1 sock addr %s addr %s rtt %lu %u\n",
3620 sock_info->address,
3621 addr,
3622 (unsigned long) sock_info->rtt.rel_value_us,
3623 my_port);
3624 burst_task = GNUNET_get_udp_socket (sock_info,
3626 GNUNET_free (sock_info);
3627}
static void udp_socket_notify(struct GNUNET_UdpSocketInfo *sock_info)
char * my_ipv4
Our ipv4 address.
static struct GNUNET_SCHEDULER_Task * burst_task
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
struct GNUNET_SCHEDULER_Task * GNUNET_get_udp_socket(struct GNUNET_UdpSocketInfo *sock_info, GNUNET_NotifyUdpSocket nus)
Method to get a UDP socket for a peer that is natted.
Definition: nat.c:509
uint64_t rel_value_us
The actual value.
Struct with the socket we like to use to send messages to another peer.
const char * bind_address
Our address without port.
enum GNUNET_GenericReturnValue has_port
Flag indicating, if the address is without port information.
struct GNUNET_TIME_Relative rtt
The actual RTT between the peers.
char * address
The address of the other peer without port.
unsigned int std_port
Default local port we are bound to.

References GNUNET_UdpSocketInfo::address, GNUNET_UdpSocketInfo::bind_address, burst_task, default_v4_sock, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_get_udp_socket(), GNUNET_log, GNUNET_memcpy, GNUNET_new, GNUNET_stop_burst(), GNUNET_strdup, GNUNET_YES, GNUNET_UdpSocketInfo::has_port, my_ipv4, my_port, GNUNET_UdpSocketInfo::pid, pid, GNUNET_TIME_Relative::rel_value_us, GNUNET_UdpSocketInfo::rtt, GNUNET_UdpSocketInfo::std_port, GNUNET_UdpSocketInfo::udp_sock, and udp_socket_notify().

Referenced by reconnect(), and run().

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

◆ create_udp_socket()

static struct GNUNET_NETWORK_Handle * create_udp_socket ( const char *  bindto,
sa_family_t  family,
struct sockaddr **  out,
socklen_t *  out_len 
)
static

Definition at line 3631 of file gnunet-communicator-udp.c.

3635{
3636 struct GNUNET_NETWORK_Handle *sock;
3637 struct sockaddr *in;
3638 socklen_t in_len;
3639 struct sockaddr_storage in_sto;
3640 socklen_t sto_len;
3641
3642 in = udp_address_to_sockaddr (bindto, family, &in_len);
3643 if (NULL == in)
3644 {
3646 "Failed to setup UDP socket address with path `%s'\n",
3647 bindto);
3648 return NULL;
3649 }
3650
3651 if ((AF_UNSPEC != family) && (in->sa_family != family))
3652 {
3654 "Invalid UDP socket address setup with path `%s'\n",
3655 bindto);
3656 GNUNET_free (in);
3657 return NULL;
3658 }
3659
3660 sock =
3661 GNUNET_NETWORK_socket_create (in->sa_family,
3662 SOCK_DGRAM,
3663 IPPROTO_UDP);
3664 if (NULL == sock)
3665 {
3668 "Failed to create socket for %s family %d\n",
3669 GNUNET_a2s (in,
3670 in_len),
3671 in->sa_family);
3672 GNUNET_free (in);
3673 return NULL;
3674 }
3675 if (GNUNET_OK !=
3677 in,
3678 in_len))
3679 {
3681 "bind",
3682 bindto);
3684 "Failed to bind socket for %s family %d sock %p\n",
3685 GNUNET_a2s (in,
3686 in_len),
3687 in->sa_family,
3688 sock);
3690 sock = NULL;
3691 GNUNET_free (in);
3692 return NULL;
3693 }
3694
3695 /* We might have bound to port 0, allowing the OS to figure it out;
3696 thus, get the real IN-address from the socket */
3697 sto_len = sizeof(in_sto);
3698 if (0 != getsockname (GNUNET_NETWORK_get_fd (sock),
3699 (struct sockaddr *) &in_sto,
3700 &sto_len))
3701 {
3702 memcpy (&in_sto, in, in_len);
3703 sto_len = in_len;
3704 }
3705 GNUNET_free (in);
3706 *out = GNUNET_malloc (sto_len);
3707 memcpy (*out, (struct sockaddr *) &in_sto, sto_len);
3708 *out_len = sto_len;
3709 return sock;
3710}
#define GNUNET_log_strerror_file(level, cmd, filename)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
int GNUNET_NETWORK_get_fd(const struct GNUNET_NETWORK_Handle *desc)
Return file descriptor for this network handle.
Definition: network.c:1001
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition: network.c:833
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_bind(struct GNUNET_NETWORK_Handle *desc, const struct sockaddr *address, socklen_t address_len)
Bind a socket to a particular address.
Definition: network.c:439

References GNUNET_a2s(), GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_log, GNUNET_log_strerror, GNUNET_log_strerror_file, GNUNET_malloc, GNUNET_NETWORK_get_fd(), GNUNET_NETWORK_socket_bind(), GNUNET_NETWORK_socket_close(), GNUNET_NETWORK_socket_create(), GNUNET_OK, and udp_address_to_sockaddr().

Referenced by run().

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

◆ shutdown_run()

static void shutdown_run ( struct sockaddr *  addrs[2])
static

Definition at line 3714 of file gnunet-communicator-udp.c.

3715{
3716 if (NULL != addrs[0])
3717 GNUNET_free (addrs[0]);
3718 if (NULL != addrs[1])
3719 GNUNET_free (addrs[1]);
3721}
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:566

References GNUNET_free, and GNUNET_SCHEDULER_shutdown().

Referenced by run().

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

◆ run()

static void run ( void *  cls,
char *const *  args,
const char *  cfgfile,
const struct GNUNET_CONFIGURATION_Handle c 
)
static

Definition at line 3725 of file gnunet-communicator-udp.c.

3729{
3730 const struct sockaddr_in *v4;
3731 char *bindto;
3732 char *bindto6;
3733 struct sockaddr *in[2];
3734 socklen_t in_len[2];
3735
3737 "Entering the run method of udp communicator.\n");
3738
3739 cfg = c;
3741 if ((GNUNET_NO == GNUNET_NETWORK_test_pf (PF_INET6)) ||
3742 (GNUNET_YES ==
3745 "DISABLE_V6")))
3746 {
3748 }
3749
3750 if (GNUNET_OK !=
3753 "BINDTO",
3754 &bindto))
3755 {
3758 "BINDTO");
3759 return;
3760 }
3762 "The udp communicator will bind to %s for IPv4\n",
3763 bindto);
3764 if (GNUNET_YES != disable_v6)
3765 {
3766 if (GNUNET_OK !=
3769 "BINDTO6",
3770 &bindto6))
3771 {
3774 "BINDTO6");
3775 return;
3776 }
3777
3779 "The udp communicator will bind to %s for IPv6\n",
3780 bindto6);
3781 }
3782 else
3783 bindto6 = NULL;
3784 if (GNUNET_OK !=
3787 "REKEY_INTERVAL",
3790
3791 if (GNUNET_OK !=
3794 "REKEY_MAX_BYTES",
3796 {
3798 }
3799
3800 memset (in, 0, sizeof(struct sockaddr*) * 2);
3801 memset (in_len, 0, sizeof(socklen_t) * 2);
3802
3803 GNUNET_assert (bindto);
3805 bindto, AF_INET, &(in[0]), &(in_len[0]));
3806 GNUNET_free (bindto);
3807
3808 if (GNUNET_YES != disable_v6)
3809 {
3810 GNUNET_assert (bindto6);
3812 bindto6, AF_INET6, &(in[1]), &(in_len[1]));
3813 GNUNET_free (bindto6);
3814 }
3815 else
3816 default_v6_sock = NULL;
3817
3818 if ((NULL == default_v4_sock) && (NULL == default_v6_sock))
3819 return;
3820
3821 my_port = 0;
3822 if (NULL != default_v4_sock)
3823 {
3824 GNUNET_assert (in[0]);
3826 "transport",
3827 "Bound to `%s' sock %p\n",
3828 GNUNET_a2s ((const struct sockaddr *) in[0],
3829 in_len[0]),
3831
3832 v4 = (const struct sockaddr_in *) in[0];
3833
3834 my_ipv4 = GNUNET_malloc (INET_ADDRSTRLEN);
3835 my_port = ntohs (((struct sockaddr_in *) in[0])->sin_port);
3836 inet_ntop (AF_INET, &v4->sin_addr, my_ipv4, in_len[0]);
3837 }
3838 if (NULL != default_v6_sock)
3839 {
3840 GNUNET_assert (in[1]);
3842 "transport",
3843 "Bound to `%s' sock %p\n",
3844 GNUNET_a2s ((const struct sockaddr *) in[1],
3845 in_len[1]),
3847 my_port = ntohs (((struct sockaddr_in6 *) in[1])->sin6_port);
3848 }
3849 stats = GNUNET_STATISTICS_create ("communicator-udp", cfg);
3859 if (NULL == my_private_key)
3860 {
3861 GNUNET_log (
3863 _ (
3864 "Transport service is lacking key configuration settings. Exiting.\n"));
3865 shutdown_run (in);
3866 return;
3867 }
3870 /* start reading */
3871 if (NULL != default_v4_sock)
3874 &sock_read,
3876 else
3877 read_v4_task = NULL;
3878 if (NULL != default_v6_sock)
3881 &sock_read,
3883 else
3884 read_v6_task = NULL;
3889 &mq_init,
3890 NULL,
3892 NULL,
3893 &start_burst);
3894 if (NULL == ch)
3895 {
3896 GNUNET_break (0);
3897 shutdown_run (in);
3898 return;
3899 }
3901 if (NULL == ah)
3902 {
3903 GNUNET_break (0);
3904 shutdown_run (in);
3905 return;
3906 }
3907 /* start broadcasting */
3908 if (GNUNET_YES !=
3911 "DISABLE_BROADCAST"))
3912 {
3914 }
3915
3918 IPPROTO_UDP,
3919 (NULL != in[0]? 1 : 0)
3920 + (NULL != in[1]? 1 : 0),
3921 (const struct sockaddr**)
3922 (NULL != in[0]? in : &(in[1])),
3923 NULL != in[0]? in_len : &(in_len[1]),
3926 NULL /* closure */);
3927 if (NULL != in[0])
3928 GNUNET_free (in[0]);
3929 if (NULL != in[1])
3930 GNUNET_free (in[1]);
3931}
#define DEFAULT_REKEY_TIME_INTERVAL
How often do we rekey based on time (at least)
static struct GNUNET_NETWORK_Handle * create_udp_socket(const char *bindto, sa_family_t family, struct sockaddr **out, socklen_t *out_len)
static void eddsa_priv_to_hpke_key(struct GNUNET_CRYPTO_EddsaPrivateKey *edpk, struct GNUNET_CRYPTO_EcdhePrivateKey *pk)
static void try_connection_reversal(void *cls, const struct sockaddr *addr, socklen_t addrlen)
static void enc_notify_cb(void *cls, const struct GNUNET_PeerIdentity *sender, const struct GNUNET_MessageHeader *msg)
Function called when the transport service has received a backchannel message for this communicator (...
static struct GNUNET_TIME_Relative rekey_interval
The rekey interval.
static void start_burst(const char *addr, struct GNUNET_TIME_Relative rtt, struct GNUNET_PeerIdentity *pid)
static void do_shutdown(void *cls)
Shutdown the UNIX communicator.
#define COMMUNICATOR_CONFIG_SECTION
Configuration section used by the communicator.
static void nat_address_cb(void *cls, void **app_ctx, int add_remove, enum GNUNET_NAT_AddressClass ac, const struct sockaddr *addr, socklen_t addrlen)
Signature of the callback passed to GNUNET_NAT_register() for a function to call whenever our set of ...
#define DEFAULT_REKEY_MAX_BYTES
Default value for how often we do rekey based on number of bytes transmitted? (additionally randomize...
static void shutdown_run(struct sockaddr *addrs[2])
static int mq_init(void *cls, const struct GNUNET_PeerIdentity *peer, const char *address)
Function called by the transport service to initialize a message queue given address information abou...
struct GNUNET_TRANSPORT_ApplicationHandle * GNUNET_TRANSPORT_application_init(const struct GNUNET_CONFIGURATION_Handle *cfg)
Initialize the TRANSPORT application client handle.
struct GNUNET_TRANSPORT_CommunicatorHandle * GNUNET_TRANSPORT_communicator_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *config_section_name, const char *addr_prefix, enum GNUNET_TRANSPORT_CommunicatorCharacteristics cc, GNUNET_TRANSPORT_CommunicatorMqInit mq_init, void *mq_init_cls, GNUNET_TRANSPORT_CommunicatorNotify notify_cb, void *notify_cb_cls, GNUNET_TRANSPORT_StartBurstNotify sb)
Connect to the transport service.
@ GNUNET_TRANSPORT_CC_UNRELIABLE
Transmission is unreliable (e.g.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_size(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *size)
Get a configuration value that should be a size in bytes.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_yesno(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Get a configuration value that should be in a set of "YES" or "NO".
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_time(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, struct GNUNET_TIME_Relative *time)
Get a configuration value that should be a relative time.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
void GNUNET_CRYPTO_eddsa_key_get_public(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Extract the public key for the given private key.
Definition: crypto_ecc.c:201
struct GNUNET_CRYPTO_EddsaPrivateKey * GNUNET_CRYPTO_eddsa_key_create_from_configuration(const struct GNUNET_CONFIGURATION_Handle *cfg)
Create a new private key by reading our peer's key from the file specified in the configuration.
struct GNUNET_CONTAINER_MultiShortmap * GNUNET_CONTAINER_multishortmap_create(unsigned int len, int do_not_copy_keys)
Create a multi peer map (hash map for public keys of peers).
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
struct GNUNET_CONTAINER_Heap * GNUNET_CONTAINER_heap_create(enum GNUNET_CONTAINER_HeapOrder order)
Create a new heap.
@ GNUNET_CONTAINER_HEAP_ORDER_MIN
Heap with the minimum cost at the root.
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
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.
struct GNUNET_NAT_Handle * GNUNET_NAT_register(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *config_section, uint8_t proto, unsigned int num_addrs, const struct sockaddr **addrs, const socklen_t *addrlens, GNUNET_NAT_AddressCallback address_callback, GNUNET_NAT_ReversalCallback reversal_callback, void *callback_cls)
Attempt to enable port redirection and detect public IP address contacting UPnP or NAT-PMP routers on...
Definition: nat_api.c:366
enum GNUNET_GenericReturnValue GNUNET_NETWORK_test_pf(int pf)
Test if the given protocol family is supported by this system.
Definition: network.c:79
struct GNUNET_NT_InterfaceScanner * GNUNET_NT_scanner_init(void)
Initialize the address characterization client handle.
Definition: nt.c:407
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received,...
Definition: scheduler.c:1338
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
#define _(String)
GNU gettext support macro.
Definition: platform.h:178

References _, ah, broadcast_task, cfg, ch, COMMUNICATOR_ADDRESS_PREFIX, COMMUNICATOR_CONFIG_SECTION, create_udp_socket(), DEFAULT_REKEY_MAX_BYTES, DEFAULT_REKEY_TIME_INTERVAL, default_v4_sock, default_v6_sock, disable_v6, do_broadcast(), do_shutdown(), eddsa_priv_to_hpke_key(), enc_notify_cb(), GNUNET_a2s(), GNUNET_assert, GNUNET_break, GNUNET_CONFIGURATION_get_value_size(), GNUNET_CONFIGURATION_get_value_string(), GNUNET_CONFIGURATION_get_value_time(), GNUNET_CONFIGURATION_get_value_yesno(), GNUNET_CONTAINER_heap_create(), GNUNET_CONTAINER_HEAP_ORDER_MIN, GNUNET_CONTAINER_multihashmap_create(), GNUNET_CONTAINER_multishortmap_create(), GNUNET_CRYPTO_eddsa_key_create_from_configuration(), GNUNET_CRYPTO_eddsa_key_get_public(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_INFO, GNUNET_free, GNUNET_log, GNUNET_log_config_missing(), GNUNET_log_from_nocheck(), GNUNET_malloc, GNUNET_NAT_register(), GNUNET_NETWORK_test_pf(), GNUNET_NO, GNUNET_NT_scanner_init(), GNUNET_OK, GNUNET_SCHEDULER_add_now(), GNUNET_SCHEDULER_add_read_net(), GNUNET_SCHEDULER_add_shutdown(), GNUNET_STATISTICS_create(), GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_TRANSPORT_application_init(), GNUNET_TRANSPORT_CC_UNRELIABLE, GNUNET_TRANSPORT_communicator_connect(), GNUNET_YES, is, key_cache, mq_init(), my_identity, my_ipv4, my_port, my_private_key, my_x25519_private_key, nat, nat_address_cb(), GNUNET_PeerIdentity::public_key, read_v4_task, read_v6_task, receivers, receivers_heap, rekey_interval, rekey_max_bytes, senders, senders_heap, shutdown_run(), sock_read(), start_burst(), stats, and try_connection_reversal().

Here is the call graph for this function:

Variable Documentation

◆ rekey_interval

struct GNUNET_TIME_Relative rekey_interval
static

The rekey interval.

Definition at line 757 of file gnunet-communicator-udp.c.

Referenced by run().

◆ rekey_max_bytes

unsigned long long rekey_max_bytes
static

How often we do rekey based on number of bytes transmitted.

Definition at line 762 of file gnunet-communicator-udp.c.

Referenced by decrypt_box(), mq_send_d(), and run().

◆ key_cache

struct GNUNET_CONTAINER_MultiShortmap* key_cache
static

Cache of pre-generated key IDs.

Definition at line 767 of file gnunet-communicator-udp.c.

Referenced by do_shutdown(), kce_destroy(), kce_generate(), run(), secret_destroy(), and sock_read().

◆ read_v4_task

struct GNUNET_SCHEDULER_Task* read_v4_task
static

ID of read IPv4 task.

Definition at line 772 of file gnunet-communicator-udp.c.

Referenced by do_shutdown(), run(), and sock_read().

◆ read_v6_task

struct GNUNET_SCHEDULER_Task* read_v6_task
static

ID of read IPv6 task.

Definition at line 777 of file gnunet-communicator-udp.c.

Referenced by do_shutdown(), run(), and sock_read().

◆ timeout_task

struct GNUNET_SCHEDULER_Task* timeout_task
static

ID of timeout task.

Definition at line 782 of file gnunet-communicator-udp.c.

Referenced by check_timeouts(), create_receiver(), do_shutdown(), and setup_sender().

◆ broadcast_task

struct GNUNET_SCHEDULER_Task* broadcast_task
static

ID of master broadcast task.

Definition at line 787 of file gnunet-communicator-udp.c.

Referenced by do_broadcast(), do_shutdown(), and run().

◆ stats

◆ ch