GNUnet  0.20.0
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_nt_lib.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
 Context information to be used while searching for operation contexts. More...
 

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   16
 
#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 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 int secret_destroy (struct SharedSecret *ss)
 Destroy ss and associated key cache entries. 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_shared_secret_ephemeral (struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral, struct ReceiverAddress *receiver)
 Setup new shared secret for encryption using KEM. 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_PeerIdentity *pid, 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 int find_sender_by_address (void *cls, const struct GNUNET_PeerIdentity *key, void *value)
 Find existing struct SenderAddress by matching addresses. 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)
 
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_PeerIdentity *target, void *value)
 Iterator over all receivers to clean up. More...
 
static int get_sender_delete_it (void *cls, const struct GNUNET_PeerIdentity *target, void *value)
 Iterator over all senders to clean up. More...
 
static void do_shutdown (void *cls)
 Shutdown the UNIX communicator. More...
 
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_MultiPeerMapreceivers
 Receivers (map from peer identity to struct ReceiverAddress) More...
 
static struct GNUNET_CONTAINER_MultiPeerMapsenders
 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...
 

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 55 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 60 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 65 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 70 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 77 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 79 of file gnunet-communicator-udp.c.

◆ AES_KEY_SIZE

#define AES_KEY_SIZE   (256 / 8)

AES key size.

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

◆ AES_IV_SIZE

#define AES_IV_SIZE   (96 / 8)

AES (GCM) IV size.

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

◆ GCM_TAG_SIZE

#define GCM_TAG_SIZE   (128 / 8)

Size of the GCM tag.

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

◆ GENERATE_AT_ONCE

#define GENERATE_AT_ONCE   16

Definition at line 97 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 108 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 116 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 127 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 138 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 144 of file gnunet-communicator-udp.c.

◆ COMMUNICATOR_ADDRESS_PREFIX

#define COMMUNICATOR_ADDRESS_PREFIX   "udp"

Address prefix used by the communicator.

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

◆ COMMUNICATOR_CONFIG_SECTION

#define COMMUNICATOR_CONFIG_SECTION   "communicator-udp"

Configuration section used by the communicator.

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

852 {
853  if (AF_INET6 == bi->sa->sa_family)
854  {
855  /* Leave the multicast group */
857  IPPROTO_IPV6,
858  IPV6_LEAVE_GROUP,
859  &bi->mcreq,
860  sizeof(bi->mcreq)))
861  {
863  }
864  }
867  GNUNET_free (bi->sa);
868  GNUNET_free (bi->ba);
869  GNUNET_free (bi);
870 }
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:806
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:975
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:

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

880 {
881 
882  receiver->receiver_destroy_called = GNUNET_YES;
883 
885  "Disconnecting receiver for peer `%s'\n",
886  GNUNET_i2s (&receiver->target));
887  if (NULL != receiver->kx_qh)
888  {
890  receiver->kx_qh = NULL;
891  receiver->kx_mq = NULL;
892  }
893  if (NULL != receiver->d_qh)
894  {
896  receiver->d_qh = NULL;
897  }
900  &receiver->target,
901  receiver));
904  "# receivers active",
906  GNUNET_NO);
907  GNUNET_free (receiver->address);
908  GNUNET_free (receiver->foreign_addr);
910 }
static struct GNUNET_CONTAINER_MultiPeerMap * receivers
Receivers (map from peer identity to struct ReceiverAddress)
static struct GNUNET_STATISTICS_Handle * stats
For logging statistics.
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.
unsigned int GNUNET_CONTAINER_multipeermap_size(const struct GNUNET_CONTAINER_MultiPeerMap *map)
Get the number of key-value pairs in the map.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multipeermap_remove(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, const void *value)
Remove the given key-value pair from the map.
void * GNUNET_CONTAINER_heap_remove_node(struct GNUNET_CONTAINER_HeapNode *node)
Removes a node from the heap.
#define GNUNET_log(kind,...)
@ GNUNET_YES
@ GNUNET_NO
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.
@ 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 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

References GNUNET_assert, GNUNET_CONTAINER_heap_remove_node(), GNUNET_CONTAINER_multipeermap_remove(), GNUNET_CONTAINER_multipeermap_size(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_i2s(), GNUNET_log, GNUNET_NO, GNUNET_STATISTICS_set(), GNUNET_TRANSPORT_communicator_mq_del(), GNUNET_YES, receiver(), receivers, 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 919 of file gnunet-communicator-udp.c.

920 {
921  struct SharedSecret *ss = kce->ss;
922 
923  ss->active_kce_count--;
924  ss->sender->acks_available--;
927  &kce->kid,
928  kce));
929  GNUNET_free (kce);
930 }
static struct GNUNET_CONTAINER_MultiShortmap * key_cache
Cache of pre-generated key IDs.
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 SharedSecret * ss
Corresponding shared secret.
unsigned int acks_available
Number of BOX keys from ACKs we have currently available for this sender.
Shared secret we generated for a particular sender or receiver.
struct KeyCacheEntry * kce_tail
Kept in a DLL, sorted by sequence number.
unsigned int active_kce_count
Number of active KCN entries.
struct SenderAddress * sender
Sender we use this shared secret with, or NULL.
struct KeyCacheEntry * kce_head
Kept in a DLL, sorted by sequence number.

References SenderAddress::acks_available, 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, SharedSecret::sender, 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 941 of file gnunet-communicator-udp.c.

944 {
945  uint32_t sid = htonl (serial);
946 
947  GNUNET_CRYPTO_hkdf (kid,
948  sizeof(*kid),
949  GCRY_MD_SHA512,
950  GCRY_MD_SHA256,
951  &sid,
952  sizeof(sid),
953  msec,
954  sizeof(*msec),
955  "UDP-KID",
956  strlen ("UDP-KID"),
957  NULL,
958  0);
959 }
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 969 of file gnunet-communicator-udp.c.

970 {
971  struct KeyCacheEntry *kce;
972 
973  GNUNET_assert (0 < seq);
974  kce = GNUNET_new (struct KeyCacheEntry);
975  kce->ss = ss;
976  kce->sequence_number = seq;
977  get_kid (&ss->master, seq, &kce->kid);
979  ss->active_kce_count++;
982  key_cache,
983  &kce->kid,
984  kce,
987  "# KIDs active",
989  GNUNET_NO);
990 }
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.
unsigned int GNUNET_CONTAINER_multishortmap_size(const struct GNUNET_CONTAINER_MultiShortmap *map)
Get the number of key-value pairs 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.
Pre-generated "kid" code (key and IV identification code) to quickly derive master key for a struct U...
uint32_t sequence_number
Sequence number used to derive this entry from master key.
struct GNUNET_HashCode master
Master shared secret.

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:

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

1001 {
1002  struct SenderAddress *sender;
1003  struct ReceiverAddress *receiver;
1004  struct KeyCacheEntry *kce;
1005 
1007  "secret %s destroy %u\n",
1008  GNUNET_h2s (&ss->master),
1009  ss->sequence_allowed);
1010  if (NULL != (sender = ss->sender))
1011  {
1012  GNUNET_CONTAINER_DLL_remove (sender->ss_head, sender->ss_tail, ss);
1013  sender->num_secrets--;
1015  "%u sender->num_secrets\n",
1016  receiver->num_secrets);
1017  if (NULL != ss->sender->kce_task)
1018  {
1020  ss->sender->kce_task = NULL;
1021  }
1022  }
1023  if (NULL != (receiver = ss->receiver))
1024  {
1025  GNUNET_CONTAINER_DLL_remove (receiver->ss_head, receiver->ss_tail, ss);
1026  receiver->num_secrets--;
1027  receiver->acks_available -= (ss->sequence_allowed - ss->sequence_used);
1029  "%u receiver->num_secrets\n",
1030  receiver->num_secrets);
1031  }
1032  while (NULL != (kce = ss->kce_head))
1033  kce_destroy (kce);
1034  GNUNET_STATISTICS_update (stats, "# Secrets active", -1, GNUNET_NO);
1036  "# KIDs active",
1038  GNUNET_NO);
1039  GNUNET_free (ss);
1040  return GNUNET_YES;
1041 }
static void kce_destroy(struct KeyCacheEntry *kce)
Free memory used by key cache entry.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
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 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 ReceiverAddress * receiver
Receiver we use this shared secret with, or NULL.

References 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, SharedSecret::receiver, receiver(), SharedSecret::sender, SharedSecret::sequence_allowed, SharedSecret::sequence_used, KeyCacheEntry::ss, SenderAddress::ss_head, SenderAddress::ss_tail, and stats.

Referenced by mq_send_d(), purge_secrets(), 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:

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

1052 {
1054  GNUNET_assert (
1055  GNUNET_YES ==
1057  GNUNET_assert (sender == GNUNET_CONTAINER_heap_remove_node (sender->hn));
1059  "# senders active",
1061  GNUNET_NO);
1062  GNUNET_free (sender->address);
1063  GNUNET_free (sender);
1064 }
static struct GNUNET_CONTAINER_MultiPeerMap * senders
Senders (map from peer identity to struct SenderAddress)
struct GNUNET_PeerIdentity target
To whom are we talking to.
struct GNUNET_CONTAINER_HeapNode * hn
Entry in sender expiration heap.
struct sockaddr * address
Address of the other peer.
int sender_destroy_called
sender_destroy already called on sender.

References SenderAddress::address, GNUNET_assert, GNUNET_CONTAINER_heap_remove_node(), GNUNET_CONTAINER_multipeermap_remove(), GNUNET_CONTAINER_multipeermap_size(), GNUNET_free, GNUNET_NO, GNUNET_STATISTICS_set(), GNUNET_YES, SenderAddress::hn, SenderAddress::sender_destroy_called, senders, stats, and SenderAddress::target.

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

