GNUnet 0.21.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 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_HashCode *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_HashCode *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_HashCode *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_EcdhePublicKey *ephemeral)
 Setup shared secret for decryption. More...
 
static struct SharedSecretsetup_initial_shared_secret_dec (const struct GNUNET_CRYPTO_ElligatorRepresentative *representative)
 Setup shared secret for decryption for initial handshake. More...
 
static struct SharedSecretsetup_shared_secret_ephemeral (struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral, struct ReceiverAddress *receiver)
 Setup new shared secret for encryption using KEM. More...
 
static struct SharedSecretsetup_initial_shared_secret_ephemeral (struct GNUNET_CRYPTO_ElligatorRepresentative *representative, 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...
 
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_EcdhePublicKey *ephemeral, 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 void sock_read (void *cls)
 Socket read task. More...
 
static struct sockaddr * udp_address_to_sockaddr (const char *bindto, socklen_t *sock_len)
 Convert UDP bind specification to a struct sockaddr * More...
 
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 run (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c)
 Setup communicator and launch network interactions. More...
 
int main (int argc, char *const *argv)
 The main function for the UNIX communicator. More...
 

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_task
 ID of read 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_Handleudp_sock
 Our socket. More...
 
static int have_v6_socket
 GNUNET_YES if udp_sock supports IPv6. More...
 
static struct GNUNET_PeerIdentity my_identity
 Our public key. More...
 
static struct GNUNET_CRYPTO_EddsaPrivateKeymy_private_key
 Our private key. 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...
 
static int disable_v6
 IPv6 disabled or not. More...
 

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

◆ 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 865 of file gnunet-communicator-udp.c.

866{
867 if (AF_INET6 == bi->sa->sa_family)
868 {
869 /* Leave the multicast group */
871 IPPROTO_IPV6,
872 IPV6_LEAVE_GROUP,
873 &bi->mcreq,
874 sizeof(bi->mcreq)))
875 {
877 }
878 }
881 GNUNET_free (bi->sa);
882 GNUNET_free (bi->ba);
883 GNUNET_free (bi);
884}
static struct BroadcastInterface * bi_tail
Broadcast interface tasks.
static struct GNUNET_NETWORK_Handle * udp_sock
Our socket.
static struct BroadcastInterface * bi_head
Broadcast interface tasks.
#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:805
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:981
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, GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_log_strerror, GNUNET_NETWORK_socket_setsockopt(), GNUNET_OK, GNUNET_SCHEDULER_cancel(), BroadcastInterface::mcreq, BroadcastInterface::sa, and udp_sock.

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 1024 of file gnunet-communicator-udp.c.

1025{
1026 struct SenderAddress *sender;
1027 struct ReceiverAddress *receiver;
1028 struct KeyCacheEntry *kce;
1029
1031 "secret %s destroy %u\n",
1032 GNUNET_h2s (&ss->master),
1034 if (NULL != (sender = ss->sender))
1035 {
1036 GNUNET_CONTAINER_DLL_remove (sender->ss_head, sender->ss_tail, ss);
1037 sender->num_secrets--;
1039 "%u sender->num_secrets %u allowed %u used, %u available\n",
1041 sender->acks_available);
1043 if (NULL != ss->sender->kce_task)
1044 {
1046 ss->sender->kce_task = NULL;
1047 }
1048 }
1049 if (NULL != (receiver = ss->receiver))
1050 {
1051 GNUNET_CONTAINER_DLL_remove (receiver->ss_head, receiver->ss_tail, ss);
1052 receiver->num_secrets--;
1053 receiver->acks_available -= (ss->sequence_allowed - ss->sequence_used);
1055 "%u receiver->num_secrets\n",
1056 receiver->num_secrets);
1057 }
1058 while (NULL != (kce = ss->kce_head))
1059 kce_destroy (kce);
1060 GNUNET_STATISTICS_update (stats, "# Secrets active", -1, GNUNET_NO);
1062 "# KIDs active",
1064 GNUNET_NO);
1065 GNUNET_free (ss);
1066 return GNUNET_YES;
1067}
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_h2s(const struct GNUNET_HashCode *hc)
Convert a 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_HashCode master
Master shared secret.

References SenderAddress::acks_available, GNUNET_CONTAINER_DLL_remove, GNUNET_CONTAINER_multishortmap_size(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_h2s(), GNUNET_log, GNUNET_NO, GNUNET_SCHEDULER_cancel(), 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 895 of file gnunet-communicator-udp.c.

896{
897 struct SharedSecret *ss;
898 receiver->receiver_destroy_called = GNUNET_YES;
899
901 "Disconnecting receiver for peer `%s'\n",
902 GNUNET_i2s (&receiver->target));
903 if (NULL != receiver->kx_qh)
904 {
906 receiver->kx_qh = NULL;
907 receiver->kx_mq = NULL;
908 }
909 if (NULL != receiver->d_qh)
910 {
912 receiver->d_qh = NULL;
913 }
914 else if (NULL != receiver->d_mq)
915 {
917 receiver->d_mq = NULL;
918 }
921 &receiver->key,
922 receiver));
925 "# receivers active",
927 GNUNET_NO);
928 while (NULL != (ss = receiver->ss_head))
929 {
930 secret_destroy (ss);
931 }
932 GNUNET_free (receiver->address);
933 GNUNET_free (receiver->foreign_addr);
935}
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.
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition: mq.c:683
Shared secret we generated for a particular sender or receiver.

References GNUNET_assert, 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_NO, 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 944 of file gnunet-communicator-udp.c.

945{
946 struct SharedSecret *ss = kce->ss;
947
948 ss->active_kce_count--;
951 &kce->kid,
952 kce));
953 GNUNET_free (kce);
954}
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_HashCode 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 965 of file gnunet-communicator-udp.c.

968{
969 uint32_t sid = htonl (serial);
970
972 sizeof(*kid),
973 GCRY_MD_SHA512,
974 GCRY_MD_SHA256,
975 &sid,
976 sizeof(sid),
977 msec,
978 sizeof(*msec),
979 "UDP-KID",
980 strlen ("UDP-KID"),
981 NULL,
982 0);
983}
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hkdf(void *result, size_t out_len, int xtr_algo, int prf_algo, const void *xts, size_t xts_len, const void *skm, size_t skm_len,...)
Derive key.
Definition: crypto_hkdf.c:341

References GNUNET_CRYPTO_hkdf().

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 993 of file gnunet-communicator-udp.c.

994{
995 struct KeyCacheEntry *kce;
996
997 GNUNET_assert (0 < seq);
998 kce = GNUNET_new (struct KeyCacheEntry);
999 kce->ss = ss;
1000 kce->sequence_number = seq;
1001 get_kid (&ss->master, seq, &kce->kid);
1006 key_cache,
1007 &kce->kid,
1008 kce,
1011 "# KIDs active",
1013 GNUNET_NO);
1014}
static void get_kid(const struct GNUNET_HashCode *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 1077 of file gnunet-communicator-udp.c.

1078{
1079 struct SharedSecret *ss;
1082 GNUNET_YES ==
1086 "# senders active",
1088 GNUNET_NO);
1089 while (NULL != (ss = sender->ss_head))
1090 {
1091 secret_destroy (ss);
1092 }
1095}
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_HashCode 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 1107 of file gnunet-communicator-udp.c.

1111{
1112 uint32_t sid = htonl (serial);
1114
1116 sizeof(res),
1117 GCRY_MD_SHA512,
1118 GCRY_MD_SHA256,
1119 &sid,
1120 sizeof(sid),
1121 msec,
1122 sizeof(*msec),
1123 "UDP-IV-KEY",
1124 strlen ("UDP-IV-KEY"),
1125 NULL,
1126 0);
1127 memcpy (key, res, AES_KEY_SIZE);
1128 memcpy (iv, &res[AES_KEY_SIZE], AES_IV_SIZE);
1129}
#define AES_KEY_SIZE
AES key size.
#define AES_IV_SIZE
AES (GCM) IV size.
struct GNUNET_HashCode key
The key used in the DHT.
static char * res
Currently read line or NULL on EOF.

References AES_IV_SIZE, AES_KEY_SIZE, GNUNET_CRYPTO_hkdf(), key, and res.

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 1138 of file gnunet-communicator-udp.c.

1139{
1140 sender->timeout =
1143}
#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 1152 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 1167 of file gnunet-communicator-udp.c.

1168{
1169 struct GNUNET_TIME_Relative st;
1170 struct GNUNET_TIME_Relative rt;
1171 struct GNUNET_TIME_Relative delay;
1172 struct ReceiverAddress *receiver;
1173 struct SenderAddress *sender;
1174
1175 (void) cls;
1176 timeout_task = NULL;
1179 {
1181 if (0 != rt.rel_value_us)
1182 break;
1184 "Receiver timed out\n");
1186 }
1188 while (NULL != (sender = GNUNET_CONTAINER_heap_peek (senders_heap)))
1189 {
1190 if (GNUNET_YES != sender->sender_destroy_called)
1191 {
1193 if (0 != st.rel_value_us)
1194 break;
1195 sender_destroy (sender);
1196 }
1197 }
1198 delay = GNUNET_TIME_relative_min (rt, st);
1199 if (delay.rel_value_us < GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
1201}
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:1278
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:343
#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:405
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(), mq_init(), 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 1210 of file gnunet-communicator-udp.c.

1211{
1213 sizeof(ss->cmac),
1214 GCRY_MD_SHA512,
1215 GCRY_MD_SHA256,
1216 "CMAC",
1217 strlen ("CMAC"),
1218 &ss->master,
1219 sizeof(ss->master),
1220 "UDP-CMAC",
1221 strlen ("UDP-CMAC"),
1222 NULL,
1223 0);
1224}
struct GNUNET_HashCode cmac
CMAC is used to identify master in ACKs.

References SharedSecret::cmac, GNUNET_CRYPTO_hkdf(), 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 1236 of file gnunet-communicator-udp.c.

