GNUnet  0.17.6
Data Structures | Macros | Functions | Variables
gnunet-communicator-udp.c File Reference

Transport plugin using UDP. More...

#include "platform.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
 UDP message box. 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   2
 
#define KCN_THRESHOLD   92
 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   128000
 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, int withoutKce)
 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 char tag[(128/8)], 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_enc (const struct GNUNET_CRYPTO_EcdhePrivateKey *ephemeral, struct ReceiverAddress *receiver, int add_to_receiver)
 Setup shared secret for encryption. More...
 
static void setup_receiver_mq (struct ReceiverAddress *receiver)
 Setup the MQ for the receiver. More...
 
static void destroy_all_secrets (struct SharedSecret *ss, int withoutKce)
 Destroying all secrets. More...
 
static void add_acks (struct SharedSecret *ss, int acks_to_add)
 
static uint32_t reset_rekey_kces (struct ReceiverAddress *receiver, uint32_t acks_to_add)
 
static void add_acks_rekey (struct ReceiverAddress *receiver)
 
static int handle_ack (void *cls, const struct GNUNET_PeerIdentity *pid, void *value)
 We received an ACK for pid. More...
 
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 kce_generate_cb (void *cls)
 
static void kce_generate_rekey_cb (void *cls)
 
static void consider_ss_ack (struct SharedSecret *ss, int initial)
 We established a shared secret with a sender. 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 void decrypt_rekey (const struct UDPRekey *rekey, size_t rekey_len, struct KeyCacheEntry *kce, struct SenderAddress *sender)
 We received a rekey 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 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 check_for_rekeying (struct ReceiverAddress *receiver, struct UDPBox *box)
 
static void send_UDPRekey (struct ReceiverAddress *receiver, struct SharedSecret *ss)
 
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 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...
 
struct SharedSecretss_finished
 Shared secret we finished the last kce working queue for. 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:

Definition in file gnunet-communicator-udp.c.

Macro Definition Documentation

◆ DEFAULT_REKEY_TIME_INTERVAL

#define DEFAULT_REKEY_TIME_INTERVAL   GNUNET_TIME_UNIT_DAYS

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

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

◆ PROTO_QUEUE_TIMEOUT

#define PROTO_QUEUE_TIMEOUT   GNUNET_TIME_UNIT_MINUTES

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

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

◆ BROADCAST_FREQUENCY

#define BROADCAST_FREQUENCY   GNUNET_TIME_UNIT_MINUTES

How often do we broadcast our presence on the LAN?

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

◆ INTERFACE_SCAN_FREQUENCY

#define INTERFACE_SCAN_FREQUENCY    GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)

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

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

◆ ADDRESS_VALIDITY_PERIOD

#define ADDRESS_VALIDITY_PERIOD   GNUNET_TIME_UNIT_HOURS

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

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

◆ WORKING_QUEUE_INTERVALL

#define WORKING_QUEUE_INTERVALL    GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MICROSECONDS,1)

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

◆ AES_KEY_SIZE

#define AES_KEY_SIZE   (256 / 8)

AES key size.

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

◆ AES_IV_SIZE

#define AES_IV_SIZE   (96 / 8)

AES (GCM) IV size.

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

◆ GCM_TAG_SIZE

#define GCM_TAG_SIZE   (128 / 8)

Size of the GCM tag.

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

◆ GENERATE_AT_ONCE

#define GENERATE_AT_ONCE   2

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

◆ KCN_THRESHOLD

#define KCN_THRESHOLD   92

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

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

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

◆ KCN_TARGET

#define KCN_TARGET   128

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

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

◆ MAX_SQN_DELTA

#define MAX_SQN_DELTA   160

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

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

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

◆ MAX_SECRETS

#define MAX_SECRETS   128000

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

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

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

◆ DEFAULT_REKEY_MAX_BYTES

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

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

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

◆ COMMUNICATOR_ADDRESS_PREFIX

#define COMMUNICATOR_ADDRESS_PREFIX   "udp"

Address prefix used by the communicator.

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

◆ COMMUNICATOR_CONFIG_SECTION

#define COMMUNICATOR_CONFIG_SECTION   "communicator-udp"

Configuration section used by the communicator.

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

Function Documentation

◆ bi_destroy()

static void bi_destroy ( struct BroadcastInterface bi)
static

An interface went away, stop broadcasting on it.

Parameters
bientity to close down

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

905 {
906  if (AF_INET6 == bi->sa->sa_family)
907  {
908  /* Leave the multicast group */
910  IPPROTO_IPV6,
911  IPV6_LEAVE_GROUP,
912  &bi->mcreq,
913  sizeof(bi->mcreq)))
914  {
916  }
917  }
920  GNUNET_free (bi->sa);
921  GNUNET_free (bi->ba);
922  GNUNET_free (bi);
923 }
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
Definition: gnunet_common.h:99
#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:828
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:957
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 932 of file gnunet-communicator-udp.c.

933 {
934 
935  receiver->receiver_destroy_called = GNUNET_YES;
936 
938  "Disconnecting receiver for peer `%s'\n",
939  GNUNET_i2s (&receiver->target));
940  /*if (NULL != (mq = receiver->kx_mq))
941  {
942  receiver->kx_mq = NULL;
943  GNUNET_MQ_destroy (mq);
944  }*/
945  if (NULL != receiver->kx_qh)
946  {
948  receiver->kx_qh = NULL;
949  receiver->kx_mq = NULL;
950  }
951  /*if (NULL != (mq = receiver->d_mq))
952  {
953  receiver->d_mq = NULL;
954  GNUNET_MQ_destroy (mq);
955  }*/
956  if (NULL != receiver->d_qh)
957  {
959  receiver->d_qh = NULL;
960  }
963  &receiver->target,
964  receiver));
967  "# receivers active",
969  GNUNET_NO);
970  GNUNET_free (receiver->address);
971  GNUNET_free (receiver->foreign_addr);
973 }
static struct GNUNET_CONTAINER_MultiPeerMap * receivers
Receivers (map from peer identity to struct ReceiverAddress)
static struct GNUNET_STATISTICS_Handle * stats
For logging statistics.
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
Definition: gnunet_common.h:98
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 GNUNET_TRANSPORT_communicator_mq_del(struct GNUNET_TRANSPORT_QueueHandle *qh)
Notify transport service that an MQ became unavailable due to a disconnect or timeout.
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:329

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

983 {
984  struct SharedSecret *ss = kce->ss;
985 
986  ss->active_kce_count--;
987  ss->sender->acks_available--;
990  &kce->kid,
991  kce));
992  GNUNET_free (kce);
993 }
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(), decrypt_rekey(), 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
kid[out]where to write the key ID

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

1007 {
1008  uint32_t sid = htonl (serial);
1009 
1010  GNUNET_CRYPTO_hkdf (kid,
1011  sizeof(*kid),
1012  GCRY_MD_SHA512,
1013  GCRY_MD_SHA256,
1014  &sid,
1015  sizeof(sid),
1016  msec,
1017  sizeof(*msec),
1018  "UDP-KID",
1019  strlen ("UDP-KID"),
1020  NULL,
1021  0);
1022 }
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:340

References GNUNET_CRYPTO_hkdf().

Referenced by kce_generate(), mq_send_d(), and send_UDPRekey().

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

1033 {
1034  struct KeyCacheEntry *kce;
1035 
1036  GNUNET_assert (0 < seq);
1037  kce = GNUNET_new (struct KeyCacheEntry);
1038  kce->ss = ss;
1039  kce->sequence_number = seq;
1040  get_kid (&ss->master, seq, &kce->kid);
1042  ss->active_kce_count++;
1043  ss->sender->acks_available++;
1045  key_cache,
1046  &kce->kid,
1047  kce,
1050  "# KIDs active",
1052  GNUNET_NO);
1053 }
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 consider_ss_ack(), kce_generate_cb(), and kce_generate_rekey_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,
int  withoutKce 
)
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 1063 of file gnunet-communicator-udp.c.

1064 {
1065  struct SenderAddress *sender;
1066  struct ReceiverAddress *receiver;
1067  struct KeyCacheEntry *kce;
1068 
1069  if (withoutKce && (ss->sequence_allowed > 0))
1070  return GNUNET_NO;
1071 
1073  "secret %s destroy %u %u\n",
1074  GNUNET_h2s (&ss->master),
1075  withoutKce,
1076  ss->sequence_allowed);
1077  if (NULL != (sender = ss->sender))
1078  {
1079  GNUNET_CONTAINER_DLL_remove (sender->ss_head, sender->ss_tail, ss);
1080  sender->num_secrets--;
1081  }
1082  if (NULL != (receiver = ss->receiver))
1083  {
1084  GNUNET_CONTAINER_DLL_remove (receiver->ss_head, receiver->ss_tail, ss);
1085  receiver->num_secrets--;
1086  // Uncomment this for alternativ 1 of backchannel functionality
1087  receiver->acks_available -= (ss->sequence_allowed - ss->sequence_used);
1089  "%u receiver->acks_available 3\n",
1090  receiver->acks_available);
1091  // Until here for alternativ 1
1092  }
1093  while (NULL != (kce = ss->kce_head))
1094  kce_destroy (kce);
1095  GNUNET_STATISTICS_update (stats, "# Secrets active", -1, GNUNET_NO);
1097  "# KIDs active",
1099  GNUNET_NO);
1100  GNUNET_free (ss);
1101  return GNUNET_YES;
1102 }
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 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_STATISTICS_set(), GNUNET_STATISTICS_update(), GNUNET_YES, kce_destroy(), SharedSecret::kce_head, 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 destroy_all_secrets().

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

1113 {
1115  GNUNET_assert (
1116  GNUNET_YES ==
1118  GNUNET_assert (sender == GNUNET_CONTAINER_heap_remove_node (sender->hn));
1120  "# senders active",
1122  GNUNET_NO);
1123  GNUNET_free (sender->address);
1124  GNUNET_free (sender);
1125 }
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
key[out]where to write the decryption key
iv[out]where to write the IV

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

1141 {
1142  uint32_t sid = htonl (serial);
1143  char res[AES_KEY_SIZE + AES_IV_SIZE];
1144 
1146  sizeof(res),
1147  GCRY_MD_SHA512,
1148  GCRY_MD_SHA256,
1149  &sid,
1150  sizeof(sid),
1151  msec,
1152  sizeof(*msec),
1153  "UDP-IV-KEY",
1154  strlen ("UDP-IV-KEY"),
1155  NULL,
1156  0);
1157  memcpy (key, res, AES_KEY_SIZE);
1158  memcpy (iv, &res[AES_KEY_SIZE], AES_IV_SIZE);
1159 }
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 1168 of file gnunet-communicator-udp.c.

1169 {
1170  sender->timeout =
1173 }
#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:315
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 1182 of file gnunet-communicator-udp.c.

1183 {
1184  receiver->timeout =
1187  receiver->timeout.abs_value_us);
1188 }

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

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:

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

1198 {
1199  struct GNUNET_TIME_Relative st;
1200  struct GNUNET_TIME_Relative rt;
1201  struct GNUNET_TIME_Relative delay;
1202  struct ReceiverAddress *receiver;
1203  struct SenderAddress *sender;
1204 
1205  (void) cls;
1206  timeout_task = NULL;
1208  while (NULL != (receiver = GNUNET_CONTAINER_heap_peek (receivers_heap)))
1209  {
1210  /* if (GNUNET_YES != receiver->receiver_destroy_called) */
1211  /* { */
1213  if (0 != rt.rel_value_us)
1214  break;
1216  "Receiver timed out\n");
1218  // }
1219  }
1221  while (NULL != (sender = GNUNET_CONTAINER_heap_peek (senders_heap)))
1222  {
1223  if (GNUNET_YES != sender->sender_destroy_called)
1224  {
1226  if (0 != st.rel_value_us)
1227  break;
1228  sender_destroy (sender);
1229  }
1230  }
1232  if (delay.rel_value_us < GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
1234 }
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:1254
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:342
#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:404
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
ss[in,out]data structure to complete

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

1244 {
1245  GNUNET_CRYPTO_hkdf (&ss->cmac,
1246  sizeof(ss->cmac),
1247  GCRY_MD_SHA512,
1248  GCRY_MD_SHA256,
1249  "CMAC",
1250  strlen ("CMAC"),
1251  &ss->master,
1252  sizeof(ss->master),
1253  "UDP-CMAC",
1254  strlen ("UDP-CMAC"),
1255  NULL,
1256  0);
1257 }
struct GNUNET_HashCode cmac
CMAC is used to identify master in ACKs.

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

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

