GNUnet 0.24.4-talerdev.1-15-g77b7ed1a6
 
Loading...
Searching...
No Matches
gnunet-service-core_kx.h File Reference

code for managing the key exchange (SET_KEY, PING, PONG) with other peers More...

Include dependency graph for gnunet-service-core_kx.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  InitiatorHelloPayload
 
struct  InitiatorHello
 TODO. More...
 
struct  ConfirmationAck
 The ACK. More...
 
struct  ResponderHello
 ResponderHello. More...
 
struct  ResponderHelloPayload
 
struct  InitiatorDone
 InitiatorDone. More...
 
struct  EncryptedMessage
 EncryptedMessage. More...
 
struct  Heartbeat
 KeyUpdate. More...
 

Enumerations

enum  HeartbeatFlags { GSC_HEARTBEAT_KEY_UPDATE_REQUESTED = 1 }
 Heartbeat flags. More...
 

Functions

void GSC_KX_encrypt_and_transmit (struct GSC_KeyExchangeInfo *kx, const void *payload, size_t payload_size)
 Encrypt and transmit a message with the given payload.
 
int GSC_KX_init (void)
 Initialize KX subsystem.
 
void GSC_KX_done (void)
 Shutdown KX subsystem.
 
int GSC_NEIGHBOURS_check_excess_bandwidth (const struct GSC_KeyExchangeInfo *target)
 Check if the given neighbour has excess bandwidth available.
 
unsigned int GSC_NEIGHBOURS_get_queue_length (const struct GSC_KeyExchangeInfo *target)
 Check how many messages are queued for the given neighbour.
 
void GSC_KX_handle_client_monitor_peers (struct GNUNET_MQ_Handle *mq)
 Handle GNUNET_MESSAGE_TYPE_CORE_MONITOR_PEERS request.
 

Detailed Description

code for managing the key exchange (SET_KEY, PING, PONG) with other peers

Author
Christian Grothoff

Definition in file gnunet-service-core_kx.h.

Enumeration Type Documentation

◆ HeartbeatFlags

Heartbeat flags.

Enumerator
GSC_HEARTBEAT_KEY_UPDATE_REQUESTED 

A key update is requested.

Definition at line 225 of file gnunet-service-core_kx.h.

226{
231
232};
@ GSC_HEARTBEAT_KEY_UPDATE_REQUESTED
A key update is requested.

Function Documentation

◆ GSC_KX_encrypt_and_transmit()

void GSC_KX_encrypt_and_transmit ( struct GSC_KeyExchangeInfo kx,
const void *  payload,
size_t  payload_size 
)

Encrypt and transmit a message with the given payload.

Parameters
kxkey exchange context
payloadpayload of the message
payload_sizenumber of bytes in 'payload'

Encrypt and transmit a message with the given payload.

Parameters
kxkey exchange info
payloadthe payload
payload_sizesize of the payload

Definition at line 2743 of file gnunet-service-core_kx.c.