1239{
1240 const struct GNUNET_MessageHeader *hdr = plaintext;
1241 const char *pos = plaintext;
1242
1243 while (ntohs (hdr->size) <= plaintext_len)
1244 {
1246 "# bytes given to core",
1247 ntohs (hdr->size),
1248 GNUNET_NO);
1250 "Giving %u bytes to TNG\n", ntohs (hdr->size));
1253 &sender->target,
1254 hdr,
1256 NULL /* no flow control possible */
1257 ,
1258 NULL));
1259 /* move on to next message, if any */
1260 plaintext_len -= ntohs (hdr->size);
1261 if (plaintext_len < sizeof(*hdr))
1262 break;
1263 pos += ntohs (hdr->size);
1264 hdr = (const struct GNUNET_MessageHeader *) pos;
1265 // TODO for now..., we do not actually sen >1msg or have a way of telling
1266 // if we are done
1267 break;
1268 }
1270 "# bytes padding discarded",
1271 plaintext_len,
1272 GNUNET_NO);
1273}
#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_HashCode 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 1285 of file gnunet-communicator-udp.c.

1288{
1289 char key[AES_KEY_SIZE];
1290 char iv[AES_IV_SIZE];
1291 int rc;
1292
1293 GNUNET_assert (0 ==
1294 gcry_cipher_open (cipher,
1295 GCRY_CIPHER_AES256 /* low level: go for speed */
1296 ,
1297 GCRY_CIPHER_MODE_GCM,
1298 0 /* flags */));
1299 get_iv_key (msec, serial, key, iv);
1300 rc = gcry_cipher_setkey (*cipher, key, sizeof(key));
1301 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
1302 rc = gcry_cipher_setiv (*cipher, iv, sizeof(iv));
1303 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
1304}
static void get_iv_key(const struct GNUNET_HashCode *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 1320 of file gnunet-communicator-udp.c.

1326{
1327 gcry_cipher_hd_t cipher;
1328
1329 setup_cipher (&ss->master, serial, &cipher);
1331 0 ==
1332 gcry_cipher_decrypt (cipher, out_buf, in_buf_size, in_buf, in_buf_size));
1333 if (0 != gcry_cipher_checktag (cipher, tag, GCM_TAG_SIZE))
1334 {
1335 gcry_cipher_close (cipher);
1337 "# AEAD authentication failures",
1338 1,
1339 GNUNET_NO);
1340 return GNUNET_SYSERR;
1341 }
1342 gcry_cipher_close (cipher);
1343 return GNUNET_OK;
1344}
static void setup_cipher(const struct GNUNET_HashCode *msec, uint32_t serial, gcry_cipher_hd_t *cipher)
Setup cipher based on shared secret msec and serial number serial.
#define GCM_TAG_SIZE
Size of the GCM tag.

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_EcdhePublicKey ephemeral)
static

Setup shared secret for decryption.

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

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

1355{
1356 struct SharedSecret *ss;
1357
1358 ss = GNUNET_new (struct SharedSecret);
1360 calculate_cmac (ss);
1361 return ss;
1362}
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_EcdhePublicKey *c, struct GNUNET_HashCode *key_material)
Decapsulate a key for a private EdDSA key.
Definition: crypto_ecc.c:764

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_ElligatorRepresentative representative)
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 1372 of file gnunet-communicator-udp.c.

1375{
1376 struct SharedSecret *ss;
1377
1378 ss = GNUNET_new (struct SharedSecret);
1380 &ss->master);
1381 calculate_cmac (ss);
1382 return ss;
1383}
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_elligator_kem_decaps(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, const struct GNUNET_CRYPTO_ElligatorRepresentative *r, struct GNUNET_HashCode *key_material)
Carries out ecdh decapsulation with own private key and the representative of the received public key...

References calculate_cmac(), GNUNET_CRYPTO_eddsa_elligator_kem_decaps(), GNUNET_new, SharedSecret::master, and my_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_EcdhePublicKey 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 1394 of file gnunet-communicator-udp.c.

1396{
1397 struct SharedSecret *ss;
1398 struct GNUNET_HashCode k;
1399
1400 GNUNET_CRYPTO_eddsa_kem_encaps (&receiver->target.public_key, ephemeral, &k);
1401 ss = GNUNET_new (struct SharedSecret);
1402 memcpy (&ss->master, &k, sizeof (k));
1403 calculate_cmac (ss);
1404 ss->receiver = receiver;
1405 GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss);
1406 receiver->num_secrets++;
1407 GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
1408 return ss;
1409}
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_kem_encaps(const struct GNUNET_CRYPTO_EddsaPublicKey *pub, struct GNUNET_CRYPTO_EcdhePublicKey *c, struct GNUNET_HashCode *key_material)
Encapsulate key material for a EdDSA public key.
Definition: crypto_ecc.c:809
A 512-bit hashcode.

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_ElligatorRepresentative representative,
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 1420 of file gnunet-communicator-udp.c.

1424{
1425 struct SharedSecret *ss;
1426 struct GNUNET_HashCode k;
1427
1429 representative, &k);
1430 ss = GNUNET_new (struct SharedSecret);
1431 memcpy (&ss->master, &k, sizeof (k));
1432 calculate_cmac (ss);
1433 ss->receiver = receiver;
1434 GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss);
1435 receiver->num_secrets++;
1436 GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
1437 return ss;
1438}
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_elligator_kem_encaps(const struct GNUNET_CRYPTO_EddsaPublicKey *pub, struct GNUNET_CRYPTO_ElligatorRepresentative *r, struct GNUNET_HashCode *key_material)
Carries out ecdh encapsulation with given public key and the private key from a freshly created ephem...

References calculate_cmac(), GNUNET_CONTAINER_DLL_insert, GNUNET_CRYPTO_eddsa_elligator_kem_encaps(), GNUNET_new, GNUNET_NO, 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 2785 of file gnunet-communicator-udp.c.

2786{
2787 size_t base_mtu;
2788
2789 switch (receiver->address->sa_family)
2790 {
2791 case AF_INET:
2792 base_mtu = 1480 /* Ethernet MTU, 1500 - Ethernet header - VLAN tag */
2793 - sizeof(struct GNUNET_TUN_IPv4Header) /* 20 */
2794 - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */;
2795 break;
2796
2797 case AF_INET6:
2798 base_mtu = 1280 /* Minimum MTU required by IPv6 */
2799 - sizeof(struct GNUNET_TUN_IPv6Header) /* 40 */
2800 - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */;
2801 break;
2802
2803 default:
2804 GNUNET_assert (0);
2805 break;
2806 }
2807 /* MTU based on full KX messages */
2808 receiver->kx_mtu = base_mtu - sizeof(struct InitialKX) /* 48 */
2809 - sizeof(struct UDPConfirmation); /* 104 */
2810 /* MTU based on BOXed messages */
2811 receiver->d_mtu = base_mtu - sizeof(struct UDPBox);
2812
2814 "Setting up MQs and QHs\n");
2815 /* => Effective MTU for CORE will range from 1080 (IPv6 + KX) to
2816 1404 (IPv4 + Box) bytes, depending on circumstances... */
2817 if (NULL == receiver->kx_mq)
2820 &mq_cancel,
2821 receiver,
2822 NULL,
2823 &mq_error,
2824 receiver);
2825 if (NULL == receiver->d_mq)
2827 &mq_destroy_d,
2828 &mq_cancel,
2829 receiver,
2830 NULL,
2831 &mq_error,
2832 receiver);
2833
2834 receiver->kx_qh =
2836 &receiver->target,
2837 receiver->foreign_addr,
2838 receiver->kx_mtu,
2840 0, /* Priority */
2841 receiver->nt,
2843 receiver->kx_mq);
2844}
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:465
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 mq_init().

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

◆ purge_secrets()

unsigned int purge_secrets ( struct SharedSecret ss_list_tail)

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 1460 of file gnunet-communicator-udp.c.

1461{
1462 struct SharedSecret *pos;
1463 struct SharedSecret *ss_to_purge;
1464 unsigned int deleted = 0;
1465
1467 "Purging secrets.\n");
1468 pos = ss_list_tail;
1469 while (NULL != pos)
1470 {
1471 ss_to_purge = pos;
1472 pos = pos->prev;
1473
1474 // FIXME we may also want to purge old unacked.
1475 if (rekey_max_bytes <= ss_to_purge->bytes_sent)
1476 {
1477 secret_destroy (ss_to_purge);
1478 deleted++;
1479 }
1480 }
1482 "Finished purging all, deleted %u.\n", deleted);
1483 return deleted;
1484}
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 1488 of file gnunet-communicator-udp.c.

1489{
1490
1491 struct ReceiverAddress *receiver = ss->receiver;
1492
1493 GNUNET_assert (NULL != ss);
1494 GNUNET_assert (NULL != receiver);
1495
1496 if (NULL == receiver->d_qh)
1497 {
1498 receiver->d_qh =
1500 &receiver->target,
1501 receiver->foreign_addr,
1502 receiver->d_mtu,
1503 acks_to_add,
1504 1, /* Priority */
1505 receiver->nt,
1507 receiver->d_mq);
1508 }
1509 else
1510 {
1512 receiver->d_qh,
1513 acks_to_add,
1514 1);
1515 }
1516
1518 "Tell transport we have %u more acks!\n",
1519 acks_to_add);
1520
1521 // Until here for alternativ 1
1522
1523 /* move ss to head to avoid discarding it anytime soon! */
1524
1525 // GNUNET_CONTAINER_DLL_remove (receiver->ss_head, receiver->ss_tail, ss);
1526 // GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss);
1527}
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 1541 of file gnunet-communicator-udp.c.

1542{
1543 const struct UDPAck *ack = cls;
1544 struct ReceiverAddress *receiver = value;
1545 uint32_t acks_to_add;
1546 uint32_t allowed;
1547
1549 "in handle ack with cmac %s\n",
1550 GNUNET_h2s (&ack->cmac));
1551
1552 (void) key;
1553 for (struct SharedSecret *ss = receiver->ss_head; NULL != ss; ss = ss->next)
1554 {
1555 if (0 == memcmp (&ack->cmac, &ss->cmac, sizeof(struct GNUNET_HashCode)))
1556 {
1557
1559 "Found matching cmac\n");
1560
1561 allowed = ntohl (ack->sequence_ack);
1562
1563 if (allowed <= ss->sequence_allowed)
1564 {
1566 "Ignoring ack, not giving us increased window\n.");
1567 return GNUNET_NO;
1568 }
1569 acks_to_add = (allowed - ss->sequence_allowed);
1570 GNUNET_assert (0 != acks_to_add);
1571 receiver->acks_available += (allowed - ss->sequence_allowed);
1572 ss->sequence_allowed = allowed;
1573 add_acks (ss, acks_to_add);
1575 "New sequence allows until %u (+%u). Acks available to us: %u. For secret %s\n",
1576 allowed,
1577 acks_to_add,
1578 receiver->acks_available,
1579 GNUNET_h2s (&ss->master));
1580 return GNUNET_NO;
1581 }
1582 }
1584 "Matching cmac not found for ack!\n");
1585 return GNUNET_YES;
1586}
static void add_acks(struct SharedSecret *ss, int acks_to_add)
static char * value
Value of the record to add/remove.
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_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 1598 of file gnunet-communicator-udp.c.