1272 {
1273  const struct GNUNET_MessageHeader *hdr = plaintext;
1274  const char *pos = plaintext;
1275 
1276  while (ntohs (hdr->size) <= plaintext_len)
1277  {
1279  "# bytes given to core",
1280  ntohs (hdr->size),
1281  GNUNET_NO);
1283  "Giving %u bytes to TNG\n", ntohs (hdr->size));
1286  &sender->target,
1287  hdr,
1289  NULL /* no flow control possible */
1290  ,
1291  NULL));
1292  /* move on to next message, if any */
1293  plaintext_len -= ntohs (hdr->size);
1294  if (plaintext_len < sizeof(*hdr))
1295  break;
1296  pos += ntohs (hdr->size);
1297  hdr = (const struct GNUNET_MessageHeader *) pos;
1298  // TODO for now..., we do not actually sen >1msg or have a way of telling
1299  // if we are done
1300  break;
1301  }
1303  "# bytes padding discarded",
1304  plaintext_len,
1305  GNUNET_NO);
1306 }
#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.
@ GNUNET_SYSERR
Definition: gnunet_common.h:97
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.
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 1318 of file gnunet-communicator-udp.c.

1321 {
1322  char key[AES_KEY_SIZE];
1323  char iv[AES_IV_SIZE];
1324  int rc;
1325 
1326  GNUNET_assert (0 ==
1327  gcry_cipher_open (cipher,
1328  GCRY_CIPHER_AES256 /* low level: go for speed */,
1329  GCRY_CIPHER_MODE_GCM,
1330  0 /* flags */));
1331  get_iv_key (msec, serial, key, iv);
1332  rc = gcry_cipher_setkey (*cipher, key, sizeof(key));
1333  GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
1334  rc = gcry_cipher_setiv (*cipher, iv, sizeof(iv));
1335  GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
1336 }
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(), mq_send_kx(), send_UDPRekey(), 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 char  tag[(128/8)],
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 1352 of file gnunet-communicator-udp.c.

1358 {
1359  gcry_cipher_hd_t cipher;
1360 
1361  setup_cipher (&ss->master, serial, &cipher);
1362  GNUNET_assert (
1363  0 ==
1364  gcry_cipher_decrypt (cipher, out_buf, in_buf_size, in_buf, in_buf_size));
1365  if (0 != gcry_cipher_checktag (cipher, tag, GCM_TAG_SIZE))
1366  {
1367  gcry_cipher_close (cipher);
1369  "# AEAD authentication failures",
1370  1,
1371  GNUNET_NO);
1372  return GNUNET_SYSERR;
1373  }
1374  gcry_cipher_close (cipher);
1375  return GNUNET_OK;
1376 }
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(), decrypt_rekey(), 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 1386 of file gnunet-communicator-udp.c.

1387 {
1388  struct SharedSecret *ss;
1389 
1390  ss = GNUNET_new (struct SharedSecret);
1391  GNUNET_CRYPTO_eddsa_ecdh (my_private_key, ephemeral, &ss->master);
1392  return ss;
1393 }
static struct GNUNET_CRYPTO_EddsaPrivateKey * my_private_key
Our private key.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_ecdh(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, const struct GNUNET_CRYPTO_EcdhePublicKey *pub, struct GNUNET_HashCode *key_material)
Derive key material from a ECDH public key and a private EdDSA key.
Definition: crypto_ecc.c:739

References GNUNET_CRYPTO_eddsa_ecdh(), GNUNET_new, SharedSecret::master, and my_private_key.

Referenced by sock_read().

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

◆ setup_shared_secret_enc()

static struct SharedSecret* setup_shared_secret_enc ( const struct GNUNET_CRYPTO_EcdhePrivateKey ephemeral,
struct ReceiverAddress receiver,
int  add_to_receiver 
)
static

Setup shared secret for encryption.

Parameters
ephemeralephemeral key we are sending to the other peer
receiver[in,out]queue to initialize encryption key for
Returns
new shared secret

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

1406 {
1407  struct SharedSecret *ss;
1408 
1409  ss = GNUNET_new (struct SharedSecret);
1410  GNUNET_CRYPTO_ecdh_eddsa (ephemeral,
1411  &receiver->target.public_key,
1412  &ss->master);
1413  calculate_cmac (ss);
1414  ss->receiver = receiver;
1415  GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss);
1416  receiver->num_secrets++;
1417  GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
1418  return ss;
1419 }
static void calculate_cmac(struct SharedSecret *ss)
Calculate cmac from master in ss.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdh_eddsa(const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, const struct GNUNET_CRYPTO_EddsaPublicKey *pub, struct GNUNET_HashCode *key_material)
Derive key material from a EdDSA public key and a private ECDH key.
Definition: crypto_ecc.c:779

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

Referenced by mq_send_kx(), and send_UDPRekey().

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

3147 {
3148  size_t base_mtu;
3149 
3150  /*if (NULL != receiver->kx_qh)
3151  {
3152  GNUNET_TRANSPORT_communicator_mq_del (receiver->kx_qh);
3153  receiver->kx_qh = NULL;
3154  }
3155  if (NULL != receiver->d_qh)
3156  {
3157  GNUNET_TRANSPORT_communicator_mq_del (receiver->d_qh);
3158  receiver->d_qh = NULL;
3159  }*/
3160  // GNUNET_assert (NULL == receiver->mq);
3161  switch (receiver->address->sa_family)
3162  {
3163  case AF_INET:
3164  base_mtu = 1480 /* Ethernet MTU, 1500 - Ethernet header - VLAN tag */
3165  - sizeof(struct GNUNET_TUN_IPv4Header) /* 20 */
3166  - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */;
3167  break;
3168 
3169  case AF_INET6:
3170  base_mtu = 1280 /* Minimum MTU required by IPv6 */
3171  - sizeof(struct GNUNET_TUN_IPv6Header) /* 40 */
3172  - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */;
3173  break;
3174 
3175  default:
3176  GNUNET_assert (0);
3177  break;
3178  }
3179  /* MTU based on full KX messages */
3180  receiver->kx_mtu = base_mtu - sizeof(struct InitialKX) /* 48 */
3181  - sizeof(struct UDPConfirmation); /* 104 */
3182  /* MTU based on BOXed messages */
3183  receiver->d_mtu = base_mtu - sizeof(struct UDPBox);
3184 
3186  "Setting up MQs and QHs\n");
3187  /* => Effective MTU for CORE will range from 1080 (IPv6 + KX) to
3188  1404 (IPv4 + Box) bytes, depending on circumstances... */
3189  if (NULL == receiver->kx_mq)
3191  &mq_destroy_kx,
3192  &mq_cancel,
3193  receiver,
3194  NULL,
3195  &mq_error,
3196  receiver);
3197  if (NULL == receiver->d_mq)
3199  &mq_destroy_d,
3200  &mq_cancel,
3201  receiver,
3202  NULL,
3203  &mq_error,
3204  receiver);
3205 
3206  receiver->kx_qh =
3208  &receiver->target,
3209  receiver->foreign_addr,
3210  receiver->kx_mtu,
3212  0, /* Priority */
3213  receiver->nt,
3215  receiver->kx_mq);
3216 }
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...
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:467
#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)
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:

◆ destroy_all_secrets()

static void destroy_all_secrets ( struct SharedSecret ss,
int  withoutKce 
)
static

Destroying all secrets.

Depending on parameter we keep those secrets having a kce.

Parameters
ssThe secret we will not destroy.
withoutKceIf GNUNET_YES shared secrets with kce will not be destroyed.

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

1440 {
1441  struct SenderAddress *sender;
1442  struct ReceiverAddress *receiver;
1443  struct SharedSecret *ss_to_destroy;
1444  struct SharedSecret *ss_start;
1445  struct SharedSecret *pos;
1446  int at_least_one_destroyed = GNUNET_NO;
1447 
1449  "Starting destroy all withoutKce: %u.\n",
1450  withoutKce);
1451 
1452  if (NULL != (sender = ss->sender))
1453  {
1454  ss_start = sender->ss_head;
1455  }
1456  else if (NULL != (receiver = ss->receiver))
1457  {
1458  ss_start = receiver->ss_head;
1459  }
1460  else
1461  {
1463  "Shared secret has no sender or receiver!\n");
1464  return;
1465  }
1466 
1467  pos = ss_start;
1468  while (NULL != pos)
1469  {
1470  ss_to_destroy = pos;
1471  pos = pos->next;
1472 
1473  if (ss != ss_to_destroy)
1474  at_least_one_destroyed = secret_destroy (ss_to_destroy, withoutKce);
1475  }
1476 
1477  if ((ss != ss_start) && ! at_least_one_destroyed)
1478  {
1480  "Really destroying all.\n");
1481  destroy_all_secrets (ss_start, GNUNET_NO);
1482  }
1483 
1485  "Finished destroy all.\n");
1486 }
static void destroy_all_secrets(struct SharedSecret *ss, int withoutKce)
Destroying all secrets.
static int secret_destroy(struct SharedSecret *ss, int withoutKce)
Destroy ss and associated key cache entries.
@ GNUNET_ERROR_TYPE_ERROR
struct SharedSecret * next
Kept in a DLL.

References GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_log, GNUNET_NO, SharedSecret::next, SharedSecret::receiver, receiver(), secret_destroy(), SharedSecret::sender, and SenderAddress::ss_head.

Referenced by add_acks(), consider_ss_ack(), and mq_send_kx().

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

1491 {
1492 
1493  struct ReceiverAddress *receiver = ss->receiver;
1494 
1495  GNUNET_assert (NULL != ss);
1496  GNUNET_assert (NULL != receiver);
1497 
1498  if (NULL == receiver->d_qh)
1499  {
1500  receiver->d_qh =
1502  &receiver->target,
1503  receiver->foreign_addr,
1504  receiver->d_mtu,
1505  acks_to_add,
1506  1, /* Priority */
1507  receiver->nt,
1509  receiver->d_mq);
1510  }
1511  else
1512  {
1514  receiver->d_qh,
1515  acks_to_add,
1516  1);
1517  }
1518 
1520  "Tell transport we have %u more acks!\n",
1521  acks_to_add);
1523  "%u kce for rekeying.\n",
1524  receiver->number_rekeying_kce);
1525 
1526  // Until here for alternativ 1
1527 
1528  /* move ss to head to avoid discarding it anytime soon! */
1529 
1530  GNUNET_CONTAINER_DLL_remove (receiver->ss_head, receiver->ss_tail, ss);
1531  GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss);
1533 }
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, destroy_all_secrets(), 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, GNUNET_YES, SharedSecret::receiver, and receiver().

Referenced by add_acks_rekey(), and handle_ack().

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

◆ reset_rekey_kces()

static uint32_t reset_rekey_kces ( struct ReceiverAddress receiver,
uint32_t  acks_to_add 
)
static

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

1539 {
1540  int needed_for_rekeying;
1541 
1543  "%u kce for rekeying and %u acks_to_add\n",
1544  receiver->number_rekeying_kce,
1545  acks_to_add);
1546 
1547  needed_for_rekeying = (3 - receiver->number_rekeying_kce);
1548  if (acks_to_add <= needed_for_rekeying)
1549  {
1550  receiver->number_rekeying_kce += acks_to_add;
1551  acks_to_add = 0;
1552  }
1553  else
1554  {
1555  acks_to_add -= (3 - receiver->number_rekeying_kce);
1556  receiver->number_rekeying_kce = 3;
1557  }
1558 
1560  "%u kce for rekeying and %u acks_to_add\n",
1561  receiver->number_rekeying_kce,
1562  acks_to_add);
1563  return acks_to_add;
1564 }

References GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, and receiver().

Referenced by add_acks_rekey(), and handle_ack().

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

◆ add_acks_rekey()

static void add_acks_rekey ( struct ReceiverAddress receiver)
static

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

1569 {
1570  uint32_t acks_to_add = receiver->ss_rekey->sequence_allowed;
1571 
1572  if (receiver->number_rekeying_kce < 3)
1573  acks_to_add = reset_rekey_kces (receiver, acks_to_add);
1574  receiver->acks_available = receiver->ss_rekey->sequence_allowed;
1576  "%u receiver->acks_available 4\n",
1577  receiver->acks_available);
1578  /* add_acks (receiver->ss_rekey, acks_to_add - 3); */
1579  if (0 != acks_to_add)
1580  {
1581  add_acks (receiver->ss_rekey, acks_to_add);
1582  }
1583  receiver->ss_rekey = NULL;
1585  "# rekeying successful\n");
1587  "# rekeying successful",
1588  1,
1589  GNUNET_NO);
1590 }
static uint32_t reset_rekey_kces(struct ReceiverAddress *receiver, uint32_t acks_to_add)
static void add_acks(struct SharedSecret *ss, int acks_to_add)

