GNUnet 0.25.2-11-g84e94e98c
 
Loading...
Searching...
No Matches
gnunet-communicator-udp.c File Reference

Transport plugin using UDP. More...

Include dependency graph for gnunet-communicator-udp.c:

Go to the source code of this file.

Data Structures

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

Macros

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

Functions

static void eddsa_priv_to_hpke_key (struct GNUNET_CRYPTO_EddsaPrivateKey *edpk, struct GNUNET_CRYPTO_HpkePrivateKey *pk)
 
static void eddsa_pub_to_hpke_key (struct GNUNET_CRYPTO_EddsaPublicKey *edpk, struct GNUNET_CRYPTO_HpkePublicKey *pk)
 
static void bi_destroy (struct BroadcastInterface *bi)
 An interface went away, stop broadcasting on it.
 
static int secret_destroy (struct SharedSecret *ss)
 Destroy ss and associated key cache entries.
 
static void receiver_destroy (struct ReceiverAddress *receiver)
 Destroys a receiving state due to timeout or shutdown.
 
static void kce_destroy (struct KeyCacheEntry *kce)
 Free memory used by key cache entry.
 
static void get_kid (const struct GNUNET_ShortHashCode *msec, uint32_t serial, struct GNUNET_ShortHashCode *kid)
 Compute kid.
 
static void kce_generate (struct SharedSecret *ss, uint32_t seq)
 Setup key cache entry for sequence number seq and shared secret ss.
 
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 get_iv_key (const struct GNUNET_ShortHashCode *msec, uint32_t serial, char key[(256/8)], char iv[(96/8)])
 Compute key and iv.
 
static void reschedule_sender_timeout (struct SenderAddress *sender)
 Increment sender timeout due to activity.
 
static void reschedule_receiver_timeout (struct ReceiverAddress *receiver)
 Increment receiver timeout due to activity.
 
static void check_timeouts (void *cls)
 Task run to check #receiver_heap and #sender_heap for timeouts.
 
static void calculate_cmac (struct SharedSecret *ss)
 Calculate cmac from master in ss.
 
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 void setup_cipher (const struct GNUNET_ShortHashCode *msec, uint32_t serial, gcry_cipher_hd_t *cipher)
 Setup cipher based on shared secret msec and serial number serial.
 
static int try_decrypt (const struct SharedSecret *ss, const uint8_t *tag, uint32_t serial, const char *in_buf, size_t in_buf_size, char *out_buf)
 Try to decrypt buf using shared secret ss and key/iv derived using serial.
 
static struct SharedSecretsetup_shared_secret_dec (const struct GNUNET_CRYPTO_HpkeEncapsulation *ephemeral)
 Setup shared secret for decryption.
 
static struct SharedSecretsetup_initial_shared_secret_dec (const struct GNUNET_CRYPTO_HpkeEncapsulation *c)
 Setup shared secret for decryption for initial handshake.
 
static struct SharedSecretsetup_shared_secret_ephemeral (struct GNUNET_CRYPTO_HpkeEncapsulation *ephemeral, struct ReceiverAddress *receiver)
 Setup new shared secret for encryption using KEM.
 
static struct SharedSecretsetup_initial_shared_secret_ephemeral (struct GNUNET_CRYPTO_HpkeEncapsulation *c, struct ReceiverAddress *receiver)
 Setup new shared secret for encryption using KEM for initial handshake.
 
static void setup_receiver_mq (struct ReceiverAddress *receiver)
 Setup the MQ for the receiver.
 
static unsigned int purge_secrets (struct SharedSecret *ss_list_tail)
 Best effort try to purge some secrets.
 
static void add_acks (struct SharedSecret *ss, int acks_to_add)
 
static int handle_ack (void *cls, const struct GNUNET_HashCode *key, void *value)
 We received an ACK for pid.
 
static void consider_ss_ack (struct SharedSecret *ss)
 We established a shared secret with a sender.
 
static void kce_generate_cb (void *cls)
 
static void try_handle_plaintext (struct SenderAddress *sender, const void *buf, size_t buf_size)
 Test if we have received a valid message in plaintext.
 
static void decrypt_box (const struct UDPBox *box, size_t box_len, struct KeyCacheEntry *kce)
 We received a box with matching kce.
 
static struct SenderAddresssetup_sender (const struct GNUNET_PeerIdentity *target, const struct sockaddr *address, socklen_t address_len)
 Create sender address for target.
 
static int verify_confirmation (const struct GNUNET_CRYPTO_HpkeEncapsulation *enc, const struct UDPConfirmation *uc)
 Check signature from uc against ephemeral.
 
static char * sockaddr_to_udpaddr_string (const struct sockaddr *address, socklen_t address_len)
 Converts address to the address string format used by this communicator in HELLOs.
 
static struct GNUNET_NETWORK_Handleget_socket (struct ReceiverAddress *receiver)
 
static struct sockaddr * udp_address_to_sockaddr (const char *bindto, sa_family_t family, socklen_t *sock_len)
 Convert UDP bind specification to a struct sockaddr *
 
static void sock_read (void *cls)
 Socket read task.
 
static enum GNUNET_GenericReturnValue create_receiver (const struct GNUNET_PeerIdentity *peer, const char *address, struct GNUNET_NETWORK_Handle *udp_sock)
 
static void do_pad (gcry_cipher_hd_t out_cipher, char *dgram, size_t pad_size)
 Pad dgram by pad_size using out_cipher.
 
static void send_msg_with_kx (const struct GNUNET_MessageHeader *msg, struct ReceiverAddress *receiver, struct GNUNET_MQ_Handle *mq)
 
static void mq_send_kx (struct GNUNET_MQ_Handle *mq, const struct GNUNET_MessageHeader *msg, void *impl_state)
 Signature of functions implementing the sending functionality of a message queue.
 
static void create_rekey (struct ReceiverAddress *receiver, struct SharedSecret *ss, struct UDPRekey *rekey)
 
static void mq_send_d (struct GNUNET_MQ_Handle *mq, const struct GNUNET_MessageHeader *msg, void *impl_state)
 Signature of functions implementing the sending functionality of a message queue.
 
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_destroy_kx (struct GNUNET_MQ_Handle *mq, void *impl_state)
 Signature of functions implementing the destruction 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 creation of the message queue.
 
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.
 
static int get_receiver_delete_it (void *cls, const struct GNUNET_HashCode *target, void *value)
 Iterator over all receivers to clean up.
 
static int get_sender_delete_it (void *cls, const struct GNUNET_HashCode *target, void *value)
 Iterator over all senders to clean up.
 
static void do_shutdown (void *cls)
 Shutdown the UNIX communicator.
 
static int handle_ack_by_sender (void *cls, const struct GNUNET_HashCode *key, void *value)
 
static void enc_notify_cb (void *cls, const struct GNUNET_PeerIdentity *sender, const struct GNUNET_MessageHeader *msg)
 Function called when the transport service has received a backchannel message for this communicator (!) via a different return path.
 
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.
 
static void ifc_broadcast (void *cls)
 Broadcast our presence on one of our 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.
 
static void do_broadcast (void *cls)
 Scan interfaces to broadcast our presence on the LAN.
 
static void try_connection_reversal (void *cls, const struct sockaddr *addr, socklen_t addrlen)
 
static void udp_socket_notify (struct GNUNET_UdpSocketInfo *sock_info)
 
static void start_burst (const char *addr, struct GNUNET_TIME_Relative rtt, struct GNUNET_PeerIdentity *pid)
 
static struct GNUNET_NETWORK_Handlecreate_udp_socket (const char *bindto, sa_family_t family, struct sockaddr **out, socklen_t *out_len)
 
static void shutdown_run (struct sockaddr *addrs[2])
 
static void load_ikm ()
 Get the initial secret key for generating the peer id.
 
void pid_change_cb (void *cls, const struct GNUNET_HELLO_Parser *parser, const struct GNUNET_HashCode *addr_hash)
 
static void run (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c)
 

Variables

static unsigned char ikm [256/8]
 The initial key material for the peer.
 
static struct GNUNET_PILS_Handlepils
 For PILS.
 
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.
 
static struct GNUNET_CONTAINER_MultiShortmapkey_cache
 Cache of pre-generated key IDs.
 
static struct GNUNET_SCHEDULER_Taskread_v4_task
 ID of read IPv4 task.
 
static struct GNUNET_SCHEDULER_Taskread_v6_task
 ID of read IPv6 task.
 
static struct GNUNET_SCHEDULER_Tasktimeout_task
 ID of timeout task.
 
static struct GNUNET_SCHEDULER_Taskbroadcast_task
 ID of master broadcast task.
 
static struct GNUNET_STATISTICS_Handlestats
 For logging statistics.
 
static struct GNUNET_TRANSPORT_CommunicatorHandlech
 Our environment.
 
static struct GNUNET_CONTAINER_MultiHashMapreceivers
 Receivers (map from peer identity to struct ReceiverAddress)
 
static struct GNUNET_CONTAINER_MultiHashMapsenders
 Senders (map from peer identity to struct SenderAddress)
 
static struct GNUNET_CONTAINER_Heapsenders_heap
 Expiration heap for senders (contains struct SenderAddress)
 
static struct GNUNET_CONTAINER_Heapreceivers_heap
 Expiration heap for receivers (contains struct ReceiverAddress)
 
static struct BroadcastInterfacebi_head
 Broadcast interface tasks.
 
static struct BroadcastInterfacebi_tail
 Broadcast interface tasks.
 
static struct GNUNET_NETWORK_Handledefault_v4_sock
 Our IPv4 socket.
 
static struct GNUNET_NETWORK_Handledefault_v6_sock
 Our IPv6 socket.
 
static struct GNUNET_PeerIdentity my_identity
 Our public key.
 
static struct GNUNET_CRYPTO_EddsaPrivateKeymy_private_key
 Our private key.
 
static struct GNUNET_CRYPTO_HpkePrivateKey my_x25519_private_key
 Our private key for HPKE.
 
static const struct GNUNET_CONFIGURATION_Handlecfg
 Our configuration.
 
static struct GNUNET_TRANSPORT_ApplicationHandleah
 Our handle to report addresses for validation to TRANSPORT.
 
static struct GNUNET_NT_InterfaceScanneris
 Network scanner to determine network types.
 
static struct GNUNET_NAT_Handlenat
 Connection to NAT service.
 
static uint16_t my_port
 Port number to which we are actually bound.
 
char * my_ipv4
 Our ipv4 address.
 
static int disable_v6
 IPv6 disabled or not.
 
static struct GNUNET_SCHEDULER_Taskburst_task
 

Detailed Description

Transport plugin using UDP.

Author
Christian Grothoff

TODO:

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

Definition in file gnunet-communicator-udp.c.

Macro Definition Documentation

◆ LOG

#define LOG (   kind,
  ... 
)    GNUNET_log_from (kind, "communicator-udp", __VA_ARGS__)

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

◆ 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 58 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 63 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 68 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 73 of file gnunet-communicator-udp.c.