1080 {
1081  uint32_t sid = htonl (serial);
1082  char res[AES_KEY_SIZE + AES_IV_SIZE];
1083 
1085  sizeof(res),
1086  GCRY_MD_SHA512,
1087  GCRY_MD_SHA256,
1088  &sid,
1089  sizeof(sid),
1090  msec,
1091  sizeof(*msec),
1092  "UDP-IV-KEY",
1093  strlen ("UDP-IV-KEY"),
1094  NULL,
1095  0);
1096  memcpy (key, res, AES_KEY_SIZE);
1097  memcpy (iv, &res[AES_KEY_SIZE], AES_IV_SIZE);
1098 }
static int res
#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.

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

1108 {
1109  sender->timeout =
1112 }
#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, 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 1121 of file gnunet-communicator-udp.c.

1122 {
1123  receiver->timeout =
1126  receiver->timeout.abs_value_us);
1127 }

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

1137 {
1138  struct GNUNET_TIME_Relative st;
1139  struct GNUNET_TIME_Relative rt;
1140  struct GNUNET_TIME_Relative delay;
1141  struct ReceiverAddress *receiver;
1142  struct SenderAddress *sender;
1143 
1144  (void) cls;
1145  timeout_task = NULL;
1147  while (NULL != (receiver = GNUNET_CONTAINER_heap_peek (receivers_heap)))
1148  {
1150  if (0 != rt.rel_value_us)
1151  break;
1153  "Receiver timed out\n");
1155  }
1157  while (NULL != (sender = GNUNET_CONTAINER_heap_peek (senders_heap)))
1158  {
1159  if (GNUNET_YES != sender->sender_destroy_called)
1160  {
1162  if (0 != st.rel_value_us)
1163  break;
1164  sender_destroy (sender);
1165  }
1166  }
1168  if (delay.rel_value_us < GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
1170 }
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.
static struct GNUNET_TIME_Relative delay
When should dkg communication start?
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:1272
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.
uint64_t rel_value_us
The actual value.

References delay, 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 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 1179 of file gnunet-communicator-udp.c.

1180 {
1181  GNUNET_CRYPTO_hkdf (&ss->cmac,
1182  sizeof(ss->cmac),
1183  GCRY_MD_SHA512,
1184  GCRY_MD_SHA256,
1185  "CMAC",
1186  strlen ("CMAC"),
1187  &ss->master,
1188  sizeof(ss->master),
1189  "UDP-CMAC",
1190  strlen ("UDP-CMAC"),
1191  NULL,
1192  0);
1193 }
struct GNUNET_HashCode cmac
CMAC is used to identify master in ACKs.

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

Referenced by 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 1205 of file gnunet-communicator-udp.c.

1208 {
1209  const struct GNUNET_MessageHeader *hdr = plaintext;
1210  const char *pos = plaintext;
1211 
1212  while (ntohs (hdr->size) <= plaintext_len)
1213  {
1215  "# bytes given to core",
1216  ntohs (hdr->size),
1217  GNUNET_NO);
1219  "Giving %u bytes to TNG\n", ntohs (hdr->size));
1222  &sender->target,
1223  hdr,
1225  NULL /* no flow control possible */
1226  ,
1227  NULL));
1228  /* move on to next message, if any */
1229  plaintext_len -= ntohs (hdr->size);
1230  if (plaintext_len < sizeof(*hdr))
1231  break;
1232  pos += ntohs (hdr->size);
1233  hdr = (const struct GNUNET_MessageHeader *) pos;
1234  // TODO for now..., we do not actually sen >1msg or have a way of telling
1235  // if we are done
1236  break;
1237  }
1239  "# bytes padding discarded",
1240  plaintext_len,
1241  GNUNET_NO);
1242 }
#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.
@ GNUNET_SYSERR
Header for all communications.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.

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

1257 {
1258  char key[AES_KEY_SIZE];
1259  char iv[AES_IV_SIZE];
1260  int rc;
1261 
1262  GNUNET_assert (0 ==
1263  gcry_cipher_open (cipher,
1264  GCRY_CIPHER_AES256 /* low level: go for speed */,
1265  GCRY_CIPHER_MODE_GCM,
1266  0 /* flags */));
1267  get_iv_key (msec, serial, key, iv);
1268  rc = gcry_cipher_setkey (*cipher, key, sizeof(key));
1269  GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
1270  rc = gcry_cipher_setiv (*cipher, iv, sizeof(iv));
1271  GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
1272 }
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 1288 of file gnunet-communicator-udp.c.

1294 {
1295  gcry_cipher_hd_t cipher;
1296 
1297  setup_cipher (&ss->master, serial, &cipher);
1298  GNUNET_assert (
1299  0 ==
1300  gcry_cipher_decrypt (cipher, out_buf, in_buf_size, in_buf, in_buf_size));
1301  if (0 != gcry_cipher_checktag (cipher, tag, GCM_TAG_SIZE))
1302  {
1303  gcry_cipher_close (cipher);
1305  "# AEAD authentication failures",
1306  1,
1307  GNUNET_NO);
1308  return GNUNET_SYSERR;
1309  }
1310  gcry_cipher_close (cipher);
1311  return GNUNET_OK;
1312 }
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 1322 of file gnunet-communicator-udp.c.

1323 {
1324  struct SharedSecret *ss;
1325 
1326  ss = GNUNET_new (struct SharedSecret);
1328  calculate_cmac (ss);
1329  return ss;
1330 }
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:749

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

Referenced by sock_read(), and try_handle_plaintext().

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

1343 {
1344  struct SharedSecret *ss;
1345  struct GNUNET_HashCode k;
1346 
1347  GNUNET_CRYPTO_eddsa_kem_encaps (&receiver->target.public_key, ephemeral, &k);
1348  ss = GNUNET_new (struct SharedSecret);
1349  memcpy (&ss->master, &k, sizeof (k));
1350  calculate_cmac (ss);
1351  ss->receiver = receiver;
1352  GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss);
1353  receiver->num_secrets++;
1354  GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
1355  return ss;
1356 }
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:794
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, SharedSecret::receiver, receiver(), and stats.

Referenced by create_rekey(), and 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 2643 of file gnunet-communicator-udp.c.

2644 {
2645  size_t base_mtu;
2646 
2647  switch (receiver->address->sa_family)
2648  {
2649  case AF_INET:
2650  base_mtu = 1480 /* Ethernet MTU, 1500 - Ethernet header - VLAN tag */
2651  - sizeof(struct GNUNET_TUN_IPv4Header) /* 20 */
2652  - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */;
2653  break;
2654 
2655  case AF_INET6:
2656  base_mtu = 1280 /* Minimum MTU required by IPv6 */
2657  - sizeof(struct GNUNET_TUN_IPv6Header) /* 40 */
2658  - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */;
2659  break;
2660 
2661  default:
2662  GNUNET_assert (0);
2663  break;
2664  }
2665  /* MTU based on full KX messages */
2666  receiver->kx_mtu = base_mtu - sizeof(struct InitialKX) /* 48 */
2667  - sizeof(struct UDPConfirmation); /* 104 */
2668  /* MTU based on BOXed messages */
2669  receiver->d_mtu = base_mtu - sizeof(struct UDPBox);
2670 
2672  "Setting up MQs and QHs\n");
2673  /* => Effective MTU for CORE will range from 1080 (IPv6 + KX) to
2674  1404 (IPv4 + Box) bytes, depending on circumstances... */
2675  if (NULL == receiver->kx_mq)
2677  &mq_destroy_kx,
2678  &mq_cancel,
2679  receiver,
2680  NULL,
2681  &mq_error,
2682  receiver);
2683  if (NULL == receiver->d_mq)
2685  &mq_destroy_d,
2686  &mq_cancel,
2687  receiver,
2688  NULL,
2689  &mq_error,
2690  receiver);
2691 
2692  receiver->kx_qh =
2694  &receiver->target,
2695  receiver->foreign_addr,
2696  receiver->kx_mtu,
2698  0, /* Priority */
2699  receiver->nt,
2701  receiver->kx_mq);
2702 }
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 1378 of file gnunet-communicator-udp.c.

1379 {
1380  struct SharedSecret *pos;
1381  struct SharedSecret *ss_to_purge;
1382  unsigned int deleted = 0;
1383 
1385  "Purging secrets.\n");
1386  pos = ss_list_tail;
1387  while (NULL != pos)
1388  {
1389  ss_to_purge = pos;
1390  pos = pos->prev;
1391 
1392  // FIXME we may also want to purge old unacked.
1393  if (rekey_max_bytes <= ss_to_purge->bytes_sent)
1394  {
1395  secret_destroy (ss_to_purge);
1396  deleted++;
1397  }
1398  }
1400  "Finished purging all, deleted %u.\n", deleted);
1401  return deleted;
1402 }
static int secret_destroy(struct SharedSecret *ss)
Destroy ss and associated key cache entries.
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 1406 of file gnunet-communicator-udp.c.

1407 {
1408 
1409  struct ReceiverAddress *receiver = ss->receiver;
1410 
1411  GNUNET_assert (NULL != ss);
1412  GNUNET_assert (NULL != receiver);
1413 
1414  if (NULL == receiver->d_qh)
1415  {
1416  receiver->d_qh =
1418  &receiver->target,
1419  receiver->foreign_addr,
1420  receiver->d_mtu,
1421  acks_to_add,
1422  1, /* Priority */
1423  receiver->nt,
1425  receiver->d_mq);
1426  }
1427  else
1428  {
1430  receiver->d_qh,
1431  acks_to_add,
1432  1);
1433  }
1434 
1436  "Tell transport we have %u more acks!\n",
1437  acks_to_add);
1438 
1439  // Until here for alternativ 1
1440 
1441  /* move ss to head to avoid discarding it anytime soon! */
1442 
1443  GNUNET_CONTAINER_DLL_remove (receiver->ss_head, receiver->ss_tail, ss);
1444  GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss);
1445 }
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_CONTAINER_DLL_insert, GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_TRANSPORT_communicator_mq_add(), GNUNET_TRANSPORT_communicator_mq_update(), GNUNET_TRANSPORT_CS_OUTBOUND, SharedSecret::receiver, and 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_PeerIdentity pid,
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 1459 of file gnunet-communicator-udp.c.