References add_acks(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_NO, GNUNET_STATISTICS_update(), receiver(), reset_rekey_kces(), and stats.

Referenced by handle_ack(), and mq_send_d().

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

1605 {
1606  const struct UDPAck *ack = cls;
1607  struct ReceiverAddress *receiver = value;
1608  uint32_t acks_to_add;
1609  uint32_t allowed;
1610  // int needed_for_rekeying;
1611 
1613  "in handle ack with cmac %s\n",
1614  GNUNET_h2s (&ack->cmac));
1615 
1616  if (NULL != receiver->ss_rekey)
1618  "We have rekey secret with cmac %s \n",
1619  GNUNET_h2s (&receiver->ss_rekey->cmac));
1620 
1621  if ((NULL != receiver->ss_rekey) && (0 == memcmp (&ack->cmac,
1622  &receiver->ss_rekey->cmac,
1623  sizeof(struct
1624  GNUNET_HashCode))) )
1625  {
1626  allowed = ntohl (ack->sequence_max);
1627 
1628  if (allowed > receiver->ss_rekey->sequence_allowed)
1629  {
1631  "%u > %u (%u %u) for rekey secrect %s\n", allowed,
1632  receiver->ss_rekey->sequence_allowed,
1633  receiver->acks_available,
1634  ack->acks_available,
1635  GNUNET_h2s (&receiver->ss_rekey->master));
1636 
1637  receiver->ss_rekey->sequence_allowed = allowed;
1638 
1639  if (GNUNET_NO == receiver->rekeying)
1641 
1642  return GNUNET_NO;
1643  }
1644  }
1645 
1646  (void) pid;
1647  for (struct SharedSecret *ss = receiver->ss_head; NULL != ss; ss = ss->next)
1648  {
1649  if (0 == memcmp (&ack->cmac, &ss->cmac, sizeof(struct GNUNET_HashCode)))
1650  {
1651 
1653  "Found matching mac\n");
1654 
1655  allowed = ntohl (ack->sequence_max);
1656 
1657  if (allowed > ss->sequence_allowed)
1658  {
1660  "%u > %u (%u %u) for secrect %s\n", allowed,
1661  ss->sequence_allowed,
1662  receiver->acks_available,
1663  ack->acks_available,
1664  GNUNET_h2s (&ss->master));
1665  // Uncomment this for alternativ 1 of backchannel functionality
1666  acks_to_add = (allowed - ss->sequence_allowed);
1667  if ((GNUNET_NO == receiver->rekeying) &&
1668  (receiver->number_rekeying_kce < 3) )
1669  acks_to_add = reset_rekey_kces (receiver, acks_to_add);
1670  /* if ((GNUNET_NO == receiver->rekeying) && */
1671  /* (receiver->number_rekeying_kce < */
1672  /* 3) ) */
1673  /* { */
1674  /* needed_for_rekeying = (3 - receiver->number_rekeying_kce); */
1675  /* if (acks_to_add <= needed_for_rekeying) */
1676  /* { */
1677  /* receiver->number_rekeying_kce += acks_to_add; */
1678  /* acks_to_add = 0; */
1679  /* } */
1680  /* else */
1681  /* { */
1682  /* acks_to_add -= (3 - receiver->number_rekeying_kce); */
1683  /* receiver->number_rekeying_kce = 3; */
1684  /* } */
1685  /* } */
1686  /* GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, */
1687  /* "%u kce for rekeying\n", */
1688  /* receiver->number_rekeying_kce); */
1689 
1690  if ((0 != acks_to_add) && (GNUNET_NO == receiver->rekeying))
1691  {
1692  receiver->acks_available += (allowed - ss->sequence_allowed);
1693  ss->sequence_allowed = allowed;
1695  "%u receiver->acks_available 5\n",
1696  receiver->acks_available);
1697  add_acks (ss, acks_to_add);
1698  }
1699  }
1700  return GNUNET_NO;
1701  }
1702  }
1703  return GNUNET_YES;
1704 }
static void add_acks_rekey(struct ReceiverAddress *receiver)
static char * value
Value of the record to add/remove.
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
A 512-bit hashcode.
UDP key acknowledgement.
uint32_t sequence_max
Sequence acknowledgement limit.
struct GNUNET_HashCode cmac
CMAC of the base key being acknowledged.
uint32_t acks_available
Sequence acknowledgement limit.

References UDPAck::acks_available, add_acks(), add_acks_rekey(), UDPAck::cmac, GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_log, GNUNET_NO, GNUNET_YES, pid, receiver(), reset_rekey_kces(), UDPAck::sequence_max, 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:

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

1719 {
1720  const struct GNUNET_MessageHeader *hdr =
1721  (const struct GNUNET_MessageHeader *) buf;
1722  const struct UDPAck *ack = (const struct UDPAck *) buf;
1723  uint16_t type;
1724 
1726  "try_handle_plaintext of size %lu (%u %lu) and type %u\n",
1727  buf_size,
1728  ntohs (hdr->size),
1729  sizeof(*hdr),
1730  ntohs (hdr->type));
1731  if (sizeof(*hdr) > buf_size)
1732  return; /* not even a header */
1733  if (ntohs (hdr->size) > buf_size)
1734  return; /* not even a header */
1735  type = ntohs (hdr->type);
1736  switch (type)
1737  {
1739  /* lookup master secret by 'cmac', then update sequence_max */
1741  &sender->target,
1742  &handle_ack,
1743  (void *) ack);
1744  /* There could be more messages after the ACK, handle those as well */
1745  buf += ntohs (hdr->size);
1746  buf_size -= ntohs (hdr->size);
1747  pass_plaintext_to_core (sender, buf, buf_size);
1748  break;
1749 
1751  /* skip padding */
1752  break;
1753 
1754  default:
1755  pass_plaintext_to_core (sender, buf, buf_size);
1756  }
1757 }
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.
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.
#define GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_PAD
UDP communicator padding.
#define GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK
UDP KX acknowledgement.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model

References buf, GNUNET_CONTAINER_multipeermap_get_multiple(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK, GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_PAD, handle_ack(), pass_plaintext_to_core(), receivers, GNUNET_MessageHeader::size, SenderAddress::target, GNUNET_MessageHeader::type, and type.

Referenced by decrypt_box(), and sock_read().

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

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

1762 {
1763  struct SharedSecret *ss = cls;
1764 
1765  ss->sender->kce_task = NULL;
1766 
1767  if (((GNUNET_NO == ss->sender->rekeying) && (ss->sender->acks_available <
1768  KCN_TARGET) ) ||
1769  ((ss->sender->ss_rekey == ss) && (GNUNET_YES == ss->sender->rekeying) &&
1770  (ss->sender->acks_available < KCN_TARGET)))
1771  {
1772 
1774  "Precomputing keys for master %s\n",
1775  GNUNET_h2s (&(ss->master)));
1776 
1777  for (int i = 0; i < GENERATE_AT_ONCE; i++)
1778  kce_generate (ss, ++ss->sequence_allowed);
1779 
1780  if (KCN_TARGET > ss->sender->acks_available)
1781  {
1785  ss);
1786  }
1787  else
1788  {
1790  "We have enough keys.\n");
1791  ss_finished = ss;
1793  }
1794  }
1795 
1796 
1797 
1798 }
#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.
struct SharedSecret * ss_finished
Shared secret we finished the last kce working queue for.
#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...
int rekeying
Flag indicating sender is initiated rekeying for this receiver.
int kce_task_finished
Is the kce_task finished?
struct GNUNET_SCHEDULER_Task * kce_task
ID of kce working queue task.
struct SharedSecret * ss_rekey
Shared secret we use with target for rekeying.

References SenderAddress::acks_available, GENERATE_AT_ONCE, GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_log, GNUNET_NO, GNUNET_SCHEDULER_add_delayed(), GNUNET_YES, kce_generate(), SenderAddress::kce_task, SenderAddress::kce_task_finished, KCN_TARGET, SharedSecret::master, SenderAddress::rekeying, SharedSecret::sender, SharedSecret::sequence_allowed, ss_finished, SenderAddress::ss_rekey, and WORKING_QUEUE_INTERVALL.

Referenced by consider_ss_ack(), and kce_generate_rekey_cb().

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

◆ kce_generate_rekey_cb()

static void kce_generate_rekey_cb ( void *  cls)
static

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

1803 {
1804  struct SharedSecret *ss = cls;
1805 
1806  ss->sender->kce_task_rekey = NULL;
1807 
1808  if (NULL == ss->sender->kce_task)
1809  {
1810 
1812  "Precomputing keys for rekey master %s\n",
1813  GNUNET_h2s (&(ss->master)));
1814 
1815  for (int i = 0; i < GENERATE_AT_ONCE; i++)
1816  kce_generate (ss, ++ss->sequence_allowed);
1817 
1821  ss);
1822  ss->sender->kce_task_rekey = NULL;
1823  }
1824  else
1825  {
1829  ss);
1830  }
1831 }
static void kce_generate_rekey_cb(void *cls)
struct GNUNET_SCHEDULER_Task * kce_task_rekey
ID of kce rekey working queue task.

References GENERATE_AT_ONCE, GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_log, GNUNET_SCHEDULER_add_delayed(), kce_generate(), kce_generate_cb(), SenderAddress::kce_task, SenderAddress::kce_task_rekey, SharedSecret::master, SharedSecret::sender, SharedSecret::sequence_allowed, and WORKING_QUEUE_INTERVALL.

Referenced by consider_ss_ack().

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,
int  initial 
)
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
initialThe SharedSecret came with initial KX.

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