1599{
1600 struct UDPAck ack;
1601 GNUNET_assert (NULL != ss->sender);
1603 "Considering SS UDPAck %s\n",
1604 GNUNET_i2s_full (&ss->sender->target));
1605
1607 "Sender has %u acks available.\n",
1608 ss->sender->acks_available);
1609 /* drop ancient KeyCacheEntries */
1610 while ((NULL != ss->kce_head) &&
1611 (MAX_SQN_DELTA <
1613 kce_destroy (ss->kce_tail);
1614
1615
1616 ack.header.type = htons (GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK);
1617 ack.header.size = htons (sizeof(ack));
1618 ack.sequence_ack = htonl (ss->sequence_allowed);
1619 ack.cmac = ss->cmac;
1621 "Notifying transport with UDPAck %s, sequence %u and master %s\n",
1623 ss->sequence_allowed,
1624 GNUNET_h2s (&(ss->master)));
1626 &ss->sender->target,
1628 &ack.header);
1629}
#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_h2s(), GNUNET_i2s_full(), GNUNET_log, GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK, 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 1633 of file gnunet-communicator-udp.c.

1634{
1635 struct SharedSecret *ss = cls;
1636 ss->sender->kce_task = NULL;
1637
1639 "Precomputing %u keys for master %s\n",
1641 GNUNET_h2s (&(ss->master)));
1642 if ((ss->override_available_acks != GNUNET_YES) &&
1643 (KCN_TARGET < ss->sender->acks_available))
1644 return;
1645 for (int i = 0; i < GENERATE_AT_ONCE; i++)
1646 kce_generate (ss, ++ss->sequence_allowed);
1647
1652 if (KCN_TARGET > ss->sender->acks_available)
1653 {
1657 ss);
1658 return;
1659 }
1661 "We have enough keys (ACKs: %u).\n", ss->sender->acks_available);
1665 consider_ss_ack (ss);
1666}
#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_h2s(), GNUNET_log, GNUNET_NO, GNUNET_SCHEDULER_add_delayed(), 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 1678 of file gnunet-communicator-udp.c.

1681{
1682 const struct GNUNET_MessageHeader *hdr;
1683 const struct UDPAck *ack;
1684 const struct UDPRekey *rekey;
1685 struct SharedSecret *ss_rekey;
1686 const char *buf_pos = buf;
1687 size_t bytes_remaining = buf_size;
1688 uint16_t type;
1689
1690 hdr = (struct GNUNET_MessageHeader*) buf_pos;
1691 if (sizeof(*hdr) > bytes_remaining)
1692 {
1693 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Plaintext too short, dropping...\n");
1694 return; /* no data left */
1695 }
1697 "try_handle_plaintext of size %llu (%u %lu) and type %u\n",
1698 (unsigned long long) bytes_remaining,
1699 ntohs (hdr->size),
1700 sizeof(*hdr),
1701 ntohs (hdr->type));
1702 if (ntohs (hdr->size) > bytes_remaining)
1703 return; /* buffer too short for indicated message length */
1704 type = ntohs (hdr->type);
1705 switch (type)
1706 {
1708 rekey = (struct UDPRekey*) buf_pos;
1709 ss_rekey = setup_shared_secret_dec (&rekey->ephemeral);
1710 ss_rekey->sender = sender;
1711 GNUNET_CONTAINER_DLL_insert (sender->ss_head, sender->ss_tail, ss_rekey);
1712 sender->num_secrets++;
1714 "Received rekey secret with cmac %s\n",
1715 GNUNET_h2s (&(ss_rekey->cmac)));
1717 "Received secret with master %s.\n",
1718 GNUNET_h2s (&(ss_rekey->master)));
1720 "We have %u sequence_allowed.\n",
1721 ss_rekey->sequence_allowed);
1723 "We have a sender %p\n",
1724 ss_rekey->sender);
1726 "We have %u acks available.\n",
1727 ss_rekey->sender->acks_available);
1729 "# rekeying successful",
1730 1,
1731 GNUNET_NO);
1734 // FIXME
1735 kce_generate_cb (ss_rekey);
1736 /* ss_rekey->sender->kce_task = GNUNET_SCHEDULER_add_delayed (
1737 WORKING_QUEUE_INTERVALL,
1738 kce_generate_cb,
1739 ss_rekey);*/
1740 // FIXME: Theoretically, this could be an Ack
1741 buf_pos += ntohs (hdr->size);
1742 bytes_remaining -= ntohs (hdr->size);
1743 pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
1744 if (0 == purge_secrets (sender->ss_tail))
1745 {
1746 // No secret purged. Delete oldest.
1747 if (sender->num_secrets > MAX_SECRETS)
1748 {
1749 secret_destroy (sender->ss_tail);
1750 }
1751 }
1752 break;
1754 /* lookup master secret by 'cmac', then update sequence_max */
1755 ack = (struct UDPAck*) buf_pos;
1757 &sender->key,
1758 &handle_ack,
1759 (void *) ack);
1760 /* There could be more messages after the ACK, handle those as well */
1761 buf_pos += ntohs (hdr->size);
1762 bytes_remaining -= ntohs (hdr->size);
1763 pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
1764 break;
1765
1767 /* skip padding */
1768 break;
1769
1770 default:
1771 pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
1772 }
1773 return;
1774}
static int handle_ack(void *cls, const struct GNUNET_HashCode *key, void *value)
We received an ACK for pid.
unsigned int purge_secrets(struct SharedSecret *ss_list_tail)
Best effort try to purge some secrets.
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.
#define MAX_SECRETS
How many shared master secrets do we keep around at most per sender? Should be large enough so that w...
static struct SharedSecret * setup_shared_secret_dec(const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral)
Setup shared secret for decryption.
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_EcdhePublicKey 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_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 1785 of file gnunet-communicator-udp.c.

1788{
1789 struct SharedSecret *ss = kce->ss;
1790 struct SharedSecret *ss_c = ss->sender->ss_tail;
1791 struct SharedSecret *ss_tmp;
1792 int ss_destroyed = 0;
1793 char out_buf[box_len - sizeof(*box)];
1794
1795 GNUNET_assert (NULL != ss->sender);
1796 if (GNUNET_OK != try_decrypt (ss,
1797 box->gcm_tag,
1798 kce->sequence_number,
1799 (const char *) &box[1],
1800 sizeof(out_buf),
1801 out_buf))
1802 {
1803 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed decryption.\n");
1805 "# Decryption failures with valid KCE",
1806 1,
1807 GNUNET_NO);
1808 kce_destroy (kce);
1809 ss->sender->acks_available--;
1810 return;
1811 }
1812 kce_destroy (kce);
1813 kce = NULL;
1814 ss->bytes_sent += box_len;
1815 ss->sender->acks_available--;
1816 ss->sequence_used++;
1818 "# bytes decrypted with BOX",
1819 sizeof(out_buf),
1820 GNUNET_NO);
1822 "# messages decrypted with BOX",
1823 1,
1824 GNUNET_NO);
1826 "decrypted UDPBox with kid %s\n",
1827 GNUNET_sh2s (&box->kid));
1828 try_handle_plaintext (ss->sender, out_buf, sizeof(out_buf));
1829
1830 while (NULL != ss_c)
1831 {
1832 if (ss_c->bytes_sent >= rekey_max_bytes)
1833 {
1835 "Removing SS because rekey bytes reached.\n");
1836 ss_tmp = ss_c->prev;
1837 if (ss == ss_c)
1838 ss_destroyed = 1;
1839 secret_destroy (ss_c);
1840 ss_c = ss_tmp;
1841 continue;
1842 }
1843 ss_c = ss_c->prev;
1844 }
1845 if (1 == ss_destroyed)
1846 return;
1848 "Sender has %u ack left.\n",
1849 ss->sender->acks_available);
1850 if ((KCN_THRESHOLD > ss->sender->acks_available) &&
1851 (NULL == ss->sender->kce_task) &&
1853 {
1855 "Sender has %u ack left which is under threshold.\n",
1856 ss->sender->acks_available);
1860 ss);
1861 }
1862}
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.
const char * GNUNET_sh2s(const struct GNUNET_ShortHashCode *shc)
Convert a short hash value to a string (for printing debug messages).
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:1305
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 1899 of file gnunet-communicator-udp.c.

1902{
1903 struct SenderAddress *sender;
1904 struct GNUNET_HashContext *hsh;
1905 struct GNUNET_HashCode sender_key;
1906
1908 GNUNET_CRYPTO_hash_context_read (hsh, address, address_len);
1909 GNUNET_CRYPTO_hash_context_read (hsh, target, sizeof(*target));
1910 GNUNET_CRYPTO_hash_context_finish (hsh, &sender_key);
1911
1912 sender = GNUNET_CONTAINER_multihashmap_get (senders, &sender_key);
1913 if (NULL != sender)
1914 {
1916 return sender;
1917 }
1918 sender = GNUNET_new (struct SenderAddress);
1919 sender->key = sender_key;
1920 sender->target = *target;
1921 sender->address = GNUNET_memdup (address, address_len);
1922 sender->address_len = address_len;
1924 senders,
1925 &sender->key,
1926 sender,
1929 "# senders active",
1931 GNUNET_NO);
1932 sender->timeout =
1935 sender,
1936 sender->timeout.abs_value_us);
1937 sender->nt = GNUNET_NT_scanner_get_type (is, address, address_len);
1938 if (NULL == timeout_task)
1940 return sender;
1941}
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:307
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_EcdhePublicKey ephemeral,
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 1952 of file gnunet-communicator-udp.c.

1954{
1955 struct UdpHandshakeSignature uhs;
1956
1957 uhs.purpose.purpose = htonl (
1959 uhs.purpose.size = htonl (sizeof(uhs));
1960 uhs.sender = uc->sender;
1961 uhs.receiver = my_identity;
1962 uhs.ephemeral = *ephemeral;
1963 uhs.monotonic_time = uc->monotonic_time;
1966 &uhs,
1967 &uc->sender_sig,
1968 &uc->sender.public_key);
1969}
static struct GNUNET_PeerIdentity my_identity
Our public key.
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_EcdhePublicKey ephemeral
Ephemeral key used by the sender.
struct GNUNET_CRYPTO_EccSignaturePurpose purpose
Purpose must be GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_HANDSHAKE.