2746{
2747 struct GNUNET_MQ_Envelope *env;
2748 struct EncryptedMessage *encrypted_msg;
2749 unsigned char enc_key[AEAD_KEY_BYTES];
2750 unsigned char enc_nonce[AEAD_NONCE_BYTES];
2751 unsigned char seq_enc_k[crypto_stream_chacha20_ietf_KEYBYTES];
2752 uint64_t sqn;
2753 uint64_t epoch;
2754 int8_t ret;
2755
2756 encrypted_msg = NULL;
2757
2758 check_rekey (kx);
2759 sqn = kx->current_sqn;
2760 epoch = kx->current_epoch;
2761 /* We are the sender and as we are going to send,
2762 * we are using the initiator key material */
2764 sqn,
2765 enc_key,
2766 enc_nonce);
2767 kx->current_sqn++;
2768 derive_sn (&kx->current_ats,
2769 seq_enc_k,
2770 sizeof seq_enc_k);
2771 env = GNUNET_MQ_msg_extra (encrypted_msg,
2772 payload_size,
2774 // only encrypt the payload for now
2775 // TODO encrypt other fields as well
2776 ret = crypto_aead_xchacha20poly1305_ietf_encrypt_detached (
2777 (unsigned char*) &encrypted_msg[1], // c - resulting ciphertext
2778 (unsigned char*) &encrypted_msg->tag, // mac - resulting mac/tag
2779 NULL, // maclen
2780 (unsigned char*) payload, // m - plain message
2781 payload_size, // mlen
2782 NULL, // ad - additional data TODO also cover the unencrypted part (epoch)
2783 0, // adlen
2784 NULL, // nsec - unused
2785 enc_nonce, // npub nonce
2786 enc_key // k - key
2787 );
2788 if (0 != ret)
2789 {
2791 "Something went wrong encrypting message\n");
2792 GNUNET_assert (0);
2793 }
2794 {
2795 /* compute the sequence number */
2796 unsigned char *seq_enc_nonce;
2797 uint64_t seq_nbo;
2798 uint32_t seq_enc_ctr;
2799
2800 seq_nbo = GNUNET_htonll (sqn);
2801 seq_enc_ctr = *((uint32_t*) encrypted_msg->tag);
2802 seq_enc_nonce = &encrypted_msg->tag[sizeof (uint32_t)];
2803 crypto_stream_chacha20_ietf_xor_ic (
2804 (unsigned char*) &encrypted_msg->sequence_number,
2805 (unsigned char*) &seq_nbo,
2806 sizeof seq_nbo,
2807 seq_enc_nonce,
2808 ntohl (seq_enc_ctr),
2809 seq_enc_k);
2810#if DEBUG_KX
2811 GNUNET_print_bytes (seq_enc_k,
2812 sizeof seq_enc_k,
2813 8,
2814 GNUNET_NO);
2815 GNUNET_print_bytes ((char*) &seq_enc_ctr,
2816 16,
2817 8,
2818 GNUNET_NO);
2819#endif
2821 "Sending encrypted message with E(SQN=%" PRIu64 ")=%" PRIu64
2822 "\n",
2823 sqn,
2824 encrypted_msg->sequence_number);
2825 }
2826 encrypted_msg->epoch = GNUNET_htonll (epoch);
2827
2828 // TODO actually copy payload
2829 GNUNET_MQ_send (kx->mq, env);
2830}
struct GNUNET_MQ_Envelope * env
Definition 005.c:1
static int ret
Final status code.
Definition gnunet-arm.c:93
#define AEAD_NONCE_BYTES
libsodium has very long symbol names
static void check_rekey(struct GSC_KeyExchangeInfo *kx)
static void derive_per_message_secrets(const struct GNUNET_ShortHashCode *ts, uint64_t seq, unsigned char key[crypto_aead_xchacha20poly1305_ietf_KEYBYTES], unsigned char nonce[crypto_aead_xchacha20poly1305_ietf_NPUBBYTES])
key = HKDF-Expand [I,R][A,H]TS, "key", 32) nonce = HKDF-Expand ([I,R][A,H]TS, "iv",...
#define AEAD_KEY_BYTES
libsodium has very long symbol names
static void derive_sn(const struct GNUNET_ShortHashCode *secret, unsigned char *sn, size_t sn_len)
static unsigned long long payload
How much data are we currently storing in the database?
#define GNUNET_log(kind,...)
uint64_t GNUNET_htonll(uint64_t n)
Convert unsigned 64-bit integer to network byte order.
@ GNUNET_NO
void GNUNET_print_bytes(const void *buf, size_t buf_len, int fold, int in_be)
Print a byte string in hexadecimal ascii notation.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition mq.c:305
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct.
#define GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE_CAKE
Encrypted message.
uint64_t current_sqn
Our current sequence number.
struct GNUNET_MQ_Handle * mq
Message queue for sending messages to peer.
uint64_t current_epoch
Our currently used epoch for sending.
struct GNUNET_ShortHashCode current_ats
*ATS - our current application traffic secret by epoch

References AEAD_KEY_BYTES, AEAD_NONCE_BYTES, check_rekey(), GSC_KeyExchangeInfo::current_ats, GSC_KeyExchangeInfo::current_epoch, GSC_KeyExchangeInfo::current_sqn, derive_per_message_secrets(), derive_sn(), env, EncryptedMessage::epoch, GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_htonll(), GNUNET_log, GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE_CAKE, GNUNET_MQ_msg_extra, GNUNET_MQ_send(), GNUNET_NO, GNUNET_print_bytes(), GSC_KeyExchangeInfo::mq, payload, ret, EncryptedMessage::sequence_number, and EncryptedMessage::tag.

Referenced by handle_heartbeat(), handle_initiator_done(), send_heartbeat(), and try_transmission().

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

◆ GSC_KX_init()

int GSC_KX_init ( void  )

Initialize KX subsystem.

Returns
GNUNET_OK on success, GNUNET_SYSERR on failure

Definition at line 2867 of file gnunet-service-core_kx.c.

2868{
2870 GNUNET_MQ_hd_var_size (initiator_hello,
2872 struct InitiatorHello,
2873 NULL),
2874 GNUNET_MQ_hd_var_size (initiator_done,
2876 struct InitiatorDone,
2877 NULL),
2878 GNUNET_MQ_hd_var_size (responder_hello,
2880 struct ResponderHello,
2881 NULL),
2882 GNUNET_MQ_hd_var_size (encrypted_message, // TODO rename?
2884 struct EncryptedMessage,
2885 NULL),
2887 };
2888
2892 NULL); // TODO potentially wait
2893 // until we have a peer_id?
2894 // pay attention to whether
2895 // we have one anyways
2896 if (NULL == pils)
2897 {
2898 GSC_KX_done ();
2899 return GNUNET_SYSERR;
2900 }
2901
2903 transport =
2906 handlers,
2907 NULL, // cls - this connection-independant
2908 // cls seems not to be needed.
2909 // the connection-specific cls
2910 // will be set as a return value
2911 // of
2912 // handle_transport_notify_connect
2915 if (NULL == transport)
2916 {
2917 GSC_KX_done ();
2918 return GNUNET_SYSERR;
2919 }
2921 "Connected to TRANSPORT\n");
2922 return GNUNET_OK;
2923}
struct GNUNET_MQ_MessageHandlers handlers[]
Definition 003.c:1
const struct GNUNET_CONFIGURATION_Handle * GSC_cfg
Our configuration.
struct GNUNET_PeerIdentity GSC_my_identity
Our identity.
static void * handle_transport_notify_connect(void *cls, const struct GNUNET_PeerIdentity *peer_id, struct GNUNET_MQ_Handle *mq)
Function called by transport to notify us that a peer connected to us (on the network level).
static void peer_id_change_cb(void *cls, const struct GNUNET_HELLO_Parser *parser, const struct GNUNET_HashCode *hash)
Callback for PILS to be called once the peer id changes.
static void handle_transport_notify_disconnect(void *cls, const struct GNUNET_PeerIdentity *peer, void *handler_cls)
Function called by transport telling us that a peer disconnected.
static struct GNUNET_NotificationContext * nc
Notification context for broadcasting to monitors.
void GSC_KX_done()
Shutdown KX subsystem.
static enum GNUNET_GenericReturnValue init_phase
Indicates whether we are still in the initialisation phase (waiting for our peer id).
static struct GNUNET_TRANSPORT_CoreHandle * transport
Transport service.
static struct GNUNET_PILS_Handle * pils
Pils service.
struct GNUNET_PILS_Handle * GNUNET_PILS_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_PILS_PidChangeCallback pid_change_cb, void *cls)
Connect to the PILS service.
Definition pils_api.c:367
struct GNUNET_TRANSPORT_CoreHandle * GNUNET_TRANSPORT_core_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, const struct GNUNET_PeerIdentity *self, const struct GNUNET_MQ_MessageHandler *handlers, void *cls, GNUNET_TRANSPORT_NotifyConnect nc, GNUNET_TRANSPORT_NotifyDisconnect nd)
Connect to the transport service.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_SYSERR
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
struct GNUNET_NotificationContext * GNUNET_notification_context_create(unsigned int queue_length)
Create a new notification context.
Definition nc.c:122
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
#define GNUNET_MESSAGE_TYPE_CORE_INITIATOR_DONE
Third and final message of the handshake, second of the initiator.
#define GNUNET_MESSAGE_TYPE_CORE_RESPONDER_HELLO
Reply to the first message from the initiator - first message sent by the responder.
#define GNUNET_MESSAGE_TYPE_CORE_INITIATOR_HELLO
for more detail on the following messages see https://lsd.gnunet.org/lsd0012/draft-schanzen-cake....
Message handler for a specific message type.

References GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE_CAKE, GNUNET_MESSAGE_TYPE_CORE_INITIATOR_DONE, GNUNET_MESSAGE_TYPE_CORE_INITIATOR_HELLO, GNUNET_MESSAGE_TYPE_CORE_RESPONDER_HELLO, GNUNET_MQ_handler_end, GNUNET_MQ_hd_var_size, GNUNET_notification_context_create(), GNUNET_OK, GNUNET_PILS_connect(), GNUNET_SYSERR, GNUNET_TRANSPORT_core_connect(), GNUNET_YES, GSC_cfg, GSC_KX_done(), GSC_my_identity, handle_transport_notify_connect(), handle_transport_notify_disconnect(), handlers, init_phase, nc, peer_id_change_cb(), pils, and transport.

Referenced by run().

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

◆ GSC_KX_done()

void GSC_KX_done ( void  )

Shutdown KX subsystem.

Definition at line 2930 of file gnunet-service-core_kx.c.

2931{
2932 struct PilsRequest *pr;
2933 while (NULL != (pr = pils_requests_head))
2934 {
2937 pr);
2938 if (NULL != pr->op)
2939 GNUNET_PILS_cancel (pr->op);
2940 GNUNET_free (pr);
2941 }
2942 if (NULL != pils)
2943 {
2945 pils = NULL;
2946 }
2947 if (NULL != transport)
2948 {
2950 transport = NULL;
2951 }
2952 if (NULL != rekey_task)
2953 {
2955 rekey_task = NULL;
2956 }
2957 if (NULL != nc)
2958 {
2960 nc = NULL;
2961 }
2962}
static struct PilsRequest * pils_requests_head
PILS Operation DLL.
static struct PilsRequest * pils_requests_tail
PILS Operation DLL.
static struct GNUNET_SCHEDULER_Task * rekey_task
Task scheduled for periodic re-generation (and thus rekeying) of our ephemeral key.
void GNUNET_PILS_disconnect(struct GNUNET_PILS_Handle *handle)
Disconnect from the PILS service.
Definition pils_api.c:390
void GNUNET_PILS_cancel(struct GNUNET_PILS_Operation *op)
Cancel request.
Definition pils_api.c:495
void GNUNET_TRANSPORT_core_disconnect(struct GNUNET_TRANSPORT_CoreHandle *handle)
Disconnect from the transport service.
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_free(ptr)
Wrapper around free.
void GNUNET_notification_context_destroy(struct GNUNET_NotificationContext *nc)
Destroy the context, force disconnect for all subscribers.
Definition nc.c:138
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition scheduler.c:980
struct GNUNET_PILS_Operation * op
The pils operation.