1845 {
1846  struct GNUNET_SCHEDULER_Task *kce_task_rekey;
1847  struct GNUNET_SCHEDULER_Task *kce_task;
1848  int kce_task_finished;
1849 
1850  kce_task_rekey = ss->sender->kce_task_rekey;
1851  kce_task_finished = ss->sender->kce_task_finished;
1852  kce_task = ss->sender->kce_task;
1853 
1854  GNUNET_assert (NULL != ss->sender);
1856  "Considering SS UDPAck %s\n",
1857  GNUNET_i2s_full (&ss->sender->target));
1858 
1860  "We have %u acks available.\n",
1861  ss->sender->acks_available);
1862  /* drop ancient KeyCacheEntries */
1863  while ((NULL != ss->kce_head) &&
1864  (MAX_SQN_DELTA <
1866  kce_destroy (ss->kce_tail);
1867 
1868 
1869  if (GNUNET_NO == initial)
1870  kce_generate (ss, ++ss->sequence_allowed);
1871 
1872  /*if (0 == ss->sender->acks_available)
1873  {
1874  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1875  "Generating keys\n");
1876  while (ss->active_kce_count < KCN_TARGET)
1877  kce_generate (ss, ++ss->sequence_allowed);
1878  }*/
1879 
1880  if (NULL != kce_task)
1882  "kce_task is not NULL\n");
1883  if (kce_task_finished)
1885  "kce_task_finished: GNUNET_YES\n");
1886  if (initial)
1888  "initial: GNUNET_YES\n");
1889 
1890  if ( kce_task_finished || (GNUNET_NO == initial))
1891  {
1892  struct UDPAck ack;
1893  struct SharedSecret *ss_tell;
1894 
1895  if (GNUNET_NO != initial)
1896  ss_tell = ss_finished;
1897  else
1898  ss_tell = ss;
1899 
1900  ack.header.type = htons (GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK);
1901  ack.header.size = htons (sizeof(ack));
1902  ack.sequence_max = htonl (ss_tell->sequence_allowed);
1903  ack.acks_available = ss->sender->acks_available;
1904  ack.cmac = ss_tell->cmac;
1906  "Notifying transport of UDPAck %s with initial %u and master %s\n",
1907  GNUNET_i2s_full (&ss_tell->sender->target),
1908  initial,
1909  GNUNET_h2s (&(ss_tell->master)));
1911  &ss_tell->sender->target,
1913  &ack.header);
1914  if (GNUNET_NO != initial)
1915  {
1918  }
1919  }
1920  else if ((NULL == kce_task) && ((KCN_THRESHOLD >
1921  ss->sender->acks_available) ||
1922  (GNUNET_YES == ss->sender->rekeying) ||
1923  (ss->sender->num_secrets > MAX_SECRETS) ))
1924  {
1925 
1926  // kce_generate (ss, ++ss->sequence_allowed);
1927  // kce_generate (ss, ++ss->sequence_allowed);
1928  // TODO This task must be per sender!
1931  ss);
1932  kce_task_finished = GNUNET_NO;
1933 
1934  }
1935  else if ((NULL == kce_task_rekey) && (GNUNET_YES ==
1936  ss->sender->rekeying) )
1937  {
1940  ss);
1941  }
1942 }
#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.
#define KCN_THRESHOLD
If we fall below this number of available KCNs, we generate additional ACKs until we reach KCN_TARGET...
#define MAX_SECRETS
How many shared master secrets do we keep around at most per sender? Should be large enough so that w...
const char * GNUNET_i2s_full(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
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...
Entry in list of pending tasks.
Definition: scheduler.c:135

References UDPAck::acks_available, SenderAddress::acks_available, ch, UDPAck::cmac, SharedSecret::cmac, COMMUNICATOR_ADDRESS_PREFIX, destroy_all_secrets(), GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_i2s_full(), GNUNET_log, GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK, GNUNET_NO, GNUNET_SCHEDULER_add_delayed(), GNUNET_TRANSPORT_communicator_notify(), GNUNET_YES, UDPAck::header, kce_destroy(), kce_generate(), kce_generate_cb(), kce_generate_rekey_cb(), SharedSecret::kce_head, SharedSecret::kce_tail, SenderAddress::kce_task, SenderAddress::kce_task_finished, SenderAddress::kce_task_rekey, KCN_THRESHOLD, SharedSecret::master, MAX_SECRETS, MAX_SQN_DELTA, SenderAddress::num_secrets, SenderAddress::rekeying, SharedSecret::sender, SharedSecret::sequence_allowed, UDPAck::sequence_max, KeyCacheEntry::sequence_number, GNUNET_MessageHeader::size, ss_finished, SenderAddress::target, GNUNET_MessageHeader::type, and WORKING_QUEUE_INTERVALL.

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

1956 {
1957  struct SharedSecret *ss = kce->ss;
1958  char out_buf[box_len - sizeof(*box)];
1959 
1960  GNUNET_assert (NULL != ss->sender);
1961  if (GNUNET_OK != try_decrypt (ss,
1962  box->gcm_tag,
1963  kce->sequence_number,
1964  (const char *) &box[1],
1965  sizeof(out_buf),
1966  out_buf))
1967  {
1969  "# Decryption failures with valid KCE",
1970  1,
1971  GNUNET_NO);
1972  kce_destroy (kce);
1973  return;
1974  }
1975  kce_destroy (kce);
1977  "# bytes decrypted with BOX",
1978  sizeof(out_buf),
1979  GNUNET_NO);
1981  "# messages decrypted with BOX",
1982  1,
1983  GNUNET_NO);
1985  "decrypted UDPBox with kid %s\n",
1986  GNUNET_sh2s (&box->kid));
1987  try_handle_plaintext (ss->sender, out_buf, sizeof(out_buf));
1988  if ((GNUNET_NO == box->rekeying) && (GNUNET_YES == ss->sender->rekeying))
1989  {
1990  ss->sender->rekeying = GNUNET_NO;
1991  ss->sender->ss_rekey = NULL;
1992  // destroy_all_secrets (ss, GNUNET_NO);
1994  "Receiver stopped rekeying.\n");
1995  }
1996  else if (GNUNET_NO == box->rekeying)
1997  consider_ss_ack (ss, GNUNET_NO);
1998  else
1999  {
2000  ss->sender->rekeying = GNUNET_YES;
2002  "Got Box: Receiver doing rekeying.\n");
2003  }
2004 }
static void consider_ss_ack(struct SharedSecret *ss, int initial)
We established a shared secret with a sender.
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.
static int try_decrypt(const struct SharedSecret *ss, const char tag[(128/8)], 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.
const char * GNUNET_sh2s(const struct GNUNET_ShortHashCode *shc)
Convert a short hash value to a string (for printing debug messages).
char gcm_tag[(128/8)]
128-bit authentication tag for the following encrypted message, from GCM.

References consider_ss_ack(), UDPBox::gcm_tag, GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_NO, GNUNET_OK, GNUNET_sh2s(), GNUNET_STATISTICS_update(), GNUNET_YES, kce_destroy(), UDPBox::kid, UDPBox::rekeying, SenderAddress::rekeying, SharedSecret::sender, KeyCacheEntry::sequence_number, KeyCacheEntry::ss, SenderAddress::ss_rekey, 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:

◆ decrypt_rekey()

static void decrypt_rekey ( const struct UDPRekey rekey,
size_t  rekey_len,
struct KeyCacheEntry kce,
struct SenderAddress sender 
)
static

We received a rekey with matching kce.

Decrypt and process it.

Parameters
rekeythe data we received
rekey_lennumber of bytes in rekey
kcekey index to decrypt rekey

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

2019 {
2020  struct SharedSecret *ss = kce->ss;
2021  struct SharedSecret *ss_rekey;
2022  char out_buf[rekey_len - sizeof(*rekey)];
2023  struct GNUNET_HashCode *master;
2024 
2025 
2027  "decrypt_rekey.\n");
2028 
2029  GNUNET_assert (NULL != ss->sender);
2030  if (GNUNET_OK != try_decrypt (ss,
2031  rekey->gcm_tag,
2032  kce->sequence_number,
2033  (const char *) &rekey[1],
2034  sizeof(out_buf),
2035  out_buf))
2036  {
2038  "# Decryption failures with valid KCE",
2039  1,
2040  GNUNET_NO);
2042  "Decryption with kid %s failed\n",
2043  GNUNET_sh2s (&rekey->kid));
2044  kce_destroy (kce);
2045  return;
2046  }
2047  kce_destroy (kce);
2049  "# bytes decrypted with Rekey",
2050  sizeof(out_buf),
2051  GNUNET_NO);
2053  "decrypted UDPRekey with kid %s\n",
2054  GNUNET_sh2s (&rekey->kid));
2055  /*cmac = (struct GNUNET_HashCode *) out_buf;
2056  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2057  "Received secret with cmac %s \n",
2058  GNUNET_h2s (&cmac));*/
2059  // ss_rekey = (struct SharedSecret *) out_buf;
2060  master = (struct GNUNET_HashCode *) out_buf;
2061  ss_rekey = GNUNET_new (struct SharedSecret);
2062  ss_rekey->master = *master;
2063  calculate_cmac (ss_rekey);
2064  ss_rekey->sender = sender;
2065  // ss_rekey->sequence_used = 0;
2066  // ss_rekey->sequence_allowed = 0;
2067  /* ss_rekey->active_kce_count = 0; */
2068  /* ss_rekey->prev = NULL; */
2069  /* ss_rekey->next = NULL; */
2070  /* GNUNET_assert (ss_rekey->prev == NULL && sender->ss_head != ss_rekey); */
2071  /* GNUNET_assert (ss_rekey->next == NULL && sender->ss_tail != ss_rekey); */
2072  GNUNET_CONTAINER_DLL_insert (sender->ss_head, sender->ss_tail, ss_rekey);
2073  sender->ss_rekey = ss_rekey;
2074  sender->num_secrets++;
2076  "Received secret with cmac %s\n",
2077  GNUNET_h2s (&(ss_rekey->cmac)));
2079  "Received secret with master %s.\n",
2080  GNUNET_h2s (&(ss_rekey->master)));
2082  "We have %u sequence_allowed.\n",
2083  ss_rekey->sequence_allowed);
2085  "We have a sender %p\n",
2086  ss_rekey->sender);
2088  "We have %u acks available.\n",
2089  ss_rekey->sender->acks_available);
2090  consider_ss_ack (ss_rekey, GNUNET_YES);
2091 
2092 }
char gcm_tag[(128/8)]
128-bit authentication tag for the following encrypted message, from GCM.

References SenderAddress::acks_available, calculate_cmac(), SharedSecret::cmac, consider_ss_ack(), UDPRekey::gcm_tag, GNUNET_assert, GNUNET_CONTAINER_DLL_insert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_log, GNUNET_new, GNUNET_NO, GNUNET_OK, GNUNET_sh2s(), GNUNET_STATISTICS_update(), GNUNET_YES, kce_destroy(), UDPRekey::kid, SharedSecret::master, SenderAddress::num_secrets, SharedSecret::sender, SharedSecret::sequence_allowed, KeyCacheEntry::sequence_number, KeyCacheEntry::ss, SenderAddress::ss_head, SenderAddress::ss_rekey, SenderAddress::ss_tail, stats, and try_decrypt().

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

2129 {
2130  struct SearchContext *sc = cls;
2131  struct SenderAddress *sender = value;
2132 
2133  if ((sender->address_len == sc->address_len) &&
2134  (0 == memcmp (sender->address, sc->address, sender->address_len)))
2135  {
2136  sc->sender = sender;
2137  return GNUNET_NO; /* stop iterating! */
2138  }
2139  return GNUNET_YES;
2140 }
static struct GNUNET_FS_SearchContext * sc
Definition: gnunet-search.c:84
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 2155 of file gnunet-communicator-udp.c.

2158 {
2159  struct SenderAddress *sender;
2160  struct SearchContext sc = { .address = address,
2161  .address_len = address_len,
2162  .sender = NULL };
2163 
2165  target,
2167  &sc);
2168  if (NULL != sc.sender)
2169  {
2170  reschedule_sender_timeout (sc.sender);
2171  return sc.sender;
2172  }
2173  sender = GNUNET_new (struct SenderAddress);
2174  sender->target = *target;
2178  senders,
2179  &sender->target,
2180  sender,
2183  "# senders active",
2185  GNUNET_NO);
2186  sender->timeout =
2189  sender,
2192  if (NULL == timeout_task)
2194  return sender;
2195 }
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:314
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:1281
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
ephermalkey that is signed
ucsignature of claimant
Returns
GNUNET_OK if signature is valid

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

2208 {
2209  struct UdpHandshakeSignature uhs;
2210 
2211  uhs.purpose.purpose = htonl (
2213  uhs.purpose.size = htonl (sizeof(uhs));
2214  uhs.sender = uc->sender;
2215  uhs.receiver = my_identity;
2216  uhs.ephemeral = *ephemeral;
2217  uhs.monotonic_time = uc->monotonic_time;
2220  &uhs,
2221  &uc->sender_sig,
2222  &uc->sender.public_key);
2223 }
#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 2235 of file gnunet-communicator-udp.c.

2237 {
2238  char *ret;
2239 
2240  switch (address->sa_family)
2241  {
2242  case AF_INET:
2243  GNUNET_asprintf (&ret,
2244  "%s-%s",
2246  GNUNET_a2s (address, address_len));
2247  break;
2248 
2249  case AF_INET6:
2250  GNUNET_asprintf (&ret,
2251  "%s-%s",
2253  GNUNET_a2s (address, address_len));
2254  break;
2255 
2256  default:
2257  GNUNET_assert (0);
2258  }
2259  return ret;
2260 }
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 2269 of file gnunet-communicator-udp.c.