168{
173
177 struct GNUNET_PeerIdentity sender;
178
183
188
193 struct GNUNET_TIME_AbsoluteNBO monotonic_time;
194};
195
196
201struct InitialKX
202{
207
212 uint8_t gcm_tag[GCM_TAG_SIZE];
213
214};
215
216
221struct UDPConfirmation
222{
227
232
238
239 /* followed by messages */
240
241 /* padding may follow actual messages */
242};
243
244
249struct UDPAck
250{
255
261
265 struct GNUNET_HashCode cmac;
266};
267
268
278{
283
288
293};
294
295
302struct UDPBroadcast
303{
308
314};
315
316
321struct UDPBox
322{
331
339 uint8_t gcm_tag[GCM_TAG_SIZE];
340
341};
342
346struct UDPRekey
347{
352
357};
358
360
364struct SharedSecret;
365
366
371struct KeyCacheEntry
372{
376 struct KeyCacheEntry *next;
377
381 struct KeyCacheEntry *prev;
382
391
395 struct SharedSecret *ss;
396
400 uint32_t sequence_number;
401};
402
403
408struct SenderAddress;
409
414struct ReceiverAddress;
415
419struct SharedSecret
420{
424 struct SharedSecret *next;
425
429 struct SharedSecret *prev;
430
434 struct KeyCacheEntry *kce_head;
435
439 struct KeyCacheEntry *kce_tail;
440
444 struct SenderAddress *sender;
445
450
455
459 struct GNUNET_HashCode cmac;
460
465 uint32_t sequence_used;
466
472 uint32_t sequence_allowed;
473
477 unsigned int active_kce_count;
478
482 size_t bytes_sent;
483
487 int rekey_initiated;
488
493};
494
495
500struct SenderAddress
501{
506
511
515 struct SharedSecret *ss_head;
516
520 struct SharedSecret *ss_tail;
521
525 struct sockaddr *address;
526
530 socklen_t address_len;
531
535 struct GNUNET_HashCode key;
536
541
545 unsigned int num_secrets;
546
551 unsigned int acks_available;
552
557
562
567
572
577};
578
579
584struct ReceiverAddress
585{
590
595
600
604 struct GNUNET_HashCode key;
605
609 struct SharedSecret *ss_head;
610
614 struct SharedSecret *ss_tail;
615
620 char *foreign_addr;
621
625 struct sockaddr *address;
626
630 socklen_t address_len;
631
636
640 struct GNUNET_MQ_Handle *kx_mq;
641
645 struct GNUNET_MQ_Handle *d_mq;
646
651
656
661
667
672
676 size_t kx_mtu;
677
681 size_t d_mtu;
682
686 unsigned int num_secrets;
687
692 unsigned int acks_available;
693
698
703};
704
709{
713 struct BroadcastInterface *next;
714
718 struct BroadcastInterface *prev;
719
724
728 struct sockaddr *sa;
729
733 struct sockaddr *ba;
734
738 struct UDPBroadcast bcm;
739
744 struct ipv6_mreq mcreq;
745
749 socklen_t salen;
750
754 int found;
755};
756
760static unsigned char ikm[256 / 8];
761
765static struct GNUNET_PILS_Handle *pils;
766
771
775static unsigned long long rekey_max_bytes;
776
781
786
791
796
801
805static struct GNUNET_STATISTICS_Handle *stats;
806
811
816
821
826
831
835static struct BroadcastInterface *bi_head;
836
840static struct BroadcastInterface *bi_tail;
841
846
851
855static struct GNUNET_PeerIdentity my_identity;
856
861
866
870static const struct GNUNET_CONFIGURATION_Handle *cfg;
871
876
880static struct GNUNET_NT_InterfaceScanner *is;
881
885static struct GNUNET_NAT_Handle *nat;
886
890static uint16_t my_port;
891
895char *my_ipv4;
896
900static int disable_v6;
901
902static struct GNUNET_SCHEDULER_Task *burst_task;
903
904
905static void
908{
910 key.type = htonl (GNUNET_PUBLIC_KEY_TYPE_EDDSA);
911 key.eddsa_key = *edpk;
913 pk);
914}
915
916
917static void
920{
922 key.type = htonl (GNUNET_PUBLIC_KEY_TYPE_EDDSA);
923 key.eddsa_key = *edpk;
925 pk);
926}
927
928
934static void
936{
937 if (AF_INET6 == bi->sa->sa_family)
938 {
939 /* Leave the multicast group */
941 IPPROTO_IPV6,
942 IPV6_LEAVE_GROUP,
943 &bi->mcreq,
944 sizeof(bi->mcreq)))
945 {
947 }
948 }
951 GNUNET_free (bi->sa);
952 GNUNET_free (bi->ba);
953 GNUNET_free (bi);
954}
955
956
957static int
958secret_destroy (struct SharedSecret *ss);
959
965static void
967{
968 struct SharedSecret *ss;
969 receiver->receiver_destroy_called = GNUNET_YES;
970
972 "Disconnecting receiver for peer `%s'\n",
973 GNUNET_i2s (&receiver->target));
974 if (NULL != receiver->kx_qh)
975 {
977 receiver->kx_qh = NULL;
978 receiver->kx_mq = NULL;
979 }
980 if (NULL != receiver->d_qh)
981 {
983 receiver->d_qh = NULL;
984 }
985 else if (NULL != receiver->d_mq)
986 {
988 receiver->d_mq = NULL;
989 }
990 if (NULL != receiver->udp_sock)
991 {
994 receiver->udp_sock = NULL;
995 }
998 &receiver->key,
999 receiver));
1002 "# receivers active",
1004 GNUNET_NO);
1005 while (NULL != (ss = receiver->ss_head))
1006 {
1007 secret_destroy (ss);
1008 }
1009 GNUNET_free (receiver->address);
1010 GNUNET_free (receiver->foreign_addr);
1012}
1013
1014
1020static void
1021kce_destroy (struct KeyCacheEntry *kce)
1022{
1023 struct SharedSecret *ss = kce->ss;
1024
1025 ss->active_kce_count--;
1028 &kce->kid,
1029 kce));
1030 GNUNET_free (kce);
1031}
1032
1033
1041static void
1042get_kid (const struct GNUNET_ShortHashCode *msec,
1043 uint32_t serial,
1044 struct GNUNET_ShortHashCode *kid)
1045{
1046 uint32_t sid = htonl (serial);
1047 struct GNUNET_ShortHashCode prk;
1049 &sid, sizeof (sid),
1050 msec, sizeof (*msec));
1051
1053 sizeof(*kid),
1054 &prk,
1055 "gnunet-communicator-udp-kid",
1056 strlen ("gnunet-communicator-udp-kid"),
1057 NULL,
1058 0);
1059}
1060
1061
1068static void
1069kce_generate (struct SharedSecret *ss, uint32_t seq)
1070{
1071 struct KeyCacheEntry *kce;
1072
1073 GNUNET_assert (0 < seq);
1074 kce = GNUNET_new (struct KeyCacheEntry);
1075 kce->ss = ss;
1076 kce->sequence_number = seq;
1077 get_kid (&ss->master, seq, &kce->kid);
1082 key_cache,
1083 &kce->kid,
1084 kce,
1087 "# KIDs active",
1089 GNUNET_NO);
1090}
1091
1092
1099static int
1101{
1102 struct SenderAddress *sender;
1103 struct ReceiverAddress *receiver;
1104 struct KeyCacheEntry *kce;
1105
1107 "secret %s destroy %u\n",
1108 GNUNET_sh2s (&ss->master),
1110 if (NULL != (sender = ss->sender))
1111 {
1112 GNUNET_CONTAINER_DLL_remove (sender->ss_head, sender->ss_tail, ss);
1113 sender->num_secrets--;
1115 "%u sender->num_secrets %u allowed %u used, %u available\n",
1117 sender->acks_available);
1119 if (NULL != ss->sender->kce_task)
1120 {
1122 ss->sender->kce_task = NULL;
1123 }
1124 }
1125 if (NULL != (receiver = ss->receiver))
1126 {
1127 GNUNET_CONTAINER_DLL_remove (receiver->ss_head, receiver->ss_tail, ss);
1128 receiver->num_secrets--;
1129 receiver->acks_available -= (ss->sequence_allowed - ss->sequence_used);
1131 "%u receiver->num_secrets\n",
1132 receiver->num_secrets);
1133 }
1134 while (NULL != (kce = ss->kce_head))
1135 kce_destroy (kce);
1136 GNUNET_STATISTICS_update (stats, "# Secrets active", -1, GNUNET_NO);
1138 "# KIDs active",
1140 GNUNET_NO);
1141 GNUNET_free (ss);
1142 return GNUNET_YES;
1143}
1144
1145
1152static void
1153sender_destroy (struct SenderAddress *sender)
1154{
1155 struct SharedSecret *ss;
1158 GNUNET_YES ==
1162 "# senders active",
1164 GNUNET_NO);
1165 while (NULL != (ss = sender->ss_head))
1166 {
1167 secret_destroy (ss);
1168 }
1171}
1172
1173
1182static void
1183get_iv_key (const struct GNUNET_ShortHashCode *msec,
1184 uint32_t serial,
1185 char key[AES_KEY_SIZE],
1186 char iv[AES_IV_SIZE])
1187{
1188 uint32_t sid = htonl (serial);
1189
1192 msec,
1193 "gnunet-communicator-udp-key",
1194 strlen ("gnunet-communicator-udp-key"),
1195 &sid, sizeof (sid),
1196 NULL,
1197 0);
1200 msec,
1201 "gnunet-communicator-udp-iv",
1202 strlen ("gnunet-communicator-udp-iv"),
1203 &sid, sizeof (sid),
1204 NULL,
1205 0);
1206}
1207
1208
1214static void
1216{
1217 sender->timeout =
1220}
1221
1222
1228static void
1230{
1231 receiver->timeout =
1234 receiver->timeout.abs_value_us);
1235}
1236
1237
1243static void
1244check_timeouts (void *cls)
1245{
1246 struct GNUNET_TIME_Relative st;
1247 struct GNUNET_TIME_Relative rt;
1248 struct GNUNET_TIME_Relative delay;
1249 struct ReceiverAddress *receiver;
1250 struct SenderAddress *sender;
1251
1252 (void) cls;
1253 timeout_task = NULL;
1256 {
1258 if (0 != rt.rel_value_us)
1259 break;
1261 "Receiver timed out\n");
1263 }
1265 while (NULL != (sender = GNUNET_CONTAINER_heap_peek (senders_heap)))
1266 {
1267 if (GNUNET_YES != sender->sender_destroy_called)
1268 {
1270 if (0 != st.rel_value_us)
1271 break;
1272 sender_destroy (sender);
1273 }
1274 }
1275 delay = GNUNET_TIME_relative_min (rt, st);
1276 if (delay.rel_value_us < GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
1278}
1279
1280
1286static void
1287calculate_cmac (struct SharedSecret *ss)
1288{
1290 sizeof(ss->cmac),
1291 &ss->master,
1292 "gnunet-communicator-udp-cmac",
1293 strlen ("gnunet-communicator-udp-cmac"),
1294 NULL,
1295 0);
1296}
1297
1298
1307static void
1309 const void *plaintext,
1310 size_t plaintext_len)
1311{
1312 const struct GNUNET_MessageHeader *hdr = plaintext;
1313 const char *pos = plaintext;
1314
1315 while (ntohs (hdr->size) <= plaintext_len)
1316 {
1318 "# bytes given to core",
1319 ntohs (hdr->size),
1320 GNUNET_NO);
1322 "Giving %u bytes to TNG\n", ntohs (hdr->size));
1325 &sender->target,
1326 hdr,
1328 NULL /* no flow control possible */
1329 ,
1330 NULL));
1331 /* move on to next message, if any */
1332 plaintext_len -= ntohs (hdr->size);
1333 if (plaintext_len < sizeof(*hdr))
1334 break;
1335 pos += ntohs (hdr->size);
1336 hdr = (const struct GNUNET_MessageHeader *) pos;
1337 // TODO for now..., we do not actually sen >1msg or have a way of telling
1338 // if we are done
1339 break;
1340 }
1342 "# bytes padding discarded",
1343 plaintext_len,
1344 GNUNET_NO);
1345}
1346
1347
1356static void
1357setup_cipher (const struct GNUNET_ShortHashCode *msec,
1358 uint32_t serial,
1359 gcry_cipher_hd_t *cipher)
1360{
1361 char key[AES_KEY_SIZE];
1362 char iv[AES_IV_SIZE];
1363 int rc;
1364
1365 GNUNET_assert (0 ==
1366 gcry_cipher_open (cipher,
1367 GCRY_CIPHER_AES256 /* low level: go for speed */
1368 ,
1369 GCRY_CIPHER_MODE_GCM,
1370 0 /* flags */));
1371 get_iv_key (msec, serial, key, iv);
1372 rc = gcry_cipher_setkey (*cipher, key, sizeof(key));
1373 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
1374 rc = gcry_cipher_setiv (*cipher, iv, sizeof(iv));
1375 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
1376}
1377
1378
1391static int
1392try_decrypt (const struct SharedSecret *ss,
1393 const uint8_t *tag,
1394 uint32_t serial,
1395 const char *in_buf,
1396 size_t in_buf_size,
1397 char *out_buf)
1398{
1399 gcry_cipher_hd_t cipher;
1400
1401 setup_cipher (&ss->master, serial, &cipher);
1403 0 ==
1404 gcry_cipher_decrypt (cipher, out_buf, in_buf_size, in_buf, in_buf_size));
1405 if (0 != gcry_cipher_checktag (cipher, tag, GCM_TAG_SIZE))
1406 {
1407 gcry_cipher_close (cipher);
1409 "# AEAD authentication failures",
1410 1,
1411 GNUNET_NO);
1412 return GNUNET_SYSERR;
1413 }
1414 gcry_cipher_close (cipher);
1415 return GNUNET_OK;
1416}
1417
1418
1425static struct SharedSecret *
1427 )
1428{
1429 struct SharedSecret *ss;
1430
1431 ss = GNUNET_new (struct SharedSecret);
1433 ephemeral,
1434 &ss->master);
1435 calculate_cmac (ss);
1436 return ss;
1437}
1438
1439
1446static struct SharedSecret *
1449{
1450 struct SharedSecret *ss;
1451
1452 ss = GNUNET_new (struct SharedSecret);
1454 &ss->master);
1456 "New receiver SS master: %s\n", GNUNET_sh2s (&ss->master));
1457 calculate_cmac (ss);
1458 return ss;
1459}
1460
1461
1469static struct SharedSecret *
1471 ,
1472 struct ReceiverAddress *receiver)
1473{
1474 struct SharedSecret *ss;
1475
1476 ss = GNUNET_new (struct SharedSecret);
1477 GNUNET_CRYPTO_eddsa_kem_encaps (&receiver->target.public_key,
1478 ephemeral,
1479 &ss->master);
1480 calculate_cmac (ss);
1481 ss->receiver = receiver;
1482 GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss);
1483 receiver->num_secrets++;
1484 GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
1485 return ss;
1486}
1487
1488
1496static struct SharedSecret *
1499 struct ReceiverAddress *receiver)
1500{
1501 struct SharedSecret *ss;
1502
1503 ss = GNUNET_new (struct SharedSecret);
1505 c, &ss->master);
1507 "New sender SS master: %s\n", GNUNET_sh2s (&ss->master));
1508 calculate_cmac (ss);
1509 ss->receiver = receiver;
1510 GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss);
1511 receiver->num_secrets++;
1512 GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
1513 return ss;
1514}
1515
1516
1524static void
1526
1527
1535static unsigned int
1536purge_secrets (struct SharedSecret *ss_list_tail)
1537{
1538 struct SharedSecret *pos;
1539 struct SharedSecret *ss_to_purge;
1540 unsigned int deleted = 0;
1541
1543 "Purging secrets.\n");
1544 pos = ss_list_tail;
1545 while (NULL != pos)
1546 {
1547 ss_to_purge = pos;
1548 pos = pos->prev;
1549
1550 // FIXME we may also want to purge old unacked.
1551 if (rekey_max_bytes <= ss_to_purge->bytes_sent)
1552 {
1553 secret_destroy (ss_to_purge);
1554 deleted++;
1555 }
1556 }
1558 "Finished purging all, deleted %u.\n", deleted);
1559 return deleted;
1560}
1561
1562
1563static void
1564add_acks (struct SharedSecret *ss, int acks_to_add)
1565{
1566
1567 struct ReceiverAddress *receiver = ss->receiver;
1568
1569 GNUNET_assert (NULL != ss);
1570 GNUNET_assert (NULL != receiver);
1571
1572 if (NULL == receiver->d_qh)
1573 {
1574 receiver->d_qh =
1576 &receiver->target,
1577 receiver->foreign_addr,
1578 receiver->d_mtu,
1579 acks_to_add,
1580 1, /* Priority */
1581 receiver->nt,
1583 receiver->d_mq);
1584 }
1585 else
1586 {
1588 receiver->d_qh,
1589 acks_to_add,
1590 1);
1591 }
1592
1594 "Tell transport we have %u more acks!\n",
1595 acks_to_add);
1596
1597 // Until here for alternative 1
1598
1599 /* move ss to head to avoid discarding it anytime soon! */
1600
1601 // GNUNET_CONTAINER_DLL_remove (receiver->ss_head, receiver->ss_tail, ss);
1602 // GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss);
1603}
1604
1605
1616static int
1617handle_ack (void *cls, const struct GNUNET_HashCode *key, void *value)
1618{
1619 const struct UDPAck *ack = cls;
1620 struct ReceiverAddress *receiver = value;
1621 uint32_t acks_to_add;
1622 uint32_t allowed;
1623
1625 "in handle ack with cmac %s\n",
1626 GNUNET_h2s (&ack->cmac));
1627
1628 (void) key;
1629 for (struct SharedSecret *ss = receiver->ss_head; NULL != ss; ss = ss->next)
1630 {
1631 if (0 == memcmp (&ack->cmac, &ss->cmac, sizeof(struct GNUNET_HashCode)))
1632 {
1633
1635 "Found matching cmac\n");
1636
1637 allowed = ntohl (ack->sequence_ack);
1638
1639 if (allowed <= ss->sequence_allowed)
1640 {
1642 "Ignoring ack, not giving us increased window\n.");
1643 return GNUNET_NO;
1644 }
1645 acks_to_add = (allowed - ss->sequence_allowed);
1646 GNUNET_assert (0 != acks_to_add);
1647 receiver->acks_available += (allowed - ss->sequence_allowed);
1648 ss->sequence_allowed = allowed;
1649 add_acks (ss, acks_to_add);
1651 "New sequence allows until %u (+%u). Acks available to us: %u. For secret %s\n",
1652 allowed,
1653 acks_to_add,
1654 receiver->acks_available,
1655 GNUNET_sh2s (&ss->master));
1656 return GNUNET_NO;
1657 }
1658 }
1660 "Matching cmac not found for ack!\n");
1661 return GNUNET_YES;
1662}
1663
1664
1673static void
1674consider_ss_ack (struct SharedSecret *ss)
1675{
1676 struct UDPAck ack;
1677 GNUNET_assert (NULL != ss->sender);
1679 "Considering SS UDPAck %s\n",
1680 GNUNET_i2s_full (&ss->sender->target));
1681
1683 "Sender has %u acks available.\n",
1684 ss->sender->acks_available);
1685 /* drop ancient KeyCacheEntries */
1686 while ((NULL != ss->kce_head) &&
1687 (MAX_SQN_DELTA <
1689 kce_destroy (ss->kce_tail);
1690
1691
1693 ack.header.size = htons (sizeof(ack));
1694 ack.sequence_ack = htonl (ss->sequence_allowed);
1695 ack.cmac = ss->cmac;
1697 "Notifying transport with UDPAck %s, sequence %u and master %s\n",
1699 ss->sequence_allowed,
1700 GNUNET_sh2s (&(ss->master)));
1702 &ss->sender->target,
1704 &ack.header);
1705}
1706
1707
1708static void
1709kce_generate_cb (void *cls)
1710{
1711 struct SharedSecret *ss = cls;
1712 ss->sender->kce_task = NULL;
1713
1715 "Precomputing %u keys for master %s\n",
1717 GNUNET_sh2s (&ss->master));
1718 if ((ss->override_available_acks != GNUNET_YES) &&
1719 (KCN_TARGET < ss->sender->acks_available))
1720 return;
1721 for (int i = 0; i < GENERATE_AT_ONCE; i++)
1722 kce_generate (ss, ++ss->sequence_allowed);
1723
1728 if (KCN_TARGET > ss->sender->acks_available)
1729 {
1733 ss);
1734 return;
1735 }
1737 "We have enough keys (ACKs: %u).\n", ss->sender->acks_available);
1741 consider_ss_ack (ss);
1742}
1743
1744
1753static void
1755 const void *buf,
1756 size_t buf_size)
1757{
1758 const struct GNUNET_MessageHeader *hdr;
1759 const struct UDPAck *ack;
1760 const struct UDPRekey *rekey;
1761 struct SharedSecret *ss_rekey;
1762 const char *buf_pos = buf;
1763 size_t bytes_remaining = buf_size;
1764 uint16_t type;
1765
1766 hdr = (struct GNUNET_MessageHeader*) buf_pos;
1767 if (sizeof(*hdr) > bytes_remaining)
1768 {
1769 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Plaintext too short, dropping...\n");
1770 return; /* no data left */
1771 }
1773 "try_handle_plaintext of size %llu (%u %lu) and type %u\n",
1774 (unsigned long long) bytes_remaining,
1775 ntohs (hdr->size),
1776 sizeof(*hdr),
1777 ntohs (hdr->type));
1778 if (ntohs (hdr->size) > bytes_remaining)
1779 return; /* buffer too short for indicated message length */
1780 type = ntohs (hdr->type);
1781 switch (type)
1782 {
1784 rekey = (struct UDPRekey*) buf_pos;
1785 ss_rekey = setup_shared_secret_dec (&rekey->ephemeral);
1786 ss_rekey->sender = sender;
1787 GNUNET_CONTAINER_DLL_insert (sender->ss_head, sender->ss_tail, ss_rekey);
1788 sender->num_secrets++;
1790 "Received rekey secret with cmac %s\n",
1791 GNUNET_h2s (&(ss_rekey->cmac)));
1793 "Received secret with master %s.\n",
1794 GNUNET_sh2s (&(ss_rekey->master)));
1796 "We have %u sequence_allowed.\n",
1797 ss_rekey->sequence_allowed);
1799 "We have a sender %p\n",
1800 ss_rekey->sender);
1802 "We have %u acks available.\n",
1803 ss_rekey->sender->acks_available);
1805 "# rekeying successful",
1806 1,
1807 GNUNET_NO);
1810 // FIXME
1811 kce_generate_cb (ss_rekey);
1812 /* ss_rekey->sender->kce_task = GNUNET_SCHEDULER_add_delayed (
1813 WORKING_QUEUE_INTERVALL,
1814 kce_generate_cb,
1815 ss_rekey);*/
1816 // FIXME: Theoretically, this could be an Ack
1817 buf_pos += ntohs (hdr->size);
1818 bytes_remaining -= ntohs (hdr->size);
1819 pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
1820 if (0 == purge_secrets (sender->ss_tail))
1821 {
1822 // No secret purged. Delete oldest.
1823 if (sender->num_secrets > MAX_SECRETS)
1824 {
1825 secret_destroy (sender->ss_tail);
1826 }
1827 }
1828 break;
1830 /* lookup master secret by 'cmac', then update sequence_max */
1831 ack = (struct UDPAck*) buf_pos;
1833 &sender->key,
1834 &handle_ack,
1835 (void *) ack);
1836 /* There could be more messages after the ACK, handle those as well */
1837 buf_pos += ntohs (hdr->size);
1838 bytes_remaining -= ntohs (hdr->size);
1839 pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
1840 break;
1841
1843 /* skip padding */
1844 break;
1845
1846 default:
1847 pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
1848 }
1849 return;
1850}
1851
1852
1860static void
1861decrypt_box (const struct UDPBox *box,
1862 size_t box_len,
1863 struct KeyCacheEntry *kce)
1864{
1865 struct SharedSecret *ss = kce->ss;
1866 struct SharedSecret *ss_c = ss->sender->ss_tail;
1867 struct SharedSecret *ss_tmp;
1868 int ss_destroyed = 0;
1869 char out_buf[box_len - sizeof(*box)];
1870
1871 GNUNET_assert (NULL != ss->sender);
1872 if (GNUNET_OK != try_decrypt (ss,
1873 box->gcm_tag,
1874 kce->sequence_number,
1875 (const char *) &box[1],
1876 sizeof(out_buf),
1877 out_buf))
1878 {
1879 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed decryption.\n");
1881 "# Decryption failures with valid KCE",
1882 1,
1883 GNUNET_NO);
1884 kce_destroy (kce);
1885 ss->sender->acks_available--;
1886 return;
1887 }
1888 kce_destroy (kce);
1889 kce = NULL;
1890 ss->bytes_sent += box_len;
1891 ss->sender->acks_available--;
1892 ss->sequence_used++;
1894 "# bytes decrypted with BOX",
1895 sizeof(out_buf),
1896 GNUNET_NO);
1898 "# messages decrypted with BOX",
1899 1,
1900 GNUNET_NO);
1902 "decrypted UDPBox with kid %s\n",
1903 GNUNET_sh2s (&box->kid));
1904 try_handle_plaintext (ss->sender, out_buf, sizeof(out_buf));
1905
1906 while (NULL != ss_c)
1907 {
1908 if (ss_c->bytes_sent >= rekey_max_bytes)
1909 {
1911 "Removing SS because rekey bytes reached.\n");
1912 ss_tmp = ss_c->prev;
1913 if (ss == ss_c)
1914 ss_destroyed = 1;
1915 secret_destroy (ss_c);
1916 ss_c = ss_tmp;
1917 continue;
1918 }
1919 ss_c = ss_c->prev;
1920 }
1921 if (1 == ss_destroyed)
1922 return;
1924 "Sender has %u ack left.\n",
1925 ss->sender->acks_available);
1926 if ((KCN_THRESHOLD > ss->sender->acks_available) &&
1927 (NULL == ss->sender->kce_task) &&
1929 {
1931 "Sender has %u ack left which is under threshold.\n",
1932 ss->sender->acks_available);
1936 ss);
1937 }
1938}
1939
1940
1944struct SearchContext
1945{
1949 const struct sockaddr *address;
1950
1954 socklen_t address_len;
1955
1959 struct SenderAddress *sender;
1960};
1961
1962
1974static struct SenderAddress *
1976 const struct sockaddr *address,
1977 socklen_t address_len)
1978{
1979 struct SenderAddress *sender;
1980 struct GNUNET_HashContext *hsh;
1981 struct GNUNET_HashCode sender_key;
1982
1984 GNUNET_CRYPTO_hash_context_read (hsh, address, address_len);
1985 GNUNET_CRYPTO_hash_context_read (hsh, target, sizeof(*target));
1986 GNUNET_CRYPTO_hash_context_finish (hsh, &sender_key);
1987
1988 sender = GNUNET_CONTAINER_multihashmap_get (senders, &sender_key);
1989 if (NULL != sender)
1990 {
1992 return sender;
1993 }
1994 sender = GNUNET_new (struct SenderAddress);
1995 sender->key = sender_key;
1996 sender->target = *target;
1997 sender->address = GNUNET_memdup (address, address_len);
1998 sender->address_len = address_len;
2000 senders,
2001 &sender->key,
2002 sender,
2005 "# senders active",
2007 GNUNET_NO);
2008 sender->timeout =
2011 sender,
2012 sender->timeout.abs_value_us);
2013 sender->nt = GNUNET_NT_scanner_get_type (is, address, address_len);
2014 if (NULL == timeout_task)
2016 return sender;
2017}
2018
2019
2027static int
2029 const struct UDPConfirmation *uc)
2030{
2031 struct UdpHandshakeSignature uhs;
2032
2033 uhs.purpose.purpose = htonl (
2035 uhs.purpose.size = htonl (sizeof(uhs));
2036 uhs.sender = uc->sender;
2037 uhs.receiver = my_identity;
2038 uhs.enc = *enc;
2039 uhs.monotonic_time = uc->monotonic_time;
2042 &uhs,
2043 &uc->sender_sig,
2044 &uc->sender.public_key);
2045}
2046
2047
2056static char *
2057sockaddr_to_udpaddr_string (const struct sockaddr *address,
2058 socklen_t address_len)
2059{
2060 char *ret;
2061
2062 switch (address->sa_family)
2063 {
2064 case AF_INET:
2066 "%s-%s",
2068 GNUNET_a2s (address, address_len));
2069 break;
2070
2071 case AF_INET6:
2073 "%s-%s",
2075 GNUNET_a2s (address, address_len));
2076 break;
2077
2078 default:
2079 GNUNET_assert (0);
2080 }
2081 return ret;
2082}
2083
2084
2085static struct GNUNET_NETWORK_Handle *
2087{
2089
2090 if (NULL == receiver->udp_sock)
2091 {
2092 if (AF_INET6 == receiver->address->sa_family)
2094 else
2096 }
2097 else
2098 udp_sock = receiver->udp_sock;
2099
2100 return udp_sock;
2101}
2102
2103
2112static struct sockaddr *
2113udp_address_to_sockaddr (const char *bindto,
2114 sa_family_t family,
2115 socklen_t *sock_len)
2116{
2117 struct sockaddr *in;
2118 unsigned int port;
2119 char dummy[2];
2120 char *colon;
2121 char *cp;
2122
2123 if (1 == sscanf (bindto, "%u%1s", &port, dummy))
2124 {
2125 /* interpreting value as just a PORT number */
2126 if (port > UINT16_MAX)
2127 {
2129 "BINDTO specification `%s' invalid: value too large for port\n",
2130 bindto);
2131 return NULL;
2132 }
2133 if ((AF_INET == family) || (GNUNET_YES == disable_v6))
2134 {
2135 struct sockaddr_in *i4;
2136
2137 i4 = GNUNET_malloc (sizeof(struct sockaddr_in));
2138 i4->sin_family = AF_INET;
2139 i4->sin_port = htons ((uint16_t) port);
2140 *sock_len = sizeof(struct sockaddr_in);
2141 in = (struct sockaddr *) i4;
2142 }
2143 else
2144 {
2145 struct sockaddr_in6 *i6;
2146
2147 i6 = GNUNET_malloc (sizeof(struct sockaddr_in6));
2148 i6->sin6_family = AF_INET6;
2149 i6->sin6_port = htons ((uint16_t) port);
2150 *sock_len = sizeof(struct sockaddr_in6);
2151 in = (struct sockaddr *) i6;
2152 }
2153 return in;
2154 }
2155 cp = GNUNET_strdup (bindto);
2156 colon = strrchr (cp, ':');
2157 if (NULL != colon)
2158 {
2159 /* interpret value after colon as port */
2160 *colon = '\0';
2161 colon++;
2162 if (1 == sscanf (colon, "%u%1s", &port, dummy))
2163 {
2164 /* interpreting value as just a PORT number */
2165 if (port > UINT16_MAX)
2166 {
2168 "BINDTO specification `%s' invalid: value too large for port\n",
2169 bindto);
2170 GNUNET_free (cp);
2171 return NULL;
2172 }
2173 }
2174 else
2175 {
2176 GNUNET_log (
2178 "BINDTO specification `%s' invalid: last ':' not followed by number\n",
2179 bindto);
2180 GNUNET_free (cp);
2181 return NULL;
2182 }
2183 }
2184 else
2185 {
2186 /* interpret missing port as 0, aka pick any free one */
2187 port = 0;
2188 }
2189 if (AF_INET6 != family)
2190 {
2191 /* try IPv4 */
2192 struct sockaddr_in v4;
2193
2194 memset (&v4, 0, sizeof(v4));
2195 if (1 == inet_pton (AF_INET, cp, &v4.sin_addr))
2196 {
2197 v4.sin_family = AF_INET;
2198 v4.sin_port = htons ((uint16_t) port);
2199#if HAVE_SOCKADDR_IN_SIN_LEN
2200 v4.sin_len = sizeof(struct sockaddr_in);
2201#endif
2202 in = GNUNET_memdup (&v4, sizeof(struct sockaddr_in));
2203 *sock_len = sizeof(struct sockaddr_in);
2204 GNUNET_free (cp);
2205 return in;
2206 }
2207 }
2208 if (AF_INET != family)
2209 {
2210 /* try IPv6 */
2211 struct sockaddr_in6 v6;
2212 const char *start;
2213
2214 memset (&v6, 0, sizeof(v6));
2215 start = cp;
2216 if (('[' == *cp) && (']' == cp[strlen (cp) - 1]))
2217 {
2218 start++; /* skip over '[' */
2219 cp[strlen (cp) - 1] = '\0'; /* eat ']' */
2220 }
2221 if (1 == inet_pton (AF_INET6, start, &v6.sin6_addr))
2222 {
2223 v6.sin6_family = AF_INET6;
2224 v6.sin6_port = htons ((uint16_t) port);
2225#if HAVE_SOCKADDR_IN_SIN_LEN
2226 v6.sin6_len = sizeof(struct sockaddr_in6);
2227#endif
2228 in = GNUNET_memdup (&v6, sizeof(v6));
2229 *sock_len = sizeof(v6);
2230 GNUNET_free (cp);
2231 return in;
2232 }
2233 }
2234 /* #5528 FIXME (feature!): maybe also try getnameinfo()? */
2235 GNUNET_free (cp);
2236 return NULL;
2237}
2238
2239
2240static void
2241sock_read (void *cls);
2242
2243
2244static enum GNUNET_GenericReturnValue
2245create_receiver (const struct GNUNET_PeerIdentity *peer,
2246 const char *address,
2248{
2249 struct GNUNET_HashContext *hsh;
2250 struct ReceiverAddress *receiver;
2251 struct GNUNET_HashCode receiver_key;
2252 const char *path;
2253 struct sockaddr *in;
2254 socklen_t in_len;
2255
2256 if (0 != strncmp (address,
2258 strlen (COMMUNICATOR_ADDRESS_PREFIX "-")))
2259 {
2260 GNUNET_break_op (0);
2261 return GNUNET_SYSERR;
2262 }
2263 path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")];
2264 in = udp_address_to_sockaddr (path, AF_UNSPEC, &in_len);
2265
2266 if (NULL == in)
2267 {
2269 "Failed to setup UDP socket address\n");
2270 return GNUNET_SYSERR;
2271 }
2272 if ((AF_INET6 == in->sa_family) &&
2274 {
2276 "IPv6 disabled, skipping %s\n", address);
2277 GNUNET_free (in);
2278 return GNUNET_SYSERR;
2279 }
2280 else if (AF_INET == in->sa_family)
2281 {
2282 struct sockaddr_in *sin = (struct sockaddr_in *) in;
2283 if (0 == sin->sin_port)
2284 {
2285 GNUNET_free (in);
2286 return GNUNET_NO;
2287 }
2288 }
2289
2291 GNUNET_CRYPTO_hash_context_read (hsh, in, in_len);
2292 GNUNET_CRYPTO_hash_context_read (hsh, peer, sizeof(*peer));
2293 GNUNET_CRYPTO_hash_context_finish (hsh, &receiver_key);
2294
2296 if (NULL != receiver)
2297 {
2299 "receiver %s already exist or is being connected to\n",
2300 address);
2301 return GNUNET_NO;
2302 }
2303
2305 receiver->udp_sock = udp_sock;
2306 receiver->key = receiver_key;
2307 receiver->address = in;
2308 receiver->address_len = in_len;
2309 receiver->target = *peer;
2310 eddsa_pub_to_hpke_key (&receiver->target.public_key,
2311 &receiver->target_hpke_key);
2312 receiver->nt = GNUNET_NT_scanner_get_type (is, in, in_len);
2314 receivers,
2315 &receiver->key,
2316 receiver,
2319 "Added %s to receivers with address %s and sock %p\n",
2320 GNUNET_i2s_full (&receiver->target),
2321 address,
2322 udp_sock);
2323 receiver->timeout =
2326 receiver,
2327 receiver->timeout.abs_value_us);
2329 "# receivers active",
2331 GNUNET_NO);
2332 receiver->foreign_addr =
2333 sockaddr_to_udpaddr_string (receiver->address, receiver->address_len);
2334 if (NULL != udp_sock)
2337 udp_sock,
2338 &sock_read,
2339 udp_sock);
2341 if (NULL == timeout_task)
2343 return GNUNET_OK;
2344}
2345
2346
2352static void
2353sock_read (void *cls)
2354{
2355 struct sockaddr_storage sa;
2356 struct sockaddr_in *addr_verify;
2357 socklen_t salen = sizeof(sa);
2358 char buf[UINT16_MAX];
2359 ssize_t rcvd;
2360
2361 struct GNUNET_NETWORK_Handle *udp_sock = cls;
2362
2365 udp_sock,
2366 &sock_read,
2367 udp_sock);
2370 udp_sock,
2371 &sock_read,
2372 udp_sock);
2373 while (1)
2374 {
2376 buf,
2377 sizeof(buf),
2378 (struct sockaddr *) &sa,
2379 &salen);
2380 if (-1 == rcvd)
2381 {
2382 struct sockaddr *addr = (struct sockaddr*) &sa;
2383
2384 if (EAGAIN == errno)
2385 break; // We are done reading data
2387 "Failed to recv from %s family %d failed sock %p\n",
2388 GNUNET_a2s ((struct sockaddr*) &sa,
2389 sizeof (*addr)),
2390 addr->sa_family,
2391 udp_sock);
2393 return;
2394 }
2396 "Read %llu bytes\n",
2397 (unsigned long long) rcvd);
2398 if (0 == rcvd)
2399 {
2400 GNUNET_break_op (0);
2402 "Read 0 bytes from UDP socket\n");
2403 return;
2404 }
2405
2406 /* first, see if it is a GNUNET_BurstMessage */
2407 if (rcvd == sizeof (struct GNUNET_BurstMessage))
2408 {
2409 struct GNUNET_BurstMessage *bm = (struct GNUNET_BurstMessage *) buf;
2410 struct sockaddr *addr = (struct sockaddr*) &sa;
2411 char *address = sockaddr_to_udpaddr_string (addr, sizeof (*addr));
2412
2413 GNUNET_assert (0 == bm->local_port);
2415 "Received a burst message for default port\n");
2416 create_receiver (&bm->peer,
2417 address,
2418 NULL);
2419 if (AF_INET6 == addr->sa_family)
2421 else
2425 return;
2426 }
2427 /* second, see if it is a UDPBox */
2428 if (rcvd > sizeof(struct UDPBox))
2429 {
2430 const struct UDPBox *box;
2431 struct KeyCacheEntry *kce;
2432
2433 box = (const struct UDPBox *) buf;
2435 if (NULL != kce)
2436 {
2438 "Found KCE with kid %s\n",
2439 GNUNET_sh2s (&box->kid));
2440 decrypt_box (box, (size_t) rcvd, kce);
2441 continue;
2442 }
2443 }
2444
2445 /* next, check if it is a broadcast */
2446 if (sizeof(struct UDPBroadcast) == rcvd)
2447 {
2448 const struct UDPBroadcast *ub;
2449 struct UdpBroadcastSignature uhs;
2450 struct GNUNET_PeerIdentity sender;
2451
2452 addr_verify = GNUNET_memdup (&sa, salen);
2453 addr_verify->sin_port = 0;
2455 "received UDPBroadcast from %s\n",
2456 GNUNET_a2s ((const struct sockaddr *) addr_verify, salen));
2457 ub = (const struct UDPBroadcast *) buf;
2458 uhs.purpose.purpose = htonl (
2460 uhs.purpose.size = htonl (sizeof(uhs));
2461 uhs.sender = ub->sender;
2462 sender = ub->sender;
2463 if (0 == memcmp (&sender, &my_identity, sizeof (struct
2465 {
2467 "Received our own broadcast\n");
2468 GNUNET_free (addr_verify);
2469 continue;
2470 }
2472 "checking UDPBroadcastSignature for %s\n",
2473 GNUNET_i2s (&sender));
2474 GNUNET_CRYPTO_hash ((struct sockaddr *) addr_verify, salen,
2475 &uhs.h_address);
2476 if (GNUNET_OK ==
2479 &uhs,
2480 &ub->sender_sig,
2481 &ub->sender.public_key))
2482 {
2483 char *addr_s;
2485
2486 addr_s =
2487 sockaddr_to_udpaddr_string ((const struct sockaddr *) &sa, salen);
2488 GNUNET_STATISTICS_update (stats, "# broadcasts received", 1, GNUNET_NO);
2489 /* use our own mechanism to determine network type */
2490 nt =
2491 GNUNET_NT_scanner_get_type (is, (const struct sockaddr *) &sa, salen);
2493 "validating address %s received from UDPBroadcast\n",
2494 GNUNET_i2s (&sender));
2496 GNUNET_free (addr_s);
2497 GNUNET_free (addr_verify);
2498 continue;
2499 }
2500 else
2501 {
2503 "VerifyingPeer %s is verifying UDPBroadcast\n",
2506 "Verifying UDPBroadcast from %s failed\n",
2507 GNUNET_i2s (&ub->sender));
2508 }
2509 GNUNET_free (addr_verify);
2510 /* continue with KX, mostly for statistics... */
2511 }
2512
2513
2514 /* finally, test if it is a KX */
2515 if (rcvd < sizeof(struct UDPConfirmation) + sizeof(struct InitialKX))
2516 {
2518 "# messages dropped (no kid, too small for KX)",
2519 1,
2520 GNUNET_NO);
2521 continue;
2522 }
2524 "Got KX\n");
2525 {
2526 const struct InitialKX *kx;
2527 struct SharedSecret *ss;
2528 char pbuf[rcvd - sizeof(struct InitialKX)];
2529 const struct UDPConfirmation *uc;
2530 struct SenderAddress *sender;
2531
2532 kx = (const struct InitialKX *) buf;
2535 "Before DEC\n");
2536
2537 if (GNUNET_OK != try_decrypt (ss,
2538 kx->gcm_tag,
2539 0,
2540 &buf[sizeof(*kx)],
2541 sizeof(pbuf),
2542 pbuf))
2543 {
2545 "Unable to decrypt tag, dropping...\n");
2546 GNUNET_free (ss);
2548 stats,
2549 "# messages dropped (no kid, AEAD decryption failed)",
2550 1,
2551 GNUNET_NO);
2552 continue;
2553 }
2555 "Before VERIFY\n");
2556
2557 uc = (const struct UDPConfirmation *) pbuf;
2558
2559 if (GNUNET_OK != verify_confirmation (&kx->enc, uc)) // TODO: need ephemeral instead of representative
2560 {
2561 GNUNET_break_op (0);
2562 GNUNET_free (ss);
2564 "# messages dropped (sender signature invalid)",
2565 1,
2566 GNUNET_NO);
2567 continue;
2568 }
2570 "Before SETUP_SENDER\n");
2571
2572 calculate_cmac (ss);
2573 sender = setup_sender (&uc->sender, (const struct sockaddr *) &sa, salen);
2574 ss->sender = sender;
2575 GNUNET_CONTAINER_DLL_insert (sender->ss_head, sender->ss_tail, ss);
2576 if ((KCN_THRESHOLD > ss->sender->acks_available) &&
2577 (NULL == ss->sender->kce_task) &&
2579 {
2580 // TODO This task must be per sender! FIXME: This is a nice todo, but I do not know what must be done here to fix.
2584 ss);
2585 }
2586 sender->num_secrets++;
2587 GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
2589 "# messages decrypted without BOX",
2590 1,
2591 GNUNET_NO);
2592 try_handle_plaintext (sender, &uc[1], sizeof(pbuf) - sizeof(*uc));
2593 if (0 == purge_secrets (sender->ss_tail))
2594 {
2595 // No secret purged. Delete oldest.
2596 if (sender->num_secrets > MAX_SECRETS)
2597 {
2598 secret_destroy (sender->ss_tail);
2599 }
2600 }
2601 }
2602 }
2603}
2604
2605
2613static void
2614do_pad (gcry_cipher_hd_t out_cipher, char *dgram, size_t pad_size)
2615{
2616 char pad[pad_size];
2617
2619 if (sizeof(pad) > sizeof(struct GNUNET_MessageHeader))
2620 {
2621 struct GNUNET_MessageHeader hdr =
2622 { .size = htons (sizeof(pad)),
2624
2625 memcpy (pad, &hdr, sizeof(hdr));
2626 }
2628 0 ==
2629 gcry_cipher_encrypt (out_cipher, dgram, sizeof(pad), pad, sizeof(pad)));
2630}
2631
2632
2633static void
2634send_msg_with_kx (const struct GNUNET_MessageHeader *msg, struct
2636 struct GNUNET_MQ_Handle *mq)
2637{
2638 uint16_t msize = ntohs (msg->size);
2639 struct UdpHandshakeSignature uhs;
2640 struct UDPConfirmation uc;
2641 struct InitialKX kx;
2642 char dgram[receiver->kx_mtu + sizeof(uc) + sizeof(kx)];
2643 size_t dpos;
2644 gcry_cipher_hd_t out_cipher;
2645 struct SharedSecret *ss;
2646
2647 if (msize > receiver->kx_mtu)
2648 {
2649 GNUNET_break (0);
2650 if (GNUNET_YES != receiver->receiver_destroy_called)
2652 return;
2653 }
2655
2656 /* setup key material */
2658
2659 if (0 == purge_secrets (receiver->ss_tail))
2660 {
2661 // No secret purged. Delete oldest.
2662 if (receiver->num_secrets > MAX_SECRETS)
2663 {
2664 secret_destroy (receiver->ss_tail);
2665 }
2666 }
2667
2668 setup_cipher (&ss->master, 0, &out_cipher);
2669 /* compute 'uc' */
2670 uc.sender = my_identity;
2671 uc.monotonic_time =
2673 uhs.purpose.purpose = htonl (
2675 uhs.purpose.size = htonl (sizeof(uhs));
2676 uhs.sender = my_identity;
2677 uhs.receiver = receiver->target;
2678 uhs.monotonic_time = uc.monotonic_time;
2680 &uhs,
2681 &uc.sender_sig);
2682 /* Leave space for kx */
2683 dpos = sizeof(kx);
2684 /* Append encrypted uc to dgram */
2685 GNUNET_assert (0 == gcry_cipher_encrypt (out_cipher,
2686 &dgram[dpos],
2687 sizeof(uc),
2688 &uc,
2689 sizeof(uc)));
2690 dpos += sizeof(uc);
2691 /* Append encrypted payload to dgram */
2693 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], msize, msg, msize));
2694 dpos += msize;
2695 do_pad (out_cipher, &dgram[dpos], sizeof(dgram) - dpos);
2696 /* Datagram starts with kx */
2697 kx.enc = uhs.enc;
2699 0 == gcry_cipher_gettag (out_cipher, kx.gcm_tag, sizeof(kx.gcm_tag)));
2700 gcry_cipher_close (out_cipher);
2701 memcpy (dgram, &kx, sizeof(kx));
2703 dgram,
2704 sizeof(dgram),
2705 receiver->address,
2706 receiver->address_len))
2707 {
2710 "Sending KX with payload size %u to %s family %d failed sock %p\n",
2711 msize,
2712 GNUNET_a2s (receiver->address,
2713 receiver->address_len),
2714 receiver->address->sa_family,
2718 return;
2719 }
2721 "Sending KX with payload size %u to %s with socket %p\n",
2722 msize,
2723 GNUNET_a2s (receiver->address,
2724 receiver->address_len),
2727}
2728
2729
2738static void
2740 const struct GNUNET_MessageHeader *msg,
2741 void *impl_state)
2742{
2743 struct ReceiverAddress *receiver = impl_state;
2744
2745 GNUNET_assert (mq == receiver->kx_mq);
2747}
2748
2749
2750static void
2751create_rekey (struct ReceiverAddress *receiver, struct SharedSecret *ss, struct
2752 UDPRekey *rekey)
2753{
2754 struct SharedSecret *ss_rekey;
2755
2757 /* setup key material */
2758 ss_rekey = setup_shared_secret_ephemeral (&rekey->ephemeral,
2759 receiver);
2760 ss_rekey->sequence_allowed = 0;
2762 "Setup secret with k = %s\n",
2763 GNUNET_sh2s (&ss_rekey->master));
2765 "Setup secret with H(k) = %s\n",
2766 GNUNET_h2s (&(ss_rekey->cmac)));
2767
2768 /* Append encrypted payload to dgram */
2770 rekey->header.size = htons (sizeof (struct UDPRekey));
2771}
2772
2773
2782static void
2784 const struct GNUNET_MessageHeader *msg,
2785 void *impl_state)
2786{
2787 struct ReceiverAddress *receiver = impl_state;
2788 struct UDPRekey rekey;
2789 struct SharedSecret *ss;
2790 int inject_rekey = GNUNET_NO;
2791 uint16_t msize = ntohs (msg->size);
2792
2793 GNUNET_assert (mq == receiver->d_mq);
2794 if ((msize > receiver->d_mtu) ||
2795 (0 == receiver->acks_available))
2796 {
2798 "msize: %u, mtu: %llu, acks: %u\n",
2799 (unsigned int) msize,
2800 (unsigned long long) receiver->d_mtu,
2801 receiver->acks_available);
2802
2803 GNUNET_break (0);
2804 if (GNUNET_YES != receiver->receiver_destroy_called)
2806 return;
2807 }
2809
2810 if (receiver->num_secrets > MAX_SECRETS)
2811 {
2812 if ((0 == purge_secrets (receiver->ss_tail)) &&
2813 (NULL != receiver->ss_tail))
2814 {
2815 // No secret purged. Delete oldest.
2816 secret_destroy (receiver->ss_tail);
2817 }
2818 }
2819 /* begin "BOX" encryption method, scan for ACKs from tail! */
2820 ss = receiver->ss_tail;
2821 while (NULL != ss)
2822 {
2823 size_t payload_len = sizeof(struct UDPBox) + receiver->d_mtu;
2825 "Considering SS %s sequence used: %u sequence allowed: %u bytes sent: %lu.\n",
2826 GNUNET_sh2s (&ss->master), ss->sequence_used,
2827 ss->sequence_allowed, ss->bytes_sent);
2828 if (ss->sequence_used >= ss->sequence_allowed)
2829 {
2830 // GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2831 // "Skipping ss because no acks to use.\n");
2832 ss = ss->prev;
2833 continue;
2834 }
2835 if (ss->bytes_sent >= rekey_max_bytes)
2836 {
2837 struct SharedSecret *ss_tmp;
2839 "Skipping ss because rekey bytes reached.\n");
2840 // FIXME cleanup ss with too many bytes sent!
2841 ss_tmp = ss->prev;
2842 secret_destroy (ss);
2843 ss = ss_tmp;
2844 continue;
2845 }
2846 if (ss->bytes_sent > rekey_max_bytes * 0.7)
2847 {
2848 if (ss->rekey_initiated == GNUNET_NO)
2849 {
2851 "Injecting rekey for ss with byte sent %lu\n",
2852 (unsigned long) ss->bytes_sent);
2853 create_rekey (receiver, ss, &rekey);
2855 payload_len += sizeof (rekey);
2857 }
2858 }
2859 if (0 < ss->sequence_used)
2861 "Trying to send UDPBox with shared secret %s sequence_used %u and ss->sequence_allowed %u\n",
2862 GNUNET_sh2s (&ss->master),
2863 ss->sequence_used,
2864 ss->sequence_allowed);
2865 {
2866 char dgram[payload_len];
2867 struct UDPBox *box;
2868 gcry_cipher_hd_t out_cipher;
2869 size_t dpos;
2870
2871 box = (struct UDPBox *) dgram;
2872 ss->sequence_used++;
2873 get_kid (&ss->master, ss->sequence_used, &box->kid);
2874 setup_cipher (&ss->master, ss->sequence_used, &out_cipher);
2875 /* Append encrypted payload to dgram */
2876 dpos = sizeof(struct UDPBox);
2877 if (GNUNET_YES == inject_rekey)
2878 {
2880 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], sizeof (rekey),
2881 &rekey, sizeof (rekey)));
2882 dpos += sizeof (rekey);
2883 }
2885 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], msize, msg, msize));
2886 dpos += msize;
2887 do_pad (out_cipher, &dgram[dpos], sizeof(dgram) - dpos);
2888 GNUNET_assert (0 == gcry_cipher_gettag (out_cipher,
2889 box->gcm_tag,
2890 sizeof(box->gcm_tag)));
2891 gcry_cipher_close (out_cipher);
2892
2894 dgram,
2895 payload_len, // FIXME why always send sizeof dgram?
2896 receiver->address,
2897 receiver->address_len))
2898 {
2901 "Sending UDPBox to %s family %d failed sock %p failed\n",
2902 GNUNET_a2s (receiver->address,
2903 receiver->address_len),
2904 receiver->address->sa_family,
2907 return;
2908 }
2910 "Sending UDPBox with payload size %u, %u acks left, %lu bytes sent with socket %p\n",
2911 msize,
2912 receiver->acks_available,
2913 (unsigned long) ss->bytes_sent,
2915 ss->bytes_sent += sizeof (dgram);
2916 receiver->acks_available--;
2918 return;
2919 }
2920 }
2922 "No suitable ss found, sending as KX...\n");
2924}
2925
2926
2935static void
2936mq_destroy_d (struct GNUNET_MQ_Handle *mq, void *impl_state)
2937{
2938 struct ReceiverAddress *receiver = impl_state;
2940 "Default MQ destroyed\n");
2941 if (mq == receiver->d_mq)
2942 {
2943 receiver->d_mq = NULL;
2944 if (GNUNET_YES != receiver->receiver_destroy_called)
2946 }
2947}
2948
2949
2958static void
2959mq_destroy_kx (struct GNUNET_MQ_Handle *mq, void *impl_state)
2960{
2961 struct ReceiverAddress *receiver = impl_state;
2963 "KX MQ destroyed\n");
2964 if (mq == receiver->kx_mq)
2965 {
2966 receiver->kx_mq = NULL;
2967 if (GNUNET_YES != receiver->receiver_destroy_called)
2969 }
2970}
2971
2972
2979static void
2980mq_cancel (struct GNUNET_MQ_Handle *mq, void *impl_state)
2981{
2982 /* Cancellation is impossible with UDP; bail */
2983 GNUNET_assert (0);
2984}
2985
2986
2996static void
2997mq_error (void *cls, enum GNUNET_MQ_Error error)
2998{
2999 struct ReceiverAddress *receiver = cls;
3000
3002 "MQ error in queue to %s: %d\n",
3003 GNUNET_i2s (&receiver->target),
3004 (int) error);
3006}
3007
3008
3016static void
3018{
3019 size_t base_mtu;
3020
3021 switch (receiver->address->sa_family)
3022 {
3023 case AF_INET:
3024 base_mtu = 1480 /* Ethernet MTU, 1500 - Ethernet header - VLAN tag */
3025 - sizeof(struct GNUNET_TUN_IPv4Header) /* 20 */
3026 - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */;
3027 break;
3028
3029 case AF_INET6:
3030 base_mtu = 1280 /* Minimum MTU required by IPv6 */
3031 - sizeof(struct GNUNET_TUN_IPv6Header) /* 40 */
3032 - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */;
3033 break;
3034
3035 default:
3036 GNUNET_assert (0);
3037 break;
3038 }
3039 /* MTU based on full KX messages */
3040 receiver->kx_mtu = base_mtu - sizeof(struct InitialKX) /* 48 */
3041 - sizeof(struct UDPConfirmation); /* 104 */
3042 /* MTU based on BOXed messages */
3043 receiver->d_mtu = base_mtu - sizeof(struct UDPBox);
3044
3046 "Setting up MQs and QHs\n");
3047 /* => Effective MTU for CORE will range from 1080 (IPv6 + KX) to
3048 1404 (IPv4 + Box) bytes, depending on circumstances... */
3049 if (NULL == receiver->kx_mq)
3052 &mq_cancel,
3053 receiver,
3054 NULL,
3055 &mq_error,
3056 receiver);
3057 if (NULL == receiver->d_mq)
3059 &mq_destroy_d,
3060 &mq_cancel,
3061 receiver,
3062 NULL,
3063 &mq_error,
3064 receiver);
3065
3066 receiver->kx_qh =
3068 &receiver->target,
3069 receiver->foreign_addr,
3070 receiver->kx_mtu,
3072 0, /* Priority */
3073 receiver->nt,
3075 receiver->kx_mq);
3076}
3077
3078
3097static int
3098mq_init (void *cls, const struct GNUNET_PeerIdentity *peer, const char *address)
3099{
3100 (void) cls;
3102 "create receiver for mq_init\n");
3103 return create_receiver (peer,
3104 address,
3105 NULL);
3106}
3107
3108
3117static int
3118get_receiver_delete_it (void *cls,
3119 const struct GNUNET_HashCode *target,
3120 void *value)
3121{
3122 struct ReceiverAddress *receiver = value;
3123
3124 (void) cls;
3125 (void) target;
3127 return GNUNET_OK;
3128}
3129
3130
3139static int
3140get_sender_delete_it (void *cls,
3141 const struct GNUNET_HashCode *target,
3142 void *value)
3143{
3144 struct SenderAddress *sender = value;
3145
3146 (void) cls;
3147 (void) target;
3148
3149
3150 sender_destroy (sender);
3151 return GNUNET_OK;
3152}
3153
3154
3160static void
3161do_shutdown (void *cls)
3162{
3164 "do_shutdown\n");
3165 GNUNET_stop_burst (NULL);
3166 if (NULL != nat)
3167 {
3169 nat = NULL;
3170 }
3171 while (NULL != bi_head)
3173 if (NULL != broadcast_task)
3174 {
3176 broadcast_task = NULL;
3177 }
3178 if (NULL != timeout_task)
3179 {
3181 timeout_task = NULL;
3182 }
3183 if (NULL != read_v6_task)
3184 {
3186 read_v6_task = NULL;
3187 }
3188 if (NULL != read_v4_task)
3189 {
3191 read_v4_task = NULL;
3192 }
3193 if (NULL != default_v6_sock)
3194 {
3197 default_v6_sock = NULL;
3198 }
3199 if (NULL != default_v4_sock)
3200 {
3203 default_v4_sock = NULL;
3204 }
3207 NULL);
3211 NULL);
3216 if (NULL != timeout_task)
3217 {
3219 timeout_task = NULL;
3220 }
3221 if (NULL != ch)
3222 {
3224 ch = NULL;
3225 }
3226 if (NULL != ah)
3227 {
3229 ah = NULL;
3230 }
3231 if (NULL != pils)
3232 {
3234 pils = NULL;
3235 }
3236 if (NULL != stats)
3237 {
3239 stats = NULL;
3240 }
3241 if (NULL != my_private_key)
3242 {
3244 my_private_key = NULL;
3245 }
3246 if (NULL != is)
3247 {
3249 is = NULL;
3250 }
3252 "do_shutdown finished\n");
3253}
3254
3255
3256struct AckInfo
3257{
3258 const struct UDPAck *ack;
3259
3260 const struct GNUNET_PeerIdentity *sender;
3261};
3262
3263static int
3264handle_ack_by_sender (void *cls, const struct GNUNET_HashCode *key, void *value)
3265{
3266 struct ReceiverAddress *receiver = value;
3267 struct AckInfo *ai = cls;
3268
3269 if (0 != GNUNET_memcmp (ai->sender, &receiver->target))
3270 {
3271 return GNUNET_YES;
3272 }
3273 handle_ack ((void*) ai->ack, key, receiver);
3274 return GNUNET_YES;
3275}
3276
3277
3287static void
3288enc_notify_cb (void *cls,
3289 const struct GNUNET_PeerIdentity *sender,
3290 const struct GNUNET_MessageHeader *msg)
3291{
3292 struct AckInfo ai;
3293
3294 (void) cls;
3296 "Storing UDPAck received from backchannel from %s\n",
3299 (ntohs (msg->size) != sizeof(struct UDPAck)))
3300 {
3301 GNUNET_break_op (0);
3302 return;
3303 }
3304 ai.ack = (const struct UDPAck *) msg;
3305 ai.sender = sender;
3308 &ai);
3309}
3310
3311
3325static void
3326nat_address_cb (void *cls,
3327 void **app_ctx,
3328 int add_remove,
3330 const struct sockaddr *addr,
3331 socklen_t addrlen)
3332{
3333 char *my_addr;
3335
3336 if (GNUNET_YES == add_remove)
3337 {
3339
3340 GNUNET_asprintf (&my_addr,
3341 "%s-%s",
3343 GNUNET_a2s (addr, addrlen));
3344 nt = GNUNET_NT_scanner_get_type (is, addr, addrlen);
3345 ai =
3347 my_addr,
3348 nt,
3350 GNUNET_free (my_addr);
3351 *app_ctx = ai;
3352 }
3353 else
3354 {
3355 ai = *app_ctx;
3357 *app_ctx = NULL;
3358 }
3359}
3360
3361
3367static void
3368ifc_broadcast (void *cls)
3369{
3370 struct BroadcastInterface *bi = cls;
3371 struct GNUNET_TIME_Relative delay;
3372
3373 delay = BROADCAST_FREQUENCY;
3374 delay.rel_value_us =
3376 bi->broadcast_task =
3378
3379 switch (bi->sa->sa_family)
3380 {
3381 case AF_INET: {
3382 static int yes = 1;
3383 static int no = 0;
3384 ssize_t sent;
3385
3386 if (GNUNET_OK !=
3388 SOL_SOCKET,
3389 SO_BROADCAST,
3390 &yes,
3391 sizeof(int)))
3393 "setsockopt");
3395 "creating UDPBroadcast from %s\n",
3396 GNUNET_i2s (&(bi->bcm.sender)));
3398 "sending UDPBroadcast to add %s\n",
3399 GNUNET_a2s (bi->ba, bi->salen));
3401 &bi->bcm,
3402 sizeof(bi->bcm),
3403 bi->ba,
3404 bi->salen);
3405 if (-1 == sent)
3407 "sendto");
3409 SOL_SOCKET,
3410 SO_BROADCAST,
3411 &no,
3412 sizeof(int)))
3414 "setsockopt");
3415 break;
3416 }
3417
3418 case AF_INET6: {
3419 ssize_t sent;
3420 struct sockaddr_in6 dst;
3421
3422 dst.sin6_family = AF_INET6;
3423 dst.sin6_port = htons (my_port);
3424 dst.sin6_addr = bi->mcreq.ipv6mr_multiaddr;
3425 dst.sin6_scope_id = ((struct sockaddr_in6 *) bi->ba)->sin6_scope_id;
3426
3428 "sending UDPBroadcast\n");
3430 &bi->bcm,
3431 sizeof(bi->bcm),
3432 (const struct sockaddr *) &dst,
3433 sizeof(dst));
3434 if (-1 == sent)
3436 break;
3437 }
3438
3439 default:
3440 GNUNET_break (0);
3441 break;
3442 }
3443}
3444
3445
3460static int
3461iface_proc (void *cls,
3462 const char *name,
3463 int isDefault,
3464 const struct sockaddr *addr,
3465 const struct sockaddr *broadcast_addr,
3466 const struct sockaddr *netmask,
3467 socklen_t addrlen)
3468{
3469 struct BroadcastInterface *bi;
3470 enum GNUNET_NetworkType network;
3471 struct UdpBroadcastSignature ubs;
3472
3473 (void) cls;
3474 (void) netmask;
3475 if (NULL == my_private_key)
3476 return GNUNET_YES;
3477 if (NULL == addr)
3478 return GNUNET_YES; /* need to know our address! */
3479 network = GNUNET_NT_scanner_get_type (is, addr, addrlen);
3480 if (GNUNET_NT_LOOPBACK == network)
3481 {
3482 /* Broadcasting on loopback does not make sense */
3483 return GNUNET_YES;
3484 }
3485 for (bi = bi_head; NULL != bi; bi = bi->next)
3486 {
3487 if ((bi->salen == addrlen) && (0 == memcmp (addr, bi->sa, addrlen)))
3488 {
3489 bi->found = GNUNET_YES;
3490 return GNUNET_OK;
3491 }
3492 }
3493
3494 if ((AF_INET6 == addr->sa_family) && (NULL == broadcast_addr))
3495 return GNUNET_OK; /* broadcast_addr is required for IPv6! */
3496 if ((AF_INET6 == addr->sa_family) && (NULL != default_v6_sock))
3497 return GNUNET_OK; /* not using IPv6 */
3498
3499 bi = GNUNET_new (struct BroadcastInterface);
3500 bi->sa = GNUNET_memdup (addr,
3501 addrlen);
3502 if ( (NULL != broadcast_addr) &&
3503 (addrlen == sizeof (struct sockaddr_in)) )
3504 {
3505 struct sockaddr_in *ba;
3506
3507 ba = GNUNET_memdup (broadcast_addr,
3508 addrlen);
3509 ba->sin_port = htons (2086); /* always GNUnet port, ignore configuration! */
3510 bi->ba = (struct sockaddr *) ba;
3511 }
3512 bi->salen = addrlen;
3513 bi->found = GNUNET_YES;
3514 bi->bcm.sender = my_identity;
3515 ubs.purpose.purpose = htonl (
3517 ubs.purpose.size = htonl (sizeof(ubs));
3518 ubs.sender = my_identity;
3520 "creating UDPBroadcastSignature for %s\n",
3521 GNUNET_a2s (addr, addrlen));
3522 GNUNET_CRYPTO_hash (addr, addrlen, &ubs.h_address);
3524 &ubs,
3525 &bi->bcm.sender_sig);
3526 if (NULL != bi->ba)
3527 {
3530 }
3531 if ((AF_INET6 == addr->sa_family) && (NULL != broadcast_addr))
3532 {
3533 /* Create IPv6 multicast request */
3534 const struct sockaddr_in6 *s6 =
3535 (const struct sockaddr_in6 *) broadcast_addr;
3536
3538 1 == inet_pton (AF_INET6, "FF05::13B", &bi->mcreq.ipv6mr_multiaddr));
3539
3540 /* http://tools.ietf.org/html/rfc2553#section-5.2:
3541 *
3542 * IPV6_JOIN_GROUP
3543 *
3544 * Join a multicast group on a specified local interface. If the
3545 * interface index is specified as 0, the kernel chooses the local
3546 * interface. For example, some kernels look up the multicast
3547 * group in the normal IPv6 routing table and using the resulting
3548 * interface; we do this for each interface, so no need to use
3549 * zero (anymore...).
3550 */
3551 bi->mcreq.ipv6mr_interface = s6->sin6_scope_id;
3552
3553 /* Join the multicast group */
3555 IPPROTO_IPV6,
3556 IPV6_JOIN_GROUP,
3557 &bi->mcreq,
3558 sizeof(bi->mcreq)))
3559 {
3561 }
3562 }
3563 return GNUNET_OK;
3564}
3565
3566
3572static void
3573do_broadcast (void *cls)
3574{
3575 struct BroadcastInterface *bin;
3576
3577 (void) cls;
3578 for (struct BroadcastInterface *bi = bi_head; NULL != bi; bi = bi->next)
3579 bi->found = GNUNET_NO;
3581 for (struct BroadcastInterface *bi = bi_head; NULL != bi; bi = bin)
3582 {
3583 bin = bi->next;
3584 if (GNUNET_NO == bi->found)
3585 bi_destroy (bi);
3586 }
3588 &do_broadcast,
3589 NULL);
3590}
3591
3592
3593static void
3594try_connection_reversal (void *cls,
3595 const struct sockaddr *addr,
3596 socklen_t addrlen)
3597{
3598 /* FIXME: support reversal: #5529 */
3600 "No connection reversal implemented!\n");
3601}
3602
3603
3604static void
3605udp_socket_notify (struct GNUNET_UdpSocketInfo *sock_info)
3606{
3608 sizeof (*sock_info->actual_address
3609 ));
3610 create_receiver (sock_info->pid,
3611 address,
3612 default_v4_sock == sock_info->udp_sock ||
3613 default_v6_sock == sock_info->udp_sock ?
3614 NULL : sock_info->udp_sock);
3616 GNUNET_free (sock_info);
3617}
3618
3619
3620static void
3621start_burst (const char *addr,
3622 struct GNUNET_TIME_Relative rtt,
3623 struct GNUNET_PeerIdentity *pid)
3624{
3625 struct GNUNET_UdpSocketInfo *sock_info;
3626
3628 "Communicator was called to start burst to address %s from %s\n",
3629 addr,
3630 my_ipv4);
3631
3632 GNUNET_stop_burst (NULL);
3633
3634 sock_info = GNUNET_new (struct GNUNET_UdpSocketInfo);
3635 sock_info->pid = GNUNET_new (struct GNUNET_PeerIdentity);
3636 sock_info->address = GNUNET_strdup (addr);
3637 sock_info->bind_address = my_ipv4;
3638 sock_info->has_port = GNUNET_YES;
3639 sock_info->udp_sock = default_v4_sock;
3640 sock_info->rtt = rtt;
3641 GNUNET_memcpy (sock_info->pid, pid, sizeof (struct GNUNET_PeerIdentity));
3642 sock_info->std_port = my_port;
3644 "1 sock addr %s addr %s rtt %lu %u\n",
3645 sock_info->address,
3646 addr,
3647 (unsigned long) sock_info->rtt.rel_value_us,
3648 my_port);
3649 burst_task = GNUNET_get_udp_socket (sock_info,
3651 GNUNET_free (sock_info);
3652}
3653
3654
3655static struct GNUNET_NETWORK_Handle*
3656create_udp_socket (const char *bindto,
3657 sa_family_t family,
3658 struct sockaddr **out,
3659 socklen_t *out_len)
3660{
3661 struct GNUNET_NETWORK_Handle *sock;
3662 struct sockaddr *in;
3663 socklen_t in_len;
3664 struct sockaddr_storage in_sto;
3665 socklen_t sto_len;
3666
3667 in = udp_address_to_sockaddr (bindto, family, &in_len);
3668 if (NULL == in)
3669 {
3671 "Failed to setup UDP socket address with path `%s'\n",
3672 bindto);
3673 return NULL;
3674 }
3675
3676 if ((AF_UNSPEC != family) && (in->sa_family != family))
3677 {
3679 "Invalid UDP socket address setup with path `%s'\n",
3680 bindto);
3681 GNUNET_free (in);
3682 return NULL;
3683 }
3684
3685 sock =
3686 GNUNET_NETWORK_socket_create (in->sa_family,
3687 SOCK_DGRAM,
3688 IPPROTO_UDP);
3689 if (NULL == sock)
3690 {
3693 "Failed to create socket for %s family %d\n",
3694 GNUNET_a2s (in,
3695 in_len),
3696 in->sa_family);
3697 GNUNET_free (in);
3698 return NULL;
3699 }
3700 if (GNUNET_OK !=
3702 in,
3703 in_len))
3704 {
3706 "bind",
3707 bindto);
3709 "Failed to bind socket for %s family %d sock %p\n",
3710 GNUNET_a2s (in,
3711 in_len),
3712 in->sa_family,
3713 sock);
3715 sock = NULL;
3716 GNUNET_free (in);
3717 return NULL;
3718 }
3719
3720 /* We might have bound to port 0, allowing the OS to figure it out;
3721 thus, get the real IN-address from the socket */
3722 sto_len = sizeof(in_sto);
3723 if (0 != getsockname (GNUNET_NETWORK_get_fd (sock),
3724 (struct sockaddr *) &in_sto,
3725 &sto_len))
3726 {
3727 memcpy (&in_sto, in, in_len);
3728 sto_len = in_len;
3729 }
3730 GNUNET_free (in);
3731 *out = GNUNET_malloc (sto_len);
3732 memcpy (*out, (struct sockaddr *) &in_sto, sto_len);
3733 *out_len = sto_len;
3734 return sock;
3735}
3736
3737
3738static void
3739shutdown_run (struct sockaddr *addrs[2])
3740{
3741 if (NULL != addrs[0])
3742 GNUNET_free (addrs[0]);
3743 if (NULL != addrs[1])
3744 GNUNET_free (addrs[1]);
3746}
3747
3748
3759static void
3760load_ikm ()
3761{
3762 char *keyfile;
3764
3765 if (GNUNET_OK !=
3767 "PEER",
3768 "PRIVATE_KEY",
3769 &keyfile))
3770 {
3772 "PEER",
3773 "PRIVATE_KEY");
3775 return;
3776 }
3777 if (GNUNET_SYSERR ==
3779 GNUNET_YES,
3780 &key))
3781 {
3783 "Failed to setup peer's private key\n");
3784 GNUNET_free (keyfile);
3786 return;
3787 }
3788 GNUNET_free (keyfile);
3789 GNUNET_assert (sizeof ikm == sizeof key.d);
3790 memcpy (ikm, key.d, sizeof ikm);
3791}
3792
3793
3794void
3795pid_change_cb (void *cls,
3796 const struct GNUNET_HELLO_Parser *parser,
3797 const struct GNUNET_HashCode *addr_hash)
3798{
3800 "Got PID to derive from `%s':\n",
3801 GNUNET_h2s (addr_hash));
3802 if (NULL == my_private_key)
3804
3806 (uint8_t*) ikm,
3807 addr_hash,
3813 /* start broadcasting */
3814 if (GNUNET_YES !=
3817 "DISABLE_BROADCAST"))
3818 {
3819 if (NULL == broadcast_task)
3821 }
3822}
3823
3824
3825static void
3826run (void *cls,
3827 char *const *args,
3828 const char *cfgfile,
3829 const struct GNUNET_CONFIGURATION_Handle *c)
3830{
3831 const struct sockaddr_in *v4;
3832 char *bindto;
3833 char *bindto6;
3834 struct sockaddr *in[2];
3835 socklen_t in_len[2];
3836
3838 "Entering the run method of udp communicator.\n");
3839
3840 cfg = c;
3842 if ((GNUNET_NO == GNUNET_NETWORK_test_pf (PF_INET6)) ||
3843 (GNUNET_YES ==
3846 "DISABLE_V6")))
3847 {
3849 }
3850
3851 if (GNUNET_OK !=
3854 "BINDTO",
3855 &bindto))
3856 {
3859 "BINDTO");
3860 return;
3861 }
3863 "The udp communicator will bind to %s for IPv4\n",
3864 bindto);
3865 if (GNUNET_YES != disable_v6)
3866 {
3867 if (GNUNET_OK !=
3870 "BINDTO6",
3871 &bindto6))
3872 {
3875 "BINDTO6");
3876 return;
3877 }
3878
3880 "The udp communicator will bind to %s for IPv6\n",
3881 bindto6);
3882 }
3883 else
3884 bindto6 = NULL;
3885 if (GNUNET_OK !=
3888 "REKEY_INTERVAL",
3891
3892 if (GNUNET_OK !=
3895 "REKEY_MAX_BYTES",
3897 {
3899 }
3900
3901 memset (in, 0, sizeof(struct sockaddr*) * 2);
3902 memset (in_len, 0, sizeof(socklen_t) * 2);
3903
3904 GNUNET_assert (bindto);
3906 bindto, AF_INET, &(in[0]), &(in_len[0]));
3907 GNUNET_free (bindto);
3908
3909 if (GNUNET_YES != disable_v6)
3910 {
3911 GNUNET_assert (bindto6);
3913 bindto6, AF_INET6, &(in[1]), &(in_len[1]));
3914 GNUNET_free (bindto6);
3915 }
3916 else
3917 default_v6_sock = NULL;
3918
3919 if ((NULL == default_v4_sock) && (NULL == default_v6_sock))
3920 return;
3921
3922 my_port = 0;
3923 if (NULL != default_v4_sock)
3924 {
3925 GNUNET_assert (in[0]);
3927 "transport",
3928 "Bound to `%s' sock %p\n",
3929 GNUNET_a2s ((const struct sockaddr *) in[0],
3930 in_len[0]),
3932
3933 v4 = (const struct sockaddr_in *) in[0];
3934
3935 my_ipv4 = GNUNET_malloc (INET_ADDRSTRLEN);
3936 my_port = ntohs (((struct sockaddr_in *) in[0])->sin_port);
3937 inet_ntop (AF_INET, &v4->sin_addr, my_ipv4, in_len[0]);
3938 }
3939 if (NULL != default_v6_sock)
3940 {
3941 GNUNET_assert (in[1]);
3943 "transport",
3944 "Bound to `%s' sock %p\n",
3945 GNUNET_a2s ((const struct sockaddr *) in[1],
3946 in_len[1]),
3948 my_port = ntohs (((struct sockaddr_in6 *) in[1])->sin6_port);
3949 }
3950 stats = GNUNET_STATISTICS_create ("communicator-udp", cfg);
3959 /* start reading */
3960 if (NULL != default_v4_sock)
3963 &sock_read,
3965 else
3966 read_v4_task = NULL;
3967 if (NULL != default_v6_sock)
3970 &sock_read,
3972 else
3973 read_v6_task = NULL;
3978 &mq_init,
3979 NULL,
3981 NULL,
3982 &start_burst);
3983 if (NULL == ch)
3984 {
3985 GNUNET_break (0);
3986 shutdown_run (in);
3987 return;
3988 }
3990 if (NULL == ah)
3991 {
3992 GNUNET_break (0);
3993 shutdown_run (in);
3994 return;
3995 }
3996 /* start broadcasting */
3997 if (GNUNET_YES !=
4000 "DISABLE_BROADCAST"))
4001 {
4003 }
4004 load_ikm ();
4006 GNUNET_assert (NULL != pils);
4007
4010 IPPROTO_UDP,
4011 (NULL != in[0]? 1 : 0)
4012 + (NULL != in[1]? 1 : 0),
4013 (const struct sockaddr**)
4014 (NULL != in[0]? in : &(in[1])),
4015 NULL != in[0]? in_len : &(in_len[1]),
4018 NULL /* closure */);
4019 if (NULL != in[0])
4020 GNUNET_free (in[0]);
4021 if (NULL != in[1])
4022 GNUNET_free (in[1]);
4023}
4024
4025
4026GNUNET_DAEMON_MAIN ("gnunet-communicator-udp",
4027 _ ("GNUnet UDP communicator"),
4028 &run)
4029/* end of gnunet-communicator-udp.c */
struct GNUNET_MessageHeader * msg
Definition 005.c:2
static int start
Set if we are to start default services (including ARM).
Definition gnunet-arm.c:38
static int ret
Final status code.
Definition gnunet-arm.c:93
static int do_shutdown
Set to GNUNET_YES if we are shutting down.
static uint16_t port
Port number.
Definition gnunet-bcd.c:146
static struct GNUNET_NETWORK_Handle * udp_sock
Our socket.
static void inject_rekey(struct Queue *queue)
Inject a struct TCPRekey message into the queue's plaintext buffer.
#define AES_KEY_SIZE
AES key size.
void pid_change_cb(void *cls, const struct GNUNET_HELLO_Parser *parser, const struct GNUNET_HashCode *addr_hash)
static struct BroadcastInterface * bi_tail
Broadcast interface tasks.
#define DEFAULT_REKEY_TIME_INTERVAL
How often do we rekey based on time (at least)
static int try_decrypt(const struct SharedSecret *ss, const uint8_t *tag, uint32_t serial, const char *in_buf, size_t in_buf_size, char *out_buf)
Try to decrypt buf using shared secret ss and key/iv derived using serial.
#define WORKING_QUEUE_INTERVALL
static void kce_destroy(struct KeyCacheEntry *kce)
Free memory used by key cache entry.
static int handle_ack(void *cls, const struct GNUNET_HashCode *key, void *value)
We received an ACK for pid.
static void create_rekey(struct ReceiverAddress *receiver, struct SharedSecret *ss, struct UDPRekey *rekey)
static void mq_destroy_d(struct GNUNET_MQ_Handle *mq, void *impl_state)
Signature of functions implementing the destruction of a message queue.
static int secret_destroy(struct SharedSecret *ss)
Destroy ss and associated key cache entries.
#define GCM_TAG_SIZE
Size of the GCM tag.
static void get_iv_key(const struct GNUNET_ShortHashCode *msec, uint32_t serial, char key[(256/8)], char iv[(96/8)])
Compute key and iv.
static struct GNUNET_PeerIdentity my_identity
Our public key.
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 struct SharedSecret * setup_initial_shared_secret_ephemeral(struct GNUNET_CRYPTO_HpkeEncapsulation *c, struct ReceiverAddress *receiver)
Setup new shared secret for encryption using KEM for initial handshake.
#define COMMUNICATOR_ADDRESS_PREFIX
Address prefix used by the communicator.
static unsigned char ikm[256/8]
The initial key material for the peer.
static void kce_generate(struct SharedSecret *ss, uint32_t seq)
Setup key cache entry for sequence number seq and shared secret ss.
static void setup_cipher(const struct GNUNET_ShortHashCode *msec, uint32_t serial, gcry_cipher_hd_t *cipher)
Setup cipher based on shared secret msec and serial number serial.
static struct GNUNET_NETWORK_Handle * create_udp_socket(const char *bindto, sa_family_t family, struct sockaddr **out, socklen_t *out_len)
static void add_acks(struct SharedSecret *ss, int acks_to_add)
#define ADDRESS_VALIDITY_PERIOD
How long do we believe our addresses to remain up (before the other peer should revalidate).
static struct GNUNET_SCHEDULER_Task * read_v6_task
ID of read IPv6 task.
static struct GNUNET_SCHEDULER_Task * read_v4_task
ID of read IPv4 task.
static void mq_destroy_kx(struct GNUNET_MQ_Handle *mq, void *impl_state)
Signature of functions implementing the destruction of a message queue.
static int get_receiver_delete_it(void *cls, const struct GNUNET_HashCode *target, void *value)
Iterator over all receivers to clean up.
static void try_connection_reversal(void *cls, const struct sockaddr *addr, socklen_t addrlen)
static struct GNUNET_SCHEDULER_Task * broadcast_task
ID of master broadcast task.
static struct GNUNET_NT_InterfaceScanner * is
Network scanner to determine network types.
static int verify_confirmation(const struct GNUNET_CRYPTO_HpkeEncapsulation *enc, const struct UDPConfirmation *uc)
Check signature from uc against ephemeral.
static int disable_v6
IPv6 disabled or not.
static struct GNUNET_STATISTICS_Handle * stats
For logging statistics.
static const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
static struct GNUNET_NETWORK_Handle * default_v4_sock
Our IPv4 socket.
static void enc_notify_cb(void *cls, const struct GNUNET_PeerIdentity *sender, const struct GNUNET_MessageHeader *msg)
Function called when the transport service has received a backchannel message for this communicator (...
static struct SenderAddress * setup_sender(const struct GNUNET_PeerIdentity *target, const struct sockaddr *address, socklen_t address_len)
Create sender address for target.
static struct GNUNET_TIME_Relative rekey_interval
The rekey interval.
static void start_burst(const char *addr, struct GNUNET_TIME_Relative rtt, struct GNUNET_PeerIdentity *pid)
static void reschedule_receiver_timeout(struct ReceiverAddress *receiver)
Increment receiver timeout due to activity.
static struct SharedSecret * setup_shared_secret_ephemeral(struct GNUNET_CRYPTO_HpkeEncapsulation *ephemeral, struct ReceiverAddress *receiver)
Setup new shared secret for encryption using KEM.
static void get_kid(const struct GNUNET_ShortHashCode *msec, uint32_t serial, struct GNUNET_ShortHashCode *kid)
Compute kid.
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 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 sock_read(void *cls)
Socket read task.
static void reschedule_sender_timeout(struct SenderAddress *sender)
Increment sender timeout due to activity.
static struct GNUNET_CONTAINER_Heap * senders_heap
Expiration heap for senders (contains struct SenderAddress)
static int get_sender_delete_it(void *cls, const struct GNUNET_HashCode *target, void *value)
Iterator over all senders to clean up.
#define COMMUNICATOR_CONFIG_SECTION
Configuration section used by the communicator.
static void nat_address_cb(void *cls, void **app_ctx, int add_remove, enum GNUNET_NAT_AddressClass ac, const struct sockaddr *addr, socklen_t addrlen)
Signature of the callback passed to GNUNET_NAT_register() for a function to call whenever our set of ...
static struct GNUNET_TRANSPORT_CommunicatorHandle * ch
Our environment.
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 struct SharedSecret * setup_initial_shared_secret_dec(const struct GNUNET_CRYPTO_HpkeEncapsulation *c)
Setup shared secret for decryption for initial handshake.
static void setup_receiver_mq(struct ReceiverAddress *receiver)
Setup the MQ for the receiver.
static int handle_ack_by_sender(void *cls, const struct GNUNET_HashCode *key, void *value)
static void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c)
#define DEFAULT_REKEY_MAX_BYTES
Default value for how often we do rekey based on number of bytes transmitted? (additionally randomize...
static struct GNUNET_CRYPTO_HpkePrivateKey my_x25519_private_key
Our private key for HPKE.
static struct GNUNET_NAT_Handle * nat
Connection to NAT service.
static void shutdown_run(struct sockaddr *addrs[2])
static struct GNUNET_CONTAINER_MultiHashMap * receivers
Receivers (map from peer identity to struct ReceiverAddress)
#define GENERATE_AT_ONCE
static void kce_generate_cb(void *cls)
static void load_ikm()
Get the initial secret key for generating the peer id.
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 void receiver_destroy(struct ReceiverAddress *receiver)
Destroys a receiving state due to timeout or shutdown.
static struct GNUNET_CONTAINER_MultiShortmap * key_cache
Cache of pre-generated key IDs.
static void udp_socket_notify(struct GNUNET_UdpSocketInfo *sock_info)
#define KCN_TARGET
How many KCNs do we keep around after we hit the KCN_THRESHOLD? Should be larger than KCN_THRESHOLD s...
static void mq_cancel(struct GNUNET_MQ_Handle *mq, void *impl_state)
Implementation function that cancels the currently sent message.
static struct GNUNET_TRANSPORT_ApplicationHandle * ah
Our handle to report addresses for validation to TRANSPORT.
static void eddsa_pub_to_hpke_key(struct GNUNET_CRYPTO_EddsaPublicKey *edpk, struct GNUNET_CRYPTO_HpkePublicKey *pk)
static void bi_destroy(struct BroadcastInterface *bi)
An interface went away, stop broadcasting on it.
static void pass_plaintext_to_core(struct SenderAddress *sender, const void *plaintext, size_t plaintext_len)
We received plaintext_len bytes of plaintext from a sender.
static struct GNUNET_CONTAINER_MultiHashMap * senders
Senders (map from peer identity to struct SenderAddress)
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...
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 struct sockaddr * udp_address_to_sockaddr(const char *bindto, sa_family_t family, socklen_t *sock_len)
Convert UDP bind specification to a struct sockaddr *
static struct GNUNET_CONTAINER_Heap * receivers_heap
Expiration heap for receivers (contains struct ReceiverAddress)
static uint16_t my_port
Port number to which we are actually bound.
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 eddsa_priv_to_hpke_key(struct GNUNET_CRYPTO_EddsaPrivateKey *edpk, struct GNUNET_CRYPTO_HpkePrivateKey *pk)
static void check_timeouts(void *cls)
Task run to check #receiver_heap and #sender_heap for timeouts.
static void calculate_cmac(struct SharedSecret *ss)
Calculate cmac from master in ss.
static struct GNUNET_SCHEDULER_Task * timeout_task
ID of timeout task.
char * my_ipv4
Our ipv4 address.
static struct GNUNET_SCHEDULER_Task * burst_task
static struct SharedSecret * setup_shared_secret_dec(const struct GNUNET_CRYPTO_HpkeEncapsulation *ephemeral)
Setup shared secret for decryption.
#define MAX_SQN_DELTA
What is the maximum delta between KCN sequence numbers that we allow.
#define LOG(kind,...)
static struct GNUNET_CRYPTO_EddsaPrivateKey * my_private_key
Our private key.
#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...
static struct BroadcastInterface * bi_head
Broadcast interface tasks.
static enum GNUNET_GenericReturnValue create_receiver(const struct GNUNET_PeerIdentity *peer, const char *address, struct GNUNET_NETWORK_Handle *udp_sock)
static struct GNUNET_NETWORK_Handle * get_socket(struct ReceiverAddress *receiver)
static void send_msg_with_kx(const struct GNUNET_MessageHeader *msg, struct ReceiverAddress *receiver, struct GNUNET_MQ_Handle *mq)
static struct GNUNET_NETWORK_Handle * default_v6_sock
Our IPv6 socket.
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...
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.
static void ifc_broadcast(void *cls)
Broadcast our presence on one of our interfaces.
static struct GNUNET_PILS_Handle * pils
For PILS.
static void decrypt_box(const struct UDPBox *box, size_t box_len, struct KeyCacheEntry *kce)
We received a box with matching kce.
static unsigned int purge_secrets(struct SharedSecret *ss_list_tail)
Best effort try to purge some secrets.
static void consider_ss_ack(struct SharedSecret *ss)
We established a shared secret with a sender.
static unsigned long long rekey_max_bytes
How often we do rekey based on number of bytes transmitted.
#define AES_IV_SIZE
AES (GCM) IV size.
#define BROADCAST_FREQUENCY
How often do we broadcast our presence on the LAN?
static struct GNUNET_TRANSPORT_AddressIdentifier * ai
Handle to the operation that publishes our address.
static struct GNUNET_SCHEDULER_Task * st
The shutdown task.
static char * address
GNS address for this phone.
struct GNUNET_HashCode key
The key used in the DHT.
static OpusEncoder * enc
OPUS encoder.
static struct in_addr dummy
Target "dummy" address of the packet we pretend to respond to.
struct GNUNET_CRYPTO_BlindablePrivateKey pk
Private key from command line option, or NULL.
static char * name
Name (label) of the records to list.
static char * value
Value of the record to add/remove.
static uint32_t type
Type string converted to DNS type value.
static struct GNUNET_NAT_AUTO_Test * nt
Handle to a NAT test operation.
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
static struct GNUNET_FS_UnindexContext * uc
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
void GNUNET_PILS_disconnect(struct GNUNET_PILS_Handle *handle)
Disconnect from the PILS service.
Definition pils_api.c:390
void GNUNET_PILS_derive_pid(size_t seed_key_bytes, const uint8_t seed_key[seed_key_bytes], const struct GNUNET_HashCode *addrs_hash, struct GNUNET_CRYPTO_EddsaPrivateKey *outkey)
Generate the peer id from the addresses hash and the initial secret key.
Definition pils_api.c:507
#define GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_BROADCAST
Signature used by UDP broadcasts.
#define GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_HANDSHAKE
Signature used by UDP communicator handshake.
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.
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.
void GNUNET_TRANSPORT_communicator_burst_finished(struct GNUNET_TRANSPORT_CommunicatorHandle *ch)
The communicator tells the transport service that it finished the burst.
void GNUNET_TRANSPORT_communicator_mq_del(struct GNUNET_TRANSPORT_QueueHandle *qh)
Notify transport service that an MQ became unavailable due to a disconnect or timeout.
void GNUNET_TRANSPORT_application_done(struct GNUNET_TRANSPORT_ApplicationHandle *ch)
Shutdown TRANSPORT application client.
#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...
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_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.
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...
void GNUNET_TRANSPORT_communicator_disconnect(struct GNUNET_TRANSPORT_CommunicatorHandle *ch)
Disconnect from the transport service.
struct GNUNET_TRANSPORT_ApplicationHandle * GNUNET_TRANSPORT_application_init(const struct GNUNET_CONFIGURATION_Handle *cfg)
Initialize the TRANSPORT application client handle.
struct GNUNET_TRANSPORT_CommunicatorHandle * GNUNET_TRANSPORT_communicator_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *config_section_name, const char *addr_prefix, enum GNUNET_TRANSPORT_CommunicatorCharacteristics cc, GNUNET_TRANSPORT_CommunicatorMqInit mq_init, void *mq_init_cls, GNUNET_TRANSPORT_CommunicatorNotify notify_cb, void *notify_cb_cls, GNUNET_TRANSPORT_StartBurstNotify sb)
Connect to the transport service.
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.
@ GNUNET_TRANSPORT_CC_UNRELIABLE
Transmission is unreliable (e.g.
@ GNUNET_TRANSPORT_CS_OUTBOUND
this is an outbound connection (transport initiated)
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_filename(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be the name of a file or directory.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_size(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *size)
Get a configuration value that should be a size in bytes.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_yesno(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Get a configuration value that should be in a set of "YES" or "NO".
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_time(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, struct GNUNET_TIME_Relative *time)
Get a configuration value that should be a relative time.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
#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?
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_kem_decaps(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, const struct GNUNET_CRYPTO_HpkeEncapsulation *c, struct GNUNET_ShortHashCode *prk)
Decapsulate a key for a private EdDSA key.
uint64_t GNUNET_CRYPTO_random_u64(enum GNUNET_CRYPTO_Quality mode, uint64_t max)
Generate a random unsigned 64-bit value.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hpke_elligator_kem_encaps(const struct GNUNET_CRYPTO_HpkePublicKey *pkR, struct GNUNET_CRYPTO_HpkeEncapsulation *c, struct GNUNET_ShortHashCode *shared_secret)
Carries out ecdh encapsulation with given public key and the private key from a freshly created ephem...
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_key_from_file(const char *filename, int do_create, struct GNUNET_CRYPTO_EddsaPrivateKey *pkey)
Create a new private key by reading it from a file.
void GNUNET_CRYPTO_random_block(enum GNUNET_CRYPTO_Quality mode, void *buffer, size_t length)
Fill block with a random values.
void GNUNET_CRYPTO_eddsa_key_get_public(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Extract the public key for the given private key.
Definition crypto_ecc.c:201
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hpke_elligator_kem_decaps(const struct GNUNET_CRYPTO_HpkePrivateKey *skR, const struct GNUNET_CRYPTO_HpkeEncapsulation *c, struct GNUNET_ShortHashCode *shared_secret)
Carries out ecdh decapsulation with own private key and the representative of the received public key...
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_kem_encaps(const struct GNUNET_CRYPTO_EddsaPublicKey *pub, struct GNUNET_CRYPTO_HpkeEncapsulation *c, struct GNUNET_ShortHashCode *prk)
Encapsulate key material for a EdDSA public key.
#define GNUNET_CRYPTO_eddsa_sign(priv, ps, sig)
EdDSA sign a given block.
#define GNUNET_CRYPTO_eddsa_verify(purp, ps, sig, pub)
Verify EdDSA signature.
@ GNUNET_CRYPTO_QUALITY_WEAK
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hkdf_extract(struct GNUNET_ShortHashCode *prk, const void *salt, size_t salt_len, const void *ikm, size_t ikm_len)
HKDF-Extract using SHA256.
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
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hkdf_expand(void *result, size_t out_len, const struct GNUNET_ShortHashCode *prk,...)
HKDF-Expand using SHA256.
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MultiHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_remove(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, const void *value)
Remove the given key-value pair from the map.
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).
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.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
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.
unsigned int GNUNET_CONTAINER_multihashmap_size(const struct GNUNET_CONTAINER_MultiHashMap *map)
Get the number of key-value pairs in the map.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
void GNUNET_CONTAINER_multishortmap_destroy(struct GNUNET_CONTAINER_MultiShortmap *map)
Destroy a hash map.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_get_multiple(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, GNUNET_CONTAINER_MultiHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map that match a particular key.
unsigned int GNUNET_CONTAINER_multishortmap_size(const struct GNUNET_CONTAINER_MultiShortmap *map)
Get the number of key-value pairs in the map.
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.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE
Allow multiple values with the same key.
void * GNUNET_CONTAINER_heap_remove_node(struct GNUNET_CONTAINER_HeapNode *node)
Removes a node from the heap.
void * GNUNET_CONTAINER_heap_peek(const struct GNUNET_CONTAINER_Heap *heap)
Get element stored at the root of heap.
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_CONTAINER_HeapNode * GNUNET_CONTAINER_heap_insert(struct GNUNET_CONTAINER_Heap *heap, void *element, GNUNET_CONTAINER_HeapCostType cost)
Inserts a new element into the heap.
struct GNUNET_CONTAINER_Heap * GNUNET_CONTAINER_heap_create(enum GNUNET_CONTAINER_HeapOrder order)
Create a new heap.
void GNUNET_CONTAINER_heap_destroy(struct GNUNET_CONTAINER_Heap *heap)
Destroys the heap.
@ GNUNET_CONTAINER_HEAP_ORDER_MIN
Heap with the minimum cost at the root.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
#define GNUNET_log(kind,...)
void GNUNET_CRYPTO_hash_context_read(struct GNUNET_HashContext *hc, const void *buf, size_t size)
Add data to be hashed.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hpke_sk_to_x25519(const struct GNUNET_CRYPTO_BlindablePrivateKey *sk, struct GNUNET_CRYPTO_HpkePrivateKey *sk_enc)
Convert a GNUnet identity key to a key sutiable for HPKE (X25519)
#define GNUNET_NETWORK_STRUCT_END
Define as empty, GNUNET_PACKED should suffice, but this won't work on W32;.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
void GNUNET_CRYPTO_hash_context_finish(struct GNUNET_HashContext *hc, struct GNUNET_HashCode *r_hash)
Finish the hash computation.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
GNUNET_GenericReturnValue
Named constants for return values.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hpke_pk_to_x25519(const struct GNUNET_CRYPTO_BlindablePublicKey *pk, struct GNUNET_CRYPTO_HpkePublicKey *pk_enc)
Convert a GNUnet identity key to a key sutiable for HPKE (X25519)
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
struct GNUNET_HashContext * GNUNET_CRYPTO_hash_context_start(void)
Start incremental hashing operation.
#define GNUNET_PACKED
gcc-ism to get packed structs.
@ GNUNET_PUBLIC_KEY_TYPE_EDDSA
EDDSA identity.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
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.
const char * GNUNET_sh2s(const struct GNUNET_ShortHashCode *shc)
Convert a short hash value to a string (for printing debug messages).
const char * GNUNET_i2s_full(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
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).
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
#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...
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...
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
@ GNUNET_ERROR_TYPE_INFO
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
#define GNUNET_memdup(buf, size)
Allocate and initialize a block of memory.
GNUNET_MQ_Error
Error codes for the queue.
struct GNUNET_MQ_Handle * GNUNET_MQ_queue_for_callbacks(GNUNET_MQ_SendImpl send, GNUNET_MQ_DestroyImpl destroy, GNUNET_MQ_CancelImpl cancel, void *impl_state, const struct GNUNET_MQ_MessageHandler *handlers, GNUNET_MQ_ErrorHandler error_handler, void *cls)
Create a message queue for the specified handlers.
Definition mq.c:482
void GNUNET_MQ_impl_send_continue(struct GNUNET_MQ_Handle *mq)
Call the send implementation for the next queued message, if any.
Definition mq.c:437
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition mq.c:700
struct GNUNET_SCHEDULER_Task * GNUNET_get_udp_socket(struct GNUNET_UdpSocketInfo *sock_info, GNUNET_NotifyUdpSocket nus)
Method to get a UDP socket for a peer that is natted.
Definition nat.c:509
struct GNUNET_NAT_Handle * GNUNET_NAT_register(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *config_section, uint8_t proto, unsigned int num_addrs, const struct sockaddr **addrs, const socklen_t *addrlens, GNUNET_NAT_AddressCallback address_callback, GNUNET_NAT_ReversalCallback reversal_callback, void *callback_cls)
Attempt to enable port redirection and detect public IP address contacting UPnP or NAT-PMP routers on...
Definition nat_api.c:366
void GNUNET_NAT_unregister(struct GNUNET_NAT_Handle *nh)
Stop port redirection and public IP address detection for the given handle.
Definition nat_api.c:703
void GNUNET_stop_burst(struct GNUNET_NETWORK_Handle *do_not_touch)
Method to stop all sockets we established to the other peer.
Definition nat.c:564
GNUNET_NAT_AddressClass
Some addresses contain sensitive information or are not suitable for global distribution.
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition network.c:508
int GNUNET_NETWORK_get_fd(const struct GNUNET_NETWORK_Handle *desc)
Return file descriptor for this network handle.
Definition network.c:1001
ssize_t GNUNET_NETWORK_socket_recvfrom(const struct GNUNET_NETWORK_Handle *desc, void *buffer, size_t length, struct sockaddr *src_addr, socklen_t *addrlen)
Read data from a socket (always non-blocking).
Definition network.c:688
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition network.c:833
enum GNUNET_GenericReturnValue GNUNET_NETWORK_test_pf(int pf)
Test if the given protocol family is supported by this system.
Definition network.c:79
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_bind(struct GNUNET_NETWORK_Handle *desc, const struct sockaddr *address, socklen_t address_len)
Bind a socket to a particular address.
Definition network.c:439
int GNUNET_NETWORK_socket_setsockopt(struct GNUNET_NETWORK_Handle *fd, int level, int option_name, const void *option_value, socklen_t option_len)
Set socket option.
Definition network.c:806
ssize_t GNUNET_NETWORK_socket_sendto(const struct GNUNET_NETWORK_Handle *desc, const void *message, size_t length, const struct sockaddr *dest_addr, socklen_t dest_len)
Send data to a particular destination (always non-blocking).
Definition network.c:772
GNUNET_NetworkType
Types of networks (with separate quotas) we support.
void GNUNET_NT_scanner_done(struct GNUNET_NT_InterfaceScanner *is)
Terminate interface scanner.
Definition nt.c:428
struct GNUNET_NT_InterfaceScanner * GNUNET_NT_scanner_init(void)
Initialize the address characterization client handle.
Definition nt.c:407
enum GNUNET_NetworkType GNUNET_NT_scanner_get_type(struct GNUNET_NT_InterfaceScanner *is, const struct sockaddr *addr, socklen_t addrlen)
Returns where the address is located: loopback, LAN or WAN.
Definition nt.c:309
@ GNUNET_NT_LOOPBACK
Loopback (same host).
void GNUNET_OS_network_interfaces_list(GNUNET_OS_NetworkInterfaceProcessor proc, void *proc_cls)
Enumerate all network interfaces.
Definition os_network.c:397
#define GNUNET_DAEMON_MAIN(daemon_name, daemon_help, init_cb)
#define GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_REKEY
UDP Rekey.
#define GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_PAD
UDP communicator padding.
#define GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK
UDP KX acknowledgement.
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition scheduler.c:567
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:1511
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:1339
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition scheduler.c:980
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:1304
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:1277
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
void GNUNET_STATISTICS_set(struct GNUNET_STATISTICS_Handle *handle, const char *name, uint64_t value, int make_persistent)
Set statistic value for the peer.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
struct GNUNET_TIME_Relative GNUNET_TIME_relative_min(struct GNUNET_TIME_Relative t1, struct GNUNET_TIME_Relative t2)
Return the minimum of two relative time values.
Definition time.c:344
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition time.c:406
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition time.c:316
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get_monotonic(const struct GNUNET_CONFIGURATION_Handle *cfg)
Obtain the current time and make sure it is monotonically increasing.
Definition time.c:860
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition time.c:636
#define _(String)
GNU gettext support macro.
Definition platform.h:179
static struct GNUNET_MQ_Handle * mq
Our connection to the resolver service, created on-demand, but then persists until error or shutdown.
void receiver(void *cls, const void *buf, size_t available, const struct sockaddr *addr, socklen_t addrlen, int errCode)
Callback to read from the SOCKS5 proxy.
Definition socks.c:330
const struct UDPAck * ack
const struct GNUNET_PeerIdentity * sender
Interface we broadcast our presence on.
socklen_t salen
Number of bytes in sa.
struct ipv6_mreq mcreq
If this is an IPv6 interface, this is the request we use to join/leave the group.
struct BroadcastInterface * next
Kept in a DLL.
int found
Was this interface found in the last iface_proc() scan?
struct UDPBroadcast bcm
Message we broadcast on this interface.
struct sockaddr * ba
Broadcast address to use on the interface.
struct GNUNET_SCHEDULER_Task * broadcast_task
Task for this broadcast interface.
struct BroadcastInterface * prev
Kept in a DLL.
struct sockaddr * sa
Sender's address of the interface.
Message send during burst mode.
struct GNUNET_PeerIdentity peer
The peer who send the msg.
unsigned int local_port
The local port the message was send from.
Handle to a node in a heap.
Internal representation of the hash map.
Internal representation of the hash map.
A private key for an identity as per LSD0001.
An identity key as per LSD0001.
Private ECC key encoded for transmission.
Public ECC key (always for curve Ed25519) encoded in a format suitable for network transmission and E...
an ECC signature using EdDSA.
HPKE DHKEM encapsulation (X25519) See RFC 9180.
A public key used for decryption.
A public key used for encryption.
header of what an ECC signature signs this must be followed by "size - 8" bytes of the actual signed ...
uint32_t purpose
What does this signature vouch for? This must contain a GNUNET_SIGNATURE_PURPOSE_XXX constant (from g...
Context for parsing HELLOs.
Definition hello-uri.c:232
A 512-bit hashcode.
Handle to a message queue.
Definition mq.c:87
Header for all communications.
Handle for active NAT registrations.
Definition nat_api.c:72
handle to a socket
Definition network.c:53
Handle to the interface scanner.
Definition nt.c:104
A handle for the PILS service.
Definition pils_api.c:82
The identity of the host (wraps the signing key of the peer).
struct GNUNET_CRYPTO_EddsaPublicKey public_key
Entry in list of pending tasks.
Definition scheduler.c:136
Handle for the service.
A 256-bit hashcode.
Time for absolute time used by GNUnet, in microseconds and in network byte order.
Time for absolute times used by GNUnet, in microseconds.
uint64_t abs_value_us
The actual value.
Time for relative time used by GNUnet, in microseconds.
uint64_t rel_value_us
The actual value.
Internal representation of an address a communicator is currently providing for the transport service...
Handle to the TRANSPORT subsystem for application management.
Opaque handle to the transport service for communicators.
Handle returned to identify the internal data structure the transport API has created to manage a mes...
Standard IPv4 header.
Standard IPv6 header.
UDP packet header.
Struct with the socket we like to use to send messages to another peer.
const char * bind_address
Our address without port.
enum GNUNET_GenericReturnValue has_port
Flag indicating, if the address is without port information.
struct GNUNET_TIME_Relative rtt
The actual RTT between the peers.
char * address
The address of the other peer without port.
unsigned int std_port
Default local port we are bound to.
struct sockaddr * actual_address
The address of the other peer we received a burst message from.
struct GNUNET_NETWORK_Handle * udp_sock
struct GNUNET_PeerIdentity * pid
The peer we like to connect to.
"Plaintext" header at beginning of KX message.
uint8_t gcm_tag[(128/8)]
HMAC for the following encrypted message, using GCM.
struct GNUNET_CRYPTO_HpkeEncapsulation enc
Representative of ephemeral key for KX.
Pre-generated "kid" code (key and IV identification code) to quickly derive master key for a struct U...
struct GNUNET_ShortHashCode kid
Key and IV identification code.
uint32_t sequence_number
Sequence number used to derive this entry from master key.
struct KeyCacheEntry * next
Kept in a DLL.
struct KeyCacheEntry * prev
Kept in a DLL.
struct SharedSecret * ss
Corresponding shared secret.
Information we track per receiving address we have recently been in contact with (encryption to recei...
struct GNUNET_CONTAINER_HeapNode * hn
Entry in sender expiration heap.
struct GNUNET_TIME_Absolute rekey_timeout
Timeout for this receiver address.
struct SharedSecret * ss_tail
Shared secrets we received with target, last used is tail.
char * foreign_addr
Address of the receiver in the human-readable format with the COMMUNICATOR_ADDRESS_PREFIX.
struct GNUNET_SCHEDULER_Task * read_task
Read task, if this receiver has its own socket.
unsigned int acks_available
Number of BOX keys from ACKs we have currently available for this receiver.
struct SharedSecret * ss_head
Shared secrets we received from target, first used is head.
struct GNUNET_TRANSPORT_QueueHandle * kx_qh
handle for KX queue with the ch.
unsigned int num_secrets
Length of the DLL at ss_head.
struct GNUNET_TIME_Absolute timeout
Timeout for this receiver address.
size_t kx_mtu
MTU we allowed transport for this receiver's KX queue.
struct sockaddr * address
Address of the other peer.
struct GNUNET_PeerIdentity target
To whom are we talking to.
socklen_t address_len
Length of the address.
struct GNUNET_MQ_Handle * kx_mq
KX message queue we are providing for the ch.
int receiver_destroy_called
receiver_destroy already called on receiver.
struct GNUNET_NETWORK_Handle * udp_sock
Socket this receiver got via NAT traversal.
size_t d_mtu
MTU we allowed transport for this receiver's default queue.
enum GNUNET_NetworkType nt
Which network type does this queue use?
struct GNUNET_MQ_Handle * d_mq
Default message queue we are providing for the ch.
struct GNUNET_CRYPTO_HpkePublicKey target_hpke_key
To whom are we talking to.
struct GNUNET_TRANSPORT_QueueHandle * d_qh
handle for default queue with the ch.
struct GNUNET_HashCode key
The address key for this entry.
Closure for #find_sender_by_address()
const struct sockaddr * address
Address we are looking for.
struct SenderAddress * sender
Return value to set if we found a match.
socklen_t address_len
Number of bytes in address.
Information we track per sender address we have recently been in contact with (we decrypt messages fr...
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.
socklen_t address_len
Length of the address.
enum GNUNET_NetworkType nt
Which network type does this queue use?
unsigned int acks_available
Number of BOX keys from ACKs we have currently available for this sender.
unsigned int num_secrets
Length of the DLL at ss_head.
int kce_send_ack_on_finish
When KCE finishes, send ACK if GNUNET_YES.
struct GNUNET_TIME_Absolute timeout
Timeout for this sender.
int kce_task_finished
Is the kce_task finished?
struct GNUNET_SCHEDULER_Task * kce_task
ID of kce working queue task.
struct GNUNET_HashCode key
The address key for this entry.
struct SharedSecret * ss_head
Shared secrets we used with target, first used is head.
int sender_destroy_called
sender_destroy already called on sender.
struct SharedSecret * ss_tail
Shared secrets we used with target, last used is tail.
Shared secret we generated for a particular sender or receiver.
struct KeyCacheEntry * kce_tail
Kept in a DLL, sorted by sequence number.
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...
struct SharedSecret * next
Kept in a DLL.
unsigned int active_kce_count
Number of active KCN entries.
uint32_t sequence_used
Up to which sequence number did we use this master already? (for encrypting only)
size_t bytes_sent
Bytes sent with this shared secret.
struct SharedSecret * prev
Kept in a DLL.
struct SenderAddress * sender
Sender we use this shared secret with, or NULL.
struct KeyCacheEntry * kce_head
Kept in a DLL, sorted by sequence number.
struct GNUNET_HashCode cmac
CMAC is used to identify master in ACKs.
struct ReceiverAddress * receiver
Receiver we use this shared secret with, or NULL.
struct GNUNET_ShortHashCode master
Master shared secret.
int override_available_acks
Also precompute keys despite sufficient acks (for rekey)
int rekey_initiated
rekey initiated for this secret?
UDP key acknowledgement.
uint32_t sequence_ack
Sequence acknowledgement limit.
struct GNUNET_HashCode cmac
CMAC of the base key being acknowledged.
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK.
UDP message box.
uint8_t gcm_tag[(128/8)]
128-bit authentication tag for the following encrypted message, from GCM.
struct GNUNET_ShortHashCode kid
Key and IV identification code.
Broadcast by peer in LAN announcing its presence.
struct GNUNET_CRYPTO_EddsaSignature sender_sig
Sender's signature of type GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_BROADCAST.
struct GNUNET_PeerIdentity sender
Sender's peer identity.
Encrypted continuation of UDP initial handshake, followed by message header with payload.
struct GNUNET_PeerIdentity sender
Sender's identity.
struct GNUNET_CRYPTO_EddsaSignature sender_sig
Sender's signature of type GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_HANDSHAKE.
struct GNUNET_TIME_AbsoluteNBO monotonic_time
Monotonic time of sender, to possibly help detect replay attacks (if receiver persists times by sende...
Plaintext of a rekey payload in a UDPBox.
struct GNUNET_CRYPTO_HpkeEncapsulation ephemeral
Ephemeral key to rekey with.
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_REKEY.
Signature we use to verify that the broadcast was really made by the peer that claims to have made it...
struct GNUNET_CRYPTO_SignaturePurpose purpose
Purpose must be GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_BROADCAST.
struct GNUNET_HashCode h_address
Hash of the sender's UDP address.
struct GNUNET_PeerIdentity sender
Identity of the inititor of the UDP broadcast.
Signature we use to verify that the ephemeral key was really chosen by the specified sender.
struct GNUNET_CRYPTO_SignaturePurpose purpose
Purpose must be GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_HANDSHAKE.

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

◆ AES_KEY_SIZE

#define AES_KEY_SIZE   (256 / 8)

AES key size.

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

◆ AES_IV_SIZE

#define AES_IV_SIZE   (96 / 8)

AES (GCM) IV size.

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

◆ GCM_TAG_SIZE

#define GCM_TAG_SIZE   (128 / 8)

Size of the GCM tag.

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

◆ GENERATE_AT_ONCE

#define GENERATE_AT_ONCE   64

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

◆ KCN_THRESHOLD

#define KCN_THRESHOLD   96

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

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

Definition at line 111 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 119 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 130 of file gnunet-communicator-udp.c.

◆ MAX_SECRETS

#define MAX_SECRETS   256

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

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

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

◆ COMMUNICATOR_ADDRESS_PREFIX

#define COMMUNICATOR_ADDRESS_PREFIX   "udp"

Address prefix used by the communicator.

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

◆ COMMUNICATOR_CONFIG_SECTION

#define COMMUNICATOR_CONFIG_SECTION   "communicator-udp"

Configuration section used by the communicator.

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

Function Documentation

◆ eddsa_priv_to_hpke_key()

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

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

909{
911 key.type = htonl (GNUNET_PUBLIC_KEY_TYPE_EDDSA);
912 key.eddsa_key = *edpk;
914 pk);
915}

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

Referenced by pid_change_cb().

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

◆ eddsa_pub_to_hpke_key()

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

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

921{
923 key.type = htonl (GNUNET_PUBLIC_KEY_TYPE_EDDSA);
924 key.eddsa_key = *edpk;
926 pk);
927}

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

Referenced by create_receiver().

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

◆ bi_destroy()

static void bi_destroy ( struct BroadcastInterface bi)
static

An interface went away, stop broadcasting on it.

Parameters
bientity to close down

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

937{
938 if (AF_INET6 == bi->sa->sa_family)
939 {
940 /* Leave the multicast group */
942 IPPROTO_IPV6,
943 IPV6_LEAVE_GROUP,
944 &bi->mcreq,
945 sizeof(bi->mcreq)))
946 {
948 }
949 }
952 GNUNET_free (bi->sa);
953 GNUNET_free (bi->ba);
954 GNUNET_free (bi);
955}

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

Referenced by do_broadcast(), and do_shutdown().

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

◆ secret_destroy()

static int secret_destroy ( struct SharedSecret ss)
static

Destroy ss and associated key cache entries.

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

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

1102{
1103 struct SenderAddress *sender;
1104 struct ReceiverAddress *receiver;
1105 struct KeyCacheEntry *kce;
1106
1108 "secret %s destroy %u\n",
1109 GNUNET_sh2s (&ss->master),
1111 if (NULL != (sender = ss->sender))
1112 {
1113 GNUNET_CONTAINER_DLL_remove (sender->ss_head, sender->ss_tail, ss);
1114 sender->num_secrets--;
1116 "%u sender->num_secrets %u allowed %u used, %u available\n",
1118 sender->acks_available);
1120 if (NULL != ss->sender->kce_task)
1121 {
1123 ss->sender->kce_task = NULL;
1124 }
1125 }
1126 if (NULL != (receiver = ss->receiver))
1127 {
1128 GNUNET_CONTAINER_DLL_remove (receiver->ss_head, receiver->ss_tail, ss);
1129 receiver->num_secrets--;
1130 receiver->acks_available -= (ss->sequence_allowed - ss->sequence_used);
1132 "%u receiver->num_secrets\n",
1133 receiver->num_secrets);
1134 }
1135 while (NULL != (kce = ss->kce_head))
1136 kce_destroy (kce);
1137 GNUNET_STATISTICS_update (stats, "# Secrets active", -1, GNUNET_NO);
1139 "# KIDs active",
1141 GNUNET_NO);
1142 GNUNET_free (ss);
1143 return GNUNET_YES;
1144}

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

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

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

◆ receiver_destroy()

static void receiver_destroy ( struct ReceiverAddress receiver)
static

Destroys a receiving state due to timeout or shutdown.

Parameters
receiverentity to close down

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

968{
969 struct SharedSecret *ss;
970 receiver->receiver_destroy_called = GNUNET_YES;
971
973 "Disconnecting receiver for peer `%s'\n",
974 GNUNET_i2s (&receiver->target));
975 if (NULL != receiver->kx_qh)
976 {
978 receiver->kx_qh = NULL;
979 receiver->kx_mq = NULL;
980 }
981 if (NULL != receiver->d_qh)
982 {
984 receiver->d_qh = NULL;
985 }
986 else if (NULL != receiver->d_mq)
987 {
989 receiver->d_mq = NULL;
990 }
991 if (NULL != receiver->udp_sock)
992 {
995 receiver->udp_sock = NULL;
996 }
999 &receiver->key,
1000 receiver));
1003 "# receivers active",
1005 GNUNET_NO);
1006 while (NULL != (ss = receiver->ss_head))
1007 {
1008 secret_destroy (ss);
1009 }
1010 GNUNET_free (receiver->address);
1011 GNUNET_free (receiver->foreign_addr);
1013}

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

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

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