References UdpHandshakeSignature::ephemeral, 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 1981 of file gnunet-communicator-udp.c.

1983{
1984 char *ret;
1985
1986 switch (address->sa_family)
1987 {
1988 case AF_INET:
1990 "%s-%s",
1992 GNUNET_a2s (address, address_len));
1993 break;
1994
1995 case AF_INET6:
1997 "%s-%s",
1999 GNUNET_a2s (address, address_len));
2000 break;
2001
2002 default:
2003 GNUNET_assert (0);
2004 }
2005 return ret;
2006}
static int ret
Final status code.
Definition: gnunet-arm.c:94
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 mq_init(), and sock_read().

Here is the call graph for this function:
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 2015 of file gnunet-communicator-udp.c.

2016{
2017 struct sockaddr_storage sa;
2018 struct sockaddr_in *addr_verify;
2019 socklen_t salen = sizeof(sa);
2020 char buf[UINT16_MAX];
2021 ssize_t rcvd;
2022
2023 (void) cls;
2025 udp_sock,
2026 &sock_read,
2027 NULL);
2028 while (1)
2029 {
2031 buf,
2032 sizeof(buf),
2033 (struct sockaddr *) &sa,
2034 &salen);
2035 if (-1 == rcvd)
2036 {
2037 struct sockaddr *addr = (struct sockaddr*) &sa;
2038
2039 if (EAGAIN == errno)
2040 break; // We are done reading data
2042 "Failed to recv from %s family %d failed sock %p\n",
2043 GNUNET_a2s ((struct sockaddr*) &sa,
2044 sizeof (*addr)),
2045 addr->sa_family,
2046 udp_sock);
2048 return;
2049 }
2051 "Read %llu bytes\n",
2052 (unsigned long long) rcvd);
2053 if (0 == rcvd)
2054 {
2055 GNUNET_break_op (0);
2057 "Read 0 bytes from UDP socket\n");
2058 return;
2059 }
2060
2061 /* first, see if it is a UDPBox */
2062 if (rcvd > sizeof(struct UDPBox))
2063 {
2064 const struct UDPBox *box;
2065 struct KeyCacheEntry *kce;
2066
2067 box = (const struct UDPBox *) buf;
2069 if (NULL != kce)
2070 {
2072 "Found KCE with kid %s\n",
2073 GNUNET_sh2s (&box->kid));
2074 decrypt_box (box, (size_t) rcvd, kce);
2075 continue;
2076 }
2077 }
2078
2079 /* next, check if it is a broadcast */
2080 if (sizeof(struct UDPBroadcast) == rcvd)
2081 {
2082 const struct UDPBroadcast *ub;
2083 struct UdpBroadcastSignature uhs;
2084 struct GNUNET_PeerIdentity sender;
2085
2086 addr_verify = GNUNET_memdup (&sa, salen);
2087 addr_verify->sin_port = 0;
2089 "received UDPBroadcast from %s\n",
2090 GNUNET_a2s ((const struct sockaddr *) addr_verify, salen));
2091 ub = (const struct UDPBroadcast *) buf;
2092 uhs.purpose.purpose = htonl (
2094 uhs.purpose.size = htonl (sizeof(uhs));
2095 uhs.sender = ub->sender;
2096 sender = ub->sender;
2097 if (0 == memcmp (&sender, &my_identity, sizeof (struct
2099 {
2101 "Received our own broadcast\n");
2102 GNUNET_free (addr_verify);
2103 continue;
2104 }
2106 "checking UDPBroadcastSignature for %s\n",
2107 GNUNET_i2s (&sender));
2108 GNUNET_CRYPTO_hash ((struct sockaddr *) addr_verify, salen,
2109 &uhs.h_address);
2110 if (GNUNET_OK ==
2113 &uhs,
2114 &ub->sender_sig,
2115 &ub->sender.public_key))
2116 {
2117 char *addr_s;
2119
2120 addr_s =
2121 sockaddr_to_udpaddr_string ((const struct sockaddr *) &sa, salen);
2122 GNUNET_STATISTICS_update (stats, "# broadcasts received", 1, GNUNET_NO);
2123 /* use our own mechanism to determine network type */
2124 nt =
2125 GNUNET_NT_scanner_get_type (is, (const struct sockaddr *) &sa, salen);
2127 "validating address %s received from UDPBroadcast\n",
2128 GNUNET_i2s (&sender));
2130 GNUNET_free (addr_s);
2131 GNUNET_free (addr_verify);
2132 continue;
2133 }
2134 else
2135 {
2137 "VerifyingPeer %s is verifying UDPBroadcast\n",
2140 "Verifying UDPBroadcast from %s failed\n",
2141 GNUNET_i2s (&ub->sender));
2142 }
2143 GNUNET_free (addr_verify);
2144 /* continue with KX, mostly for statistics... */
2145 }
2146
2147
2148 /* finally, test if it is a KX */
2149 if (rcvd < sizeof(struct UDPConfirmation) + sizeof(struct InitialKX))
2150 {
2152 "# messages dropped (no kid, too small for KX)",
2153 1,
2154 GNUNET_NO);
2155 continue;
2156 }
2158 "Got KX\n");
2159 {
2160 const struct InitialKX *kx;
2161 struct SharedSecret *ss;
2162 char pbuf[rcvd - sizeof(struct InitialKX)];
2163 const struct UDPConfirmation *uc;
2164 struct SenderAddress *sender;
2165
2166 kx = (const struct InitialKX *) buf;
2169 "Before DEC\n");
2170
2171 if (GNUNET_OK != try_decrypt (ss,
2172 kx->gcm_tag,
2173 0,
2174 &buf[sizeof(*kx)],
2175 sizeof(pbuf),
2176 pbuf))
2177 {
2179 "Unable to decrypt tag, dropping...\n");
2180 GNUNET_free (ss);
2182 stats,
2183 "# messages dropped (no kid, AEAD decryption failed)",
2184 1,
2185 GNUNET_NO);
2186 continue;
2187 }
2189 "Before VERIFY\n");
2190
2191 uc = (const struct UDPConfirmation *) pbuf;
2192
2193 struct GNUNET_CRYPTO_EcdhePublicKey pub_ephemeral;
2194 GNUNET_CRYPTO_ecdhe_elligator_decoding (&pub_ephemeral, NULL,
2195 &kx->representative);
2196 if (GNUNET_OK != verify_confirmation (&pub_ephemeral, uc)) // TODO: need ephemeral instead of representative
2197 {
2198 GNUNET_break_op (0);
2199 GNUNET_free (ss);
2201 "# messages dropped (sender signature invalid)",
2202 1,
2203 GNUNET_NO);
2204 continue;
2205 }
2207 "Before SETUP_SENDER\n");
2208
2209 calculate_cmac (ss);
2210 sender = setup_sender (&uc->sender, (const struct sockaddr *) &sa, salen);
2211 ss->sender = sender;
2212 GNUNET_CONTAINER_DLL_insert (sender->ss_head, sender->ss_tail, ss);
2213 if ((KCN_THRESHOLD > ss->sender->acks_available) &&
2214 (NULL == ss->sender->kce_task) &&
2216 {
2217 // 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.
2221 ss);
2222 }
2223 sender->num_secrets++;
2224 GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
2226 "# messages decrypted without BOX",
2227 1,
2228 GNUNET_NO);
2229 try_handle_plaintext (sender, &uc[1], sizeof(pbuf) - sizeof(*uc));
2230 if (0 == purge_secrets (sender->ss_tail))
2231 {
2232 // No secret purged. Delete oldest.
2233 if (sender->num_secrets > MAX_SECRETS)
2234 {
2235 secret_destroy (sender->ss_tail);
2236 }
2237 }
2238 }
2239 }
2240}
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 GNUNET_SCHEDULER_Task * read_task
ID of read task.
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 struct SharedSecret * setup_initial_shared_secret_dec(const struct GNUNET_CRYPTO_ElligatorRepresentative *representative)
Setup shared secret for decryption for initial handshake.
static void decrypt_box(const struct UDPBox *box, size_t box_len, struct KeyCacheEntry *kce)
We received a box with matching kce.
static int verify_confirmation(const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral, const struct UDPConfirmation *uc)
Check signature from uc against ephemeral.
static struct GNUNET_NAT_AUTO_Test * nt
Handle to a NAT test operation.
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_ecdhe_elligator_decoding(struct GNUNET_CRYPTO_EcdhePublicKey *point, bool *high_y, const struct GNUNET_CRYPTO_ElligatorRepresentative *representative)
Clears the most significant bit and second most significant bit of the serialized representaive befor...
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.
@ GNUNET_ERROR_TYPE_ERROR
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:687
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:1512
#define GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_BROADCAST
Signature used by UDP broadcasts.
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and encr...
The identity of the host (wraps the signing key of the peer).
struct GNUNET_CRYPTO_EddsaPublicKey public_key
struct GNUNET_CRYPTO_ElligatorRepresentative representative
Representative of ephemeral key for KX.
uint8_t gcm_tag[(128/8)]
HMAC for the following encrypted message, using GCM.
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.
Signature we use to verify that the broadcast was really made by the peer that claims to have made it...

References SenderAddress::acks_available, ah, calculate_cmac(), decrypt_box(), InitialKX::gcm_tag, GNUNET_a2s(), GNUNET_break_op, GNUNET_CONTAINER_DLL_insert, GNUNET_CONTAINER_multishortmap_get(), GNUNET_CRYPTO_ecdhe_elligator_decoding(), 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_TIME_UNIT_FOREVER_REL, GNUNET_TRANSPORT_application_validate(), 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, MAX_SECRETS, my_identity, nt, SenderAddress::num_secrets, GNUNET_PeerIdentity::public_key, purge_secrets(), GNUNET_CRYPTO_EccSignaturePurpose::purpose, UdpBroadcastSignature::purpose, read_task, InitialKX::representative, secret_destroy(), 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(), SenderAddress::ss_head, SenderAddress::ss_tail, stats, try_decrypt(), try_handle_plaintext(), uc, udp_sock, and verify_confirmation().