2270 {
2271  struct sockaddr_storage sa;
2272  struct sockaddr_in *addr_verify;
2273  socklen_t salen = sizeof(sa);
2274  char buf[UINT16_MAX];
2275  ssize_t rcvd;
2276 
2277  (void) cls;
2279  udp_sock,
2280  &sock_read,
2281  NULL);
2283  buf,
2284  sizeof(buf),
2285  (struct sockaddr *) &sa,
2286  &salen);
2287  if (-1 == rcvd)
2288  {
2290  return;
2291  }
2293  "Read %lu bytes\n", rcvd);
2294 
2295  if (rcvd > sizeof(struct UDPRekey))
2296  {
2297  const struct UDPRekey *rekey;
2298  const struct UDPBox *box;
2299  struct KeyCacheEntry *kce;
2300  struct SenderAddress *sender;
2301  int do_decrypt = GNUNET_NO;
2302 
2303  rekey = (const struct UDPRekey *) buf;
2304  box = (const struct UDPBox *) buf;
2306 
2307  if ((GNUNET_YES == box->rekeying) || (GNUNET_NO == box->rekeying))
2309  "UDPRekey has rekeying %u\n",
2310  box->rekeying);
2311  else
2313 
2314  if ((GNUNET_YES == do_decrypt) && (NULL != kce) && (GNUNET_YES ==
2315  kce->ss->sender->
2316  rekeying))
2317  {
2319  "UDPRekey with kid %s\n",
2320  GNUNET_sh2s (&rekey->kid));
2321  sender = setup_sender (&rekey->sender, (const struct sockaddr *) &sa,
2322  salen);
2323 
2324  if (NULL != sender->ss_rekey)
2325  return;
2326 
2327  decrypt_rekey (rekey, (size_t) rcvd, kce, sender);
2328  return;
2329  }
2330  }
2331 
2332  /* first, see if it is a UDPBox */
2333  if (rcvd > sizeof(struct UDPBox))
2334  {
2335  const struct UDPBox *box;
2336  struct KeyCacheEntry *kce;
2337 
2338  box = (const struct UDPBox *) buf;
2340  if (NULL != kce)
2341  {
2342  decrypt_box (box, (size_t) rcvd, kce);
2343  return;
2344  }
2345  }
2346 
2347  /* next, check if it is a broadcast */
2348  if (sizeof(struct UDPBroadcast) == rcvd)
2349  {
2350  const struct UDPBroadcast *ub;
2351  struct UdpBroadcastSignature uhs;
2352  struct GNUNET_PeerIdentity sender;
2353 
2354  addr_verify = GNUNET_memdup (&sa, salen);
2355  addr_verify->sin_port = 0;
2357  "received UDPBroadcast from %s\n",
2358  GNUNET_a2s ((const struct sockaddr *) addr_verify, salen));
2359  ub = (const struct UDPBroadcast *) buf;
2360  uhs.purpose.purpose = htonl (
2362  uhs.purpose.size = htonl (sizeof(uhs));
2363  uhs.sender = ub->sender;
2364  sender = ub->sender;
2365  if (0 == memcmp (&sender, &my_identity, sizeof (struct
2367  {
2369  "Received our own broadcast\n");
2370  return;
2371  }
2373  "checking UDPBroadcastSignature for %s\n",
2374  GNUNET_i2s (&sender));
2375  GNUNET_CRYPTO_hash ((struct sockaddr *) addr_verify, salen, &uhs.h_address);
2376  if (GNUNET_OK ==
2379  &uhs,
2380  &ub->sender_sig,
2381  &ub->sender.public_key))
2382  {
2383  char *addr_s;
2384  enum GNUNET_NetworkType nt;
2385 
2386  addr_s =
2387  sockaddr_to_udpaddr_string ((const struct sockaddr *) &sa, salen);
2388  GNUNET_STATISTICS_update (stats, "# broadcasts received", 1, GNUNET_NO);
2389  /* use our own mechanism to determine network type */
2390  nt =
2391  GNUNET_NT_scanner_get_type (is, (const struct sockaddr *) &sa, salen);
2393  "validating address %s received from UDPBroadcast\n",
2394  GNUNET_i2s (&sender));
2396  GNUNET_free (addr_s);
2397  GNUNET_free (addr_verify);
2398  return;
2399  }
2400  else
2401  {
2403  "VerifyingPeer %s is verifying UDPBroadcast\n",
2404  GNUNET_i2s (&my_identity));
2406  "Verifying UDPBroadcast from %s failed\n",
2407  GNUNET_i2s (&ub->sender));
2408  }
2409  GNUNET_free (addr_verify);
2410  /* continue with KX, mostly for statistics... */
2411  }
2412 
2413 
2414  /* finally, test if it is a KX */
2415  if (rcvd < sizeof(struct UDPConfirmation) + sizeof(struct InitialKX))
2416  {
2418  "# messages dropped (no kid, too small for KX)",
2419  1,
2420  GNUNET_NO);
2421  return;
2422  }
2424  "Got KX\n");
2425  {
2426  const struct InitialKX *kx;
2427  struct SharedSecret *ss;
2428  char pbuf[rcvd - sizeof(struct InitialKX)];
2429  const struct UDPConfirmation *uc;
2430  struct SenderAddress *sender;
2431 
2432  kx = (const struct InitialKX *) buf;
2433  ss = setup_shared_secret_dec (&kx->ephemeral);
2435  "Before DEC\n");
2436 
2437  if (GNUNET_OK != try_decrypt (ss,
2438  kx->gcm_tag,
2439  0,
2440  &buf[sizeof(*kx)],
2441  sizeof(pbuf),
2442  pbuf))
2443  {
2445  "Unable to decrypt tag, dropping...\n");
2446  GNUNET_free (ss);
2448  stats,
2449  "# messages dropped (no kid, AEAD decryption failed)",
2450  1,
2451  GNUNET_NO);
2452  return;
2453  }
2455  "Before VERIFY\n");
2456 
2457  uc = (const struct UDPConfirmation *) pbuf;
2458  if (GNUNET_OK != verify_confirmation (&kx->ephemeral, uc))
2459  {
2460  GNUNET_break_op (0);
2461  GNUNET_free (ss);
2463  "# messages dropped (sender signature invalid)",
2464  1,
2465  GNUNET_NO);
2466  return;
2467  }
2469  "Before SETUP_SENDER\n");
2470 
2471  calculate_cmac (ss);
2472  sender = setup_sender (&uc->sender, (const struct sockaddr *) &sa, salen);
2473  ss->sender = sender;
2474  GNUNET_CONTAINER_DLL_insert (sender->ss_head, sender->ss_tail, ss);
2475  sender->num_secrets++;
2476  GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
2478  "# messages decrypted without BOX",
2479  1,
2480  GNUNET_NO);
2481  try_handle_plaintext (sender, &uc[1], sizeof(pbuf) - sizeof(*uc));
2482  if ((GNUNET_NO == kx->rekeying) && (GNUNET_YES == ss->sender->rekeying))
2483  {
2484  ss->sender->rekeying = GNUNET_NO;
2485  sender->ss_rekey = NULL;
2486  // destroy_all_secrets (ss, GNUNET_NO);
2488  "Receiver stopped rekeying.\n");
2489  }
2490  else if (GNUNET_NO == kx->rekeying)
2492  else
2493  {
2494  ss->sender->rekeying = GNUNET_YES;
2496  "Got KX: Receiver doing rekeying.\n");
2497  }
2498  /*if (sender->num_secrets > MAX_SECRETS)
2499  secret_destroy (sender->ss_tail);*/
2500  }
2501 }
#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 void decrypt_rekey(const struct UDPRekey *rekey, size_t rekey_len, struct KeyCacheEntry *kce, struct SenderAddress *sender)
We received a rekey with matching kce.
static struct SharedSecret * setup_shared_secret_dec(const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral)
Setup shared secret for decryption.
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.
static int do_decrypt(struct GSC_KeyExchangeInfo *kx, const struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, const void *in, void *out, size_t size)
Decrypt size bytes from in and write the result to out.
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:702
GNUNET_NetworkType
Types of networks (with separate quotas) we support.
Definition: gnunet_nt_lib.h:36
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:1502
The identity of the host (wraps the signing key of the peer).
struct GNUNET_CRYPTO_EddsaPublicKey public_key
char gcm_tag[(128/8)]
HMAC for the following encrypted message, using GCM.
int rekeying
A flag indicating, if the sender is doing rekeying.
struct GNUNET_CRYPTO_EcdhePublicKey ephemeral
Ephemeral key for KX.
int rekeying
A flag indicating, if the sender is doing rekeying.
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.
UDP message box.
struct GNUNET_PeerIdentity sender
Sender's identity.
struct GNUNET_ShortHashCode kid
Key and IV identification code.
Signature we use to verify that the broadcast was really made by the peer that claims to have made it...

References ah, buf, calculate_cmac(), consider_ss_ack(), decrypt_box(), decrypt_rekey(), do_decrypt(), 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_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, key_cache, UDPBox::kid, UDPRekey::kid, my_identity, nt, GNUNET_PeerIdentity::public_key, GNUNET_CRYPTO_EccSignaturePurpose::purpose, UdpBroadcastSignature::purpose, read_task, InitialKX::rekeying, UDPBox::rekeying, SenderAddress::rekeying, UDPConfirmation::sender, UdpBroadcastSignature::sender, UDPBroadcast::sender, UDPRekey::sender, SharedSecret::sender, UDPBroadcast::sender_sig, setup_sender(), setup_shared_secret_dec(), GNUNET_CRYPTO_EccSignaturePurpose::size, sockaddr_to_udpaddr_string(), KeyCacheEntry::ss, SenderAddress::ss_rekey, 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 2512 of file gnunet-communicator-udp.c.

2513 {
2514  struct sockaddr *in;
2515  unsigned int port;
2516  char dummy[2];
2517  char *colon;
2518  char *cp;
2519 
2520  if (1 == sscanf (bindto, "%u%1s", &port, dummy))
2521  {
2522  /* interpreting value as just a PORT number */
2523  if (port > UINT16_MAX)
2524  {
2526  "BINDTO specification `%s' invalid: value too large for port\n",
2527  bindto);
2528  return NULL;
2529  }
2530  if ((GNUNET_NO == GNUNET_NETWORK_test_pf (PF_INET6)) ||
2531  (GNUNET_YES ==
2534  "DISABLE_V6")))
2535  {
2536  struct sockaddr_in *i4;
2537 
2538  i4 = GNUNET_malloc (sizeof(struct sockaddr_in));
2539  i4->sin_family = AF_INET;
2540  i4->sin_port = htons ((uint16_t) port);
2541  *sock_len = sizeof(struct sockaddr_in);
2542  in = (struct sockaddr *) i4;
2543  }
2544  else
2545  {
2546  struct sockaddr_in6 *i6;
2547 
2548  i6 = GNUNET_malloc (sizeof(struct sockaddr_in6));
2549  i6->sin6_family = AF_INET6;
2550  i6->sin6_port = htons ((uint16_t) port);
2551  *sock_len = sizeof(struct sockaddr_in6);
2552  in = (struct sockaddr *) i6;
2553  }
2554  return in;
2555  }
2556  cp = GNUNET_strdup (bindto);
2557  colon = strrchr (cp, ':');
2558  if (NULL != colon)
2559  {
2560  /* interpret value after colon as port */
2561  *colon = '\0';
2562  colon++;
2563  if (1 == sscanf (colon, "%u%1s", &port, dummy))
2564  {
2565  /* interpreting value as just a PORT number */
2566  if (port > UINT16_MAX)
2567  {
2569  "BINDTO specification `%s' invalid: value too large for port\n",
2570  bindto);
2571  GNUNET_free (cp);
2572  return NULL;
2573  }
2574  }
2575  else
2576  {
2577  GNUNET_log (
2579  "BINDTO specification `%s' invalid: last ':' not followed by number\n",
2580  bindto);
2581  GNUNET_free (cp);
2582  return NULL;
2583  }
2584  }
2585  else
2586  {
2587  /* interpret missing port as 0, aka pick any free one */
2588  port = 0;
2589  }
2590  {
2591  /* try IPv4 */
2592  struct sockaddr_in v4;
2593 
2594  memset (&v4, 0, sizeof(v4));
2595  if (1 == inet_pton (AF_INET, cp, &v4.sin_addr))
2596  {
2597  v4.sin_family = AF_INET;
2598  v4.sin_port = htons ((uint16_t) port);
2599 #if HAVE_SOCKADDR_IN_SIN_LEN
2600  v4.sin_len = sizeof(struct sockaddr_in);
2601 #endif
2602  in = GNUNET_memdup (&v4, sizeof(struct sockaddr_in));
2603  *sock_len = sizeof(struct sockaddr_in);
2604  GNUNET_free (cp);
2605  return in;
2606  }
2607  }
2608  {
2609  /* try IPv6 */
2610  struct sockaddr_in6 v6;
2611  const char *start;
2612 
2613  memset (&v6, 0, sizeof(v6));
2614  start = cp;
2615  if (('[' == *cp) && (']' == cp[strlen (cp) - 1]))
2616  {
2617  start++; /* skip over '[' */
2618  cp[strlen (cp) - 1] = '\0'; /* eat ']' */
2619  }
2620  if (1 == inet_pton (AF_INET6, start, &v6.sin6_addr))
2621  {
2622  v6.sin6_family = AF_INET6;
2623  v6.sin6_port = htons ((uint16_t) port);
2624 #if HAVE_SOCKADDR_IN_SIN_LEN
2625  v6.sin6_len = sizeof(sizeof(struct sockaddr_in6));
2626 #endif
2627  in = GNUNET_memdup (&v6, sizeof(v6));
2628  *sock_len = sizeof(v6);
2629  GNUNET_free (cp);
2630  return in;
2631  }
2632  }
2633  /* #5528 FIXME (feature!): maybe also try getnameinfo()? */
2634  GNUNET_free (cp);
2635  return NULL;
2636 }
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:79

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