◆ kce_destroy()

static void kce_destroy ( struct KeyCacheEntry kce)
static

Free memory used by key cache entry.

Parameters
kcethe key cache entry

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

1023{
1024 struct SharedSecret *ss = kce->ss;
1025
1026 ss->active_kce_count--;
1029 &kce->kid,
1030 kce));
1031 GNUNET_free (kce);
1032}

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

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

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

◆ get_kid()

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

Compute kid.

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

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

1046{
1047 uint32_t sid = htonl (serial);
1048 struct GNUNET_ShortHashCode prk;
1050 &sid, sizeof (sid),
1051 msec, sizeof (*msec));
1052
1054 sizeof(*kid),
1055 &prk,
1056 "gnunet-communicator-udp-kid",
1057 strlen ("gnunet-communicator-udp-kid"),
1058 NULL,
1059 0);
1060}

References GNUNET_CRYPTO_hkdf_expand(), and GNUNET_CRYPTO_hkdf_extract().

Referenced by kce_generate(), and mq_send_d().

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

◆ kce_generate()

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

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

Parameters
ssshared secret
seqsequence number for the key cache entry

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

1071{
1072 struct KeyCacheEntry *kce;
1073
1074 GNUNET_assert (0 < seq);
1075 kce = GNUNET_new (struct KeyCacheEntry);
1076 kce->ss = ss;
1077 kce->sequence_number = seq;
1078 get_kid (&ss->master, seq, &kce->kid);
1083 key_cache,
1084 &kce->kid,
1085 kce,
1088 "# KIDs active",
1090 GNUNET_NO);
1091}

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