Referenced by run(), and sock_read().

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,
socklen_t *  sock_len 
)
static

Convert UDP bind specification to a struct sockaddr *

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

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

2252{
2253 struct sockaddr *in;
2254 unsigned int port;
2255 char dummy[2];
2256 char *colon;
2257 char *cp;
2258
2259 if (1 == sscanf (bindto, "%u%1s", &port, dummy))
2260 {
2261 /* interpreting value as just a PORT number */
2262 if (port > UINT16_MAX)
2263 {
2265 "BINDTO specification `%s' invalid: value too large for port\n",
2266 bindto);
2267 return NULL;
2268 }
2269 if (GNUNET_YES == disable_v6)
2270 {
2271 struct sockaddr_in *i4;
2272
2273 i4 = GNUNET_malloc (sizeof(struct sockaddr_in));
2274 i4->sin_family = AF_INET;
2275 i4->sin_port = htons ((uint16_t) port);
2276 *sock_len = sizeof(struct sockaddr_in);
2277 in = (struct sockaddr *) i4;
2278 }
2279 else
2280 {
2281 struct sockaddr_in6 *i6;
2282
2283 i6 = GNUNET_malloc (sizeof(struct sockaddr_in6));
2284 i6->sin6_family = AF_INET6;
2285 i6->sin6_port = htons ((uint16_t) port);
2286 *sock_len = sizeof(struct sockaddr_in6);
2287 in = (struct sockaddr *) i6;
2288 }
2289 return in;
2290 }
2291 cp = GNUNET_strdup (bindto);
2292 colon = strrchr (cp, ':');
2293 if (NULL != colon)
2294 {
2295 /* interpret value after colon as port */
2296 *colon = '\0';
2297 colon++;
2298 if (1 == sscanf (colon, "%u%1s", &port, dummy))
2299 {
2300 /* interpreting value as just a PORT number */
2301 if (port > UINT16_MAX)
2302 {
2304 "BINDTO specification `%s' invalid: value too large for port\n",
2305 bindto);
2306 GNUNET_free (cp);
2307 return NULL;
2308 }
2309 }
2310 else
2311 {
2312 GNUNET_log (
2314 "BINDTO specification `%s' invalid: last ':' not followed by number\n",
2315 bindto);
2316 GNUNET_free (cp);
2317 return NULL;
2318 }
2319 }
2320 else
2321 {
2322 /* interpret missing port as 0, aka pick any free one */
2323 port = 0;
2324 }
2325 {
2326 /* try IPv4 */
2327 struct sockaddr_in v4;
2328
2329 memset (&v4, 0, sizeof(v4));
2330 if (1 == inet_pton (AF_INET, cp, &v4.sin_addr))
2331 {
2332 v4.sin_family = AF_INET;
2333 v4.sin_port = htons ((uint16_t) port);
2334#if HAVE_SOCKADDR_IN_SIN_LEN
2335 v4.sin_len = sizeof(struct sockaddr_in);
2336#endif
2337 in = GNUNET_memdup (&v4, sizeof(struct sockaddr_in));
2338 *sock_len = sizeof(struct sockaddr_in);
2339 GNUNET_free (cp);
2340 return in;
2341 }
2342 }
2343 {
2344 /* try IPv6 */
2345 struct sockaddr_in6 v6;
2346 const char *start;
2347
2348 memset (&v6, 0, sizeof(v6));
2349 start = cp;
2350 if (('[' == *cp) && (']' == cp[strlen (cp) - 1]))
2351 {
2352 start++; /* skip over '[' */
2353 cp[strlen (cp) - 1] = '\0'; /* eat ']' */
2354 }
2355 if (1 == inet_pton (AF_INET6, start, &v6.sin6_addr))
2356 {
2357 v6.sin6_family = AF_INET6;
2358 v6.sin6_port = htons ((uint16_t) port);
2359#if HAVE_SOCKADDR_IN_SIN_LEN
2360 v6.sin6_len = sizeof(struct sockaddr_in6);
2361#endif
2362 in = GNUNET_memdup (&v6, sizeof(v6));
2363 *sock_len = sizeof(v6);
2364 GNUNET_free (cp);
2365 return in;
2366 }
2367 }
2368 /* #5528 FIXME (feature!): maybe also try getnameinfo()? */
2369 GNUNET_free (cp);
2370 return NULL;
2371}
static int start
Set if we are to start default services (including ARM).
Definition: gnunet-arm.c:39
static uint16_t port
Port number.
Definition: gnunet-bcd.c:147
static int disable_v6
IPv6 disabled or not.
static struct in_addr dummy
Target "dummy" address of the packet we pretend to respond to.
#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 mq_init(), and run().

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 2382 of file gnunet-communicator-udp.c.

2383{
2384 char pad[pad_size];
2385
2387 if (sizeof(pad) > sizeof(struct GNUNET_MessageHeader))
2388 {
2389 struct GNUNET_MessageHeader hdr =
2390 { .size = htons (sizeof(pad)),
2392
2393 memcpy (pad, &hdr, sizeof(hdr));
2394 }
2396 0 ==
2397 gcry_cipher_encrypt (out_cipher, dgram, sizeof(pad), pad, sizeof(pad)));
2398}
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 2402 of file gnunet-communicator-udp.c.

2405{
2406 uint16_t msize = ntohs (msg->size);
2407 struct UdpHandshakeSignature uhs;
2408 struct UDPConfirmation uc;
2409 struct InitialKX kx;
2410 char dgram[receiver->kx_mtu + sizeof(uc) + sizeof(kx)];
2411 size_t dpos;
2412 gcry_cipher_hd_t out_cipher;
2413 struct SharedSecret *ss;
2414
2415 if (msize > receiver->kx_mtu)
2416 {
2417 GNUNET_break (0);
2418 if (GNUNET_YES != receiver->receiver_destroy_called)
2420 return;
2421 }
2423
2424 /* setup key material */
2427 GNUNET_CRYPTO_ecdhe_elligator_decoding (&uhs.ephemeral, NULL,
2428 &repr);
2429
2430 if (0 == purge_secrets (receiver->ss_tail))
2431 {
2432 // No secret purged. Delete oldest.
2433 if (receiver->num_secrets > MAX_SECRETS)
2434 {
2435 secret_destroy (receiver->ss_tail);
2436 }
2437 }
2438
2439 setup_cipher (&ss->master, 0, &out_cipher);
2440 /* compute 'uc' */
2441 uc.sender = my_identity;
2442 uc.monotonic_time =
2444 uhs.purpose.purpose = htonl (
2446 uhs.purpose.size = htonl (sizeof(uhs));
2447 uhs.sender = my_identity;
2448 uhs.receiver = receiver->target;
2449 uhs.monotonic_time = uc.monotonic_time;
2451 &uhs,
2452 &uc.sender_sig);
2453 /* Leave space for kx */
2454 dpos = sizeof(kx);
2455 /* Append encrypted uc to dgram */
2456 GNUNET_assert (0 == gcry_cipher_encrypt (out_cipher,
2457 &dgram[dpos],
2458 sizeof(uc),
2459 &uc,
2460 sizeof(uc)));
2461 dpos += sizeof(uc);
2462 /* Append encrypted payload to dgram */
2464 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], msize, msg, msize));
2465 dpos += msize;
2466 do_pad (out_cipher, &dgram[dpos], sizeof(dgram) - dpos);
2467 /* Datagram starts with kx */
2468 kx.representative = repr;
2470 0 == gcry_cipher_gettag (out_cipher, kx.gcm_tag, sizeof(kx.gcm_tag)));
2471 gcry_cipher_close (out_cipher);
2472 memcpy (dgram, &kx, sizeof(kx));
2474 dgram,
2475 sizeof(dgram),
2476 receiver->address,
2477 receiver->address_len))
2478 {
2481 "Sending KX with payload size %u to %s family %d failed sock %p\n",
2482 msize,
2483 GNUNET_a2s (receiver->address,
2484 receiver->address_len),
2485 receiver->address->sa_family,
2486 udp_sock);
2489 return;
2490 }
2492 "Sending KX with payload size %u to %s\n",
2493 msize,
2494 GNUNET_a2s (receiver->address,
2495 receiver->address_len));
2497}
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
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 SharedSecret * setup_initial_shared_secret_ephemeral(struct GNUNET_CRYPTO_ElligatorRepresentative *representative, struct ReceiverAddress *receiver)
Setup new shared secret for encryption using KEM for initial handshake.
#define GNUNET_CRYPTO_eddsa_sign(priv, ps, sig)
EdDSA sign a given block.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
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:421
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:771
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:860
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:638
Elligator representative (always for Curve25519)

References cfg, do_pad(), UdpHandshakeSignature::ephemeral, InitialKX::gcm_tag, GNUNET_a2s(), GNUNET_assert, GNUNET_break, GNUNET_CRYPTO_ecdhe_elligator_decoding(), 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(), InitialKX::representative, reschedule_receiver_timeout(), secret_destroy(), UdpHandshakeSignature::sender, setup_cipher(), setup_initial_shared_secret_ephemeral(), GNUNET_MessageHeader::size, GNUNET_CRYPTO_EccSignaturePurpose::size, uc, and udp_sock.

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 2509 of file gnunet-communicator-udp.c.

2512{
2513 struct ReceiverAddress *receiver = impl_state;
2514
2515 GNUNET_assert (mq == receiver->kx_mq);
2517}
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 2521 of file gnunet-communicator-udp.c.