2648 {
2649  char pad[pad_size];
2650 
2652  if (sizeof(pad) > sizeof(struct GNUNET_MessageHeader))
2653  {
2654  struct GNUNET_MessageHeader hdr =
2655  { .size = htons (sizeof(pad)),
2656  .type = htons (GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_PAD) };
2657 
2658  memcpy (pad, &hdr, sizeof(hdr));
2659  }
2660  GNUNET_assert (
2661  0 ==
2662  gcry_cipher_encrypt (out_cipher, dgram, sizeof(pad), pad, sizeof(pad)));
2663 }
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(), mq_send_kx(), and send_UDPRekey().

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

2678 {
2679  struct ReceiverAddress *receiver = impl_state;
2680  uint16_t msize = ntohs (msg->size);
2681  struct UdpHandshakeSignature uhs;
2682  struct UDPConfirmation uc;
2683  struct InitialKX kx;
2684  struct GNUNET_CRYPTO_EcdhePrivateKey epriv;
2685  char dgram[receiver->kx_mtu + sizeof(uc) + sizeof(kx)];
2686  size_t dpos;
2687  gcry_cipher_hd_t out_cipher;
2688  struct SharedSecret *ss;
2689 
2690  GNUNET_assert (mq == receiver->kx_mq);
2691  if (msize > receiver->kx_mtu)
2692  {
2693  GNUNET_break (0);
2694  if (GNUNET_YES != receiver->receiver_destroy_called)
2696  return;
2697  }
2699 
2700  /* setup key material */
2702 
2704 
2705  if (receiver->num_secrets > MAX_SECRETS)
2706  {
2708  }
2709 
2710  setup_cipher (&ss->master, 0, &out_cipher);
2711  /* compute 'uc' */
2712  uc.sender = my_identity;
2713  uc.monotonic_time =
2715  uhs.purpose.purpose = htonl (
2717  uhs.purpose.size = htonl (sizeof(uhs));
2718  uhs.sender = my_identity;
2719  uhs.receiver = receiver->target;
2720  GNUNET_CRYPTO_ecdhe_key_get_public (&epriv, &uhs.ephemeral);
2721  uhs.monotonic_time = uc.monotonic_time;
2723  &uhs,
2724  &uc.sender_sig);
2725  /* Leave space for kx */
2726  dpos = sizeof(kx);
2727  /* Append encrypted uc to dgram */
2728  GNUNET_assert (0 == gcry_cipher_encrypt (out_cipher,
2729  &dgram[dpos],
2730  sizeof(uc),
2731  &uc,
2732  sizeof(uc)));
2733  dpos += sizeof(uc);
2734  /* Append encrypted payload to dgram */
2735  GNUNET_assert (
2736  0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], msize, msg, msize));
2737  dpos += msize;
2738  do_pad (out_cipher, &dgram[dpos], sizeof(dgram) - dpos);
2739  /* Datagram starts with kx */
2740  kx.ephemeral = uhs.ephemeral;
2741  GNUNET_assert (
2742  0 == gcry_cipher_gettag (out_cipher, kx.gcm_tag, sizeof(kx.gcm_tag)));
2743  gcry_cipher_close (out_cipher);
2744  if (GNUNET_NO == receiver->rekeying)
2745  kx.rekeying = GNUNET_NO;
2746  else
2747  kx.rekeying = GNUNET_YES;
2748  memcpy (dgram, &kx, sizeof(kx));
2750  dgram,
2751  sizeof(dgram),
2752  receiver->address,
2753  receiver->address_len))
2756  "Sending KX with payload size %u to %s\n",
2757  msize,
2758  GNUNET_a2s (receiver->address,
2759  receiver->address_len));
2761 }
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
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_enc(const struct GNUNET_CRYPTO_EcdhePrivateKey *ephemeral, struct ReceiverAddress *receiver, int add_to_receiver)
Setup shared secret for encryption.
void GNUNET_CRYPTO_ecdhe_key_create(struct GNUNET_CRYPTO_EcdhePrivateKey *pk)
Create a new private key.
Definition: crypto_ecc.c:435
#define GNUNET_CRYPTO_eddsa_sign(priv, ps, sig)
EdDSA sign a given block.
void GNUNET_CRYPTO_ecdhe_key_get_public(const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, struct GNUNET_CRYPTO_EcdhePublicKey *pub)
Extract the public key for the given private key.
Definition: crypto_ecc.c:213
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
void GNUNET_MQ_impl_send_continue(struct GNUNET_MQ_Handle *mq)
Call the send implementation for the next queued message, if any.
Definition: mq.c:423
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:794
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:859
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:637
Private ECC key encoded for transmission.

References cfg, destroy_all_secrets(), do_pad(), UdpHandshakeSignature::ephemeral, InitialKX::ephemeral, InitialKX::gcm_tag, GNUNET_a2s(), GNUNET_assert, GNUNET_break, GNUNET_CRYPTO_ecdhe_key_create(), GNUNET_CRYPTO_ecdhe_key_get_public(), GNUNET_CRYPTO_eddsa_sign, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, GNUNET_log, GNUNET_log_strerror, GNUNET_MQ_impl_send_continue(), GNUNET_NETWORK_socket_sendto(), GNUNET_NO, GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_HANDSHAKE, GNUNET_TIME_absolute_get_monotonic(), GNUNET_TIME_absolute_hton(), GNUNET_YES, SharedSecret::master, MAX_SECRETS, UdpHandshakeSignature::monotonic_time, mq, msg, my_identity, my_private_key, GNUNET_CRYPTO_EccSignaturePurpose::purpose, UdpHandshakeSignature::purpose, UdpHandshakeSignature::receiver, receiver(), receiver_destroy(), InitialKX::rekeying, reschedule_receiver_timeout(), UdpHandshakeSignature::sender, setup_cipher(), setup_shared_secret_enc(), GNUNET_MessageHeader::size, GNUNET_CRYPTO_EccSignaturePurpose::size, uc, and udp_sock.

Referenced by setup_receiver_mq().

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

◆ check_for_rekeying()

static void check_for_rekeying ( struct ReceiverAddress receiver,
struct UDPBox box 
)
static

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

2766 {
2767 
2768  struct GNUNET_TIME_Relative rt;
2769 
2771  "Timeout is %llu\n.",
2772  (unsigned long long) receiver->rekey_timeout.abs_value_us);
2773 
2774  if (0 == receiver->rekey_timeout.abs_value_us)
2775  {
2776  receiver->rekey_timeout = GNUNET_TIME_relative_to_absolute (
2777  rekey_interval);
2778  }
2779  else
2780  {
2781  rt = GNUNET_TIME_absolute_get_remaining (receiver->rekey_timeout);
2783  "Relative time is %llu and timeout is %llu\n.",
2784  (unsigned long long) rt.rel_value_us,
2785  (unsigned long long) receiver->rekey_timeout.abs_value_us);
2786 
2787  if ((0 == rt.rel_value_us) || (receiver->rekey_send_bytes >
2788  rekey_max_bytes) )
2789  {
2791  "Bytes send %llu greater than %llu max bytes\n.",
2792  (unsigned long long) receiver->rekey_send_bytes,
2793  rekey_max_bytes);
2795  "Relative time is %llu and timeout is %llu\n.",
2796  (unsigned long long) rt.rel_value_us,
2797  (unsigned long long) receiver->rekey_timeout.abs_value_us);
2798 
2799  receiver->rekey_timeout.abs_value_us = 0;
2800  receiver->rekey_send_bytes = 0;
2801  receiver->ss_rekey = NULL;
2802  // destroy_all_secrets (ss, GNUNET_NO);
2803  receiver->rekeying = GNUNET_YES;
2804  receiver->rekey_acks_available = receiver->acks_available;
2805  box->rekeying = GNUNET_YES;
2807  "Sender started rekeying.\n");
2808  if (GNUNET_YES == box->rekeying)
2810  "Sending rekeying with kid %s\n",
2811  GNUNET_sh2s (&box->kid));
2812  }
2813  }
2814 }
static struct GNUNET_TIME_Relative rekey_interval
The rekey interval.
static unsigned long long rekey_max_bytes
How often we do rekey based on number of bytes transmitted.

References GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_sh2s(), GNUNET_TIME_absolute_get_remaining(), GNUNET_TIME_relative_to_absolute(), GNUNET_YES, UDPBox::kid, receiver(), rekey_interval, rekey_max_bytes, UDPBox::rekeying, and GNUNET_TIME_Relative::rel_value_us.

Referenced by mq_send_d().

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

◆ send_UDPRekey()

static void send_UDPRekey ( struct ReceiverAddress receiver,
struct SharedSecret ss 
)
static

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

2819 {
2820  uint8_t is_ss_rekey_sequence_allowed_zero = GNUNET_NO;
2821  uint8_t is_acks_available_below = GNUNET_NO;
2822  uint8_t send_rekey = GNUNET_NO;
2823  uint16_t not_below;
2824  struct GNUNET_CRYPTO_EcdhePrivateKey epriv;
2825  struct UDPRekey *rekey;
2826  size_t dpos;
2827 
2828  char rekey_dgram[sizeof(struct UDPRekey) + receiver->d_mtu];
2829 
2830  if (NULL != receiver->ss_rekey)
2831  {
2832  not_below = (receiver->rekey_acks_available
2833  - (receiver->rekey_acks_available % 3)) / 3;
2834  is_ss_rekey_sequence_allowed_zero = (0 ==
2835  receiver->ss_rekey->sequence_allowed);
2836  is_acks_available_below = (receiver->acks_available >= not_below);
2837  send_rekey = (0 == (receiver->acks_available - not_below) % not_below) &&
2838  is_acks_available_below && is_ss_rekey_sequence_allowed_zero;
2840  "send_rekey: %u, %u, %u\n",
2841  send_rekey,
2842  receiver->rekey_acks_available,
2843  receiver->acks_available);
2844  }
2845  else if (NULL == receiver->ss_rekey)
2846  {
2847  /* setup key material */
2849  receiver->ss_rekey = setup_shared_secret_enc (&epriv, receiver,
2850  GNUNET_NO);
2851  receiver->ss_rekey->sequence_allowed = 0;
2853  "Setup secret with cmac %s\n",
2854  GNUNET_h2s (&(receiver->ss_rekey->cmac)));
2856  "Setup secret with master %s.\n",
2857  GNUNET_h2s (&(receiver->ss_rekey->master)));
2858  }
2859 
2860  if (send_rekey)
2861  {
2862  GNUNET_assert (0 != receiver->number_rekeying_kce);
2863  gcry_cipher_hd_t rekey_out_cipher;
2864 
2865  while (NULL != ss && ss->sequence_used >= ss->sequence_allowed)
2866  {
2867  ss = ss->prev;
2868  }
2869 
2870  if (NULL != ss)
2871  {
2872  rekey = (struct UDPRekey *) rekey_dgram;
2873  rekey->sender = my_identity;
2874  ss->sequence_used++;
2875  get_kid (&ss->master, ss->sequence_used, &rekey->kid);
2876  receiver->number_rekeying_kce--;
2877  setup_cipher (&ss->master, ss->sequence_used, &rekey_out_cipher);
2878  /* Append encrypted payload to dgram */
2879  dpos = sizeof(struct UDPRekey);
2880 
2881  GNUNET_assert (
2882  0 == gcry_cipher_encrypt (rekey_out_cipher, &rekey_dgram[dpos],
2883  sizeof(receiver->ss_rekey->master),
2884  &(receiver->ss_rekey->master),
2885  sizeof(receiver->ss_rekey->master)));
2886  dpos += sizeof(receiver->ss_rekey->master);
2887  /* GNUNET_assert ( */
2888  /* 0 == gcry_cipher_encrypt (rekey_out_cipher, &rekey_dgram[dpos], */
2889  /* /\*sizeof(receiver->ss_rekey->cmac), */
2890  /* &(receiver->ss_rekey->cmac), */
2891  /* sizeof(receiver->ss_rekey->cmac))); */
2892  /* dpos += sizeof(receiver->ss_rekey->cmac);*\/ */
2893  /* sizeof(receiver->ss_rekey), */
2894  /* receiver->ss_rekey, */
2895  /* sizeof(receiver->ss_rekey))); */
2896  /* dpos += sizeof(receiver->ss_rekey); */
2897  do_pad (rekey_out_cipher, &rekey_dgram[dpos], sizeof(rekey_dgram)
2898  - dpos);
2899  GNUNET_assert (0 == gcry_cipher_gettag (rekey_out_cipher,
2900  rekey->gcm_tag,
2901  sizeof(rekey->gcm_tag)));
2902  gcry_cipher_close (rekey_out_cipher);
2903 
2905  "Sending rekey with kid %s and master %s\n",
2906  GNUNET_sh2s (&rekey->kid),
2907  GNUNET_h2s (&(receiver->ss_rekey->master)));
2909  "Sending rekey with cmac %s\n",
2910  GNUNET_h2s (&(receiver->ss_rekey->cmac)));
2912  "%u rekey kces left.\n",
2913  receiver->number_rekeying_kce);
2914 
2916  rekey_dgram,
2917  sizeof(rekey_dgram),
2918  receiver->address,
2919  receiver->address_len))
2921 
2922  receiver->acks_available--;
2924  "%u receiver->acks_available 1\n",
2925  receiver->acks_available);
2927  "Sending UDPRekey to %s\n", GNUNET_a2s (receiver->address,
2928  receiver->
2929  address_len));
2930  }
2931  }
2932 }
struct SharedSecret * prev
Kept in a DLL.