Referenced by kce_generate_cb().

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

◆ sender_destroy()

static void sender_destroy ( struct SenderAddress sender)
static

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

Parameters
senderentity to close down

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

1155{
1156 struct SharedSecret *ss;
1159 GNUNET_YES ==
1163 "# senders active",
1165 GNUNET_NO);
1166 while (NULL != (ss = sender->ss_head))
1167 {
1168 secret_destroy (ss);
1169 }
1172}

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

Referenced by check_timeouts(), and get_sender_delete_it().

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

◆ get_iv_key()

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

Compute key and iv.

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

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

1188{
1189 uint32_t sid = htonl (serial);
1190
1193 msec,
1194 "gnunet-communicator-udp-key",
1195 strlen ("gnunet-communicator-udp-key"),
1196 &sid, sizeof (sid),
1197 NULL,
1198 0);
1201 msec,
1202 "gnunet-communicator-udp-iv",
1203 strlen ("gnunet-communicator-udp-iv"),
1204 &sid, sizeof (sid),
1205 NULL,
1206 0);
1207}

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

Referenced by setup_cipher().

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

◆ reschedule_sender_timeout()

static void reschedule_sender_timeout ( struct SenderAddress sender)
static

Increment sender timeout due to activity.

Parameters
senderaddress for which the timeout should be rescheduled

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

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