1460 {
1461  const struct UDPAck *ack = cls;
1462  struct ReceiverAddress *receiver = value;
1463  uint32_t acks_to_add;
1464  uint32_t allowed;
1465 
1467  "in handle ack with cmac %s\n",
1468  GNUNET_h2s (&ack->cmac));
1469 
1470  (void) pid;
1471  for (struct SharedSecret *ss = receiver->ss_head; NULL != ss; ss = ss->next)
1472  {
1473  if (0 == memcmp (&ack->cmac, &ss->cmac, sizeof(struct GNUNET_HashCode)))
1474  {
1475 
1477  "Found matching cmac\n");
1478 
1479  allowed = ntohl (ack->sequence_ack);
1480 
1481  if (allowed <= ss->sequence_allowed)
1482  {
1484  "Ignoring ack, not giving us increased window\n.");
1485  return GNUNET_NO;
1486  }
1487  acks_to_add = (allowed - ss->sequence_allowed);
1488  GNUNET_assert (0 != acks_to_add);
1489  receiver->acks_available += (allowed - ss->sequence_allowed);
1490  ss->sequence_allowed = allowed;
1491  add_acks (ss, acks_to_add);
1493  "New sequence allows until %u (+%u). Acks available to us: %u. For secret %s\n",
1494  allowed,
1495  acks_to_add,
1496  receiver->acks_available,
1497  GNUNET_h2s (&ss->master));
1498  return GNUNET_NO;
1499  }
1500  }
1502  "Matching cmac not found for ack!\n");
1503  return GNUNET_YES;
1504 }
static void add_acks(struct SharedSecret *ss, int acks_to_add)
static char * value
Value of the record to add/remove.
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
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, pid, receiver(), UDPAck::sequence_ack, and value.

Referenced by enc_notify_cb(), 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 1516 of file gnunet-communicator-udp.c.

1517 {
1518  struct UDPAck ack;
1519  GNUNET_assert (NULL != ss->sender);
1521  "Considering SS UDPAck %s\n",
1522  GNUNET_i2s_full (&ss->sender->target));
1523 
1525  "Sender has %u acks available.\n",
1526  ss->sender->acks_available);
1527  /* drop ancient KeyCacheEntries */
1528  while ((NULL != ss->kce_head) &&
1529  (MAX_SQN_DELTA <
1531  kce_destroy (ss->kce_tail);
1532 
1533 
1534  ack.header.type = htons (GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK);
1535  ack.header.size = htons (sizeof(ack));
1536  ack.sequence_ack = htonl (ss->sequence_allowed);
1537  ack.cmac = ss->cmac;
1539  "Notifying transport with UDPAck %s, sequence %u and master %s\n",
1540  GNUNET_i2s_full (&ss->sender->target),
1541  ss->sequence_allowed,
1542  GNUNET_h2s (&(ss->master)));
1544  &ss->sender->target,
1546  &ack.header);
1547 }
#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 1551 of file gnunet-communicator-udp.c.

1552 {
1553  struct SharedSecret *ss = cls;
1554  ss->sender->kce_task = NULL;
1555 
1557  "Precomputing %u keys for master %s\n",
1559  GNUNET_h2s (&(ss->master)));
1560  if ((ss->override_available_acks != GNUNET_YES) &&
1561  (KCN_TARGET < ss->sender->acks_available))
1562  return;
1563  for (int i = 0; i < GENERATE_AT_ONCE; i++)
1564  kce_generate (ss, ++ss->sequence_allowed);
1565 
1570  if (KCN_TARGET > ss->sender->acks_available)
1571  {
1575  ss);
1576  return;
1577  }
1579  "We have enough keys (ACKs: %u).\n", ss->sender->acks_available);
1583  consider_ss_ack (ss);
1584 }
#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(), 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(), 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 1596 of file gnunet-communicator-udp.c.

1599 {
1600  const struct GNUNET_MessageHeader *hdr;
1601  const struct UDPAck *ack;
1602  const struct UDPRekey *rekey;
1603  struct SharedSecret *ss_rekey;
1604  const char *buf_pos = buf;
1605  size_t bytes_remaining = buf_size;
1606  uint16_t type;
1607 
1608  hdr = (struct GNUNET_MessageHeader*) buf_pos;
1609  if (sizeof(*hdr) > bytes_remaining)
1610  {
1611  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Plaintext too short, dropping...\n");
1612  return; /* no data left */
1613  }
1615  "try_handle_plaintext of size %lu (%u %lu) and type %u\n",
1616  bytes_remaining,
1617  ntohs (hdr->size),
1618  sizeof(*hdr),
1619  ntohs (hdr->type));
1620  if (ntohs (hdr->size) > bytes_remaining)
1621  return; /* buffer too short for indicated message length */
1622  type = ntohs (hdr->type);
1623  switch (type)
1624  {
1626  rekey = (struct UDPRekey*) buf_pos;
1627  ss_rekey = setup_shared_secret_dec (&rekey->ephemeral);
1628  ss_rekey->sender = sender;
1629  GNUNET_CONTAINER_DLL_insert (sender->ss_head, sender->ss_tail, ss_rekey);
1630  sender->num_secrets++;
1632  "Received rekey secret with cmac %s\n",
1633  GNUNET_h2s (&(ss_rekey->cmac)));
1635  "Received secret with master %s.\n",
1636  GNUNET_h2s (&(ss_rekey->master)));
1638  "We have %u sequence_allowed.\n",
1639  ss_rekey->sequence_allowed);
1641  "We have a sender %p\n",
1642  ss_rekey->sender);
1644  "We have %u acks available.\n",
1645  ss_rekey->sender->acks_available);
1647  ss_rekey->override_available_acks = GNUNET_YES;
1648  // FIXME
1652  ss_rekey);
1653  // FIXME: Theoretically, this could be an Ack
1654  buf_pos += ntohs (hdr->size);
1655  bytes_remaining -= ntohs (hdr->size);
1656  pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
1657  if (sender->num_secrets > MAX_SECRETS)
1658  {
1659  if (0 == purge_secrets (sender->ss_tail))
1660  {
1661  // No secret purged. Delete oldest.
1662  secret_destroy (sender->ss_tail);
1663  }
1664  }
1665  break;
1667  /* lookup master secret by 'cmac', then update sequence_max */
1668  ack = (struct UDPAck*) buf_pos;
1670  &sender->target,
1671  &handle_ack,
1672  (void *) ack);
1673  /* There could be more messages after the ACK, handle those as well */
1674  buf_pos += ntohs (hdr->size);
1675  bytes_remaining -= ntohs (hdr->size);
1676  pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
1677  break;
1678 
1680  /* skip padding */
1681  break;
1682 
1683  default:
1684  pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
1685  }
1686  return;
1687 }
unsigned int purge_secrets(struct SharedSecret *ss_list_tail)
Best effort try to purge some secrets.
static int handle_ack(void *cls, const struct GNUNET_PeerIdentity *pid, void *value)
We received an ACK for pid.
static void pass_plaintext_to_core(struct SenderAddress *sender, const void *plaintext, size_t plaintext_len)
We received plaintext_len bytes of plaintext from a sender.
#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 char buf[2048]
int GNUNET_CONTAINER_multipeermap_get_multiple(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, GNUNET_CONTAINER_PeerMapIterator it, void *it_cls)
Iterate over all entries in the map that match a particular key.
@ GNUNET_ERROR_TYPE_ERROR
#define GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_REKEY
UDP Rekey.
#define GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_PAD
UDP communicator padding.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
Plaintext of a rekey payload in a UDPBox.
struct GNUNET_CRYPTO_EcdhePublicKey ephemeral
Ephemeral key to rekey with.
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model

References SenderAddress::acks_available, buf, SharedSecret::cmac, UDPRekey::ephemeral, GNUNET_CONTAINER_DLL_insert, GNUNET_CONTAINER_multipeermap_get_multiple(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_h2s(), GNUNET_log, GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK, GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_PAD, GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_REKEY, GNUNET_SCHEDULER_add_delayed(), GNUNET_YES, handle_ack(), kce_generate_cb(), SenderAddress::kce_send_ack_on_finish, SenderAddress::kce_task, 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, SenderAddress::target, GNUNET_MessageHeader::type, type, and WORKING_QUEUE_INTERVALL.

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

1701 {
1702  struct SharedSecret *ss = kce->ss;
1703  char out_buf[box_len - sizeof(*box)];
1704 
1705  GNUNET_assert (NULL != ss->sender);
1706  if (GNUNET_OK != try_decrypt (ss,
1707  box->gcm_tag,
1708  kce->sequence_number,
1709  (const char *) &box[1],
1710  sizeof(out_buf),
1711  out_buf))
1712  {
1713  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed decryption.\n");
1715  "# Decryption failures with valid KCE",
1716  1,
1717  GNUNET_NO);
1718  kce_destroy (kce);
1719  return;
1720  }
1721  kce_destroy (kce);
1722  kce = NULL;
1724  "# bytes decrypted with BOX",
1725  sizeof(out_buf),
1726  GNUNET_NO);
1728  "# messages decrypted with BOX",
1729  1,
1730  GNUNET_NO);
1732  "decrypted UDPBox with kid %s\n",
1733  GNUNET_sh2s (&box->kid));
1734  try_handle_plaintext (ss->sender, out_buf, sizeof(out_buf));
1735  if ((KCN_THRESHOLD > ss->sender->acks_available) &&
1736  (NULL == ss->sender->kce_task) &&
1738  {
1740  "Sender has %u ack left which is under threshold.\n",
1741  ss->sender->acks_available);
1745  ss);
1746  }
1747 }
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...
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:1299
uint8_t gcm_tag[(128/8)]
128-bit authentication tag for the following encrypted message, from GCM.

References SenderAddress::acks_available, 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::sender, KeyCacheEntry::sequence_number, KeyCacheEntry::ss, 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:

◆ find_sender_by_address()