References do_pad(), UDPRekey::gcm_tag, get_kid(), GNUNET_a2s(), GNUNET_assert, GNUNET_CRYPTO_ecdhe_key_create(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, GNUNET_h2s(), GNUNET_log, GNUNET_log_strerror, GNUNET_NETWORK_socket_sendto(), GNUNET_NO, GNUNET_sh2s(), UDPRekey::kid, SharedSecret::master, my_identity, SharedSecret::prev, receiver(), UDPRekey::sender, SharedSecret::sequence_allowed, SharedSecret::sequence_used, setup_cipher(), setup_shared_secret_enc(), and udp_sock.

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

2947 {
2948  struct ReceiverAddress *receiver = impl_state;
2949  uint16_t msize = ntohs (msg->size);
2950 
2951  GNUNET_assert (mq == receiver->d_mq);
2952  if ((msize > receiver->d_mtu) ||
2953  (0 == receiver->acks_available))
2954  {
2956  "msize: %u, mtu: %lu, acks: %u\n",
2957  msize,
2958  receiver->d_mtu,
2959  receiver->acks_available);
2960 
2961  GNUNET_break (0);
2962  if (GNUNET_YES != receiver->receiver_destroy_called)
2964  return;
2965  }
2967 
2968  /* begin "BOX" encryption method, scan for ACKs from tail! */
2969  for (struct SharedSecret *ss = receiver->ss_tail; NULL != ss; ss = ss->prev)
2970  {
2971  if (0 < ss->sequence_used)
2973  "Trying to send UDPBox with shared secrect %s sequence_used %u and ss->sequence_allowed %u\n",
2974  GNUNET_h2s (&ss->master),
2975  ss->sequence_used,
2976  ss->sequence_allowed);
2977  // Uncomment this for alternativ 1 of backchannel functionality
2978  if (ss->sequence_used >= ss->sequence_allowed)
2979  // Until here for alternativ 1
2980  // Uncomment this for alternativ 2 of backchannel functionality
2981  // if (0 == ss->sequence_allowed)
2982  // Until here for alternativ 2
2983  {
2984  continue;
2985  }
2986  char dgram[sizeof(struct UDPBox) + receiver->d_mtu];
2987  struct UDPBox *box;
2988  gcry_cipher_hd_t out_cipher;
2989  size_t dpos;
2990 
2991  box = (struct UDPBox *) dgram;
2992  ss->sequence_used++;
2993  get_kid (&ss->master, ss->sequence_used, &box->kid);
2994  setup_cipher (&ss->master, ss->sequence_used, &out_cipher);
2995  /* Append encrypted payload to dgram */
2996  dpos = sizeof(struct UDPBox);
2997  GNUNET_assert (
2998  0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], msize, msg, msize));
2999  dpos += msize;
3000  do_pad (out_cipher, &dgram[dpos], sizeof(dgram) - dpos);
3001  GNUNET_assert (0 == gcry_cipher_gettag (out_cipher,
3002  box->gcm_tag,
3003  sizeof(box->gcm_tag)));
3004  gcry_cipher_close (out_cipher);
3005 
3006  receiver->rekey_send_bytes += sizeof(struct UDPBox) + receiver->d_mtu;
3007 
3008  if (GNUNET_NO == receiver->rekeying)
3009  box->rekeying = GNUNET_NO;
3010  else
3011  box->rekeying = GNUNET_YES;
3012 
3014  dgram,
3015  sizeof(dgram),
3016  receiver->address,
3017  receiver->address_len))
3020  "Sending UDPBox with payload size %u, %u acks left\n",
3021  msize,
3022  receiver->acks_available);
3024  receiver->acks_available--;
3026  "%u receiver->acks_available 2\n",
3027  receiver->acks_available);
3029  if (0 == receiver->acks_available - receiver->number_rekeying_kce)
3030  {
3031  /* We have no more ACKs */
3033  "No more acks\n");
3034  if (GNUNET_YES == receiver->rekeying)
3035  {
3036  receiver->rekeying = GNUNET_NO;
3038  "Sender stopped rekeying\n");
3039 
3040  if ((NULL != receiver->ss_rekey) && (0 <
3041  receiver->ss_rekey->
3042  sequence_allowed) )
3044  }
3045  }
3046  else if ((GNUNET_YES == receiver->rekeying) )
3047  {
3048  send_UDPRekey (receiver, ss);
3049  }
3050 
3051  return;
3052  }
3053 }
static void check_for_rekeying(struct ReceiverAddress *receiver, struct UDPBox *box)
static void send_UDPRekey(struct ReceiverAddress *receiver, struct SharedSecret *ss)

References add_acks_rekey(), check_for_rekeying(), do_pad(), UDPBox::gcm_tag, get_kid(), GNUNET_assert, GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, GNUNET_h2s(), GNUNET_log, GNUNET_log_strerror, GNUNET_MQ_impl_send_continue(), GNUNET_NETWORK_socket_sendto(), GNUNET_NO, GNUNET_YES, UDPBox::kid, mq, msg, receiver(), receiver_destroy(), UDPBox::rekeying, reschedule_receiver_timeout(), send_UDPRekey(), 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 3065 of file gnunet-communicator-udp.c.

3066 {
3067  struct ReceiverAddress *receiver = impl_state;
3069  "Default MQ destroyed\n");
3070  if (mq == receiver->d_mq)
3071  {
3072  receiver->d_mq = NULL;
3073  if (GNUNET_YES != receiver->receiver_destroy_called)
3075  }
3076 }

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

3089 {
3090  struct ReceiverAddress *receiver = impl_state;
3092  "KX MQ destroyed\n");
3093  if (mq == receiver->kx_mq)
3094  {
3095  receiver->kx_mq = NULL;
3096  if (GNUNET_YES != receiver->receiver_destroy_called)
3098  }
3099 }

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

3110 {
3111  /* Cancellation is impossible with UDP; bail */
3112  GNUNET_assert (0);
3113 }

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

3127 {
3128  struct ReceiverAddress *receiver = cls;
3129 
3131  "MQ error in queue to %s: %d\n",
3132  GNUNET_i2s (&receiver->target),
3133  (int) error);
3135 }

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

3239 {
3240  struct ReceiverAddress *receiver;
3241  const char *path;
3242  struct sockaddr *in;
3243  socklen_t in_len;
3244 
3245  if (0 != strncmp (address,
3247  strlen (COMMUNICATOR_ADDRESS_PREFIX "-")))
3248  {
3249  GNUNET_break_op (0);
3250  return GNUNET_SYSERR;
3251  }
3252  path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")];
3253  in = udp_address_to_sockaddr (path, &in_len);
3254 
3255  receiver = GNUNET_new (struct ReceiverAddress);
3256  receiver->address = in;
3257  receiver->address_len = in_len;
3258  receiver->target = *peer;
3259  receiver->nt = GNUNET_NT_scanner_get_type (is, in, in_len);
3261  receivers,
3262  &receiver->target,
3263  receiver,
3266  "Added %s to receivers\n",
3267  GNUNET_i2s_full (&receiver->target));
3268  receiver->timeout =
3271  receiver,
3272  receiver->timeout.abs_value_us);
3274  "# receivers active",
3276  GNUNET_NO);
3277  receiver->foreign_addr =
3278  sockaddr_to_udpaddr_string (receiver->address, receiver->address_len);
3280  if (NULL == timeout_task)
3282  return GNUNET_OK;
3283 }
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 3295 of file gnunet-communicator-udp.c.

3298 {
3299  struct ReceiverAddress *receiver = value;
3300 
3301  (void) cls;
3302  (void) target;
3304  return GNUNET_OK;
3305 }
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 3317 of file gnunet-communicator-udp.c.

3320 {
3321  struct SenderAddress *sender = value;
3322 
3323  (void) cls;
3324  (void) target;
3325 
3326  if (NULL != sender->kce_task_rekey)
3327  {
3329  sender->kce_task_rekey = NULL;
3330  }
3331  if (NULL != sender->kce_task)
3332  {
3334  sender->kce_task = NULL;
3335  }
3336 
3337  sender_destroy (sender);
3338  return GNUNET_OK;
3339 }

References GNUNET_OK, GNUNET_SCHEDULER_cancel(), SenderAddress::kce_task, SenderAddress::kce_task_rekey, 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 3348 of file gnunet-communicator-udp.c.

3349 {
3351  "do_shutdown\n");
3352  if (NULL != nat)
3353  {
3355  nat = NULL;
3356  }
3357  while (NULL != bi_head)
3358  bi_destroy (bi_head);
3359  if (NULL != broadcast_task)
3360  {
3362  broadcast_task = NULL;
3363  }
3364  if (NULL != timeout_task)
3365  {
3367  timeout_task = NULL;
3368  }
3369  if (NULL != read_task)
3370  {
3372  read_task = NULL;
3373  }
3374  if (NULL != udp_sock)
3375  {
3378  udp_sock = NULL;
3379  }
3382  NULL);
3386  NULL);
3391  if (NULL != timeout_task)
3392  {
3394  timeout_task = NULL;
3395  }
3396  if (NULL != ch)
3397  {
3399  ch = NULL;
3400  }
3401  if (NULL != ah)
3402  {
3404  ah = NULL;
3405  }
3406  if (NULL != stats)
3407  {
3409  stats = NULL;
3410  }
3411  if (NULL != my_private_key)
3412  {
3414  my_private_key = NULL;
3415  }
3416  if (NULL != is)
3417  {
3419  is = NULL;
3420  }
3422  "do_shutdown finished\n");
3423 }
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_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:701
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:508
void GNUNET_NT_scanner_done(struct GNUNET_NT_InterfaceScanner *is)
Terminate interface scanner.
Definition: nt.c:433
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
void GNUNET_TRANSPORT_communicator_disconnect(struct GNUNET_TRANSPORT_CommunicatorHandle *ch)
Disconnect from the transport service.

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

3439 {
3440  const struct UDPAck *ack;
3441 
3442  (void) cls;
3444  "Storing UDPAck received from backchannel from %s\n",
3445  GNUNET_i2s_full (sender));
3447  (ntohs (msg->size) != sizeof(struct UDPAck)))
3448  {
3449  GNUNET_break_op (0);
3450  return;
3451  }
3452  ack = (const struct UDPAck *) msg;
3454  sender,
3455  &handle_ack,
3456  (void *) ack);
3457 }

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

3480 {
3481  char *my_addr;
3483 
3484  if (GNUNET_YES == add_remove)
3485  {
3486  enum GNUNET_NetworkType nt;
3487 
3488  GNUNET_asprintf (&my_addr,
3489  "%s-%s",
3491  GNUNET_a2s (addr, addrlen));
3492  nt = GNUNET_NT_scanner_get_type (is, addr, addrlen);
3493  ai =
3495  my_addr,
3496  nt,
3498  GNUNET_free (my_addr);
3499  *app_ctx = ai;
3500  }
3501  else
3502  {
3503  ai = *app_ctx;
3505  *app_ctx = NULL;
3506  }
3507 }
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 3516 of file gnunet-communicator-udp.c.