References GNUNET_CONTAINER_DLL_remove, GNUNET_free, GNUNET_notification_context_destroy(), GNUNET_PILS_cancel(), GNUNET_PILS_disconnect(), GNUNET_SCHEDULER_cancel(), GNUNET_TRANSPORT_core_disconnect(), nc, PilsRequest::op, pils, pils_requests_head, pils_requests_tail, rekey_task, and transport.

Referenced by GSC_KX_init(), and shutdown_task().

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

◆ GSC_NEIGHBOURS_check_excess_bandwidth()

int GSC_NEIGHBOURS_check_excess_bandwidth ( const struct GSC_KeyExchangeInfo target)

Check if the given neighbour has excess bandwidth available.

Parameters
targetneighbour to check
Returns
GNUNET_YES if excess bandwidth is available, GNUNET_NO if not

Definition at line 2979 of file gnunet-service-core_kx.c.

2980{
2981 return kxinfo->has_excess_bandwidth;
2982}

References GSC_KeyExchangeInfo::has_excess_bandwidth.

Referenced by try_transmission().

Here is the caller graph for this function:

◆ GSC_NEIGHBOURS_get_queue_length()

unsigned int GSC_NEIGHBOURS_get_queue_length ( const struct GSC_KeyExchangeInfo kxinfo)