Referenced by setup_sender().

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

◆ reschedule_receiver_timeout()

static void reschedule_receiver_timeout ( struct ReceiverAddress receiver)
static

Increment receiver timeout due to activity.

Parameters
receiveraddress for which the timeout should be rescheduled

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

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

Referenced by mq_send_d(), and send_msg_with_kx().

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

◆ check_timeouts()

static void check_timeouts ( void *  cls)
static

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

Parameters
clsunused, NULL

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

1246{
1247 struct GNUNET_TIME_Relative st;
1248 struct GNUNET_TIME_Relative rt;
1249 struct GNUNET_TIME_Relative delay;
1250 struct ReceiverAddress *receiver;
1251 struct SenderAddress *sender;
1252
1253 (void) cls;
1254 timeout_task = NULL;
1257 {
1259 if (0 != rt.rel_value_us)
1260 break;
1262 "Receiver timed out\n");
1264 }
1266 while (NULL != (sender = GNUNET_CONTAINER_heap_peek (senders_heap)))
1267 {
1268 if (GNUNET_YES != sender->sender_destroy_called)
1269 {
1271 if (0 != st.rel_value_us)
1272 break;
1273 sender_destroy (sender);
1274 }
1275 }
1276 delay = GNUNET_TIME_relative_min (rt, st);
1277 if (delay.rel_value_us < GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
1279}

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

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

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