2523{
2524 struct SharedSecret *ss_rekey;
2525
2527 /* setup key material */
2528 ss_rekey = setup_shared_secret_ephemeral (&rekey->ephemeral,
2529 receiver);
2530 ss_rekey->sequence_allowed = 0;
2532 "Setup secret with k = %s\n",
2533 GNUNET_h2s (&(ss_rekey->master)));
2535 "Setup secret with H(k) = %s\n",
2536 GNUNET_h2s (&(ss_rekey->cmac)));
2537
2538 /* Append encrypted payload to dgram */
2540 rekey->header.size = htons (sizeof (struct UDPRekey));
2541}
static struct SharedSecret * setup_shared_secret_ephemeral(struct GNUNET_CRYPTO_EcdhePublicKey *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_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 2553 of file gnunet-communicator-udp.c.

2556{
2557 struct ReceiverAddress *receiver = impl_state;
2558 struct UDPRekey rekey;
2559 struct SharedSecret *ss;
2560 int inject_rekey = GNUNET_NO;
2561 uint16_t msize = ntohs (msg->size);
2562
2563 GNUNET_assert (mq == receiver->d_mq);
2564 if ((msize > receiver->d_mtu) ||
2565 (0 == receiver->acks_available))
2566 {
2568 "msize: %u, mtu: %llu, acks: %u\n",
2569 (unsigned int) msize,
2570 (unsigned long long) receiver->d_mtu,
2571 receiver->acks_available);
2572
2573 GNUNET_break (0);
2574 if (GNUNET_YES != receiver->receiver_destroy_called)
2576 return;
2577 }
2579
2580 if (receiver->num_secrets > MAX_SECRETS)
2581 {
2582 if ((0 == purge_secrets (receiver->ss_tail)) &&
2583 (NULL != receiver->ss_tail))
2584 {
2585 // No secret purged. Delete oldest.
2586 secret_destroy (receiver->ss_tail);
2587 }
2588 }
2589 /* begin "BOX" encryption method, scan for ACKs from tail! */
2590 ss = receiver->ss_tail;
2591 struct SharedSecret *ss_tmp;
2592 while (NULL != ss)
2593 {
2594 size_t payload_len = sizeof(struct UDPBox) + receiver->d_mtu;
2596 "Considering SS %s sequence used: %u sequence allowed: %u bytes sent: %lu.\n",
2597 GNUNET_h2s (&ss->master), ss->sequence_used,
2598 ss->sequence_allowed, ss->bytes_sent);
2599 if (ss->sequence_used >= ss->sequence_allowed)
2600 {
2601 // GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2602 // "Skipping ss because no acks to use.\n");
2603 ss = ss->prev;
2604 continue;
2605 }
2606 if (ss->bytes_sent >= rekey_max_bytes)
2607 {
2609 "Skipping ss because rekey bytes reached.\n");
2610 // FIXME cleanup ss with too many bytes sent!
2611 ss_tmp = ss->prev;
2612 secret_destroy (ss);
2613 ss = ss_tmp;
2614 continue;
2615 }
2616 if (ss->bytes_sent > rekey_max_bytes * 0.7)
2617 {
2618 if (ss->rekey_initiated == GNUNET_NO)
2619 {
2621 "Injecting rekey for ss with byte sent %lu\n",
2622 (unsigned long) ss->bytes_sent);
2623 create_rekey (receiver, ss, &rekey);
2625 payload_len += sizeof (rekey);
2627 }
2628 }
2629 if (0 < ss->sequence_used)
2631 "Trying to send UDPBox with shared secrect %s sequence_used %u and ss->sequence_allowed %u\n",
2632 GNUNET_h2s (&ss->master),
2633 ss->sequence_used,
2634 ss->sequence_allowed);
2635
2636 char dgram[payload_len];
2637 struct UDPBox *box;
2638 gcry_cipher_hd_t out_cipher;
2639 size_t dpos;
2640
2641 box = (struct UDPBox *) dgram;
2642 ss->sequence_used++;
2643 get_kid (&ss->master, ss->sequence_used, &box->kid);
2644 setup_cipher (&ss->master, ss->sequence_used, &out_cipher);
2645 /* Append encrypted payload to dgram */
2646 dpos = sizeof(struct UDPBox);
2647 if (GNUNET_YES == inject_rekey)
2648 {
2650 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], sizeof (rekey),
2651 &rekey, sizeof (rekey)));
2652 dpos += sizeof (rekey);
2653 }
2655 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], msize, msg, msize));
2656 dpos += msize;
2657 do_pad (out_cipher, &dgram[dpos], sizeof(dgram) - dpos);
2658 GNUNET_assert (0 == gcry_cipher_gettag (out_cipher,
2659 box->gcm_tag,
2660 sizeof(box->gcm_tag)));
2661 gcry_cipher_close (out_cipher);
2662
2664 dgram,
2665 payload_len, // FIXME why always send sizeof dgram?
2666 receiver->address,
2667 receiver->address_len))
2668 {
2671 "Sending UDPBox to %s family %d failed sock %p failed\n",
2672 GNUNET_a2s (receiver->address,
2673 receiver->address_len),
2674 receiver->address->sa_family,
2675 udp_sock);
2677 return;
2678 }
2680 "Sending UDPBox with payload size %u, %u acks left, %lu bytes sent\n",
2681 msize,
2682 receiver->acks_available,
2683 (unsigned long) ss->bytes_sent);
2684 ss->bytes_sent += sizeof (dgram);
2685 receiver->acks_available--;
2687 return;
2688 }
2690 "No suitable ss found, sending as KX...\n");
2692}
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(), GNUNET_a2s(), GNUNET_assert, GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_WARNING, GNUNET_h2s(), GNUNET_log, GNUNET_log_strerror, GNUNET_MQ_impl_send_continue(), GNUNET_NETWORK_socket_sendto(), GNUNET_NO, 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(), GNUNET_MessageHeader::size, and udp_sock.

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 2704 of file gnunet-communicator-udp.c.

2705{
2706 struct ReceiverAddress *receiver = impl_state;
2708 "Default MQ destroyed\n");
2709 if (mq == receiver->d_mq)
2710 {
2711 receiver->d_mq = NULL;
2712 if (GNUNET_YES != receiver->receiver_destroy_called)
2714 }
2715}

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 2727 of file gnunet-communicator-udp.c.

2728{
2729 struct ReceiverAddress *receiver = impl_state;
2731 "KX MQ destroyed\n");
2732 if (mq == receiver->kx_mq)
2733 {
2734 receiver->kx_mq = NULL;
2735 if (GNUNET_YES != receiver->receiver_destroy_called)
2737 }
2738}

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 2748 of file gnunet-communicator-udp.c.

2749{
2750 /* Cancellation is impossible with UDP; bail */
2751 GNUNET_assert (0);
2752}

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 2765 of file gnunet-communicator-udp.c.

2766{
2767 struct ReceiverAddress *receiver = cls;
2768
2770 "MQ error in queue to %s: %d\n",
2771 GNUNET_i2s (&receiver->target),
2772 (int) error);
2774}

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 2866 of file gnunet-communicator-udp.c.

2867{
2868 struct ReceiverAddress *receiver;
2869 struct GNUNET_HashContext *hsh;
2870 struct GNUNET_HashCode receiver_key;
2871 const char *path;
2872 struct sockaddr *in;
2873 socklen_t in_len;
2874
2875 if (0 != strncmp (address,
2877 strlen (COMMUNICATOR_ADDRESS_PREFIX "-")))
2878 {
2879 GNUNET_break_op (0);
2880 return GNUNET_SYSERR;
2881 }
2882 path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")];
2883 in = udp_address_to_sockaddr (path, &in_len);
2884
2885 if (NULL == in)
2886 {
2888 "Failed to setup UDP socket address\n");
2889 return GNUNET_SYSERR;
2890 }
2891 if ((AF_INET6 == in->sa_family) &&
2893 {
2895 "IPv6 disabled, skipping %s\n", address);
2896 GNUNET_free (in);
2897 return GNUNET_SYSERR;
2898 }
2899
2901 GNUNET_CRYPTO_hash_context_read (hsh, in, in_len);
2902 GNUNET_CRYPTO_hash_context_read (hsh, peer, sizeof(*peer));
2903 GNUNET_CRYPTO_hash_context_finish (hsh, &receiver_key);
2904
2906 if (NULL != receiver)
2907 {
2909 "receiver %s already exist or is being connected to\n",
2910 address);
2911 GNUNET_free (in);
2912 return GNUNET_NO;
2913 }
2914
2916 receiver->key = receiver_key;
2917 receiver->address = in;
2918 receiver->address_len = in_len;
2919 receiver->target = *peer;
2920 receiver->nt = GNUNET_NT_scanner_get_type (is, in, in_len);
2922 receivers,
2923 &receiver->key,
2924 receiver,
2927 "Added %s to receivers\n",
2928 GNUNET_i2s_full (&receiver->target));
2929 receiver->timeout =
2932 receiver,
2933 receiver->timeout.abs_value_us);
2935 "# receivers active",
2937 GNUNET_NO);
2938 receiver->foreign_addr =
2939 sockaddr_to_udpaddr_string (receiver->address, receiver->address_len);
2941 if (NULL == timeout_task)
2943 return GNUNET_OK;
2944}
static void setup_receiver_mq(struct ReceiverAddress *receiver)
Setup the MQ for the receiver.
static struct sockaddr * udp_address_to_sockaddr(const char *bindto, socklen_t *sock_len)
Convert UDP bind specification to a struct sockaddr *

References address, check_timeouts(), COMMUNICATOR_ADDRESS_PREFIX, disable_v6, 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_STATISTICS_set(), GNUNET_SYSERR, GNUNET_TIME_relative_to_absolute(), GNUNET_YES, is, receiver(), receivers, receivers_heap, setup_receiver_mq(), sockaddr_to_udpaddr_string(), stats, timeout_task, and udp_address_to_sockaddr().

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 2956 of file gnunet-communicator-udp.c.

2959{
2960 struct ReceiverAddress *receiver = value;
2961
2962 (void) cls;
2963 (void) target;
2965 return GNUNET_OK;
2966}
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 2978 of file gnunet-communicator-udp.c.

2981{
2982 struct SenderAddress *sender = value;
2983
2984 (void) cls;
2985 (void) target;
2986
2987
2988 sender_destroy (sender);
2989 return GNUNET_OK;
2990}

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 2999 of file gnunet-communicator-udp.c.

3000{
3002 "do_shutdown\n");
3003 if (NULL != nat)
3004 {
3006 nat = NULL;
3007 }
3008 while (NULL != bi_head)
3010 if (NULL != broadcast_task)
3011 {
3013 broadcast_task = NULL;
3014 }
3015 if (NULL != timeout_task)
3016 {
3018 timeout_task = NULL;
3019 }
3020 if (NULL != read_task)
3021 {
3023 read_task = NULL;
3024 }
3025 if (NULL != udp_sock)
3026 {
3029 udp_sock = NULL;
3030 }
3033 NULL);
3037 NULL);
3042 if (NULL != timeout_task)
3043 {
3045 timeout_task = NULL;
3046 }
3047 if (NULL != ch)
3048 {
3050 ch = NULL;
3051 }
3052 if (NULL != ah)
3053 {
3055 ah = NULL;
3056 }
3057 if (NULL != stats)
3058 {
3060 stats = NULL;
3061 }
3062 if (NULL != my_private_key)
3063 {
3065 my_private_key = NULL;
3066 }
3067 if (NULL != is)
3068 {
3070 is = NULL;
3071 }
3073 "do_shutdown finished\n");
3074}
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:702
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:508
void GNUNET_NT_scanner_done(struct GNUNET_NT_InterfaceScanner *is)
Terminate interface scanner.
Definition: nt.c:426
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, 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_TRANSPORT_application_done(), GNUNET_TRANSPORT_communicator_disconnect(), GNUNET_YES, is, key_cache, my_private_key, nat, read_task, receivers, receivers_heap, senders, senders_heap, stats, timeout_task, and udp_sock.

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 3085 of file gnunet-communicator-udp.c.