static int find_sender_by_address ( void *  cls,
const struct GNUNET_PeerIdentity key,
void *  value 
)
static

Find existing struct SenderAddress by matching addresses.

Parameters
clsa struct SearchContext
keyignored, must match already
valuea struct SenderAddress
Returns
GNUNET_YES if not found (continue to search), GNUNET_NO if found

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

1784 {
1785  struct SearchContext *sc = cls;
1786  struct SenderAddress *sender = value;
1787 
1788  if ((sender->address_len == sc->address_len) &&
1789  (0 == memcmp (sender->address, sc->address, sender->address_len)))
1790  {
1791  sc->sender = sender;
1792  return GNUNET_NO; /* stop iterating! */
1793  }
1794  return GNUNET_YES;
1795 }
static struct GNUNET_FS_SearchContext * sc
Definition: gnunet-search.c:87
Context information to be used while searching for operation contexts.
Definition: testbed_api.c:226
socklen_t address_len
Length of the address.

References SenderAddress::address, SenderAddress::address_len, GNUNET_NO, GNUNET_YES, sc, and value.

Referenced by setup_sender().

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

1813 {
1814  struct SenderAddress *sender;
1815  struct SearchContext sc = { .address = address,
1816  .address_len = address_len,
1817  .sender = NULL };
1818 
1820  target,
1822  &sc);
1823  if (NULL != sc.sender)
1824  {
1825  reschedule_sender_timeout (sc.sender);
1826  return sc.sender;
1827  }
1828  sender = GNUNET_new (struct SenderAddress);
1829  sender->target = *target;
1833  senders,
1834  &sender->target,
1835  sender,
1838  "# senders active",
1840  GNUNET_NO);
1841  sender->timeout =
1844  sender,
1847  if (NULL == timeout_task)
1849  return sender;
1850 }
static int find_sender_by_address(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
Find existing struct SenderAddress by matching addresses.
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.
int GNUNET_CONTAINER_multipeermap_put(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *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.
#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:308
struct SenderAddress * sender
Return value to set if we found a match.
socklen_t address_len
Number of bytes in 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, SearchContext::address_len, check_timeouts(), find_sender_by_address(), GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, GNUNET_CONTAINER_heap_insert(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE, GNUNET_CONTAINER_multipeermap_get_multiple(), GNUNET_CONTAINER_multipeermap_put(), GNUNET_CONTAINER_multipeermap_size(), 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::nt, receivers, reschedule_sender_timeout(), sc, SearchContext::sender, 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 1861 of file gnunet-communicator-udp.c.

1863 {
1864  struct UdpHandshakeSignature uhs;
1865 
1866  uhs.purpose.purpose = htonl (
1868  uhs.purpose.size = htonl (sizeof(uhs));
1869  uhs.sender = uc->sender;
1870  uhs.receiver = my_identity;
1871  uhs.ephemeral = *ephemeral;
1872  uhs.monotonic_time = uc->monotonic_time;
1875  &uhs,
1876  &uc->sender_sig,
1877  &uc->sender.public_key);
1878 }
#define GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_HANDSHAKE
Signature used by UDP communicator handshake.
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.
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 1890 of file gnunet-communicator-udp.c.

1892 {
1893  char *ret;
1894 
1895  switch (address->sa_family)
1896  {
1897  case AF_INET:
1898  GNUNET_asprintf (&ret,
1899  "%s-%s",
1901  GNUNET_a2s (address, address_len));
1902  break;
1903 
1904  case AF_INET6:
1905  GNUNET_asprintf (&ret,
1906  "%s-%s",
1908  GNUNET_a2s (address, address_len));
1909  break;
1910 
1911  default:
1912  GNUNET_assert (0);
1913  }
1914  return ret;
1915 }
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
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 1924 of file gnunet-communicator-udp.c.

1925 {
1926  struct sockaddr_storage sa;
1927  struct sockaddr_in *addr_verify;
1928  socklen_t salen = sizeof(sa);
1929  char buf[UINT16_MAX];
1930  ssize_t rcvd;
1931 
1932  (void) cls;
1934  udp_sock,
1935  &sock_read,
1936  NULL);
1937  while (1)
1938  {
1940  buf,
1941  sizeof(buf),
1942  (struct sockaddr *) &sa,
1943  &salen);
1944  if (-1 == rcvd)
1945  {
1946  if (EAGAIN == errno)
1947  break; // We are done reading data
1949  return;
1950  }
1952  "Read %lu bytes\n", rcvd);
1953 
1954  /* first, see if it is a UDPBox */
1955  if (rcvd > sizeof(struct UDPBox))
1956  {
1957  const struct UDPBox *box;
1958  struct KeyCacheEntry *kce;
1959 
1960  box = (const struct UDPBox *) buf;
1962  if (NULL != kce)
1963  {
1965  "Found KCE with kid %s\n",
1966  GNUNET_sh2s (&box->kid));
1967  decrypt_box (box, (size_t) rcvd, kce);
1968  continue;
1969  }
1970  }
1971 
1972  /* next, check if it is a broadcast */
1973  if (sizeof(struct UDPBroadcast) == rcvd)
1974  {
1975  const struct UDPBroadcast *ub;
1976  struct UdpBroadcastSignature uhs;
1977  struct GNUNET_PeerIdentity sender;
1978 
1979  addr_verify = GNUNET_memdup (&sa, salen);
1980  addr_verify->sin_port = 0;
1982  "received UDPBroadcast from %s\n",
1983  GNUNET_a2s ((const struct sockaddr *) addr_verify, salen));
1984  ub = (const struct UDPBroadcast *) buf;
1985  uhs.purpose.purpose = htonl (
1987  uhs.purpose.size = htonl (sizeof(uhs));
1988  uhs.sender = ub->sender;
1989  sender = ub->sender;
1990  if (0 == memcmp (&sender, &my_identity, sizeof (struct
1992  {
1994  "Received our own broadcast\n");
1995  GNUNET_free (addr_verify);
1996  continue;
1997  }
1999  "checking UDPBroadcastSignature for %s\n",
2000  GNUNET_i2s (&sender));
2001  GNUNET_CRYPTO_hash ((struct sockaddr *) addr_verify, salen,
2002  &uhs.h_address);
2003  if (GNUNET_OK ==
2006  &uhs,
2007  &ub->sender_sig,
2008  &ub->sender.public_key))
2009  {
2010  char *addr_s;
2011  enum GNUNET_NetworkType nt;
2012 
2013  addr_s =
2014  sockaddr_to_udpaddr_string ((const struct sockaddr *) &sa, salen);
2015  GNUNET_STATISTICS_update (stats, "# broadcasts received", 1, GNUNET_NO);
2016  /* use our own mechanism to determine network type */
2017  nt =
2018  GNUNET_NT_scanner_get_type (is, (const struct sockaddr *) &sa, salen);
2020  "validating address %s received from UDPBroadcast\n",
2021  GNUNET_i2s (&sender));
2023  GNUNET_free (addr_s);
2024  GNUNET_free (addr_verify);
2025  continue;
2026  }
2027  else
2028  {
2030  "VerifyingPeer %s is verifying UDPBroadcast\n",
2031  GNUNET_i2s (&my_identity));
2033  "Verifying UDPBroadcast from %s failed\n",
2034  GNUNET_i2s (&ub->sender));
2035  }
2036  GNUNET_free (addr_verify);
2037  /* continue with KX, mostly for statistics... */
2038  }
2039 
2040 
2041  /* finally, test if it is a KX */
2042  if (rcvd < sizeof(struct UDPConfirmation) + sizeof(struct InitialKX))
2043  {
2045  "# messages dropped (no kid, too small for KX)",
2046  1,
2047  GNUNET_NO);
2048  continue;
2049  }
2051  "Got KX\n");
2052  {
2053  const struct InitialKX *kx;
2054  struct SharedSecret *ss;
2055  char pbuf[rcvd - sizeof(struct InitialKX)];
2056  const struct UDPConfirmation *uc;
2057  struct SenderAddress *sender;
2058 
2059  kx = (const struct InitialKX *) buf;
2060  ss = setup_shared_secret_dec (&kx->ephemeral);
2062  "Before DEC\n");
2063 
2064  if (GNUNET_OK != try_decrypt (ss,
2065  kx->gcm_tag,
2066  0,
2067  &buf[sizeof(*kx)],
2068  sizeof(pbuf),
2069  pbuf))
2070  {
2072  "Unable to decrypt tag, dropping...\n");
2073  GNUNET_free (ss);
2075  stats,
2076  "# messages dropped (no kid, AEAD decryption failed)",
2077  1,
2078  GNUNET_NO);
2079  continue;
2080  }
2082  "Before VERIFY\n");
2083 
2084  uc = (const struct UDPConfirmation *) pbuf;
2085  if (GNUNET_OK != verify_confirmation (&kx->ephemeral, uc))
2086  {
2087  GNUNET_break_op (0);
2088  GNUNET_free (ss);
2090  "# messages dropped (sender signature invalid)",
2091  1,
2092  GNUNET_NO);
2093  continue;
2094  }
2096  "Before SETUP_SENDER\n");
2097 
2098  calculate_cmac (ss);
2099  sender = setup_sender (&uc->sender, (const struct sockaddr *) &sa, salen);
2100  ss->sender = sender;
2101  GNUNET_CONTAINER_DLL_insert (sender->ss_head, sender->ss_tail, ss);
2102  if ((KCN_THRESHOLD > ss->sender->acks_available) &&
2103  (NULL == ss->sender->kce_task) &&
2105  {
2106  // 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.
2110  ss);
2111  }
2112  sender->num_secrets++;
2113  GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
2115  "# messages decrypted without BOX",
2116  1,
2117  GNUNET_NO);
2118  try_handle_plaintext (sender, &uc[1], sizeof(pbuf) - sizeof(*uc));
2119  if (sender->num_secrets > MAX_SECRETS)
2120  {
2121  if (0 == purge_secrets (sender->ss_tail))
2122  {
2123  // No secret purged. Delete oldest.
2124  secret_destroy (sender->ss_tail);
2125  }
2126  }
2127  }
2128  }
2129 }
#define GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_BROADCAST
Signature used by UDP broadcasts.
static void sock_read(void *cls)
Socket read task.
static struct SenderAddress * setup_sender(const struct GNUNET_PeerIdentity *target, const struct sockaddr *address, socklen_t address_len)
Create sender address for target.
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 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_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.
ssize_t GNUNET_NETWORK_socket_recvfrom(const struct GNUNET_NETWORK_Handle *desc, void *buffer, size_t length, struct sockaddr *src_addr, socklen_t *addrlen)
Read data from a socket (always non-blocking).
Definition: network.c:688
GNUNET_NetworkType
Types of networks (with separate quotas) we support.
Definition: gnunet_nt_lib.h:39
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:1506
The identity of the host (wraps the signing key of the peer).
struct GNUNET_CRYPTO_EddsaPublicKey public_key
uint8_t gcm_tag[(128/8)]
HMAC for the following encrypted message, using GCM.
struct GNUNET_CRYPTO_EcdhePublicKey ephemeral
Ephemeral key for KX.
struct GNUNET_ShortHashCode kid
Key and IV identification code.
Broadcast by peer in LAN announcing its presence.
struct GNUNET_CRYPTO_EddsaSignature sender_sig
Sender's signature of type GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_BROADCAST.
struct GNUNET_PeerIdentity sender
Sender's peer identity.
struct GNUNET_PeerIdentity sender
Sender's identity.
Signature we use to verify that the broadcast was really made by the peer that claims to have made it...