◆ calculate_cmac()

static void calculate_cmac ( struct SharedSecret ss)
static

Calculate cmac from master in ss.

Parameters
[in,out]ssdata structure to complete

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

1289{
1291 sizeof(ss->cmac),
1292 &ss->master,
1293 "gnunet-communicator-udp-cmac",
1294 strlen ("gnunet-communicator-udp-cmac"),
1295 NULL,
1296 0);
1297}

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

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

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

◆ pass_plaintext_to_core()

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

We received plaintext_len bytes of plaintext from a sender.

Pass it on to CORE.

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

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

1312{
1313 const struct GNUNET_MessageHeader *hdr = plaintext;
1314 const char *pos = plaintext;
1315
1316 while (ntohs (hdr->size) <= plaintext_len)
1317 {
1319 "# bytes given to core",
1320 ntohs (hdr->size),
1321 GNUNET_NO);
1323 "Giving %u bytes to TNG\n", ntohs (hdr->size));
1326 &sender->target,
1327 hdr,
1329 NULL /* no flow control possible */
1330 ,
1331 NULL));
1332 /* move on to next message, if any */
1333 plaintext_len -= ntohs (hdr->size);
1334 if (plaintext_len < sizeof(*hdr))
1335 break;
1336 pos += ntohs (hdr->size);
1337 hdr = (const struct GNUNET_MessageHeader *) pos;
1338 // TODO for now..., we do not actually sen >1msg or have a way of telling
1339 // if we are done
1340 break;
1341 }
1343 "# bytes padding discarded",
1344 plaintext_len,
1345 GNUNET_NO);
1346}

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

Referenced by try_handle_plaintext().

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

◆ setup_cipher()

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

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

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

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

1361{
1362 char key[AES_KEY_SIZE];
1363 char iv[AES_IV_SIZE];
1364 int rc;
1365
1366 GNUNET_assert (0 ==
1367 gcry_cipher_open (cipher,
1368 GCRY_CIPHER_AES256 /* low level: go for speed */
1369 ,
1370 GCRY_CIPHER_MODE_GCM,
1371 0 /* flags */));
1372 get_iv_key (msec, serial, key, iv);
1373 rc = gcry_cipher_setkey (*cipher, key, sizeof(key));
1374 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
1375 rc = gcry_cipher_setiv (*cipher, iv, sizeof(iv));
1376 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
1377}

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

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

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

◆ try_decrypt()

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

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

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

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

1399{
1400 gcry_cipher_hd_t cipher;
1401
1402 setup_cipher (&ss->master, serial, &cipher);
1404 0 ==
1405 gcry_cipher_decrypt (cipher, out_buf, in_buf_size, in_buf, in_buf_size));
1406 if (0 != gcry_cipher_checktag (cipher, tag, GCM_TAG_SIZE))
1407 {
1408 gcry_cipher_close (cipher);
1410 "# AEAD authentication failures",
1411 1,
1412 GNUNET_NO);
1413 return GNUNET_SYSERR;
1414 }
1415 gcry_cipher_close (cipher);
1416 return GNUNET_OK;
1417}

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

Referenced by decrypt_box(), and sock_read().

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

◆ setup_shared_secret_dec()

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

Setup shared secret for decryption.

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

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

1429{
1430 struct SharedSecret *ss;
1431
1432 ss = GNUNET_new (struct SharedSecret);
1434 ephemeral,
1435 &ss->master);
1436 calculate_cmac (ss);
1437 return ss;
1438}

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

Referenced by try_handle_plaintext().

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

◆ setup_initial_shared_secret_dec()

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

Setup shared secret for decryption for initial handshake.

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

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

1450{
1451 struct SharedSecret *ss;
1452
1453 ss = GNUNET_new (struct SharedSecret);
1455 &ss->master);
1457 "New receiver SS master: %s\n", GNUNET_sh2s (&ss->master));
1458 calculate_cmac (ss);
1459 return ss;
1460}

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

Referenced by sock_read().

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

◆ setup_shared_secret_ephemeral()

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

Setup new shared secret for encryption using KEM.

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

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

1474{
1475 struct SharedSecret *ss;
1476
1477 ss = GNUNET_new (struct SharedSecret);
1478 GNUNET_CRYPTO_eddsa_kem_encaps (&receiver->target.public_key,
1479 ephemeral,
1480 &ss->master);
1481 calculate_cmac (ss);
1482 ss->receiver = receiver;
1483 GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss);
1484 receiver->num_secrets++;
1485 GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
1486 return ss;
1487}

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

Referenced by create_rekey().

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

◆ setup_initial_shared_secret_ephemeral()

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

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

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

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

1501{
1502 struct SharedSecret *ss;
1503
1504 ss = GNUNET_new (struct SharedSecret);
1506 c, &ss->master);
1508 "New sender SS master: %s\n", GNUNET_sh2s (&ss->master));
1509 calculate_cmac (ss);
1510 ss->receiver = receiver;
1511 GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss);
1512 receiver->num_secrets++;
1513 GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
1514 return ss;
1515}

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

Referenced by send_msg_with_kx().

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

◆ setup_receiver_mq()

static void setup_receiver_mq ( struct ReceiverAddress receiver)
static

Setup the MQ for the receiver.

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

Parameters
receiverreceiver to setup MQ for

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

3019{
3020 size_t base_mtu;
3021
3022 switch (receiver->address->sa_family)
3023 {
3024 case AF_INET:
3025 base_mtu = 1480 /* Ethernet MTU, 1500 - Ethernet header - VLAN tag */
3026 - sizeof(struct GNUNET_TUN_IPv4Header) /* 20 */
3027 - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */;
3028 break;
3029
3030 case AF_INET6:
3031 base_mtu = 1280 /* Minimum MTU required by IPv6 */
3032 - sizeof(struct GNUNET_TUN_IPv6Header) /* 40 */
3033 - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */;
3034 break;
3035
3036 default:
3037 GNUNET_assert (0);
3038 break;
3039 }
3040 /* MTU based on full KX messages */
3041 receiver->kx_mtu = base_mtu - sizeof(struct InitialKX) /* 48 */
3042 - sizeof(struct UDPConfirmation); /* 104 */
3043 /* MTU based on BOXed messages */
3044 receiver->d_mtu = base_mtu - sizeof(struct UDPBox);
3045
3047 "Setting up MQs and QHs\n");
3048 /* => Effective MTU for CORE will range from 1080 (IPv6 + KX) to
3049 1404 (IPv4 + Box) bytes, depending on circumstances... */
3050 if (NULL == receiver->kx_mq)
3053 &mq_cancel,
3054 receiver,
3055 NULL,
3056 &mq_error,
3057 receiver);
3058 if (NULL == receiver->d_mq)
3060 &mq_destroy_d,
3061 &mq_cancel,
3062 receiver,
3063 NULL,
3064 &mq_error,
3065 receiver);
3066
3067 receiver->kx_qh =
3069 &receiver->target,
3070 receiver->foreign_addr,
3071 receiver->kx_mtu,
3073 0, /* Priority */
3074 receiver->nt,
3076 receiver->kx_mq);
3077}

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

Referenced by create_receiver().

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

◆ purge_secrets()

static unsigned int purge_secrets ( struct SharedSecret ss_list_tail)
static

Best effort try to purge some secrets.

Ideally those, not ACKed.

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

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

1538{
1539 struct SharedSecret *pos;
1540 struct SharedSecret *ss_to_purge;
1541 unsigned int deleted = 0;
1542
1544 "Purging secrets.\n");
1545 pos = ss_list_tail;
1546 while (NULL != pos)
1547 {
1548 ss_to_purge = pos;
1549 pos = pos->prev;
1550
1551 // FIXME we may also want to purge old unacked.
1552 if (rekey_max_bytes <= ss_to_purge->bytes_sent)
1553 {
1554 secret_destroy (ss_to_purge);
1555 deleted++;
1556 }
1557 }
1559 "Finished purging all, deleted %u.\n", deleted);
1560 return deleted;
1561}

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

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

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

◆ add_acks()

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

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

1566{
1567
1568 struct ReceiverAddress *receiver = ss->receiver;
1569
1570 GNUNET_assert (NULL != ss);
1571 GNUNET_assert (NULL != receiver);
1572
1573 if (NULL == receiver->d_qh)
1574 {
1575 receiver->d_qh =
1577 &receiver->target,
1578 receiver->foreign_addr,
1579 receiver->d_mtu,
1580 acks_to_add,
1581 1, /* Priority */
1582 receiver->nt,
1584 receiver->d_mq);
1585 }
1586 else
1587 {
1589 receiver->d_qh,
1590 acks_to_add,
1591 1);
1592 }
1593
1595 "Tell transport we have %u more acks!\n",
1596 acks_to_add);
1597
1598 // Until here for alternative 1
1599
1600 /* move ss to head to avoid discarding it anytime soon! */
1601
1602 // GNUNET_CONTAINER_DLL_remove (receiver->ss_head, receiver->ss_tail, ss);
1603 // GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss);
1604}

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

Referenced by handle_ack().

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

◆ handle_ack()

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

We received an ACK for pid.

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

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

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

1619{
1620 const struct UDPAck *ack = cls;
1621 struct ReceiverAddress *receiver = value;
1622 uint32_t acks_to_add;
1623 uint32_t allowed;
1624
1626 "in handle ack with cmac %s\n",
1627 GNUNET_h2s (&ack->cmac));
1628
1629 (void) key;
1630 for (struct SharedSecret *ss = receiver->ss_head; NULL != ss; ss = ss->next)
1631 {
1632 if (0 == memcmp (&ack->cmac, &ss->cmac, sizeof(struct GNUNET_HashCode)))
1633 {
1634
1636 "Found matching cmac\n");
1637
1638 allowed = ntohl (ack->sequence_ack);
1639
1640 if (allowed <= ss->sequence_allowed)
1641 {
1643 "Ignoring ack, not giving us increased window\n.");
1644 return GNUNET_NO;
1645 }
1646 acks_to_add = (allowed - ss->sequence_allowed);
1647 GNUNET_assert (0 != acks_to_add);
1648 receiver->acks_available += (allowed - ss->sequence_allowed);
1649 ss->sequence_allowed = allowed;
1650 add_acks (ss, acks_to_add);
1652 "New sequence allows until %u (+%u). Acks available to us: %u. For secret %s\n",
1653 allowed,
1654 acks_to_add,
1655 receiver->acks_available,
1656 GNUNET_sh2s (&ss->master));
1657 return GNUNET_NO;
1658 }
1659 }
1661 "Matching cmac not found for ack!\n");
1662 return GNUNET_YES;
1663}

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

Referenced by handle_ack_by_sender(), and try_handle_plaintext().

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

◆ consider_ss_ack()

static void consider_ss_ack ( struct SharedSecret ss)
static

We established a shared secret with a sender.

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

Parameters
ssshared secret to generate ACKs for

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

1676{
1677 struct UDPAck ack;
1678 GNUNET_assert (NULL != ss->sender);
1680 "Considering SS UDPAck %s\n",
1681 GNUNET_i2s_full (&ss->sender->target));
1682
1684 "Sender has %u acks available.\n",
1685 ss->sender->acks_available);
1686 /* drop ancient KeyCacheEntries */
1687 while ((NULL != ss->kce_head) &&
1688 (MAX_SQN_DELTA <
1690 kce_destroy (ss->kce_tail);
1691
1692
1693 ack.header.type = htons (GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK);
1694 ack.header.size = htons (sizeof(ack));
1695 ack.sequence_ack = htonl (ss->sequence_allowed);
1696 ack.cmac = ss->cmac;
1698 "Notifying transport with UDPAck %s, sequence %u and master %s\n",
1700 ss->sequence_allowed,
1701 GNUNET_sh2s (&(ss->master)));
1703 &ss->sender->target,
1705 &ack.header);
1706}

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

Referenced by kce_generate_cb().

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

◆ kce_generate_cb()

static void kce_generate_cb ( void *  cls)
static

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

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

1711{
1712 struct SharedSecret *ss = cls;
1713 ss->sender->kce_task = NULL;
1714
1716 "Precomputing %u keys for master %s\n",
1718 GNUNET_sh2s (&ss->master));
1719 if ((ss->override_available_acks != GNUNET_YES) &&
1720 (KCN_TARGET < ss->sender->acks_available))
1721 return;
1722 for (int i = 0; i < GENERATE_AT_ONCE; i++)
1723 kce_generate (ss, ++ss->sequence_allowed);
1724
1729 if (KCN_TARGET > ss->sender->acks_available)
1730 {
1734 ss);
1735 return;
1736 }
1738 "We have enough keys (ACKs: %u).\n", ss->sender->acks_available);
1742 consider_ss_ack (ss);
1743}

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

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

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

◆ try_handle_plaintext()

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

Test if we have received a valid message in plaintext.

If so, handle it.

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

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

1758{
1759 const struct GNUNET_MessageHeader *hdr;
1760 const struct UDPAck *ack;
1761 const struct UDPRekey *rekey;
1762 struct SharedSecret *ss_rekey;
1763 const char *buf_pos = buf;
1764 size_t bytes_remaining = buf_size;
1765 uint16_t type;
1766
1767 hdr = (struct GNUNET_MessageHeader*) buf_pos;
1768 if (sizeof(*hdr) > bytes_remaining)
1769 {
1770 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Plaintext too short, dropping...\n");
1771 return; /* no data left */
1772 }
1774 "try_handle_plaintext of size %llu (%u %lu) and type %u\n",
1775 (unsigned long long) bytes_remaining,
1776 ntohs (hdr->size),
1777 sizeof(*hdr),
1778 ntohs (hdr->type));
1779 if (ntohs (hdr->size) > bytes_remaining)
1780 return; /* buffer too short for indicated message length */
1781 type = ntohs (hdr->type);
1782 switch (type)
1783 {
1785 rekey = (struct UDPRekey*) buf_pos;
1786 ss_rekey = setup_shared_secret_dec (&rekey->ephemeral);
1787 ss_rekey->sender = sender;
1788 GNUNET_CONTAINER_DLL_insert (sender->ss_head, sender->ss_tail, ss_rekey);
1789 sender->num_secrets++;
1791 "Received rekey secret with cmac %s\n",
1792 GNUNET_h2s (&(ss_rekey->cmac)));
1794 "Received secret with master %s.\n",
1795 GNUNET_sh2s (&(ss_rekey->master)));
1797 "We have %u sequence_allowed.\n",
1798 ss_rekey->sequence_allowed);
1800 "We have a sender %p\n",
1801 ss_rekey->sender);
1803 "We have %u acks available.\n",
1804 ss_rekey->sender->acks_available);
1806 "# rekeying successful",
1807 1,
1808 GNUNET_NO);
1811 // FIXME
1812 kce_generate_cb (ss_rekey);
1813 /* ss_rekey->sender->kce_task = GNUNET_SCHEDULER_add_delayed (
1814 WORKING_QUEUE_INTERVALL,
1815 kce_generate_cb,
1816 ss_rekey);*/
1817 // FIXME: Theoretically, this could be an Ack
1818 buf_pos += ntohs (hdr->size);
1819 bytes_remaining -= ntohs (hdr->size);
1820 pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
1821 if (0 == purge_secrets (sender->ss_tail))
1822 {
1823 // No secret purged. Delete oldest.
1824 if (sender->num_secrets > MAX_SECRETS)
1825 {
1826 secret_destroy (sender->ss_tail);
1827 }
1828 }
1829 break;
1831 /* lookup master secret by 'cmac', then update sequence_max */
1832 ack = (struct UDPAck*) buf_pos;
1834 &sender->key,
1835 &handle_ack,
1836 (void *) ack);
1837 /* There could be more messages after the ACK, handle those as well */
1838 buf_pos += ntohs (hdr->size);
1839 bytes_remaining -= ntohs (hdr->size);
1840 pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
1841 break;
1842
1844 /* skip padding */
1845 break;
1846
1847 default:
1848 pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
1849 }
1850 return;
1851}

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

Referenced by decrypt_box(), and sock_read().

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

◆ decrypt_box()

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

We received a box with matching kce.

Decrypt and process it.

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

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

1865{
1866 struct SharedSecret *ss = kce->ss;
1867 struct SharedSecret *ss_c = ss->sender->ss_tail;
1868 struct SharedSecret *ss_tmp;
1869 int ss_destroyed = 0;
1870 char out_buf[box_len - sizeof(*box)];
1871
1872 GNUNET_assert (NULL != ss->sender);
1873 if (GNUNET_OK != try_decrypt (ss,
1874 box->gcm_tag,
1875 kce->sequence_number,
1876 (const char *) &box[1],
1877 sizeof(out_buf),
1878 out_buf))
1879 {
1880 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed decryption.\n");
1882 "# Decryption failures with valid KCE",
1883 1,
1884 GNUNET_NO);
1885 kce_destroy (kce);
1886 ss->sender->acks_available--;
1887 return;
1888 }
1889 kce_destroy (kce);
1890 kce = NULL;
1891 ss->bytes_sent += box_len;
1892 ss->sender->acks_available--;
1893 ss->sequence_used++;
1895 "# bytes decrypted with BOX",
1896 sizeof(out_buf),
1897 GNUNET_NO);
1899 "# messages decrypted with BOX",
1900 1,
1901 GNUNET_NO);
1903 "decrypted UDPBox with kid %s\n",
1904 GNUNET_sh2s (&box->kid));
1905 try_handle_plaintext (ss->sender, out_buf, sizeof(out_buf));
1906
1907 while (NULL != ss_c)
1908 {
1909 if (ss_c->bytes_sent >= rekey_max_bytes)
1910 {
1912 "Removing SS because rekey bytes reached.\n");
1913 ss_tmp = ss_c->prev;
1914 if (ss == ss_c)
1915 ss_destroyed = 1;
1916 secret_destroy (ss_c);
1917 ss_c = ss_tmp;
1918 continue;
1919 }
1920 ss_c = ss_c->prev;
1921 }
1922 if (1 == ss_destroyed)
1923 return;
1925 "Sender has %u ack left.\n",
1926 ss->sender->acks_available);
1927 if ((KCN_THRESHOLD > ss->sender->acks_available) &&
1928 (NULL == ss->sender->kce_task) &&
1930 {
1932 "Sender has %u ack left which is under threshold.\n",
1933 ss->sender->acks_available);
1937 ss);
1938 }
1939}

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

Referenced by sock_read().

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

◆ setup_sender()

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

Create sender address for target.

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

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

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

1979{
1980 struct SenderAddress *sender;
1981 struct GNUNET_HashContext *hsh;
1982 struct GNUNET_HashCode sender_key;
1983
1985 GNUNET_CRYPTO_hash_context_read (hsh, address, address_len);
1986 GNUNET_CRYPTO_hash_context_read (hsh, target, sizeof(*target));
1987 GNUNET_CRYPTO_hash_context_finish (hsh, &sender_key);
1988
1989 sender = GNUNET_CONTAINER_multihashmap_get (senders, &sender_key);
1990 if (NULL != sender)
1991 {
1993 return sender;
1994 }
1995 sender = GNUNET_new (struct SenderAddress);
1996 sender->key = sender_key;
1997 sender->target = *target;
1998 sender->address = GNUNET_memdup (address, address_len);
1999 sender->address_len = address_len;
2001 senders,
2002 &sender->key,
2003 sender,
2006 "# senders active",
2008 GNUNET_NO);
2009 sender->timeout =
2012 sender,
2013 sender->timeout.abs_value_us);
2014 sender->nt = GNUNET_NT_scanner_get_type (is, address, address_len);
2015 if (NULL == timeout_task)
2017 return sender;
2018}

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

Referenced by sock_read().

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

◆ verify_confirmation()

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

Check signature from uc against ephemeral.

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

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

2031{
2032 struct UdpHandshakeSignature uhs;
2033
2034 uhs.purpose.purpose = htonl (
2036 uhs.purpose.size = htonl (sizeof(uhs));
2037 uhs.sender = uc->sender;
2038 uhs.receiver = my_identity;
2039 uhs.enc = *enc;
2040 uhs.monotonic_time = uc->monotonic_time;
2043 &uhs,
2044 &uc->sender_sig,
2045 &uc->sender.public_key);
2046}

References enc, UdpHandshakeSignature::enc, GNUNET_CRYPTO_eddsa_verify, GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_HANDSHAKE, UdpHandshakeSignature::monotonic_time, my_identity, GNUNET_CRYPTO_SignaturePurpose::purpose, UdpHandshakeSignature::purpose, UdpHandshakeSignature::receiver, UdpHandshakeSignature::sender, GNUNET_CRYPTO_SignaturePurpose::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 2058 of file gnunet-communicator-udp.c.

2060{
2061 char *ret;
2062
2063 switch (address->sa_family)
2064 {
2065 case AF_INET:
2067 "%s-%s",
2069 GNUNET_a2s (address, address_len));
2070 break;
2071
2072 case AF_INET6:
2074 "%s-%s",
2076 GNUNET_a2s (address, address_len));
2077 break;
2078
2079 default:
2080 GNUNET_assert (0);
2081 }
2082 return ret;
2083}

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

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

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

◆ get_socket()

static struct GNUNET_NETWORK_Handle * get_socket ( struct ReceiverAddress receiver)
static

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

2088{
2090
2091 if (NULL == receiver->udp_sock)
2092 {
2093 if (AF_INET6 == receiver->address->sa_family)
2095 else
2097 }
2098 else
2099 udp_sock = receiver->udp_sock;
2100
2101 return udp_sock;
2102}

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