Check how many messages are queued for the given neighbour.

Parameters
targetneighbour to check
Returns
number of items in the message queue
Parameters
kxinfodata about neighbour to check
Returns
number of items in the message queue

Definition at line 2972 of file gnunet-service-core_kx.c.

2973{
2974 return GNUNET_MQ_get_length (kxinfo->mq);
2975}
unsigned int GNUNET_MQ_get_length(struct GNUNET_MQ_Handle *mq)
Obtain the current length of the message queue.
Definition mq.c:293

References GNUNET_MQ_get_length(), and GSC_KeyExchangeInfo::mq.

Referenced by try_transmission().

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

◆ GSC_KX_handle_client_monitor_peers()

void GSC_KX_handle_client_monitor_peers ( struct GNUNET_MQ_Handle mq)

Handle GNUNET_MESSAGE_TYPE_CORE_MONITOR_PEERS request.

For this request type, the client does not have to have transmitted an INIT request. All current peers are returned, regardless of which message types they accept.

Parameters
mqmessage queue to add for monitoring

Definition at line 2994 of file gnunet-service-core_kx.c.

2995{
2996 struct GNUNET_MQ_Envelope *env;
2997 struct MonitorNotifyMessage *done_msg;
2998 struct GSC_KeyExchangeInfo *kx;
2999
3001 for (kx = kx_head; NULL != kx; kx = kx->next)
3002 {
3003 struct GNUNET_MQ_Envelope *env_notify;
3004 struct MonitorNotifyMessage *msg;
3005
3007 msg->state = htonl ((uint32_t) kx->status);
3008 msg->peer = kx->peer;
3009 msg->timeout = GNUNET_TIME_absolute_hton (kx->timeout);
3010 GNUNET_MQ_send (mq, env_notify);
3011 }
3013 done_msg->state = htonl ((uint32_t) GNUNET_CORE_KX_ITERATION_FINISHED);
3016}
struct GNUNET_MessageHeader * msg
Definition 005.c:2
static struct GSC_KeyExchangeInfo * kx_head
DLL head.
@ GNUNET_CORE_KX_ITERATION_FINISHED
This is not a state in a peer's state machine, but a special value used with the GNUNET_CORE_MonitorC...
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
void GNUNET_notification_context_add(struct GNUNET_NotificationContext *nc, struct GNUNET_MQ_Handle *mq)
Add a subscriber to the notification context.
Definition nc.c:161
#define GNUNET_MESSAGE_TYPE_CORE_MONITOR_NOTIFY
Reply for monitor by CORE service.
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition time.c:640
#define GNUNET_TIME_UNIT_FOREVER_ABS
Constant used to specify "forever".
static struct GNUNET_MQ_Handle * mq
Our connection to the resolver service, created on-demand, but then persists until error or shutdown.
Information about the status of a key exchange with another peer.
struct GSC_KeyExchangeInfo * next
DLL.
struct GNUNET_PeerIdentity peer
Identity of the peer.
struct GNUNET_TIME_Absolute timeout
When should the session time out (if there are no Acks to HEARTBEATs)?
enum GNUNET_CORE_KxState status
What is our connection state?
Message sent by the service to monitor clients to notify them about a peer changing status.
Definition core.h:313
uint32_t state
New peer state, an enum GNUNET_CORE_KxState in NBO.
Definition core.h:322
struct GNUNET_TIME_AbsoluteNBO timeout
How long will we stay in this state (if nothing else happens)?
Definition core.h:332

References env, GNUNET_CORE_KX_ITERATION_FINISHED, GNUNET_MESSAGE_TYPE_CORE_MONITOR_NOTIFY, GNUNET_MQ_msg, GNUNET_MQ_send(), GNUNET_notification_context_add(), GNUNET_TIME_absolute_hton(), GNUNET_TIME_UNIT_FOREVER_ABS, kx_head, mq, msg, nc, GSC_KeyExchangeInfo::next, GSC_KeyExchangeInfo::peer, MonitorNotifyMessage::state, GSC_KeyExchangeInfo::status, MonitorNotifyMessage::timeout, and GSC_KeyExchangeInfo::timeout.

Referenced by handle_client_monitor_peers().

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