References SenderAddress::acks_available, ah, buf, calculate_cmac(), decrypt_box(), InitialKX::ephemeral, InitialKX::gcm_tag, GNUNET_a2s(), GNUNET_break_op, GNUNET_CONTAINER_DLL_insert, GNUNET_CONTAINER_multishortmap_get(), GNUNET_CRYPTO_eddsa_verify, GNUNET_CRYPTO_hash(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_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, GNUNET_PeerIdentity::public_key, purge_secrets(), GNUNET_CRYPTO_EccSignaturePurpose::purpose, UdpBroadcastSignature::purpose, read_task, secret_destroy(), UDPConfirmation::sender, UDPBroadcast::sender, UdpBroadcastSignature::sender, SharedSecret::sender, UDPBroadcast::sender_sig, setup_sender(), setup_shared_secret_dec(), GNUNET_CRYPTO_EccSignaturePurpose::size, sockaddr_to_udpaddr_string(), stats, try_decrypt(), try_handle_plaintext(), uc, udp_sock, and verify_confirmation().

Referenced by run().

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

2141 {
2142  struct sockaddr *in;
2143  unsigned int port;
2144  char dummy[2];
2145  char *colon;
2146  char *cp;
2147 
2148  if (1 == sscanf (bindto, "%u%1s", &port, dummy))
2149  {
2150  /* interpreting value as just a PORT number */
2151  if (port > UINT16_MAX)
2152  {
2154  "BINDTO specification `%s' invalid: value too large for port\n",
2155  bindto);
2156  return NULL;
2157  }
2158  if ((GNUNET_NO == GNUNET_NETWORK_test_pf (PF_INET6)) ||
2159  (GNUNET_YES ==
2162  "DISABLE_V6")))
2163  {
2164  struct sockaddr_in *i4;
2165 
2166  i4 = GNUNET_malloc (sizeof(struct sockaddr_in));
2167  i4->sin_family = AF_INET;
2168  i4->sin_port = htons ((uint16_t) port);
2169  *sock_len = sizeof(struct sockaddr_in);
2170  in = (struct sockaddr *) i4;
2171  }
2172  else
2173  {
2174  struct sockaddr_in6 *i6;
2175 
2176  i6 = GNUNET_malloc (sizeof(struct sockaddr_in6));
2177  i6->sin6_family = AF_INET6;
2178  i6->sin6_port = htons ((uint16_t) port);
2179  *sock_len = sizeof(struct sockaddr_in6);
2180  in = (struct sockaddr *) i6;
2181  }
2182  return in;
2183  }
2184  cp = GNUNET_strdup (bindto);
2185  colon = strrchr (cp, ':');
2186  if (NULL != colon)
2187  {
2188  /* interpret value after colon as port */
2189  *colon = '\0';
2190  colon++;
2191  if (1 == sscanf (colon, "%u%1s", &port, dummy))
2192  {
2193  /* interpreting value as just a PORT number */
2194  if (port > UINT16_MAX)
2195  {
2197  "BINDTO specification `%s' invalid: value too large for port\n",
2198  bindto);
2199  GNUNET_free (cp);
2200  return NULL;
2201  }
2202  }
2203  else
2204  {
2205  GNUNET_log (
2207  "BINDTO specification `%s' invalid: last ':' not followed by number\n",
2208  bindto);
2209  GNUNET_free (cp);
2210  return NULL;
2211  }
2212  }
2213  else
2214  {
2215  /* interpret missing port as 0, aka pick any free one */
2216  port = 0;
2217  }
2218  {
2219  /* try IPv4 */
2220  struct sockaddr_in v4;
2221 
2222  memset (&v4, 0, sizeof(v4));
2223  if (1 == inet_pton (AF_INET, cp, &v4.sin_addr))
2224  {
2225  v4.sin_family = AF_INET;
2226  v4.sin_port = htons ((uint16_t) port);
2227 #if HAVE_SOCKADDR_IN_SIN_LEN
2228  v4.sin_len = sizeof(struct sockaddr_in);
2229 #endif
2230  in = GNUNET_memdup (&v4, sizeof(struct sockaddr_in));
2231  *sock_len = sizeof(struct sockaddr_in);
2232  GNUNET_free (cp);
2233  return in;
2234  }
2235  }
2236  {
2237  /* try IPv6 */
2238  struct sockaddr_in6 v6;
2239  const char *start;
2240 
2241  memset (&v6, 0, sizeof(v6));
2242  start = cp;
2243  if (('[' == *cp) && (']' == cp[strlen (cp) - 1]))
2244  {
2245  start++; /* skip over '[' */
2246  cp[strlen (cp) - 1] = '\0'; /* eat ']' */
2247  }
2248  if (1 == inet_pton (AF_INET6, start, &v6.sin6_addr))
2249  {
2250  v6.sin6_family = AF_INET6;
2251  v6.sin6_port = htons ((uint16_t) port);
2252 #if HAVE_SOCKADDR_IN_SIN_LEN
2253  v6.sin6_len = sizeof(sizeof(struct sockaddr_in6));
2254 #endif
2255  in = GNUNET_memdup (&v6, sizeof(v6));
2256  *sock_len = sizeof(v6);
2257  GNUNET_free (cp);
2258  return in;
2259  }
2260  }
2261  /* #5528 FIXME (feature!): maybe also try getnameinfo()? */
2262  GNUNET_free (cp);
2263  return NULL;
2264 }
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 const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
#define COMMUNICATOR_CONFIG_SECTION
Configuration section used by the communicator.
static struct in_addr dummy
Target "dummy" address of the packet we pretend to respond to.
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".
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_malloc(size)
Wrapper around malloc.
enum GNUNET_GenericReturnValue GNUNET_NETWORK_test_pf(int pf)
Test if the given protocol family is supported by this system.
Definition: network.c:80

References cfg, COMMUNICATOR_CONFIG_SECTION, dummy, GNUNET_CONFIGURATION_get_value_yesno(), GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_log, GNUNET_malloc, GNUNET_memdup, GNUNET_NETWORK_test_pf(), GNUNET_NO, GNUNET_strdup, GNUNET_YES, port, and start.

Referenced by mq_init(), and run().

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

◆ do_pad()

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

Pad dgram by pad_size using out_cipher.

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

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

2276 {
2277  char pad[pad_size];
2278 
2280  if (sizeof(pad) > sizeof(struct GNUNET_MessageHeader))
2281  {
2282  struct GNUNET_MessageHeader hdr =
2283  { .size = htons (sizeof(pad)),
2284  .type = htons (GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_PAD) };
2285 
2286  memcpy (pad, &hdr, sizeof(hdr));
2287  }
2288  GNUNET_assert (
2289  0 ==
2290  gcry_cipher_encrypt (out_cipher, dgram, sizeof(pad), pad, sizeof(pad)));
2291 }
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 
)
static

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