Referenced by mq_send_d(), and send_msg_with_kx().

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

◆ udp_address_to_sockaddr()

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

Convert UDP bind specification to a struct sockaddr *

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

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

2117{
2118 struct sockaddr *in;
2119 unsigned int port;
2120 char dummy[2];
2121 char *colon;
2122 char *cp;
2123
2124 if (1 == sscanf (bindto, "%u%1s", &port, dummy))
2125 {
2126 /* interpreting value as just a PORT number */
2127 if (port > UINT16_MAX)
2128 {
2130 "BINDTO specification `%s' invalid: value too large for port\n",
2131 bindto);
2132 return NULL;
2133 }
2134 if ((AF_INET == family) || (GNUNET_YES == disable_v6))
2135 {
2136 struct sockaddr_in *i4;
2137
2138 i4 = GNUNET_malloc (sizeof(struct sockaddr_in));
2139 i4->sin_family = AF_INET;
2140 i4->sin_port = htons ((uint16_t) port);
2141 *sock_len = sizeof(struct sockaddr_in);
2142 in = (struct sockaddr *) i4;
2143 }
2144 else
2145 {
2146 struct sockaddr_in6 *i6;
2147
2148 i6 = GNUNET_malloc (sizeof(struct sockaddr_in6));
2149 i6->sin6_family = AF_INET6;
2150 i6->sin6_port = htons ((uint16_t) port);
2151 *sock_len = sizeof(struct sockaddr_in6);
2152 in = (struct sockaddr *) i6;
2153 }
2154 return in;
2155 }
2156 cp = GNUNET_strdup (bindto);
2157 colon = strrchr (cp, ':');
2158 if (NULL != colon)
2159 {
2160 /* interpret value after colon as port */
2161 *colon = '\0';
2162 colon++;
2163 if (1 == sscanf (colon, "%u%1s", &port, dummy))
2164 {
2165 /* interpreting value as just a PORT number */
2166 if (port > UINT16_MAX)
2167 {
2169 "BINDTO specification `%s' invalid: value too large for port\n",
2170 bindto);
2171 GNUNET_free (cp);
2172 return NULL;
2173 }
2174 }
2175 else
2176 {
2177 GNUNET_log (
2179 "BINDTO specification `%s' invalid: last ':' not followed by number\n",
2180 bindto);
2181 GNUNET_free (cp);
2182 return NULL;
2183 }
2184 }
2185 else
2186 {
2187 /* interpret missing port as 0, aka pick any free one */
2188 port = 0;
2189 }
2190 if (AF_INET6 != family)
2191 {
2192 /* try IPv4 */
2193 struct sockaddr_in v4;
2194
2195 memset (&v4, 0, sizeof(v4));
2196 if (1 == inet_pton (AF_INET, cp, &v4.sin_addr))
2197 {
2198 v4.sin_family = AF_INET;
2199 v4.sin_port = htons ((uint16_t) port);
2200#if HAVE_SOCKADDR_IN_SIN_LEN
2201 v4.sin_len = sizeof(struct sockaddr_in);
2202#endif
2203 in = GNUNET_memdup (&v4, sizeof(struct sockaddr_in));
2204 *sock_len = sizeof(struct sockaddr_in);
2205 GNUNET_free (cp);
2206 return in;
2207 }
2208 }
2209 if (AF_INET != family)
2210 {
2211 /* try IPv6 */
2212 struct sockaddr_in6 v6;
2213 const char *start;
2214
2215 memset (&v6, 0, sizeof(v6));
2216 start = cp;
2217 if (('[' == *cp) && (']' == cp[strlen (cp) - 1]))
2218 {
2219 start++; /* skip over '[' */
2220 cp[strlen (cp) - 1] = '\0'; /* eat ']' */
2221 }
2222 if (1 == inet_pton (AF_INET6, start, &v6.sin6_addr))
2223 {
2224 v6.sin6_family = AF_INET6;
2225 v6.sin6_port = htons ((uint16_t) port);
2226#if HAVE_SOCKADDR_IN_SIN_LEN
2227 v6.sin6_len = sizeof(struct sockaddr_in6);
2228#endif
2229 in = GNUNET_memdup (&v6, sizeof(v6));
2230 *sock_len = sizeof(v6);
2231 GNUNET_free (cp);
2232 return in;
2233 }
2234 }
2235 /* #5528 FIXME (feature!): maybe also try getnameinfo()? */
2236 GNUNET_free (cp);
2237 return NULL;
2238}

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

Referenced by create_receiver(), and create_udp_socket().

Here is the caller graph for this function:

◆ sock_read()

static void sock_read ( void *  cls)
static

Socket read task.

Parameters
clsNULL

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

2355{
2356 struct sockaddr_storage sa;
2357 struct sockaddr_in *addr_verify;
2358 socklen_t salen = sizeof(sa);
2359 char buf[UINT16_MAX];
2360 ssize_t rcvd;
2361
2362 struct GNUNET_NETWORK_Handle *udp_sock = cls;
2363
2366 udp_sock,
2367 &sock_read,
2368 udp_sock);
2371 udp_sock,
2372 &sock_read,
2373 udp_sock);
2374 while (1)
2375 {
2377 buf,
2378 sizeof(buf),
2379 (struct sockaddr *) &sa,
2380 &salen);
2381 if (-1 == rcvd)
2382 {
2383 struct sockaddr *addr = (struct sockaddr*) &sa;
2384
2385 if (EAGAIN == errno)
2386 break; // We are done reading data
2388 "Failed to recv from %s family %d failed sock %p\n",
2389 GNUNET_a2s ((struct sockaddr*) &sa,
2390 sizeof (*addr)),
2391 addr->sa_family,
2392 udp_sock);
2394 return;
2395 }
2397 "Read %llu bytes\n",
2398 (unsigned long long) rcvd);
2399 if (0 == rcvd)
2400 {
2401 GNUNET_break_op (0);
2403 "Read 0 bytes from UDP socket\n");
2404 return;
2405 }
2406
2407 /* first, see if it is a GNUNET_BurstMessage */
2408 if (rcvd == sizeof (struct GNUNET_BurstMessage))
2409 {
2410 struct GNUNET_BurstMessage *bm = (struct GNUNET_BurstMessage *) buf;
2411 struct sockaddr *addr = (struct sockaddr*) &sa;
2412 char *address = sockaddr_to_udpaddr_string (addr, sizeof (*addr));
2413
2414 GNUNET_assert (0 == bm->local_port);
2416 "Received a burst message for default port\n");
2417 create_receiver (&bm->peer,
2418 address,
2419 NULL);
2420 if (AF_INET6 == addr->sa_family)
2422 else
2426 return;
2427 }
2428 /* second, see if it is a UDPBox */
2429 if (rcvd > sizeof(struct UDPBox))
2430 {
2431 const struct UDPBox *box;
2432 struct KeyCacheEntry *kce;
2433
2434 box = (const struct UDPBox *) buf;
2436 if (NULL != kce)
2437 {
2439 "Found KCE with kid %s\n",
2440 GNUNET_sh2s (&box->kid));
2441 decrypt_box (box, (size_t) rcvd, kce);
2442 continue;
2443 }
2444 }
2445
2446 /* next, check if it is a broadcast */
2447 if (sizeof(struct UDPBroadcast) == rcvd)
2448 {
2449 const struct UDPBroadcast *ub;
2450 struct UdpBroadcastSignature uhs;
2451 struct GNUNET_PeerIdentity sender;
2452
2453 addr_verify = GNUNET_memdup (&sa, salen);
2454 addr_verify->sin_port = 0;
2456 "received UDPBroadcast from %s\n",
2457 GNUNET_a2s ((const struct sockaddr *) addr_verify, salen));
2458 ub = (const struct UDPBroadcast *) buf;
2459 uhs.purpose.purpose = htonl (
2461 uhs.purpose.size = htonl (sizeof(uhs));
2462 uhs.sender = ub->sender;
2463 sender = ub->sender;
2464 if (0 == memcmp (&sender, &my_identity, sizeof (struct
2466 {
2468 "Received our own broadcast\n");
2469 GNUNET_free (addr_verify);
2470 continue;
2471 }
2473 "checking UDPBroadcastSignature for %s\n",
2474 GNUNET_i2s (&sender));
2475 GNUNET_CRYPTO_hash ((struct sockaddr *) addr_verify, salen,
2476 &uhs.h_address);
2477 if (GNUNET_OK ==
2480 &uhs,
2481 &ub->sender_sig,
2482 &ub->sender.public_key))
2483 {
2484 char *addr_s;
2486
2487 addr_s =
2488 sockaddr_to_udpaddr_string ((const struct sockaddr *) &sa, salen);
2489 GNUNET_STATISTICS_update (stats, "# broadcasts received", 1, GNUNET_NO);
2490 /* use our own mechanism to determine network type */
2491 nt =
2492 GNUNET_NT_scanner_get_type (is, (const struct sockaddr *) &sa, salen);
2494 "validating address %s received from UDPBroadcast\n",
2495 GNUNET_i2s (&sender));
2497 GNUNET_free (addr_s);
2498 GNUNET_free (addr_verify);
2499 continue;
2500 }
2501 else
2502 {
2504 "VerifyingPeer %s is verifying UDPBroadcast\n",
2507 "Verifying UDPBroadcast from %s failed\n",
2508 GNUNET_i2s (&ub->sender));
2509 }
2510 GNUNET_free (addr_verify);
2511 /* continue with KX, mostly for statistics... */
2512 }
2513
2514
2515 /* finally, test if it is a KX */
2516 if (rcvd < sizeof(struct UDPConfirmation) + sizeof(struct InitialKX))
2517 {
2519 "# messages dropped (no kid, too small for KX)",
2520 1,
2521 GNUNET_NO);
2522 continue;
2523 }
2525 "Got KX\n");
2526 {
2527 const struct InitialKX *kx;
2528 struct SharedSecret *ss;
2529 char pbuf[rcvd - sizeof(struct InitialKX)];
2530 const struct UDPConfirmation *uc;
2531 struct SenderAddress *sender;
2532
2533 kx = (const struct InitialKX *) buf;
2536 "Before DEC\n");
2537
2538 if (GNUNET_OK != try_decrypt (ss,
2539 kx->gcm_tag,
2540 0,
2541 &buf[sizeof(*kx)],
2542 sizeof(pbuf),
2543 pbuf))
2544 {
2546 "Unable to decrypt tag, dropping...\n");
2547 GNUNET_free (ss);
2549 stats,
2550 "# messages dropped (no kid, AEAD decryption failed)",
2551 1,
2552 GNUNET_NO);
2553 continue;
2554 }
2556 "Before VERIFY\n");
2557
2558 uc = (const struct UDPConfirmation *) pbuf;
2559
2560 if (GNUNET_OK != verify_confirmation (&kx->enc, uc)) // TODO: need ephemeral instead of representative
2561 {
2562 GNUNET_break_op (0);
2563 GNUNET_free (ss);
2565 "# messages dropped (sender signature invalid)",
2566 1,
2567 GNUNET_NO);
2568 continue;
2569 }
2571 "Before SETUP_SENDER\n");
2572
2573 calculate_cmac (ss);
2574 sender = setup_sender (&uc->sender, (const struct sockaddr *) &sa, salen);
2575 ss->sender = sender;
2576 GNUNET_CONTAINER_DLL_insert (sender->ss_head, sender->ss_tail, ss);
2577 if ((KCN_THRESHOLD > ss->sender->acks_available) &&
2578 (NULL == ss->sender->kce_task) &&
2580 {
2581 // TODO This task must be per sender! FIXME: This is a nice todo, but I do not know what must be done here to fix.
2585 ss);
2586 }
2587 sender->num_secrets++;
2588 GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
2590 "# messages decrypted without BOX",
2591 1,
2592 GNUNET_NO);
2593 try_handle_plaintext (sender, &uc[1], sizeof(pbuf) - sizeof(*uc));
2594 if (0 == purge_secrets (sender->ss_tail))
2595 {
2596 // No secret purged. Delete oldest.
2597 if (sender->num_secrets > MAX_SECRETS)
2598 {
2599 secret_destroy (sender->ss_tail);
2600 }
2601 }
2602 }
2603 }
2604}

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

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

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

◆ create_receiver()

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

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

2249{
2250 struct GNUNET_HashContext *hsh;
2251 struct ReceiverAddress *receiver;
2252 struct GNUNET_HashCode receiver_key;
2253 const char *path;
2254 struct sockaddr *in;
2255 socklen_t in_len;
2256
2257 if (0 != strncmp (address,
2259 strlen (COMMUNICATOR_ADDRESS_PREFIX "-")))
2260 {
2261 GNUNET_break_op (0);
2262 return GNUNET_SYSERR;
2263 }
2264 path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")];
2265 in = udp_address_to_sockaddr (path, AF_UNSPEC, &in_len);
2266
2267 if (NULL == in)
2268 {
2270 "Failed to setup UDP socket address\n");
2271 return GNUNET_SYSERR;
2272 }
2273 if ((AF_INET6 == in->sa_family) &&
2275 {
2277 "IPv6 disabled, skipping %s\n", address);
2278 GNUNET_free (in);
2279 return GNUNET_SYSERR;
2280 }
2281 else if (AF_INET == in->sa_family)
2282 {
2283 struct sockaddr_in *sin = (struct sockaddr_in *) in;
2284 if (0 == sin->sin_port)
2285 {
2286 GNUNET_free (in);
2287 return GNUNET_NO;
2288 }
2289 }
2290
2292 GNUNET_CRYPTO_hash_context_read (hsh, in, in_len);
2293 GNUNET_CRYPTO_hash_context_read (hsh, peer, sizeof(*peer));
2294 GNUNET_CRYPTO_hash_context_finish (hsh, &receiver_key);
2295
2297 if (NULL != receiver)
2298 {
2300 "receiver %s already exist or is being connected to\n",
2301 address);
2302 return GNUNET_NO;
2303 }
2304
2306 receiver->udp_sock = udp_sock;
2307 receiver->key = receiver_key;
2308 receiver->address = in;
2309 receiver->address_len = in_len;
2310 receiver->target = *peer;
2311 eddsa_pub_to_hpke_key (&receiver->target.public_key,
2312 &receiver->target_hpke_key);
2313 receiver->nt = GNUNET_NT_scanner_get_type (is, in, in_len);
2315 receivers,
2316 &receiver->key,
2317 receiver,
2320 "Added %s to receivers with address %s and sock %p\n",
2321 GNUNET_i2s_full (&receiver->target),
2322 address,
2323 udp_sock);
2324 receiver->timeout =
2327 receiver,
2328 receiver->timeout.abs_value_us);
2330 "# receivers active",
2332 GNUNET_NO);
2333 receiver->foreign_addr =
2334 sockaddr_to_udpaddr_string (receiver->address, receiver->address_len);
2335 if (NULL != udp_sock)
2338 udp_sock,
2339 &sock_read,
2340 udp_sock);
2342 if (NULL == timeout_task)
2344 return GNUNET_OK;
2345}

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

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

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

◆ do_pad()

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

Pad dgram by pad_size using out_cipher.

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

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

2616{
2617 char pad[pad_size];
2618
2620 if (sizeof(pad) > sizeof(struct GNUNET_MessageHeader))
2621 {
2622 struct GNUNET_MessageHeader hdr =
2623 { .size = htons (sizeof(pad)),
2625
2626 memcpy (pad, &hdr, sizeof(hdr));
2627 }
2629 0 ==
2630 gcry_cipher_encrypt (out_cipher, dgram, sizeof(pad), pad, sizeof(pad)));
2631}

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

Referenced by mq_send_d(), and send_msg_with_kx().

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

◆ send_msg_with_kx()

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

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

2638{
2639 uint16_t msize = ntohs (msg->size);
2640 struct UdpHandshakeSignature uhs;
2641 struct UDPConfirmation uc;
2642 struct InitialKX kx;
2643 char dgram[receiver->kx_mtu + sizeof(uc) + sizeof(kx)];
2644 size_t dpos;
2645 gcry_cipher_hd_t out_cipher;
2646 struct SharedSecret *ss;
2647
2648 if (msize > receiver->kx_mtu)
2649 {
2650 GNUNET_break (0);
2651 if (GNUNET_YES != receiver->receiver_destroy_called)
2653 return;
2654 }
2656
2657 /* setup key material */
2659
2660 if (0 == purge_secrets (receiver->ss_tail))
2661 {
2662 // No secret purged. Delete oldest.
2663 if (receiver->num_secrets > MAX_SECRETS)
2664 {
2665 secret_destroy (receiver->ss_tail);
2666 }
2667 }
2668
2669 setup_cipher (&ss->master, 0, &out_cipher);
2670 /* compute 'uc' */
2671 uc.sender = my_identity;
2672 uc.monotonic_time =
2674 uhs.purpose.purpose = htonl (
2676 uhs.purpose.size = htonl (sizeof(uhs));
2677 uhs.sender = my_identity;
2678 uhs.receiver = receiver->target;
2679 uhs.monotonic_time = uc.monotonic_time;
2681 &uhs,
2682 &uc.sender_sig);
2683 /* Leave space for kx */
2684 dpos = sizeof(kx);
2685 /* Append encrypted uc to dgram */
2686 GNUNET_assert (0 == gcry_cipher_encrypt (out_cipher,
2687 &dgram[dpos],
2688 sizeof(uc),
2689 &uc,
2690 sizeof(uc)));
2691 dpos += sizeof(uc);
2692 /* Append encrypted payload to dgram */
2694 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], msize, msg, msize));
2695 dpos += msize;
2696 do_pad (out_cipher, &dgram[dpos], sizeof(dgram) - dpos);
2697 /* Datagram starts with kx */
2698 kx.enc = uhs.enc;
2700 0 == gcry_cipher_gettag (out_cipher, kx.gcm_tag, sizeof(kx.gcm_tag)));
2701 gcry_cipher_close (out_cipher);
2702 memcpy (dgram, &kx, sizeof(kx));
2704 dgram,
2705 sizeof(dgram),
2706 receiver->address,
2707 receiver->address_len))
2708 {
2711 "Sending KX with payload size %u to %s family %d failed sock %p\n",
2712 msize,
2713 GNUNET_a2s (receiver->address,
2714 receiver->address_len),
2715 receiver->address->sa_family,
2719 return;
2720 }
2722 "Sending KX with payload size %u to %s with socket %p\n",
2723 msize,
2724 GNUNET_a2s (receiver->address,
2725 receiver->address_len),
2728}

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

Referenced by mq_send_d(), and mq_send_kx().

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

◆ mq_send_kx()

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

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

Parameters
mqthe message queue
msgthe message to send
impl_stateour struct ReceiverAddress

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

2743{
2744 struct ReceiverAddress *receiver = impl_state;
2745
2746 GNUNET_assert (mq == receiver->kx_mq);
2748}

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

Referenced by setup_receiver_mq().

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

◆ create_rekey()

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

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

2754{
2755 struct SharedSecret *ss_rekey;
2756
2758 /* setup key material */
2759 ss_rekey = setup_shared_secret_ephemeral (&rekey->ephemeral,
2760 receiver);
2761 ss_rekey->sequence_allowed = 0;
2763 "Setup secret with k = %s\n",
2764 GNUNET_sh2s (&ss_rekey->master));
2766 "Setup secret with H(k) = %s\n",
2767 GNUNET_h2s (&(ss_rekey->cmac)));
2768
2769 /* Append encrypted payload to dgram */
2771 rekey->header.size = htons (sizeof (struct UDPRekey));
2772}

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

Referenced by mq_send_d().

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

◆ mq_send_d()

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

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

Parameters
mqthe message queue
msgthe message to send
impl_stateour struct ReceiverAddress

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

2787{
2788 struct ReceiverAddress *receiver = impl_state;
2789 struct UDPRekey rekey;
2790 struct SharedSecret *ss;
2791 int inject_rekey = GNUNET_NO;
2792 uint16_t msize = ntohs (msg->size);
2793
2794 GNUNET_assert (mq == receiver->d_mq);
2795 if ((msize > receiver->d_mtu) ||
2796 (0 == receiver->acks_available))
2797 {
2799 "msize: %u, mtu: %llu, acks: %u\n",
2800 (unsigned int) msize,
2801 (unsigned long long) receiver->d_mtu,
2802 receiver->acks_available);
2803
2804 GNUNET_break (0);
2805 if (GNUNET_YES != receiver->receiver_destroy_called)
2807 return;
2808 }
2810
2811 if (receiver->num_secrets > MAX_SECRETS)
2812 {
2813 if ((0 == purge_secrets (receiver->ss_tail)) &&
2814 (NULL != receiver->ss_tail))
2815 {
2816 // No secret purged. Delete oldest.
2817 secret_destroy (receiver->ss_tail);
2818 }
2819 }
2820 /* begin "BOX" encryption method, scan for ACKs from tail! */
2821 ss = receiver->ss_tail;
2822 while (NULL != ss)
2823 {
2824 size_t payload_len = sizeof(struct UDPBox) + receiver->d_mtu;
2826 "Considering SS %s sequence used: %u sequence allowed: %u bytes sent: %lu.\n",
2827 GNUNET_sh2s (&ss->master), ss->sequence_used,
2828 ss->sequence_allowed, ss->bytes_sent);
2829 if (ss->sequence_used >= ss->sequence_allowed)
2830 {
2831 // GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2832 // "Skipping ss because no acks to use.\n");
2833 ss = ss->prev;
2834 continue;
2835 }
2836 if (ss->bytes_sent >= rekey_max_bytes)
2837 {
2838 struct SharedSecret *ss_tmp;
2840 "Skipping ss because rekey bytes reached.\n");
2841 // FIXME cleanup ss with too many bytes sent!
2842 ss_tmp = ss->prev;
2843 secret_destroy (ss);
2844 ss = ss_tmp;
2845 continue;
2846 }
2847 if (ss->bytes_sent > rekey_max_bytes * 0.7)
2848 {
2849 if (ss->rekey_initiated == GNUNET_NO)
2850 {
2852 "Injecting rekey for ss with byte sent %lu\n",
2853 (unsigned long) ss->bytes_sent);
2854 create_rekey (receiver, ss, &rekey);
2856 payload_len += sizeof (rekey);
2858 }
2859 }
2860 if (0 < ss->sequence_used)
2862 "Trying to send UDPBox with shared secret %s sequence_used %u and ss->sequence_allowed %u\n",
2863 GNUNET_sh2s (&ss->master),
2864 ss->sequence_used,
2865 ss->sequence_allowed);
2866 {
2867 char dgram[payload_len];
2868 struct UDPBox *box;
2869 gcry_cipher_hd_t out_cipher;
2870 size_t dpos;
2871
2872 box = (struct UDPBox *) dgram;
2873 ss->sequence_used++;
2874 get_kid (&ss->master, ss->sequence_used, &box->kid);
2875 setup_cipher (&ss->master, ss->sequence_used, &out_cipher);
2876 /* Append encrypted payload to dgram */
2877 dpos = sizeof(struct UDPBox);
2878 if (GNUNET_YES == inject_rekey)
2879 {
2881 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], sizeof (rekey),
2882 &rekey, sizeof (rekey)));
2883 dpos += sizeof (rekey);
2884 }
2886 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], msize, msg, msize));
2887 dpos += msize;
2888 do_pad (out_cipher, &dgram[dpos], sizeof(dgram) - dpos);
2889 GNUNET_assert (0 == gcry_cipher_gettag (out_cipher,
2890 box->gcm_tag,
2891 sizeof(box->gcm_tag)));
2892 gcry_cipher_close (out_cipher);
2893
2895 dgram,
2896 payload_len, // FIXME why always send sizeof dgram?
2897 receiver->address,
2898 receiver->address_len))
2899 {
2902 "Sending UDPBox to %s family %d failed sock %p failed\n",
2903 GNUNET_a2s (receiver->address,
2904 receiver->address_len),
2905 receiver->address->sa_family,
2908 return;
2909 }
2911 "Sending UDPBox with payload size %u, %u acks left, %lu bytes sent with socket %p\n",
2912 msize,
2913 receiver->acks_available,
2914 (unsigned long) ss->bytes_sent,
2916 ss->bytes_sent += sizeof (dgram);
2917 receiver->acks_available--;
2919 return;
2920 }
2921 }
2923 "No suitable ss found, sending as KX...\n");
2925}

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

Referenced by setup_receiver_mq().

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

◆ mq_destroy_d()

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

Signature of functions implementing the destruction of a message queue.

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

Parameters
mqthe message queue to destroy
impl_stateour struct ReceiverAddress

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

2938{
2939 struct ReceiverAddress *receiver = impl_state;
2941 "Default MQ destroyed\n");
2942 if (mq == receiver->d_mq)
2943 {
2944 receiver->d_mq = NULL;
2945 if (GNUNET_YES != receiver->receiver_destroy_called)
2947 }
2948}

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

2961{
2962 struct ReceiverAddress *receiver = impl_state;
2964 "KX MQ destroyed\n");
2965 if (mq == receiver->kx_mq)
2966 {
2967 receiver->kx_mq = NULL;
2968 if (GNUNET_YES != receiver->receiver_destroy_called)
2970 }
2971}

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

2982{
2983 /* Cancellation is impossible with UDP; bail */
2984 GNUNET_assert (0);
2985}

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

2999{
3000 struct ReceiverAddress *receiver = cls;
3001
3003 "MQ error in queue to %s: %d\n",
3004 GNUNET_i2s (&receiver->target),
3005 (int) error);
3007}

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

3100{
3101 (void) cls;
3103 "create receiver for mq_init\n");
3104 return create_receiver (peer,
3105 address,
3106 NULL);
3107}

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

Referenced by run().

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

◆ get_receiver_delete_it()

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

Iterator over all receivers to clean up.

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

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