3086{
3087 struct ReceiverAddress *receiver = value;
3088 struct AckInfo *ai = cls;
3089
3090 if (0 != GNUNET_memcmp (ai->sender, &receiver->target))
3091 {
3092 return GNUNET_YES;
3093 }
3094 handle_ack ((void*) ai->ack, key, receiver);
3095 return GNUNET_YES;
3096}
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 3109 of file gnunet-communicator-udp.c.

3112{
3113 struct AckInfo ai;
3114
3115 (void) cls;
3117 "Storing UDPAck received from backchannel from %s\n",
3120 (ntohs (msg->size) != sizeof(struct UDPAck)))
3121 {
3122 GNUNET_break_op (0);
3123 return;
3124 }
3125 ai.ack = (const struct UDPAck *) msg;
3126 ai.sender = sender;
3129 &ai);
3130}
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 3147 of file gnunet-communicator-udp.c.

3153{
3154 char *my_addr;
3156
3157 if (GNUNET_YES == add_remove)
3158 {
3160
3161 GNUNET_asprintf (&my_addr,
3162 "%s-%s",
3164 GNUNET_a2s (addr, addrlen));
3165 nt = GNUNET_NT_scanner_get_type (is, addr, addrlen);
3166 ai =
3168 my_addr,
3169 nt,
3171 GNUNET_free (my_addr);
3172 *app_ctx = ai;
3173 }
3174 else
3175 {
3176 ai = *app_ctx;
3178 *app_ctx = NULL;
3179 }
3180}
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 3189 of file gnunet-communicator-udp.c.

3190{
3191 struct BroadcastInterface *bi = cls;
3192 struct GNUNET_TIME_Relative delay;
3193
3194 delay = BROADCAST_FREQUENCY;
3195 delay.rel_value_us =
3197 bi->broadcast_task =
3199
3200 switch (bi->sa->sa_family)
3201 {
3202 case AF_INET: {
3203 static int yes = 1;
3204 static int no = 0;
3205 ssize_t sent;
3206
3207 if (GNUNET_OK !=
3209 SOL_SOCKET,
3210 SO_BROADCAST,
3211 &yes,
3212 sizeof(int)))
3214 "setsockopt");
3216 "creating UDPBroadcast from %s\n",
3217 GNUNET_i2s (&(bi->bcm.sender)));
3219 "sending UDPBroadcast to add %s\n",
3220 GNUNET_a2s (bi->ba, bi->salen));
3222 &bi->bcm,
3223 sizeof(bi->bcm),
3224 bi->ba,
3225 bi->salen);
3226 if (-1 == sent)
3228 "sendto");
3230 SOL_SOCKET,
3231 SO_BROADCAST,
3232 &no,
3233 sizeof(int)))
3235 "setsockopt");
3236 break;
3237 }
3238
3239 case AF_INET6: {
3240 ssize_t sent;
3241 struct sockaddr_in6 dst;
3242
3243 dst.sin6_family = AF_INET6;
3244 dst.sin6_port = htons (my_port);
3245 dst.sin6_addr = bi->mcreq.ipv6mr_multiaddr;
3246 dst.sin6_scope_id = ((struct sockaddr_in6 *) bi->ba)->sin6_scope_id;
3247
3249 "sending UDPBroadcast\n");
3251 &bi->bcm,
3252 sizeof(bi->bcm),
3253 (const struct sockaddr *) &dst,
3254 sizeof(dst));
3255 if (-1 == sent)
3257 break;
3258 }
3259
3260 default:
3261 GNUNET_break (0);
3262 break;
3263 }
3264}
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, 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, UDPBroadcast::sender, and udp_sock.

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 3282 of file gnunet-communicator-udp.c.

3289{
3290 struct BroadcastInterface *bi;
3291 enum GNUNET_NetworkType network;
3292 struct UdpBroadcastSignature ubs;
3293
3294 (void) cls;
3295 (void) netmask;
3296 if (NULL == addr)
3297 return GNUNET_YES; /* need to know our address! */
3298 network = GNUNET_NT_scanner_get_type (is, addr, addrlen);
3299 if (GNUNET_NT_LOOPBACK == network)
3300 {
3301 /* Broadcasting on loopback does not make sense */
3302 return GNUNET_YES;
3303 }
3304 for (bi = bi_head; NULL != bi; bi = bi->next)
3305 {
3306 if ((bi->salen == addrlen) && (0 == memcmp (addr, bi->sa, addrlen)))
3307 {
3308 bi->found = GNUNET_YES;
3309 return GNUNET_OK;
3310 }
3311 }
3312
3313 if ((AF_INET6 == addr->sa_family) && (NULL == broadcast_addr))
3314 return GNUNET_OK; /* broadcast_addr is required for IPv6! */
3315 if ((AF_INET6 == addr->sa_family) && (GNUNET_YES != have_v6_socket))
3316 return GNUNET_OK; /* not using IPv6 */
3317
3318 bi = GNUNET_new (struct BroadcastInterface);
3319 bi->sa = GNUNET_memdup (addr,
3320 addrlen);
3321 if ( (NULL != broadcast_addr) &&
3322 (addrlen == sizeof (struct sockaddr_in)) )
3323 {
3324 struct sockaddr_in *ba;
3325
3326 ba = GNUNET_memdup (broadcast_addr,
3327 addrlen);
3328 ba->sin_port = htons (2086); /* always GNUnet port, ignore configuration! */
3329 bi->ba = (struct sockaddr *) ba;
3330 }
3331 bi->salen = addrlen;
3332 bi->found = GNUNET_YES;
3333 bi->bcm.sender = my_identity;
3334 ubs.purpose.purpose = htonl (
3336 ubs.purpose.size = htonl (sizeof(ubs));
3337 ubs.sender = my_identity;
3339 "creating UDPBroadcastSignature for %s\n",
3340 GNUNET_a2s (addr, addrlen));
3341 GNUNET_CRYPTO_hash (addr, addrlen, &ubs.h_address);
3343 &ubs,
3344 &bi->bcm.sender_sig);
3345 if (NULL != bi->ba)
3346 {
3349 }
3350 if ((AF_INET6 == addr->sa_family) && (NULL != broadcast_addr))
3351 {
3352 /* Create IPv6 multicast request */
3353 const struct sockaddr_in6 *s6 =
3354 (const struct sockaddr_in6 *) broadcast_addr;
3355
3357 1 == inet_pton (AF_INET6, "FF05::13B", &bi->mcreq.ipv6mr_multiaddr));
3358
3359 /* http://tools.ietf.org/html/rfc2553#section-5.2:
3360 *
3361 * IPV6_JOIN_GROUP
3362 *
3363 * Join a multicast group on a specified local interface. If the
3364 * interface index is specified as 0, the kernel chooses the local
3365 * interface. For example, some kernels look up the multicast
3366 * group in the normal IPv6 routing table and using the resulting
3367 * interface; we do this for each interface, so no need to use
3368 * zero (anymore...).
3369 */
3370 bi->mcreq.ipv6mr_interface = s6->sin6_scope_id;
3371
3372 /* Join the multicast group */
3374 IPPROTO_IPV6,
3375 IPV6_JOIN_GROUP,
3376 &bi->mcreq,
3377 sizeof(bi->mcreq)))
3378 {
3380 }
3381 }
3382 return GNUNET_OK;
3383}
static int have_v6_socket
GNUNET_YES if udp_sock supports IPv6.
@ 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, 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, have_v6_socket, 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, GNUNET_CRYPTO_EccSignaturePurpose::size, and udp_sock.

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 3392 of file gnunet-communicator-udp.c.

3393{
3394 struct BroadcastInterface *bin;
3395
3396 (void) cls;
3397 for (struct BroadcastInterface *bi = bi_head; NULL != bi; bi = bi->next)
3398 bi->found = GNUNET_NO;
3400 for (struct BroadcastInterface *bi = bi_head; NULL != bi; bi = bin)
3401 {
3402 bin = bi->next;
3403 if (GNUNET_NO == bi->found)
3404 bi_destroy (bi);
3405 }
3407 &do_broadcast,
3408 NULL);
3409}
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 3413 of file gnunet-communicator-udp.c.

3416{
3417 /* FIXME: support reversal: #5529 */
3419 "No connection reversal implemented!");
3420}
@ GNUNET_ERROR_TYPE_INFO

References GNUNET_ERROR_TYPE_INFO, and GNUNET_log.

Referenced by run().

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

Setup communicator and launch network interactions.

Parameters
clsNULL (always)
argsremaining command-line arguments
cfgfilename of the configuration file used (for saving, can be NULL!)
cconfiguration

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