2297 {
2298  uint16_t msize = ntohs (msg->size);
2299  struct UdpHandshakeSignature uhs;
2300  struct UDPConfirmation uc;
2301  struct InitialKX kx;
2302  char dgram[receiver->kx_mtu + sizeof(uc) + sizeof(kx)];
2303  size_t dpos;
2304  gcry_cipher_hd_t out_cipher;
2305  struct SharedSecret *ss;
2306 
2307  if (msize > receiver->kx_mtu)
2308  {
2309  GNUNET_break (0);
2310  if (GNUNET_YES != receiver->receiver_destroy_called)
2312  return;
2313  }
2315 
2316  /* setup key material */
2317 
2318  ss = setup_shared_secret_ephemeral (&uhs.ephemeral, receiver);
2319 
2320  if (receiver->num_secrets > MAX_SECRETS)
2321  {
2322  if (0 == purge_secrets (receiver->ss_tail))
2323  {
2324  // No secret purged. Delete oldest.
2325  secret_destroy (receiver->ss_tail);
2326  }
2327  }
2328 
2329  setup_cipher (&ss->master, 0, &out_cipher);
2330  /* compute 'uc' */
2331  uc.sender = my_identity;
2332  uc.monotonic_time =
2334  uhs.purpose.purpose = htonl (
2336  uhs.purpose.size = htonl (sizeof(uhs));
2337  uhs.sender = my_identity;
2338  uhs.receiver = receiver->target;
2339  uhs.monotonic_time = uc.monotonic_time;
2341  &uhs,
2342  &uc.sender_sig);
2343  /* Leave space for kx */
2344  dpos = sizeof(kx);
2345  /* Append encrypted uc to dgram */
2346  GNUNET_assert (0 == gcry_cipher_encrypt (out_cipher,
2347  &dgram[dpos],
2348  sizeof(uc),
2349  &uc,
2350  sizeof(uc)));
2351  dpos += sizeof(uc);
2352  /* Append encrypted payload to dgram */
2353  GNUNET_assert (
2354  0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], msize, msg, msize));
2355  dpos += msize;
2356  do_pad (out_cipher, &dgram[dpos], sizeof(dgram) - dpos);
2357  /* Datagram starts with kx */
2358  kx.ephemeral = uhs.ephemeral;
2359  GNUNET_assert (
2360  0 == gcry_cipher_gettag (out_cipher, kx.gcm_tag, sizeof(kx.gcm_tag)));
2361  gcry_cipher_close (out_cipher);
2362  memcpy (dgram, &kx, sizeof(kx));
2364  dgram,
2365  sizeof(dgram),
2366  receiver->address,
2367  receiver->address_len))
2370  "Sending KX with payload size %u to %s\n",
2371  msize,
2372  GNUNET_a2s (receiver->address,
2373  receiver->address_len));
2374 }
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
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_shared_secret_ephemeral(struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral, struct ReceiverAddress *receiver)
Setup new shared secret for encryption using KEM.
#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.
ssize_t GNUNET_NETWORK_socket_sendto(const struct GNUNET_NETWORK_Handle *desc, const void *message, size_t length, const struct sockaddr *dest_addr, socklen_t dest_len)
Send data to a particular destination (always non-blocking).
Definition: network.c:772
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get_monotonic(const struct GNUNET_CONFIGURATION_Handle *cfg)
Obtain the current time and make sure it is monotonically increasing.
Definition: time.c: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

References cfg, do_pad(), InitialKX::ephemeral, UdpHandshakeSignature::ephemeral, InitialKX::gcm_tag, GNUNET_a2s(), GNUNET_assert, GNUNET_break, GNUNET_CRYPTO_eddsa_sign, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, GNUNET_log, GNUNET_log_strerror, 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, msg, my_identity, my_private_key, purge_secrets(), GNUNET_CRYPTO_EccSignaturePurpose::purpose, UdpHandshakeSignature::purpose, UdpHandshakeSignature::receiver, receiver(), receiver_destroy(), reschedule_receiver_timeout(), secret_destroy(), UdpHandshakeSignature::sender, setup_cipher(), setup_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 2386 of file gnunet-communicator-udp.c.

2389 {
2390  struct ReceiverAddress *receiver = impl_state;
2391 
2392  GNUNET_assert (mq == receiver->kx_mq);
2395 }
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
static void send_msg_with_kx(const struct GNUNET_MessageHeader *msg, struct ReceiverAddress *receiver)
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

References GNUNET_assert, GNUNET_MQ_impl_send_continue(), 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 2399 of file gnunet-communicator-udp.c.

2401 {
2402  struct SharedSecret *ss_rekey;
2403 
2405  /* setup key material */
2406  ss_rekey = setup_shared_secret_ephemeral (&rekey->ephemeral,
2407  receiver);
2408  ss_rekey->sequence_allowed = 0;
2410  "Setup secret with k = %s\n",
2411  GNUNET_h2s (&(ss_rekey->master)));
2413  "Setup secret with H(k) = %s\n",
2414  GNUNET_h2s (&(ss_rekey->cmac)));
2415 
2416  /* Append encrypted payload to dgram */
2418  rekey->header.size = htons (sizeof (struct UDPRekey));
2419 }
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 2431 of file gnunet-communicator-udp.c.

2434 {
2435  struct ReceiverAddress *receiver = impl_state;
2436  struct UDPRekey rekey;
2437  struct SharedSecret *ss;
2438  int inject_rekey = GNUNET_NO;
2439  uint16_t msize = ntohs (msg->size);
2440 
2441  GNUNET_assert (mq == receiver->d_mq);
2442  if ((msize > receiver->d_mtu) ||
2443  (0 == receiver->acks_available))
2444  {
2446  "msize: %u, mtu: %lu, acks: %u\n",
2447  msize,
2448  receiver->d_mtu,
2449  receiver->acks_available);
2450 
2451  GNUNET_break (0);
2452  if (GNUNET_YES != receiver->receiver_destroy_called)
2454  return;
2455  }
2457 
2458  if (receiver->num_secrets > MAX_SECRETS)
2459  {
2460  if (0 == purge_secrets (receiver->ss_tail))
2461  {
2462  // No secret purged. Delete oldest.
2463  secret_destroy (receiver->ss_tail);
2464  }
2465  }
2466  /* begin "BOX" encryption method, scan for ACKs from tail! */
2467  for (ss = receiver->ss_tail; NULL != ss; ss = ss->prev)
2468  {
2469  size_t payload_len = sizeof(struct UDPBox) + receiver->d_mtu;
2470  if (ss->sequence_used >= ss->sequence_allowed)
2471  {
2473  "Skipping ss because no acks to use.\n");
2474  continue;
2475  }
2476  if (ss->bytes_sent >= rekey_max_bytes)
2477  {
2479  "Skipping ss because rekey bytes reached.\n");
2480  // FIXME cleanup ss with too many bytes sent!
2481  continue;
2482  }
2483  if (ss->bytes_sent > rekey_max_bytes * 0.7)
2484  {
2485  if (ss->rekey_initiated == GNUNET_NO)
2486  {
2488  "Injecting rekey for ss with byte sent %lu\n",
2489  (unsigned long) ss->bytes_sent);
2490  create_rekey (receiver, ss, &rekey);
2492  payload_len += sizeof (rekey);
2494  }
2495  }
2496  if (0 < ss->sequence_used)
2498  "Trying to send UDPBox with shared secrect %s sequence_used %u and ss->sequence_allowed %u\n",
2499  GNUNET_h2s (&ss->master),
2500  ss->sequence_used,
2501  ss->sequence_allowed);
2502 
2503  char dgram[payload_len];
2504  struct UDPBox *box;
2505  gcry_cipher_hd_t out_cipher;
2506  size_t dpos;
2507 
2508  box = (struct UDPBox *) dgram;
2509  ss->sequence_used++;
2510  get_kid (&ss->master, ss->sequence_used, &box->kid);
2511  setup_cipher (&ss->master, ss->sequence_used, &out_cipher);
2512  /* Append encrypted payload to dgram */
2513  dpos = sizeof(struct UDPBox);
2514  if (GNUNET_YES == inject_rekey)
2515  {
2516  GNUNET_assert (
2517  0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], sizeof (rekey),
2518  &rekey, sizeof (rekey)));
2519  dpos += sizeof (rekey);
2520  }
2521  GNUNET_assert (
2522  0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], msize, msg, msize));
2523  dpos += msize;
2524  do_pad (out_cipher, &dgram[dpos], sizeof(dgram) - dpos);
2525  GNUNET_assert (0 == gcry_cipher_gettag (out_cipher,
2526  box->gcm_tag,
2527  sizeof(box->gcm_tag)));
2528  gcry_cipher_close (out_cipher);
2529 
2531  dgram,
2532  payload_len, // FIXME why always send sizeof dgram?
2533  receiver->address,
2534  receiver->address_len))
2537  "Sending UDPBox with payload size %u, %u acks left, %lu bytes sent\n",
2538  msize,
2539  receiver->acks_available,
2540  (unsigned long) ss->bytes_sent);
2541  ss->bytes_sent += sizeof (dgram);
2542  receiver->acks_available--;
2544  return;
2545  }
2547  "No suitable ss found, sending as KX...\n");
2550 }
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)
static unsigned long long rekey_max_bytes
How often we do rekey based on number of bytes transmitted.

References SharedSecret::bytes_sent, create_rekey(), do_pad(), UDPBox::gcm_tag, get_kid(), 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 2562 of file gnunet-communicator-udp.c.

2563 {
2564  struct ReceiverAddress *receiver = impl_state;
2566  "Default MQ destroyed\n");
2567  if (mq == receiver->d_mq)
2568  {
2569  receiver->d_mq = NULL;
2570  if (GNUNET_YES != receiver->receiver_destroy_called)
2572  }
2573 }

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

2586 {
2587  struct ReceiverAddress *receiver = impl_state;
2589  "KX MQ destroyed\n");
2590  if (mq == receiver->kx_mq)
2591  {
2592  receiver->kx_mq = NULL;
2593  if (GNUNET_YES != receiver->receiver_destroy_called)
2595  }
2596 }

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

2607 {
2608  /* Cancellation is impossible with UDP; bail */
2609  GNUNET_assert (0);
2610 }

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

2624 {
2625  struct ReceiverAddress *receiver = cls;
2626 
2628  "MQ error in queue to %s: %d\n",
2629  GNUNET_i2s (&receiver->target),
2630  (int) error);
2632 }

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

2725 {
2726  struct ReceiverAddress *receiver;
2727  const char *path;
2728  struct sockaddr *in;
2729  socklen_t in_len;
2730 
2731  if (0 != strncmp (address,
2733  strlen (COMMUNICATOR_ADDRESS_PREFIX "-")))
2734  {
2735  GNUNET_break_op (0);
2736  return GNUNET_SYSERR;
2737  }
2738  path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")];
2739  in = udp_address_to_sockaddr (path, &in_len);
2740 
2741  receiver = GNUNET_new (struct ReceiverAddress);
2742  receiver->address = in;
2743  receiver->address_len = in_len;
2744  receiver->target = *peer;
2745  receiver->nt = GNUNET_NT_scanner_get_type (is, in, in_len);
2747  receivers,
2748  &receiver->target,
2749  receiver,
2752  "Added %s to receivers\n",
2753  GNUNET_i2s_full (&receiver->target));
2754  receiver->timeout =
2757  receiver,
2758  receiver->timeout.abs_value_us);
2760  "# receivers active",
2762  GNUNET_NO);
2763  receiver->foreign_addr =
2764  sockaddr_to_udpaddr_string (receiver->address, receiver->address_len);
2766  if (NULL == timeout_task)
2768  return GNUNET_OK;
2769 }
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 *
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.