3122{
3123 struct ReceiverAddress *receiver = value;
3124
3125 (void) cls;
3126 (void) target;
3128 return GNUNET_OK;
3129}

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

Referenced by do_shutdown().

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

◆ get_sender_delete_it()

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

Iterator over all senders to clean up.

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

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

3144{
3145 struct SenderAddress *sender = value;
3146
3147 (void) cls;
3148 (void) target;
3149
3150
3151 sender_destroy (sender);
3152 return GNUNET_OK;
3153}

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

Referenced by do_shutdown().

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

◆ do_shutdown()

static void do_shutdown ( void *  cls)
static

Shutdown the UNIX communicator.

Parameters
clsNULL (always)

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

3163{
3165 "do_shutdown\n");
3166 GNUNET_stop_burst (NULL);
3167 if (NULL != nat)
3168 {
3170 nat = NULL;
3171 }
3172 while (NULL != bi_head)
3174 if (NULL != broadcast_task)
3175 {
3177 broadcast_task = NULL;
3178 }
3179 if (NULL != timeout_task)
3180 {
3182 timeout_task = NULL;
3183 }
3184 if (NULL != read_v6_task)
3185 {
3187 read_v6_task = NULL;
3188 }
3189 if (NULL != read_v4_task)
3190 {
3192 read_v4_task = NULL;
3193 }
3194 if (NULL != default_v6_sock)
3195 {
3198 default_v6_sock = NULL;
3199 }
3200 if (NULL != default_v4_sock)
3201 {
3204 default_v4_sock = NULL;
3205 }
3208 NULL);
3212 NULL);
3217 if (NULL != timeout_task)
3218 {
3220 timeout_task = NULL;
3221 }
3222 if (NULL != ch)
3223 {
3225 ch = NULL;
3226 }
3227 if (NULL != ah)
3228 {
3230 ah = NULL;
3231 }
3232 if (NULL != pils)
3233 {
3235 pils = NULL;
3236 }
3237 if (NULL != stats)
3238 {
3240 stats = NULL;
3241 }
3242 if (NULL != my_private_key)
3243 {
3245 my_private_key = NULL;
3246 }
3247 if (NULL != is)
3248 {
3250 is = NULL;
3251 }
3253 "do_shutdown finished\n");
3254}

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

Here is the call graph for this function:

◆ handle_ack_by_sender()

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

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

3266{
3267 struct ReceiverAddress *receiver = value;
3268 struct AckInfo *ai = cls;
3269
3270 if (0 != GNUNET_memcmp (ai->sender, &receiver->target))
3271 {
3272 return GNUNET_YES;
3273 }
3274 handle_ack ((void*) ai->ack, key, receiver);
3275 return GNUNET_YES;
3276}

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

Referenced by enc_notify_cb().

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

◆ enc_notify_cb()

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

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

Should be an acknowledgement.

Parameters
clsclosure, NULL
senderwhich peer sent the notification
msgpayload

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

3292{
3293 struct AckInfo ai;
3294
3295 (void) cls;
3297 "Storing UDPAck received from backchannel from %s\n",
3300 (ntohs (msg->size) != sizeof(struct UDPAck)))
3301 {
3302 GNUNET_break_op (0);
3303 return;
3304 }
3305 ai.ack = (const struct UDPAck *) msg;
3306 ai.sender = sender;
3309 &ai);
3310}

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

Referenced by run().

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

◆ nat_address_cb()

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

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

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

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

3333{
3334 char *my_addr;
3336
3337 if (GNUNET_YES == add_remove)
3338 {
3340
3341 GNUNET_asprintf (&my_addr,
3342 "%s-%s",
3344 GNUNET_a2s (addr, addrlen));
3345 nt = GNUNET_NT_scanner_get_type (is, addr, addrlen);
3346 ai =
3348 my_addr,
3349 nt,
3351 GNUNET_free (my_addr);
3352 *app_ctx = ai;
3353 }
3354 else
3355 {
3356 ai = *app_ctx;
3358 *app_ctx = NULL;
3359 }
3360}

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

3370{
3371 struct BroadcastInterface *bi = cls;
3372 struct GNUNET_TIME_Relative delay;
3373
3374 delay = BROADCAST_FREQUENCY;
3375 delay.rel_value_us =
3377 bi->broadcast_task =
3379
3380 switch (bi->sa->sa_family)
3381 {
3382 case AF_INET: {
3383 static int yes = 1;
3384 static int no = 0;
3385 ssize_t sent;
3386
3387 if (GNUNET_OK !=
3389 SOL_SOCKET,
3390 SO_BROADCAST,
3391 &yes,
3392 sizeof(int)))
3394 "setsockopt");
3396 "creating UDPBroadcast from %s\n",
3397 GNUNET_i2s (&(bi->bcm.sender)));
3399 "sending UDPBroadcast to add %s\n",
3400 GNUNET_a2s (bi->ba, bi->salen));
3402 &bi->bcm,
3403 sizeof(bi->bcm),
3404 bi->ba,
3405 bi->salen);
3406 if (-1 == sent)
3408 "sendto");
3410 SOL_SOCKET,
3411 SO_BROADCAST,
3412 &no,
3413 sizeof(int)))
3415 "setsockopt");
3416 break;
3417 }
3418
3419 case AF_INET6: {
3420 ssize_t sent;
3421 struct sockaddr_in6 dst;
3422
3423 dst.sin6_family = AF_INET6;
3424 dst.sin6_port = htons (my_port);
3425 dst.sin6_addr = bi->mcreq.ipv6mr_multiaddr;
3426 dst.sin6_scope_id = ((struct sockaddr_in6 *) bi->ba)->sin6_scope_id;
3427
3429 "sending UDPBroadcast\n");
3431 &bi->bcm,
3432 sizeof(bi->bcm),
3433 (const struct sockaddr *) &dst,
3434 sizeof(dst));
3435 if (-1 == sent)
3437 break;
3438 }
3439
3440 default:
3441 GNUNET_break (0);
3442 break;
3443 }
3444}

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

Referenced by iface_proc(), and ifc_broadcast().

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

◆ iface_proc()

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

Callback function invoked for each interface found.

Activates/deactivates broadcast interfaces.

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

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

3469{
3470 struct BroadcastInterface *bi;
3471 enum GNUNET_NetworkType network;
3472 struct UdpBroadcastSignature ubs;
3473
3474 (void) cls;
3475 (void) netmask;
3476 if (NULL == my_private_key)
3477 return GNUNET_YES;
3478 if (NULL == addr)
3479 return GNUNET_YES; /* need to know our address! */
3480 network = GNUNET_NT_scanner_get_type (is, addr, addrlen);
3481 if (GNUNET_NT_LOOPBACK == network)
3482 {
3483 /* Broadcasting on loopback does not make sense */
3484 return GNUNET_YES;
3485 }
3486 for (bi = bi_head; NULL != bi; bi = bi->next)
3487 {
3488 if ((bi->salen == addrlen) && (0 == memcmp (addr, bi->sa, addrlen)))
3489 {
3490 bi->found = GNUNET_YES;
3491 return GNUNET_OK;
3492 }
3493 }
3494
3495 if ((AF_INET6 == addr->sa_family) && (NULL == broadcast_addr))
3496 return GNUNET_OK; /* broadcast_addr is required for IPv6! */
3497 if ((AF_INET6 == addr->sa_family) && (NULL != default_v6_sock))
3498 return GNUNET_OK; /* not using IPv6 */
3499
3500 bi = GNUNET_new (struct BroadcastInterface);
3501 bi->sa = GNUNET_memdup (addr,
3502 addrlen);
3503 if ( (NULL != broadcast_addr) &&
3504 (addrlen == sizeof (struct sockaddr_in)) )
3505 {
3506 struct sockaddr_in *ba;
3507
3508 ba = GNUNET_memdup (broadcast_addr,
3509 addrlen);
3510 ba->sin_port = htons (2086); /* always GNUnet port, ignore configuration! */
3511 bi->ba = (struct sockaddr *) ba;
3512 }
3513 bi->salen = addrlen;
3514 bi->found = GNUNET_YES;
3515 bi->bcm.sender = my_identity;
3516 ubs.purpose.purpose = htonl (
3518 ubs.purpose.size = htonl (sizeof(ubs));
3519 ubs.sender = my_identity;
3521 "creating UDPBroadcastSignature for %s\n",
3522 GNUNET_a2s (addr, addrlen));
3523 GNUNET_CRYPTO_hash (addr, addrlen, &ubs.h_address);
3525 &ubs,
3526 &bi->bcm.sender_sig);
3527 if (NULL != bi->ba)
3528 {
3531 }
3532 if ((AF_INET6 == addr->sa_family) && (NULL != broadcast_addr))
3533 {
3534 /* Create IPv6 multicast request */
3535 const struct sockaddr_in6 *s6 =
3536 (const struct sockaddr_in6 *) broadcast_addr;
3537
3539 1 == inet_pton (AF_INET6, "FF05::13B", &bi->mcreq.ipv6mr_multiaddr));
3540
3541 /* http://tools.ietf.org/html/rfc2553#section-5.2:
3542 *
3543 * IPV6_JOIN_GROUP
3544 *
3545 * Join a multicast group on a specified local interface. If the
3546 * interface index is specified as 0, the kernel chooses the local
3547 * interface. For example, some kernels look up the multicast
3548 * group in the normal IPv6 routing table and using the resulting
3549 * interface; we do this for each interface, so no need to use
3550 * zero (anymore...).
3551 */
3552 bi->mcreq.ipv6mr_interface = s6->sin6_scope_id;
3553
3554 /* Join the multicast group */
3556 IPPROTO_IPV6,
3557 IPV6_JOIN_GROUP,
3558 &bi->mcreq,
3559 sizeof(bi->mcreq)))
3560 {
3562 }
3563 }
3564 return GNUNET_OK;
3565}

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

Referenced by do_broadcast().

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

◆ do_broadcast()

static void do_broadcast ( void *  cls)
static

Scan interfaces to broadcast our presence on the LAN.

Parameters
clsNULL, unused

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

3575{
3576 struct BroadcastInterface *bin;
3577
3578 (void) cls;
3579 for (struct BroadcastInterface *bi = bi_head; NULL != bi; bi = bi->next)
3580 bi->found = GNUNET_NO;
3582 for (struct BroadcastInterface *bi = bi_head; NULL != bi; bi = bin)
3583 {
3584 bin = bi->next;
3585 if (GNUNET_NO == bi->found)
3586 bi_destroy (bi);
3587 }
3589 &do_broadcast,
3590 NULL);
3591}

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

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

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

◆ try_connection_reversal()

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

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

3598{
3599 /* FIXME: support reversal: #5529 */
3601 "No connection reversal implemented!\n");
3602}

References GNUNET_ERROR_TYPE_INFO, and GNUNET_log.

Referenced by run().

Here is the caller graph for this function:

◆ udp_socket_notify()

static void udp_socket_notify ( struct GNUNET_UdpSocketInfo sock_info)
static

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

3607{
3609 sizeof (*sock_info->actual_address
3610 ));
3611 create_receiver (sock_info->pid,
3612 address,
3613 default_v4_sock == sock_info->udp_sock ||
3614 default_v6_sock == sock_info->udp_sock ?
3615 NULL : sock_info->udp_sock);
3617 GNUNET_free (sock_info);
3618}

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

Referenced by start_burst().

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

◆ start_burst()

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

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

3625{
3626 struct GNUNET_UdpSocketInfo *sock_info;
3627
3629 "Communicator was called to start burst to address %s from %s\n",
3630 addr,
3631 my_ipv4);
3632
3633 GNUNET_stop_burst (NULL);
3634
3635 sock_info = GNUNET_new (struct GNUNET_UdpSocketInfo);
3636 sock_info->pid = GNUNET_new (struct GNUNET_PeerIdentity);
3637 sock_info->address = GNUNET_strdup (addr);
3638 sock_info->bind_address = my_ipv4;
3639 sock_info->has_port = GNUNET_YES;
3640 sock_info->udp_sock = default_v4_sock;
3641 sock_info->rtt = rtt;
3642 GNUNET_memcpy (sock_info->pid, pid, sizeof (struct GNUNET_PeerIdentity));
3643 sock_info->std_port = my_port;
3645 "1 sock addr %s addr %s rtt %lu %u\n",
3646 sock_info->address,
3647 addr,
3648 (unsigned long) sock_info->rtt.rel_value_us,
3649 my_port);
3650 burst_task = GNUNET_get_udp_socket (sock_info,
3652 GNUNET_free (sock_info);
3653}

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

Referenced by reconnect(), and run().

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

◆ create_udp_socket()

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

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

3661{
3662 struct GNUNET_NETWORK_Handle *sock;
3663 struct sockaddr *in;
3664 socklen_t in_len;
3665 struct sockaddr_storage in_sto;
3666 socklen_t sto_len;
3667
3668 in = udp_address_to_sockaddr (bindto, family, &in_len);
3669 if (NULL == in)
3670 {
3672 "Failed to setup UDP socket address with path `%s'\n",
3673 bindto);
3674 return NULL;
3675 }
3676
3677 if ((AF_UNSPEC != family) && (in->sa_family != family))
3678 {
3680 "Invalid UDP socket address setup with path `%s'\n",
3681 bindto);
3682 GNUNET_free (in);
3683 return NULL;
3684 }
3685
3686 sock =
3687 GNUNET_NETWORK_socket_create (in->sa_family,
3688 SOCK_DGRAM,
3689 IPPROTO_UDP);
3690 if (NULL == sock)
3691 {
3694 "Failed to create socket for %s family %d\n",
3695 GNUNET_a2s (in,
3696 in_len),
3697 in->sa_family);
3698 GNUNET_free (in);
3699 return NULL;
3700 }
3701 if (GNUNET_OK !=
3703 in,
3704 in_len))
3705 {
3707 "bind",
3708 bindto);
3710 "Failed to bind socket for %s family %d sock %p\n",
3711 GNUNET_a2s (in,
3712 in_len),
3713 in->sa_family,
3714 sock);
3716 sock = NULL;
3717 GNUNET_free (in);
3718 return NULL;
3719 }
3720
3721 /* We might have bound to port 0, allowing the OS to figure it out;
3722 thus, get the real IN-address from the socket */
3723 sto_len = sizeof(in_sto);
3724 if (0 != getsockname (GNUNET_NETWORK_get_fd (sock),
3725 (struct sockaddr *) &in_sto,
3726 &sto_len))
3727 {
3728 memcpy (&in_sto, in, in_len);
3729 sto_len = in_len;
3730 }
3731 GNUNET_free (in);
3732 *out = GNUNET_malloc (sto_len);
3733 memcpy (*out, (struct sockaddr *) &in_sto, sto_len);
3734 *out_len = sto_len;
3735 return sock;
3736}

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

Referenced by run().

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

◆ shutdown_run()

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

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

3741{
3742 if (NULL != addrs[0])
3743 GNUNET_free (addrs[0]);
3744 if (NULL != addrs[1])
3745 GNUNET_free (addrs[1]);
3747}

References GNUNET_free, and GNUNET_SCHEDULER_shutdown().

Referenced by run().

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

◆ load_ikm()

static void load_ikm ( )
static

Get the initial secret key for generating the peer id.

This is supposed to be generated at random once in the lifetime of a peer, so all generated peer ids use the same initial secret key to obtain the same peer id per set of addresses.

First check whether there's already a initial secret key. If so: return it. If no initial secret key exists yet, generate at random and store it where it will be found.

Parameters
initialsecret key the memory the initial secret key can be written to.

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

3762{
3763 char *keyfile;
3765
3766 if (GNUNET_OK !=
3768 "PEER",
3769 "PRIVATE_KEY",
3770 &keyfile))
3771 {
3773 "PEER",
3774 "PRIVATE_KEY");
3776 return;
3777 }
3778 if (GNUNET_SYSERR ==
3780 GNUNET_YES,
3781 &key))
3782 {
3784 "Failed to setup peer's private key\n");
3785 GNUNET_free (keyfile);
3787 return;
3788 }
3789 GNUNET_free (keyfile);
3790 GNUNET_assert (sizeof ikm == sizeof key.d);
3791 memcpy (ikm, key.d, sizeof ikm);
3792}

References cfg, GNUNET_assert, GNUNET_CONFIGURATION_get_value_filename(), GNUNET_CRYPTO_eddsa_key_from_file(), GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_log, GNUNET_log_config_missing(), GNUNET_OK, GNUNET_SCHEDULER_shutdown(), GNUNET_SYSERR, GNUNET_YES, ikm, and key.

Referenced by run().

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

◆ pid_change_cb()

void pid_change_cb ( void *  cls,
const struct GNUNET_HELLO_Parser parser,
const struct GNUNET_HashCode addr_hash 
)

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

3799{
3801 "Got PID to derive from `%s':\n",
3802 GNUNET_h2s (addr_hash));
3803 if (NULL == my_private_key)
3805
3807 (uint8_t*) ikm,
3808 addr_hash,
3814 /* start broadcasting */
3815 if (GNUNET_YES !=
3818 "DISABLE_BROADCAST"))
3819 {
3820 if (NULL == broadcast_task)
3822 }
3823}

References broadcast_task, cfg, COMMUNICATOR_CONFIG_SECTION, do_broadcast(), eddsa_priv_to_hpke_key(), GNUNET_CONFIGURATION_get_value_yesno(), GNUNET_CRYPTO_eddsa_key_get_public(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_new, GNUNET_PILS_derive_pid(), GNUNET_SCHEDULER_add_now(), GNUNET_YES, ikm, LOG, my_identity, my_private_key, my_x25519_private_key, and GNUNET_PeerIdentity::public_key.

Referenced by run().

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

◆ run()

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

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

3831{
3832 const struct sockaddr_in *v4;
3833 char *bindto;
3834 char *bindto6;
3835 struct sockaddr *in[2];
3836 socklen_t in_len[2];
3837
3839 "Entering the run method of udp communicator.\n");
3840
3841 cfg = c;
3843 if ((GNUNET_NO == GNUNET_NETWORK_test_pf (PF_INET6)) ||
3844 (GNUNET_YES ==
3847 "DISABLE_V6")))
3848 {
3850 }
3851
3852 if (GNUNET_OK !=
3855 "BINDTO",
3856 &bindto))
3857 {
3860 "BINDTO");
3861 return;
3862 }
3864 "The udp communicator will bind to %s for IPv4\n",
3865 bindto);
3866 if (GNUNET_YES != disable_v6)
3867 {
3868 if (GNUNET_OK !=
3871 "BINDTO6",
3872 &bindto6))
3873 {
3876 "BINDTO6");
3877 return;
3878 }
3879
3881 "The udp communicator will bind to %s for IPv6\n",
3882 bindto6);
3883 }
3884 else
3885 bindto6 = NULL;
3886 if (GNUNET_OK !=
3889 "REKEY_INTERVAL",
3892
3893 if (GNUNET_OK !=
3896 "REKEY_MAX_BYTES",
3898 {
3900 }
3901
3902 memset (in, 0, sizeof(struct sockaddr*) * 2);
3903 memset (in_len, 0, sizeof(socklen_t) * 2);
3904
3905 GNUNET_assert (bindto);
3907 bindto, AF_INET, &(in[0]), &(in_len[0]));
3908 GNUNET_free (bindto);
3909
3910 if (GNUNET_YES != disable_v6)
3911 {
3912 GNUNET_assert (bindto6);
3914 bindto6, AF_INET6, &(in[1]), &(in_len[1]));
3915 GNUNET_free (bindto6);
3916 }
3917 else
3918 default_v6_sock = NULL;
3919
3920 if ((NULL == default_v4_sock) && (NULL == default_v6_sock))
3921 return;
3922
3923 my_port = 0;
3924 if (NULL != default_v4_sock)
3925 {
3926 GNUNET_assert (in[0]);
3928 "transport",
3929 "Bound to `%s' sock %p\n",
3930 GNUNET_a2s ((const struct sockaddr *) in[0],
3931 in_len[0]),
3933
3934 v4 = (const struct sockaddr_in *) in[0];
3935
3936 my_ipv4 = GNUNET_malloc (INET_ADDRSTRLEN);
3937 my_port = ntohs (((struct sockaddr_in *) in[0])->sin_port);
3938 inet_ntop (AF_INET, &v4->sin_addr, my_ipv4, in_len[0]);
3939 }
3940 if (NULL != default_v6_sock)
3941 {
3942 GNUNET_assert (in[1]);
3944 "transport",
3945 "Bound to `%s' sock %p\n",
3946 GNUNET_a2s ((const struct sockaddr *) in[1],
3947 in_len[1]),
3949 my_port = ntohs (((struct sockaddr_in6 *) in[1])->sin6_port);
3950 }
3951 stats = GNUNET_STATISTICS_create ("communicator-udp", cfg);
3960 /* start reading */
3961 if (NULL != default_v4_sock)
3964 &sock_read,
3966 else
3967 read_v4_task = NULL;
3968 if (NULL != default_v6_sock)
3971 &sock_read,
3973 else
3974 read_v6_task = NULL;
3979 &mq_init,
3980 NULL,
3982 NULL,
3983 &start_burst);
3984 if (NULL == ch)
3985 {
3986 GNUNET_break (0);
3987 shutdown_run (in);
3988 return;
3989 }
3991 if (NULL == ah)
3992 {
3993 GNUNET_break (0);
3994 shutdown_run (in);
3995 return;
3996 }
3997 /* start broadcasting */
3998 if (GNUNET_YES !=
4001 "DISABLE_BROADCAST"))
4002 {
4004 }
4005 load_ikm ();
4007 GNUNET_assert (NULL != pils);
4008
4011 IPPROTO_UDP,
4012 (NULL != in[0]? 1 : 0)
4013 + (NULL != in[1]? 1 : 0),
4014 (const struct sockaddr**)
4015 (NULL != in[0]? in : &(in[1])),
4016 NULL != in[0]? in_len : &(in_len[1]),
4019 NULL /* closure */);
4020 if (NULL != in[0])
4021 GNUNET_free (in[0]);
4022 if (NULL != in[1])
4023 GNUNET_free (in[1]);
4024}

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

Here is the call graph for this function:

Variable Documentation

◆ ikm

unsigned char ikm[256/8]
static

The initial key material for the peer.

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

Referenced by load_ikm(), and pid_change_cb().

◆ pils

struct GNUNET_PILS_Handle* pils
static

For PILS.

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

Referenced by do_shutdown(), and run().

◆ rekey_interval

struct GNUNET_TIME_Relative rekey_interval
static

The rekey interval.

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

Referenced by run().

◆ rekey_max_bytes

unsigned long long rekey_max_bytes
static

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

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

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

◆ key_cache

struct GNUNET_CONTAINER_MultiShortmap* key_cache
static

Cache of pre-generated key IDs.

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

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

◆ read_v4_task

struct GNUNET_SCHEDULER_Task* read_v4_task
static

ID of read IPv4 task.

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

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

◆ read_v6_task

struct GNUNET_SCHEDULER_Task* read_v6_task
static

ID of read IPv6 task.

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

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

◆ broadcast_task

struct GNUNET_SCHEDULER_Task* broadcast_task
static

ID of master broadcast task.

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

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

◆ stats

◆ ch

◆ receivers

struct GNUNET_CONTAINER_MultiHashMap* receivers
static

Receivers (map from peer identity to struct ReceiverAddress)

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

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

◆ senders

struct GNUNET_CONTAINER_MultiHashMap* senders
static

Senders (map from peer identity to struct SenderAddress)

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

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

◆ senders_heap

struct GNUNET_CONTAINER_Heap* senders_heap
static

Expiration heap for senders (contains struct SenderAddress)

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

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

◆ receivers_heap

struct GNUNET_CONTAINER_Heap* receivers_heap
static

Expiration heap for receivers (contains struct ReceiverAddress)

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

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

◆ bi_head

struct BroadcastInterface* bi_head
static

Broadcast interface tasks.

Kept in a DLL.

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

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

◆ bi_tail

struct BroadcastInterface* bi_tail
static

Broadcast interface tasks.

Kept in a DLL.

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

Referenced by bi_destroy(), and iface_proc().

◆ default_v4_sock

struct GNUNET_NETWORK_Handle* default_v4_sock
static

Our IPv4 socket.

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

Referenced by do_shutdown(), get_socket(), ifc_broadcast(), run(), sock_read(), start_burst(), and udp_socket_notify().

◆ default_v6_sock

struct GNUNET_NETWORK_Handle* default_v6_sock
static

◆ my_identity

struct GNUNET_PeerIdentity my_identity
static

Our public key.

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

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

◆ my_private_key

struct GNUNET_CRYPTO_EddsaPrivateKey* my_private_key
static

Our private key.

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

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

◆ my_x25519_private_key

struct GNUNET_CRYPTO_HpkePrivateKey my_x25519_private_key
static

Our private key for HPKE.

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

Referenced by pid_change_cb(), and setup_initial_shared_secret_dec().

◆ cfg

const struct GNUNET_CONFIGURATION_Handle* cfg
static

Our configuration.

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

Referenced by load_ikm(), pid_change_cb(), run(), and send_msg_with_kx().

◆ ah

Our handle to report addresses for validation to TRANSPORT.

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

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

◆ is

struct GNUNET_NT_InterfaceScanner* is
static

Network scanner to determine network types.

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

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

◆ nat

struct GNUNET_NAT_Handle* nat
static

Connection to NAT service.

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

Referenced by do_shutdown(), and run().

◆ my_port

uint16_t my_port
static

Port number to which we are actually bound.

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

Referenced by ifc_broadcast(), run(), and start_burst().

◆ my_ipv4

char* my_ipv4

Our ipv4 address.

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

Referenced by run(), and start_burst().

◆ disable_v6

int disable_v6
static

IPv6 disabled or not.

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

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

◆ burst_task

struct GNUNET_SCHEDULER_Task* burst_task
static

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

Referenced by start_burst().