3436{
3437 char *bindto;
3438 struct sockaddr *in;
3439 socklen_t in_len;
3440 struct sockaddr_storage in_sto;
3441 socklen_t sto_len;
3442
3443 (void) cls;
3444 cfg = c;
3445 if (GNUNET_OK !=
3448 "BINDTO",
3449 &bindto))
3450 {
3453 "BINDTO");
3454 return;
3455 }
3456
3457 if (GNUNET_OK !=
3460 "REKEY_INTERVAL",
3463
3464 if (GNUNET_OK !=
3467 "REKEY_MAX_BYTES",
3469 {
3471 }
3473 if ((GNUNET_NO == GNUNET_NETWORK_test_pf (PF_INET6)) ||
3474 (GNUNET_YES ==
3477 "DISABLE_V6")))
3478 {
3480 }
3481
3482 in = udp_address_to_sockaddr (bindto, &in_len);
3483 if (NULL == in)
3484 {
3486 "Failed to setup UDP socket address with path `%s'\n",
3487 bindto);
3488 GNUNET_free (bindto);
3489 return;
3490 }
3491 udp_sock =
3492 GNUNET_NETWORK_socket_create (in->sa_family,
3493 SOCK_DGRAM,
3494 IPPROTO_UDP);
3495 if (NULL == udp_sock)
3496 {
3499 "Failed to create socket for %s family %d\n",
3500 GNUNET_a2s (in,
3501 in_len),
3502 in->sa_family);
3503 GNUNET_free (in);
3504 GNUNET_free (bindto);
3505 return;
3506 }
3507 if (AF_INET6 == in->sa_family)
3509 if (GNUNET_OK !=
3511 in,
3512 in_len))
3513 {
3515 "bind",
3516 bindto);
3518 "Failed to bind socket for %s family %d sock %p\n",
3519 GNUNET_a2s (in,
3520 in_len),
3521 in->sa_family,
3522 udp_sock);
3524 udp_sock = NULL;
3525 GNUNET_free (in);
3526 GNUNET_free (bindto);
3527 return;
3528 }
3529
3530 /* We might have bound to port 0, allowing the OS to figure it out;
3531 thus, get the real IN-address from the socket */
3532 sto_len = sizeof(in_sto);
3533 if (0 != getsockname (GNUNET_NETWORK_get_fd (udp_sock),
3534 (struct sockaddr *) &in_sto,
3535 &sto_len))
3536 {
3537 memcpy (&in_sto, in, in_len);
3538 sto_len = in_len;
3539 }
3540 GNUNET_free (in);
3541 GNUNET_free (bindto);
3542 in = (struct sockaddr *) &in_sto;
3543 in_len = sto_len;
3545 "transport",
3546 "Bound to `%s' sock %p\n",
3547 GNUNET_a2s ((const struct sockaddr *) &in_sto,
3548 sto_len),
3549 udp_sock);
3550 switch (in->sa_family)
3551 {
3552 case AF_INET:
3553 my_port = ntohs (((struct sockaddr_in *) in)->sin_port);
3554 break;
3555
3556 case AF_INET6:
3557 my_port = ntohs (((struct sockaddr_in6 *) in)->sin6_port);
3558 break;
3559
3560 default:
3561 GNUNET_break (0);
3562 my_port = 0;
3563 }
3564 stats = GNUNET_STATISTICS_create ("communicator-udp", cfg);
3574 if (NULL == my_private_key)
3575 {
3576 GNUNET_log (
3578 _ (
3579 "Transport service is lacking key configuration settings. Exiting.\n"));
3581 return;
3582 }
3584 /* start reading */
3586 udp_sock,
3587 &sock_read,
3588 NULL);
3593 &mq_init,
3594 NULL,
3596 NULL);
3597 if (NULL == ch)
3598 {
3599 GNUNET_break (0);
3601 return;
3602 }
3604 if (NULL == ah)
3605 {
3606 GNUNET_break (0);
3608 return;
3609 }
3610 /* start broadcasting */
3611 if (GNUNET_YES !=
3614 "DISABLE_BROADCAST"))
3615 {
3617 }
3620 IPPROTO_UDP,
3621 1 /* one address */,
3622 (const struct sockaddr **) &in,
3623 &in_len,
3626 NULL /* closure */);
3627}
#define DEFAULT_REKEY_TIME_INTERVAL
How often do we rekey based on time (at least)
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 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 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_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)
Connect to the transport service.
struct GNUNET_TRANSPORT_ApplicationHandle * GNUNET_TRANSPORT_application_init(const struct GNUNET_CONFIGURATION_Handle *cfg)
Initialize the TRANSPORT application client handle.
@ 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:198
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.
#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...
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
int GNUNET_NETWORK_get_fd(const struct GNUNET_NETWORK_Handle *desc)
Return file descriptor for this network handle.
Definition: network.c:1000
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition: network.c:832
enum GNUNET_GenericReturnValue GNUNET_NETWORK_test_pf(int pf)
Test if the given protocol family is supported by this system.
Definition: network.c:79
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
struct GNUNET_NT_InterfaceScanner * GNUNET_NT_scanner_init(void)
Initialize the address characterization client handle.
Definition: nt.c:405
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:567
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:1340
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, DEFAULT_REKEY_MAX_BYTES, DEFAULT_REKEY_TIME_INTERVAL, disable_v6, do_broadcast(), do_shutdown(), enc_notify_cb(), GNUNET_a2s(), 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_ERROR, GNUNET_ERROR_TYPE_INFO, GNUNET_free, GNUNET_log, GNUNET_log_config_missing(), GNUNET_log_from_nocheck(), GNUNET_log_strerror, GNUNET_log_strerror_file, GNUNET_NAT_register(), GNUNET_NETWORK_get_fd(), GNUNET_NETWORK_socket_bind(), GNUNET_NETWORK_socket_close(), GNUNET_NETWORK_socket_create(), 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_SCHEDULER_shutdown(), GNUNET_STATISTICS_create(), GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_TRANSPORT_application_init(), GNUNET_TRANSPORT_CC_UNRELIABLE, GNUNET_TRANSPORT_communicator_connect(), GNUNET_YES, have_v6_socket, is, key_cache, mq_init(), my_identity, my_port, my_private_key, nat, nat_address_cb(), GNUNET_PeerIdentity::public_key, read_task, receivers, receivers_heap, rekey_interval, rekey_max_bytes, senders, senders_heap, sock_read(), stats, try_connection_reversal(), udp_address_to_sockaddr(), and udp_sock.

Referenced by main().

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

◆ main()

int main ( int  argc,
char *const *  argv 
)

The main function for the UNIX communicator.

Parameters
argcnumber of arguments from the command line
argvcommand line arguments
Returns
0 ok, 1 on error

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

3639{
3640 static const struct GNUNET_GETOPT_CommandLineOption options[] = {
3642 };
3643 int ret;
3644
3646 "transport",
3647 "Starting udp communicator\n");
3648 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
3649 return 2;
3650
3651 ret = (GNUNET_OK == GNUNET_PROGRAM_run (argc,
3652 argv,
3653 "gnunet-communicator-udp",
3654 _ ("GNUnet UDP communicator"),
3655 options,
3656 &run,
3657 NULL))
3658 ? 0
3659 : 1;
3660 GNUNET_free_nz ((void *) argv);
3661 return ret;
3662}
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_OPTION_END
Definition: 002.c:13
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
static void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c)
Setup communicator and launch network interactions.
#define GNUNET_free_nz(ptr)
Wrapper around free.
enum GNUNET_GenericReturnValue GNUNET_PROGRAM_run(int argc, char *const *argv, const char *binaryName, const char *binaryHelp, const struct GNUNET_GETOPT_CommandLineOption *options, GNUNET_PROGRAM_Main task, void *task_cls)
Run a standard GNUnet command startup sequence (initialize loggers and configuration,...
Definition: program.c:400
enum GNUNET_GenericReturnValue GNUNET_STRINGS_get_utf8_args(int argc, char *const *argv, int *u8argc, char *const **u8argv)
Returns utf-8 encoded arguments.
Definition: strings.c:1230
Definition of a command line option.

References _, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free_nz, GNUNET_GETOPT_OPTION_END, GNUNET_log_from_nocheck(), GNUNET_OK, GNUNET_PROGRAM_run(), GNUNET_STRINGS_get_utf8_args(), options, ret, and run().

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 741 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 746 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 751 of file gnunet-communicator-udp.c.

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

◆ read_task

struct GNUNET_SCHEDULER_Task* read_task
static

ID of read task.

Definition at line 756 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 761 of file gnunet-communicator-udp.c.

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

◆ broadcast_task

struct GNUNET_SCHEDULER_Task* broadcast_task
static

ID of master broadcast task.

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

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

◆ stats

◆ ch

◆ receivers

struct GNUNET_CONTAINER_MultiHashMap* receivers
static

Receivers (map from peer identity to struct ReceiverAddress)

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

Referenced by do_shutdown(), enc_notify_cb(), mq_init(), receiver_destroy(), run(), setup_sender(), and try_handle_plaintext().

◆ senders

struct GNUNET_CONTAINER_MultiHashMap* senders
static

Senders (map from peer identity to struct SenderAddress)

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

Referenced by do_shutdown(), run(), sender_destroy(), and setup_sender().

◆ senders_heap

struct GNUNET_CONTAINER_Heap* senders_heap
static

Expiration heap for senders (contains struct SenderAddress)

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

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

◆ receivers_heap

struct GNUNET_CONTAINER_Heap* receivers_heap
static

Expiration heap for receivers (contains struct ReceiverAddress)

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

Referenced by check_timeouts(), do_shutdown(), mq_init(), and run().

◆ bi_head

struct BroadcastInterface* bi_head
static

Broadcast interface tasks.

Kept in a DLL.

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

Referenced by bi_destroy(), do_broadcast(), do_shutdown(), and iface_proc().

◆ bi_tail

struct BroadcastInterface* bi_tail
static

Broadcast interface tasks.

Kept in a DLL.

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

Referenced by bi_destroy(), and iface_proc().

◆ udp_sock

struct GNUNET_NETWORK_Handle* udp_sock
static

◆ have_v6_socket

int have_v6_socket
static

GNUNET_YES if udp_sock supports IPv6.

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

Referenced by iface_proc(), and run().

◆ my_identity

struct GNUNET_PeerIdentity my_identity
static

Our public key.

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

Referenced by iface_proc(), run(), send_msg_with_kx(), sock_read(), and verify_confirmation().

◆ my_private_key

struct GNUNET_CRYPTO_EddsaPrivateKey* my_private_key
static

◆ cfg

const struct GNUNET_CONFIGURATION_Handle* cfg
static

Our configuration.

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

Referenced by run(), and send_msg_with_kx().

◆ ah

Our handle to report addresses for validation to TRANSPORT.

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

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

◆ is

struct GNUNET_NT_InterfaceScanner* is
static

Network scanner to determine network types.

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

Referenced by do_shutdown(), iface_proc(), mq_init(), nat_address_cb(), run(), setup_sender(), and sock_read().

◆ nat

struct GNUNET_NAT_Handle* nat
static

Connection to NAT service.

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

Referenced by do_shutdown(), and run().

◆ my_port

uint16_t my_port
static

Port number to which we are actually bound.

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

Referenced by ifc_broadcast(), and run().

◆ disable_v6

int disable_v6
static

IPv6 disabled or not.

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

Referenced by mq_init(), run(), and udp_address_to_sockaddr().