References address, check_timeouts(), COMMUNICATOR_ADDRESS_PREFIX, GNUNET_break_op, GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, GNUNET_CONTAINER_heap_insert(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE, GNUNET_CONTAINER_multipeermap_put(), GNUNET_CONTAINER_multipeermap_size(), GNUNET_ERROR_TYPE_DEBUG, 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(), is, peer, 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_PeerIdentity 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 2781 of file gnunet-communicator-udp.c.

2784 {
2785  struct ReceiverAddress *receiver = value;
2786 
2787  (void) cls;
2788  (void) target;
2790  return GNUNET_OK;
2791 }
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_PeerIdentity 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 2803 of file gnunet-communicator-udp.c.

2806 {
2807  struct SenderAddress *sender = value;
2808 
2809  (void) cls;
2810  (void) target;
2811 
2812 
2813  sender_destroy (sender);
2814  return GNUNET_OK;
2815 }

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

2825 {
2827  "do_shutdown\n");
2828  if (NULL != nat)
2829  {
2831  nat = NULL;
2832  }
2833  while (NULL != bi_head)
2834  bi_destroy (bi_head);
2835  if (NULL != broadcast_task)
2836  {
2838  broadcast_task = NULL;
2839  }
2840  if (NULL != timeout_task)
2841  {
2843  timeout_task = NULL;
2844  }
2845  if (NULL != read_task)
2846  {
2848  read_task = NULL;
2849  }
2850  if (NULL != udp_sock)
2851  {
2854  udp_sock = NULL;
2855  }
2858  NULL);
2862  NULL);
2867  if (NULL != timeout_task)
2868  {
2870  timeout_task = NULL;
2871  }
2872  if (NULL != ch)
2873  {
2875  ch = NULL;
2876  }
2877  if (NULL != ah)
2878  {
2880  ah = NULL;
2881  }
2882  if (NULL != stats)
2883  {
2885  stats = NULL;
2886  }
2887  if (NULL != my_private_key)
2888  {
2890  my_private_key = NULL;
2891  }
2892  if (NULL != is)
2893  {
2895  is = NULL;
2896  }
2898  "do_shutdown finished\n");
2899 }
static struct GNUNET_SCHEDULER_Task * broadcast_task
ID of master broadcast task.
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.
static int get_receiver_delete_it(void *cls, const struct GNUNET_PeerIdentity *target, void *value)
Iterator over all receivers to clean up.
static int get_sender_delete_it(void *cls, const struct GNUNET_PeerIdentity *target, void *value)
Iterator over all senders to clean up.
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.
void GNUNET_CONTAINER_multipeermap_destroy(struct GNUNET_CONTAINER_MultiPeerMap *map)
Destroy a hash map.
int GNUNET_CONTAINER_multipeermap_iterate(struct GNUNET_CONTAINER_MultiPeerMap *map, GNUNET_CONTAINER_PeerMapIterator it, void *it_cls)
Iterate over all entries in the 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:674
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:509
void GNUNET_NT_scanner_done(struct GNUNET_NT_InterfaceScanner *is)
Terminate interface scanner.
Definition: nt.c:427
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_multipeermap_destroy(), GNUNET_CONTAINER_multipeermap_iterate(), GNUNET_CONTAINER_multishortmap_destroy(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_log, GNUNET_NAT_unregister(), GNUNET_NETWORK_socket_close(), GNUNET_NO, GNUNET_NT_scanner_done(), GNUNET_OK, GNUNET_SCHEDULER_cancel(), GNUNET_STATISTICS_destroy(), GNUNET_TRANSPORT_application_done(), GNUNET_TRANSPORT_communicator_disconnect(), 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:

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

2915 {
2916  const struct UDPAck *ack;
2917 
2918  (void) cls;
2920  "Storing UDPAck received from backchannel from %s\n",
2921  GNUNET_i2s_full (sender));
2923  (ntohs (msg->size) != sizeof(struct UDPAck)))
2924  {
2925  GNUNET_break_op (0);
2926  return;
2927  }
2928  ack = (const struct UDPAck *) msg;
2930  sender,
2931  &handle_ack,
2932  (void *) ack);
2933 }

References GNUNET_break_op, GNUNET_CONTAINER_multipeermap_get_multiple(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s_full(), GNUNET_log, GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK, handle_ack(), msg, receivers, 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 2950 of file gnunet-communicator-udp.c.

2956 {
2957  char *my_addr;
2959 
2960  if (GNUNET_YES == add_remove)
2961  {
2962  enum GNUNET_NetworkType nt;
2963 
2964  GNUNET_asprintf (&my_addr,
2965  "%s-%s",
2967  GNUNET_a2s (addr, addrlen));
2968  nt = GNUNET_NT_scanner_get_type (is, addr, addrlen);
2969  ai =
2971  my_addr,
2972  nt,
2974  GNUNET_free (my_addr);
2975  *app_ctx = ai;
2976  }
2977  else
2978  {
2979  ai = *app_ctx;
2981  *app_ctx = NULL;
2982  }
2983 }
static struct GNUNET_TRANSPORT_AddressIdentifier * ai
Handle to the operation that publishes our address.
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 2992 of file gnunet-communicator-udp.c.

2993 {
2994  struct BroadcastInterface *bi = cls;
2995  struct GNUNET_TIME_Relative delay;
2996 
3000  bi->broadcast_task =
3002 
3003  switch (bi->sa->sa_family)
3004  {
3005  case AF_INET: {
3006  static int yes = 1;
3007  static int no = 0;
3008  ssize_t sent;
3009 
3010  if (GNUNET_OK !=
3012  SOL_SOCKET,
3013  SO_BROADCAST,
3014  &yes,
3015  sizeof(int)))
3017  "setsockopt");
3019  "creating UDPBroadcast from %s\n",
3020  GNUNET_i2s (&(bi->bcm.sender)));
3022  "sending UDPBroadcast to add %s\n",
3023  GNUNET_a2s (bi->ba, bi->salen));
3025  &bi->bcm,
3026  sizeof(bi->bcm),
3027  bi->ba,
3028  bi->salen);
3029  if (-1 == sent)
3031  "sendto");
3033  SOL_SOCKET,
3034  SO_BROADCAST,
3035  &no,
3036  sizeof(int)))
3038  "setsockopt");
3039  break;
3040  }
3041 
3042  case AF_INET6: {
3043  ssize_t sent;
3044  struct sockaddr_in6 dst;
3045 
3046  dst.sin6_family = AF_INET6;
3047  dst.sin6_port = htons (my_port);
3048  dst.sin6_addr = bi->mcreq.ipv6mr_multiaddr;
3049  dst.sin6_scope_id = ((struct sockaddr_in6 *) bi->ba)->sin6_scope_id;
3050 
3052  "sending UDPBroadcast\n");
3054  &bi->bcm,
3055  sizeof(bi->bcm),
3056  (const struct sockaddr *) &dst,
3057  sizeof(dst));
3058  if (-1 == sent)
3060  break;
3061  }
3062 
3063  default:
3064  GNUNET_break (0);
3065  break;
3066  }
3067 }
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, delay, 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(), BroadcastInterface::mcreq, my_port, GNUNET_TIME_Relative::rel_value_us, BroadcastInterface::sa, BroadcastInterface::salen, UDPBroadcast::sender, and udp_sock.

Referenced by iface_proc().

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

3092 {
3093  struct BroadcastInterface *bi;
3094  enum GNUNET_NetworkType network;
3095  struct UdpBroadcastSignature ubs;
3096 
3097  (void) cls;
3098  (void) netmask;
3099  if (NULL == addr)
3100  return GNUNET_YES; /* need to know our address! */
3101  network = GNUNET_NT_scanner_get_type (is, addr, addrlen);
3102  if (GNUNET_NT_LOOPBACK == network)
3103  {
3104  /* Broadcasting on loopback does not make sense */
3105  return GNUNET_YES;
3106  }
3107  for (bi = bi_head; NULL != bi; bi = bi->next)
3108  {
3109  if ((bi->salen == addrlen) && (0 == memcmp (addr, bi->sa, addrlen)))
3110  {
3111  bi->found = GNUNET_YES;
3112  return GNUNET_OK;
3113  }
3114  }
3115 
3116  if ((AF_INET6 == addr->sa_family) && (NULL == broadcast_addr))
3117  return GNUNET_OK; /* broadcast_addr is required for IPv6! */
3118  if ((AF_INET6 == addr->sa_family) && (GNUNET_YES != have_v6_socket))
3119  return GNUNET_OK; /* not using IPv6 */
3120 
3121  bi = GNUNET_new (struct BroadcastInterface);
3122  bi->sa = GNUNET_memdup (addr,
3123  addrlen);
3124  if ( (NULL != broadcast_addr) &&
3125  (addrlen == sizeof (struct sockaddr_in)) )
3126  {
3127  struct sockaddr_in *ba;
3128 
3129  ba = GNUNET_memdup (broadcast_addr,
3130  addrlen);
3131  ba->sin_port = htons (2086); /* always GNUnet port, ignore configuration! */
3132  bi->ba = (struct sockaddr *) ba;
3133  }
3134  bi->salen = addrlen;
3135  bi->found = GNUNET_YES;
3136  bi->bcm.sender = my_identity;
3137  ubs.purpose.purpose = htonl (
3139  ubs.purpose.size = htonl (sizeof(ubs));
3140  ubs.sender = my_identity;
3142  "creating UDPBroadcastSignature for %s\n",
3143  GNUNET_a2s (addr, addrlen));
3144  GNUNET_CRYPTO_hash (addr, addrlen, &ubs.h_address);
3146  &ubs,
3147  &bi->bcm.sender_sig);
3148  if (NULL != bi->ba)
3149  {
3152  }
3153  if ((AF_INET6 == addr->sa_family) && (NULL != broadcast_addr))
3154  {
3155  /* Create IPv6 multicast request */
3156  const struct sockaddr_in6 *s6 =
3157  (const struct sockaddr_in6 *) broadcast_addr;
3158 
3159  GNUNET_assert (
3160  1 == inet_pton (AF_INET6, "FF05::13B", &bi->mcreq.ipv6mr_multiaddr));
3161 
3162  /* http://tools.ietf.org/html/rfc2553#section-5.2:
3163  *
3164  * IPV6_JOIN_GROUP
3165  *
3166  * Join a multicast group on a specified local interface. If the
3167  * interface index is specified as 0, the kernel chooses the local
3168  * interface. For example, some kernels look up the multicast
3169  * group in the normal IPv6 routing table and using the resulting
3170  * interface; we do this for each interface, so no need to use
3171  * zero (anymore...).
3172  */
3173  bi->mcreq.ipv6mr_interface = s6->sin6_scope_id;
3174 
3175  /* Join the multicast group */
3177  IPPROTO_IPV6,
3178  IPV6_JOIN_GROUP,
3179  &bi->mcreq,
3180  sizeof(bi->mcreq)))
3181  {
3183  }
3184  }
3185  return GNUNET_OK;
3186 }
static int have_v6_socket
GNUNET_YES if udp_sock supports IPv6.
@ GNUNET_NT_LOOPBACK
Loopback (same host).
Definition: gnunet_nt_lib.h:48
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 3195 of file gnunet-communicator-udp.c.