3517 {
3518  struct BroadcastInterface *bi = cls;
3519  struct GNUNET_TIME_Relative delay;
3520 
3524  bi->broadcast_task =
3526 
3527  switch (bi->sa->sa_family)
3528  {
3529  case AF_INET: {
3530  static int yes = 1;
3531  static int no = 0;
3532  ssize_t sent;
3533 
3534  if (GNUNET_OK !=
3536  SOL_SOCKET,
3537  SO_BROADCAST,
3538  &yes,
3539  sizeof(int)))
3541  "setsockopt");
3543  "creating UDPBroadcast from %s\n",
3544  GNUNET_i2s (&(bi->bcm.sender)));
3546  "sending UDPBroadcast to add %s\n",
3547  GNUNET_a2s (bi->ba, bi->salen));
3549  &bi->bcm,
3550  sizeof(bi->bcm),
3551  bi->ba,
3552  bi->salen);
3553  if (-1 == sent)
3555  "sendto");
3557  SOL_SOCKET,
3558  SO_BROADCAST,
3559  &no,
3560  sizeof(int)))
3562  "setsockopt");
3563  break;
3564  }
3565 
3566  case AF_INET6: {
3567  ssize_t sent;
3568  struct sockaddr_in6 dst;
3569 
3570  dst.sin6_family = AF_INET6;
3571  dst.sin6_port = htons (my_port);
3572  dst.sin6_addr = bi->mcreq.ipv6mr_multiaddr;
3573  dst.sin6_scope_id = ((struct sockaddr_in6 *) bi->ba)->sin6_scope_id;
3574 
3576  "sending UDPBroadcast\n");
3578  &bi->bcm,
3579  sizeof(bi->bcm),
3580  (const struct sockaddr *) &dst,
3581  sizeof(dst));
3582  if (-1 == sent)
3584  break;
3585  }
3586 
3587  default:
3588  GNUNET_break (0);
3589  break;
3590  }
3591 }
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 3609 of file gnunet-communicator-udp.c.

3616 {
3617  struct BroadcastInterface *bi;
3618  enum GNUNET_NetworkType network;
3619  struct UdpBroadcastSignature ubs;
3620 
3621  (void) cls;
3622  (void) netmask;
3623  if (NULL == addr)
3624  return GNUNET_YES; /* need to know our address! */
3625  network = GNUNET_NT_scanner_get_type (is, addr, addrlen);
3626  if (GNUNET_NT_LOOPBACK == network)
3627  {
3628  /* Broadcasting on loopback does not make sense */
3629  return GNUNET_YES;
3630  }
3631  for (bi = bi_head; NULL != bi; bi = bi->next)
3632  {
3633  if ((bi->salen == addrlen) && (0 == memcmp (addr, bi->sa, addrlen)))
3634  {
3635  bi->found = GNUNET_YES;
3636  return GNUNET_OK;
3637  }
3638  }
3639 
3640  if ((AF_INET6 == addr->sa_family) && (NULL == broadcast_addr))
3641  return GNUNET_OK; /* broadcast_addr is required for IPv6! */
3642  if ((AF_INET6 == addr->sa_family) && (GNUNET_YES != have_v6_socket))
3643  return GNUNET_OK; /* not using IPv6 */
3644 
3645  bi = GNUNET_new (struct BroadcastInterface);
3646  bi->sa = GNUNET_memdup (addr,
3647  addrlen);
3648  if ( (NULL != broadcast_addr) &&
3649  (addrlen == sizeof (struct sockaddr_in)) )
3650  {
3651  struct sockaddr_in *ba;
3652 
3653  ba = GNUNET_memdup (broadcast_addr,
3654  addrlen);
3655  ba->sin_port = htons (2086); /* always GNUnet port, ignore configuration! */
3656  bi->ba = (struct sockaddr *) ba;
3657  }
3658  bi->salen = addrlen;
3659  bi->found = GNUNET_YES;
3660  bi->bcm.sender = my_identity;
3661  ubs.purpose.purpose = htonl (
3663  ubs.purpose.size = htonl (sizeof(ubs));
3664  ubs.sender = my_identity;
3666  "creating UDPBroadcastSignature for %s\n",
3667  GNUNET_a2s (addr, addrlen));
3668  GNUNET_CRYPTO_hash (addr, addrlen, &ubs.h_address);
3670  &ubs,
3671  &bi->bcm.sender_sig);
3672  if (NULL != bi->ba)
3673  {
3676  }
3677  if ((AF_INET6 == addr->sa_family) && (NULL != broadcast_addr))
3678  {
3679  /* Create IPv6 multicast request */
3680  const struct sockaddr_in6 *s6 =
3681  (const struct sockaddr_in6 *) broadcast_addr;
3682 
3683  GNUNET_assert (
3684  1 == inet_pton (AF_INET6, "FF05::13B", &bi->mcreq.ipv6mr_multiaddr));
3685 
3686  /* http://tools.ietf.org/html/rfc2553#section-5.2:
3687  *
3688  * IPV6_JOIN_GROUP
3689  *
3690  * Join a multicast group on a specified local interface. If the
3691  * interface index is specified as 0, the kernel chooses the local
3692  * interface. For example, some kernels look up the multicast
3693  * group in the normal IPv6 routing table and using the resulting
3694  * interface; we do this for each interface, so no need to use
3695  * zero (anymore...).
3696  */bi->mcreq.ipv6mr_interface = s6->sin6_scope_id;
3697 
3698  /* Join the multicast group */
3700  IPPROTO_IPV6,
3701  IPV6_JOIN_GROUP,
3702  &bi->mcreq,
3703  sizeof(bi->mcreq)))
3704  {
3706  }
3707  }
3708  return GNUNET_OK;
3709 }
static int have_v6_socket
GNUNET_YES if udp_sock supports IPv6.
@ GNUNET_NT_LOOPBACK
Loopback (same host).
Definition: gnunet_nt_lib.h:45
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 3718 of file gnunet-communicator-udp.c.

3719 {
3720  struct BroadcastInterface *bin;
3721 
3722  (void) cls;
3723  for (struct BroadcastInterface *bi = bi_head; NULL != bi; bi = bi->next)
3724  bi->found = GNUNET_NO;
3726  for (struct BroadcastInterface *bi = bi_head; NULL != bi; bi = bin)
3727  {
3728  bin = bi->next;
3729  if (GNUNET_NO == bi->found)
3730  bi_destroy (bi);
3731  }
3733  &do_broadcast,
3734  NULL);
3735 }
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:396

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:

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

3751 {
3752  char *bindto;
3753  struct sockaddr *in;
3754  socklen_t in_len;
3755  struct sockaddr_storage in_sto;
3756  socklen_t sto_len;
3757 
3758  (void) cls;
3759  cfg = c;
3760  if (GNUNET_OK !=
3763  "BINDTO",
3764  &bindto))
3765  {
3768  "BINDTO");
3769  return;
3770  }
3771 
3772  if (GNUNET_OK !=
3775  "REKEY_INTERVAL",
3776  &rekey_interval))
3778 
3779  if (GNUNET_OK !=
3782  "REKEY_MAX_BYTES",
3783  &rekey_max_bytes))
3785 
3786  in = udp_address_to_sockaddr (bindto, &in_len);
3787  if (NULL == in)
3788  {
3790  "Failed to setup UDP socket address with path `%s'\n",
3791  bindto);
3792  GNUNET_free (bindto);
3793  return;
3794  }
3795  udp_sock =
3796  GNUNET_NETWORK_socket_create (in->sa_family,
3797  SOCK_DGRAM,
3798  IPPROTO_UDP);
3799  if (NULL == udp_sock)
3800  {
3802  GNUNET_free (in);
3803  GNUNET_free (bindto);
3804  return;
3805  }
3806  if (AF_INET6 == in->sa_family)
3808  if (GNUNET_OK !=
3810  in,
3811  in_len))
3812  {
3814  "bind",
3815  bindto);
3817  udp_sock = NULL;
3818  GNUNET_free (in);
3819  GNUNET_free (bindto);
3820  return;
3821  }
3822 
3823  /* We might have bound to port 0, allowing the OS to figure it out;
3824  thus, get the real IN-address from the socket */
3825  sto_len = sizeof(in_sto);
3826  if (0 != getsockname (GNUNET_NETWORK_get_fd (udp_sock),
3827  (struct sockaddr *) &in_sto,
3828  &sto_len))
3829  {
3830  memcpy (&in_sto, in, in_len);
3831  sto_len = in_len;
3832  }
3833  GNUNET_free (in);
3834  GNUNET_free (bindto);
3835  in = (struct sockaddr *) &in_sto;
3836  in_len = sto_len;
3838  "transport",
3839  "Bound to `%s'\n",
3840  GNUNET_a2s ((const struct sockaddr *) &in_sto,
3841  sto_len));
3842  switch (in->sa_family)
3843  {
3844  case AF_INET:
3845  my_port = ntohs (((struct sockaddr_in *) in)->sin_port);
3846  break;
3847 
3848  case AF_INET6:
3849  my_port = ntohs (((struct sockaddr_in6 *) in)->sin6_port);
3850  break;
3851 
3852  default:
3853  GNUNET_break (0);
3854  my_port = 0;
3855  }
3856  stats = GNUNET_STATISTICS_create ("C-UDP", cfg);
3860  receivers_heap =
3866  if (NULL == my_private_key)
3867  {
3868  GNUNET_log (
3870  _ (
3871  "Transport service is lacking key configuration settings. Exiting.\n"));
3873  return;
3874  }
3876  /* start reading */
3878  udp_sock,
3879  &sock_read,
3880  NULL);
3885  &mq_init,
3886  NULL,
3887  &enc_notify_cb,
3888  NULL);
3889  if (NULL == ch)
3890  {
3891  GNUNET_break (0);
3893  return;
3894  }
3896  if (NULL == ah)
3897  {
3898  GNUNET_break (0);
3900  return;
3901  }
3902  /* start broadcasting */
3903  if (GNUNET_YES !=
3906  "DISABLE_BROADCAST"))
3907  {
3909  }
3912  IPPROTO_UDP,
3913  1 /* one address */,
3914  (const struct sockaddr **) &in,
3915  &in_len,
3916  &nat_address_cb,
3917  NULL /* FIXME: support reversal: #5529 */,
3918  NULL /* closure */);
3919 }
#define DEFAULT_REKEY_TIME_INTERVAL
How often do we rekey based on time (at least)
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 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.
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:197
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:386
int GNUNET_NETWORK_get_fd(const struct GNUNET_NETWORK_Handle *desc)
Return file descriptor for this network handle.
Definition: network.c:1023
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition: network.c:855
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_bind(struct GNUNET_NETWORK_Handle *desc, const struct sockaddr *address, socklen_t address_len)
Bind a socket to a particular address.
Definition: network.c:439
struct GNUNET_NT_InterfaceScanner * GNUNET_NT_scanner_init(void)
Initialize the address characterization client handle.
Definition: nt.c:412
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:533
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:1316
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
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.
#define _(String)
GNU gettext support macro.
Definition: platform.h:177

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

3931 {
3932  static const struct GNUNET_GETOPT_CommandLineOption options[] = {
3934  };
3935  int ret;
3936 
3938  "transport",
3939  "Starting udp communicator\n");
3940  if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
3941  return 2;
3942 
3943  ret = (GNUNET_OK == GNUNET_PROGRAM_run (argc,
3944  argv,
3945  "gnunet-communicator-udp",
3946  _ ("GNUnet UDP communicator"),
3947  options,
3948  &run,
3949  NULL))
3950  ? 0
3951  : 1;
3952  GNUNET_free_nz ((void *) argv);
3953  return ret;
3954 }
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:399
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:1223
Definition of a command line option.

Variable Documentation

◆ rekey_interval

struct GNUNET_TIME_Relative rekey_interval
static

The rekey interval.

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

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

Referenced by check_for_rekeying(), and run().

◆ ss_finished

struct SharedSecret* ss_finished

Shared secret we finished the last kce working queue for.

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

Referenced by consider_ss_ack(), and kce_generate_cb().

◆ key_cache

struct GNUNET_CONTAINER_MultiShortmap* key_cache
static

Cache of pre-generated key IDs.

Definition at line 795 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 800 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 805 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 810 of file gnunet-communicator-udp.c.

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

◆ stats

struct GNUNET_STATISTICS_Handle* stats
static

◆ ch

◆ receivers

struct GNUNET_CONTAINER_MultiPeerMap* receivers
static

Receivers (map from peer identity to struct ReceiverAddress)

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

Referenced by do_shutdown(),