3196 {
3197  struct BroadcastInterface *bin;
3198 
3199  (void) cls;
3200  for (struct BroadcastInterface *bi = bi_head; NULL != bi; bi = bi->next)
3201  bi->found = GNUNET_NO;
3203  for (struct BroadcastInterface *bi = bi_head; NULL != bi; bi = bin)
3204  {
3205  bin = bi->next;
3206  if (GNUNET_NO == bi->found)
3207  bi_destroy (bi);
3208  }
3210  &do_broadcast,
3211  NULL);
3212 }
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, BroadcastInterface::found, GNUNET_NO, GNUNET_OS_network_interfaces_list(), GNUNET_SCHEDULER_add_delayed(), iface_proc(), INTERFACE_SCAN_FREQUENCY, and BroadcastInterface::next.

Referenced by 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 3216 of file gnunet-communicator-udp.c.

3219 {
3220  /* FIXME: support reversal: #5529 */
3222  "No connection reversal implemented!");
3223 }
@ 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 3235 of file gnunet-communicator-udp.c.

3239 {
3240  char *bindto;
3241  struct sockaddr *in;
3242  socklen_t in_len;
3243  struct sockaddr_storage in_sto;
3244  socklen_t sto_len;
3245 
3246  (void) cls;
3247  cfg = c;
3248  if (GNUNET_OK !=
3251  "BINDTO",
3252  &bindto))
3253  {
3256  "BINDTO");
3257  return;
3258  }
3259 
3260  if (GNUNET_OK !=
3263  "REKEY_INTERVAL",
3264  &rekey_interval))
3266 
3267  if (GNUNET_OK !=
3270  "REKEY_MAX_BYTES",
3271  &rekey_max_bytes))
3273 
3274  in = udp_address_to_sockaddr (bindto, &in_len);
3275  if (NULL == in)
3276  {
3278  "Failed to setup UDP socket address with path `%s'\n",
3279  bindto);
3280  GNUNET_free (bindto);
3281  return;
3282  }
3283  udp_sock =
3284  GNUNET_NETWORK_socket_create (in->sa_family,
3285  SOCK_DGRAM,
3286  IPPROTO_UDP);
3287  if (NULL == udp_sock)
3288  {
3290  GNUNET_free (in);
3291  GNUNET_free (bindto);
3292  return;
3293  }
3294  if (AF_INET6 == in->sa_family)
3296  if (GNUNET_OK !=
3298  in,
3299  in_len))
3300  {
3302  "bind",
3303  bindto);
3305  udp_sock = NULL;
3306  GNUNET_free (in);
3307  GNUNET_free (bindto);
3308  return;
3309  }
3310 
3311  /* We might have bound to port 0, allowing the OS to figure it out;
3312  thus, get the real IN-address from the socket */
3313  sto_len = sizeof(in_sto);
3314  if (0 != getsockname (GNUNET_NETWORK_get_fd (udp_sock),
3315  (struct sockaddr *) &in_sto,
3316  &sto_len))
3317  {
3318  memcpy (&in_sto, in, in_len);
3319  sto_len = in_len;
3320  }
3321  GNUNET_free (in);
3322  GNUNET_free (bindto);
3323  in = (struct sockaddr *) &in_sto;
3324  in_len = sto_len;
3326  "transport",
3327  "Bound to `%s'\n",
3328  GNUNET_a2s ((const struct sockaddr *) &in_sto,
3329  sto_len));
3330  switch (in->sa_family)
3331  {
3332  case AF_INET:
3333  my_port = ntohs (((struct sockaddr_in *) in)->sin_port);
3334  break;
3335 
3336  case AF_INET6:
3337  my_port = ntohs (((struct sockaddr_in6 *) in)->sin6_port);
3338  break;
3339 
3340  default:
3341  GNUNET_break (0);
3342  my_port = 0;
3343  }
3344  stats = GNUNET_STATISTICS_create ("C-UDP", cfg);
3348  receivers_heap =
3354  if (NULL == my_private_key)
3355  {
3356  GNUNET_log (
3358  _ (
3359  "Transport service is lacking key configuration settings. Exiting.\n"));
3361  return;
3362  }
3364  /* start reading */
3366  udp_sock,
3367  &sock_read,
3368  NULL);
3373  &mq_init,
3374  NULL,
3375  &enc_notify_cb,
3376  NULL);
3377  if (NULL == ch)
3378  {
3379  GNUNET_break (0);
3381  return;
3382  }
3384  if (NULL == ah)
3385  {
3386  GNUNET_break (0);
3388  return;
3389  }
3390  /* start broadcasting */
3391  if (GNUNET_YES !=
3394  "DISABLE_BROADCAST"))
3395  {
3397  }
3400  IPPROTO_UDP,
3401  1 /* one address */,
3402  (const struct sockaddr **) &in,
3403  &in_len,
3404  &nat_address_cb,
3406  NULL /* closure */);
3407 }
#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.
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_ApplicationHandle * GNUNET_TRANSPORT_application_init(const struct GNUNET_CONFIGURATION_Handle *cfg)
Initialize the TRANSPORT application client handle.
struct GNUNET_TRANSPORT_CommunicatorHandle * GNUNET_TRANSPORT_communicator_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *config_section_name, const char *addr_prefix, enum GNUNET_TRANSPORT_CommunicatorCharacteristics cc, GNUNET_TRANSPORT_CommunicatorMqInit mq_init, void *mq_init_cls, GNUNET_TRANSPORT_CommunicatorNotify notify_cb, void *notify_cb_cls)
Connect to the transport service.
@ GNUNET_TRANSPORT_CC_UNRELIABLE
Transmission is unreliable (e.g.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_size(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *size)
Get a configuration value that should be a size in bytes.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_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.
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.
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_CONTAINER_MultiPeerMap * GNUNET_CONTAINER_multipeermap_create(unsigned int len, int do_not_copy_keys)
Create a multi peer map (hash map for public keys of peers).
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_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:1001
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition: network.c:833
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_bind(struct GNUNET_NETWORK_Handle *desc, const struct sockaddr *address, socklen_t address_len)
Bind a socket to a particular address.
Definition: network.c:440
struct GNUNET_NT_InterfaceScanner * GNUNET_NT_scanner_init(void)
Initialize the address characterization client handle.
Definition: nt.c:406
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:562
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:1334
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, 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_multipeermap_create(), GNUNET_CONTAINER_multishortmap_create(), GNUNET_CRYPTO_eddsa_key_create_from_configuration(), GNUNET_CRYPTO_eddsa_key_get_public(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_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_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.

Here is the call 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 3418 of file gnunet-communicator-udp.c.

3419 {
3420  static const struct GNUNET_GETOPT_CommandLineOption options[] = {
3422  };
3423  int ret;
3424 
3426  "transport",
3427  "Starting udp communicator\n");
3428  if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
3429  return 2;
3430 
3431  ret = (GNUNET_OK == GNUNET_PROGRAM_run (argc,
3432  argv,
3433  "gnunet-communicator-udp",
3434  _ ("GNUnet UDP communicator"),
3435  options,
3436  &run,
3437  NULL))
3438  ? 0
3439  : 1;
3440  GNUNET_free_nz ((void *) argv);
3441  return ret;
3442 }
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:1222
Definition of a command line option.

Variable Documentation

◆ rekey_interval

struct GNUNET_TIME_Relative rekey_interval
static

The rekey interval.

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

Referenced by mq_send_d(), and run().

◆ key_cache

struct GNUNET_CONTAINER_MultiShortmap* key_cache
static

Cache of pre-generated key IDs.

Definition at line 742 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 747 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 752 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 757 of file gnunet-communicator-udp.c.

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

◆ stats

◆ ch

◆ receivers

struct GNUNET_CONTAINER_MultiPeerMap* receivers
static

Receivers (map from peer identity to struct ReceiverAddress)

Definition at line 772 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_MultiPeerMap* senders
static

Senders (map from peer identity to struct SenderAddress)

Definition at line 777 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 782 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 787 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 792 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 797 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 807 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 807 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

Our private key.

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

Referenced by do_shutdown(), iface_proc(), run(), send_msg_with_kx(), and setup_shared_secret_dec().

◆ cfg

const struct GNUNET_CONFIGURATION_Handle* cfg
static

Our configuration.

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

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

◆ ah

Our handle to report addresses for validation to TRANSPORT.

Definition at line 827 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 832 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 837 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 842 of file gnunet-communicator-udp.c.

Referenced by ifc_broadcast(), and run().