GNUnet 0.27.0
 
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 (const struct GNUNET_CRYPTO_EddsaPrivateKey *edpk, struct GNUNET_CRYPTO_HpkePrivateKey *pk)
 
static void eddsa_pub_to_hpke_key (const 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 run (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c)
 

Variables

static struct GNUNET_PILS_KeyRingkey_ring
 For PILS.
 
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 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 struct GNUNET_PILS_KeyRing *key_ring;
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 const struct GNUNET_CONFIGURATION_Handle *cfg;
856
861
865static struct GNUNET_NT_InterfaceScanner *is;
866
870static struct GNUNET_NAT_Handle *nat;
871
875static uint16_t my_port;
876
880char *my_ipv4;
881
885static int disable_v6;
886
887static struct GNUNET_SCHEDULER_Task *burst_task;
888
889
890static void
893{
895 key.type = htonl (GNUNET_PUBLIC_KEY_TYPE_EDDSA);
896 key.eddsa_key = *edpk;
898 pk);
899}
900
901
902static void
905{
907 key.type = htonl (GNUNET_PUBLIC_KEY_TYPE_EDDSA);
908 key.eddsa_key = *edpk;
910 pk);
911}
912
913
919static void
921{
922 if (AF_INET6 == bi->sa->sa_family)
923 {
924 /* Leave the multicast group */
926 IPPROTO_IPV6,
927 IPV6_LEAVE_GROUP,
928 &bi->mcreq,
929 sizeof(bi->mcreq)))
930 {
932 }
933 }
936 GNUNET_free (bi->sa);
937 GNUNET_free (bi->ba);
938 GNUNET_free (bi);
939}
940
941
942static int
943secret_destroy (struct SharedSecret *ss);
944
950static void
952{
953 struct SharedSecret *ss;
954 receiver->receiver_destroy_called = GNUNET_YES;
955
957 "Disconnecting receiver for peer `%s'\n",
958 GNUNET_i2s (&receiver->target));
959 if (NULL != receiver->kx_qh)
960 {
962 receiver->kx_qh = NULL;
963 receiver->kx_mq = NULL;
964 }
965 if (NULL != receiver->d_qh)
966 {
968 receiver->d_qh = NULL;
969 }
970 else if (NULL != receiver->d_mq)
971 {
973 receiver->d_mq = NULL;
974 }
975 if (NULL != receiver->udp_sock)
976 {
979 receiver->udp_sock = NULL;
980 }
983 &receiver->key,
984 receiver));
987 "# receivers active",
989 GNUNET_NO);
990 while (NULL != (ss = receiver->ss_head))
991 {
992 secret_destroy (ss);
993 }
994 GNUNET_free (receiver->address);
995 GNUNET_free (receiver->foreign_addr);
997}
998
999
1005static void
1006kce_destroy (struct KeyCacheEntry *kce)
1007{
1008 struct SharedSecret *ss = kce->ss;
1009
1010 ss->active_kce_count--;
1013 &kce->kid,
1014 kce));
1015 GNUNET_free (kce);
1016}
1017
1018
1026static void
1027get_kid (const struct GNUNET_ShortHashCode *msec,
1028 uint32_t serial,
1029 struct GNUNET_ShortHashCode *kid)
1030{
1031 uint32_t sid = htonl (serial);
1032 struct GNUNET_ShortHashCode prk;
1034 &sid, sizeof (sid),
1035 msec, sizeof (*msec));
1036
1038 kid,
1039 sizeof(*kid),
1040 &prk,
1041 GNUNET_CRYPTO_kdf_arg_string ("gnunet-communicator-udp-kid"));
1042}
1043
1044
1051static void
1052kce_generate (struct SharedSecret *ss, uint32_t seq)
1053{
1054 struct KeyCacheEntry *kce;
1055
1056 GNUNET_assert (0 < seq);
1057 kce = GNUNET_new (struct KeyCacheEntry);
1058 kce->ss = ss;
1059 kce->sequence_number = seq;
1060 get_kid (&ss->master, seq, &kce->kid);
1065 key_cache,
1066 &kce->kid,
1067 kce,
1070 "# KIDs active",
1072 GNUNET_NO);
1073}
1074
1075
1082static int
1084{
1085 struct SenderAddress *sender;
1086 struct ReceiverAddress *receiver;
1087 struct KeyCacheEntry *kce;
1088
1090 "secret %s destroy %u\n",
1091 GNUNET_sh2s (&ss->master),
1093 if (NULL != (sender = ss->sender))
1094 {
1095 GNUNET_CONTAINER_DLL_remove (sender->ss_head, sender->ss_tail, ss);
1096 sender->num_secrets--;
1098 "%u sender->num_secrets %u allowed %u used, %u available\n",
1100 sender->acks_available);
1102 if (NULL != ss->sender->kce_task)
1103 {
1105 ss->sender->kce_task = NULL;
1106 }
1107 }
1108 if (NULL != (receiver = ss->receiver))
1109 {
1110 GNUNET_CONTAINER_DLL_remove (receiver->ss_head, receiver->ss_tail, ss);
1111 receiver->num_secrets--;
1112 receiver->acks_available -= (ss->sequence_allowed - ss->sequence_used);
1114 "%u receiver->num_secrets\n",
1115 receiver->num_secrets);
1116 }
1117 while (NULL != (kce = ss->kce_head))
1118 kce_destroy (kce);
1119 GNUNET_STATISTICS_update (stats, "# Secrets active", -1, GNUNET_NO);
1121 "# KIDs active",
1123 GNUNET_NO);
1124 GNUNET_free (ss);
1125 return GNUNET_YES;
1126}
1127
1128
1135static void
1136sender_destroy (struct SenderAddress *sender)
1137{
1138 struct SharedSecret *ss;
1141 GNUNET_YES ==
1145 "# senders active",
1147 GNUNET_NO);
1148 while (NULL != (ss = sender->ss_head))
1149 {
1150 secret_destroy (ss);
1151 }
1154}
1155
1156
1165static void
1166get_iv_key (const struct GNUNET_ShortHashCode *msec,
1167 uint32_t serial,
1168 char key[AES_KEY_SIZE],
1169 char iv[AES_IV_SIZE])
1170{
1171 uint32_t sid = htonl (serial);
1172
1174 key,
1176 msec,
1177 GNUNET_CRYPTO_kdf_arg_string ("gnunet-communicator-udp-key"),
1180 iv,
1182 msec,
1183 GNUNET_CRYPTO_kdf_arg_string ("gnunet-communicator-udp-iv"),
1185}
1186
1187
1193static void
1195{
1196 sender->timeout =
1199}
1200
1201
1207static void
1209{
1210 receiver->timeout =
1213 receiver->timeout.abs_value_us);
1214}
1215
1216
1222static void
1223check_timeouts (void *cls)
1224{
1225 struct GNUNET_TIME_Relative st;
1226 struct GNUNET_TIME_Relative rt;
1227 struct GNUNET_TIME_Relative delay;
1228 struct ReceiverAddress *receiver;
1229 struct SenderAddress *sender;
1230
1231 (void) cls;
1232 timeout_task = NULL;
1235 {
1237 if (0 != rt.rel_value_us)
1238 break;
1240 "Receiver timed out\n");
1242 }
1244 while (NULL != (sender = GNUNET_CONTAINER_heap_peek (senders_heap)))
1245 {
1246 if (GNUNET_YES != sender->sender_destroy_called)
1247 {
1249 if (0 != st.rel_value_us)
1250 break;
1251 sender_destroy (sender);
1252 }
1253 }
1254 delay = GNUNET_TIME_relative_min (rt, st);
1255 if (delay.rel_value_us < GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
1257}
1258
1259
1265static void
1266calculate_cmac (struct SharedSecret *ss)
1267{
1269 &ss->cmac,
1270 sizeof(ss->cmac),
1271 &ss->master,
1272 GNUNET_CRYPTO_kdf_arg_string ("gnunet-communicator-udp-cmac"));
1273}
1274
1275
1284static void
1286 const void *plaintext,
1287 size_t plaintext_len)
1288{
1289 const struct GNUNET_MessageHeader *hdr = plaintext;
1290 const char *pos = plaintext;
1291
1292 while (ntohs (hdr->size) <= plaintext_len)
1293 {
1295 "# bytes given to core",
1296 ntohs (hdr->size),
1297 GNUNET_NO);
1299 "Giving %u bytes to TNG\n", ntohs (hdr->size));
1302 &sender->target,
1303 hdr,
1305 NULL /* no flow control possible */
1306 ,
1307 NULL));
1308 /* move on to next message, if any */
1309 plaintext_len -= ntohs (hdr->size);
1310 if (plaintext_len < sizeof(*hdr))
1311 break;
1312 pos += ntohs (hdr->size);
1313 hdr = (const struct GNUNET_MessageHeader *) pos;
1314 // TODO for now..., we do not actually sen >1msg or have a way of telling
1315 // if we are done
1316 break;
1317 }
1319 "# bytes padding discarded",
1320 plaintext_len,
1321 GNUNET_NO);
1322}
1323
1324
1333static void
1334setup_cipher (const struct GNUNET_ShortHashCode *msec,
1335 uint32_t serial,
1336 gcry_cipher_hd_t *cipher)
1337{
1338 char key[AES_KEY_SIZE];
1339 char iv[AES_IV_SIZE];
1340 int rc;
1341
1342 GNUNET_assert (0 ==
1343 gcry_cipher_open (cipher,
1344 GCRY_CIPHER_AES256 /* low level: go for speed */
1345 ,
1346 GCRY_CIPHER_MODE_GCM,
1347 0 /* flags */));
1348 get_iv_key (msec, serial, key, iv);
1349 rc = gcry_cipher_setkey (*cipher, key, sizeof(key));
1350 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
1351 rc = gcry_cipher_setiv (*cipher, iv, sizeof(iv));
1352 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
1353}
1354
1355
1368static int
1369try_decrypt (const struct SharedSecret *ss,
1370 const uint8_t *tag,
1371 uint32_t serial,
1372 const char *in_buf,
1373 size_t in_buf_size,
1374 char *out_buf)
1375{
1376 gcry_cipher_hd_t cipher;
1377
1378 setup_cipher (&ss->master, serial, &cipher);
1380 0 ==
1381 gcry_cipher_decrypt (cipher, out_buf, in_buf_size, in_buf, in_buf_size));
1382 if (0 != gcry_cipher_checktag (cipher, tag, GCM_TAG_SIZE))
1383 {
1384 gcry_cipher_close (cipher);
1386 "# AEAD authentication failures",
1387 1,
1388 GNUNET_NO);
1389 return GNUNET_SYSERR;
1390 }
1391 gcry_cipher_close (cipher);
1392 return GNUNET_OK;
1393}
1394
1395
1402static struct SharedSecret *
1404 )
1405{
1407 struct SharedSecret *ss;
1408
1411
1412 ss = GNUNET_new (struct SharedSecret);
1414 ephemeral,
1415 &ss->master);
1416 calculate_cmac (ss);
1417 return ss;
1418}
1419
1420
1427static struct SharedSecret *
1430{
1432 struct GNUNET_CRYPTO_HpkePrivateKey my_hpke_key;
1433 struct SharedSecret *ss;
1434
1437
1438 eddsa_priv_to_hpke_key (my_private_key, &my_hpke_key);
1439
1440 ss = GNUNET_new (struct SharedSecret);
1442 &ss->master);
1444 "New receiver SS master: %s\n", GNUNET_sh2s (&ss->master));
1445 calculate_cmac (ss);
1446 return ss;
1447}
1448
1449
1457static struct SharedSecret *
1459 ,
1460 struct ReceiverAddress *receiver)
1461{
1462 struct SharedSecret *ss;
1463
1464 ss = GNUNET_new (struct SharedSecret);
1465 GNUNET_CRYPTO_eddsa_kem_encaps (&receiver->target.public_key,
1466 ephemeral,
1467 &ss->master);
1468 calculate_cmac (ss);
1469 ss->receiver = receiver;
1470 GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss);
1471 receiver->num_secrets++;
1472 GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
1473 return ss;
1474}
1475
1476
1484static struct SharedSecret *
1487 struct ReceiverAddress *receiver)
1488{
1489 struct SharedSecret *ss;
1490
1491 ss = GNUNET_new (struct SharedSecret);
1493 c, &ss->master);
1495 "New sender SS master: %s\n", GNUNET_sh2s (&ss->master));
1496 calculate_cmac (ss);
1497 ss->receiver = receiver;
1498 GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss);
1499 receiver->num_secrets++;
1500 GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
1501 return ss;
1502}
1503
1504
1512static void
1514
1515
1523static unsigned int
1524purge_secrets (struct SharedSecret *ss_list_tail)
1525{
1526 struct SharedSecret *pos;
1527 struct SharedSecret *ss_to_purge;
1528 unsigned int deleted = 0;
1529
1531 "Purging secrets.\n");
1532 pos = ss_list_tail;
1533 while (NULL != pos)
1534 {
1535 ss_to_purge = pos;
1536 pos = pos->prev;
1537
1538 // FIXME we may also want to purge old unacked.
1539 if (rekey_max_bytes <= ss_to_purge->bytes_sent)
1540 {
1541 secret_destroy (ss_to_purge);
1542 deleted++;
1543 }
1544 }
1546 "Finished purging all, deleted %u.\n", deleted);
1547 return deleted;
1548}
1549
1550
1551static void
1552add_acks (struct SharedSecret *ss, int acks_to_add)
1553{
1554
1555 struct ReceiverAddress *receiver = ss->receiver;
1556
1557 GNUNET_assert (NULL != ss);
1558 GNUNET_assert (NULL != receiver);
1559
1560 if (NULL == receiver->d_qh)
1561 {
1562 receiver->d_qh =
1564 &receiver->target,
1565 receiver->foreign_addr,
1566 receiver->d_mtu,
1567 acks_to_add,
1568 1, /* Priority */
1569 receiver->nt,
1571 receiver->d_mq);
1572 }
1573 else
1574 {
1576 receiver->d_qh,
1577 acks_to_add,
1578 1);
1579 }
1580
1582 "Tell transport we have %u more acks!\n",
1583 acks_to_add);
1584
1585 // Until here for alternative 1
1586
1587 /* move ss to head to avoid discarding it anytime soon! */
1588
1589 // GNUNET_CONTAINER_DLL_remove (receiver->ss_head, receiver->ss_tail, ss);
1590 // GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss);
1591}
1592
1593
1604static int
1605handle_ack (void *cls, const struct GNUNET_HashCode *key, void *value)
1606{
1607 const struct UDPAck *ack = cls;
1608 struct ReceiverAddress *receiver = value;
1609 uint32_t acks_to_add;
1610 uint32_t allowed;
1611
1613 "in handle ack with cmac %s\n",
1614 GNUNET_h2s (&ack->cmac));
1615
1616 (void) key;
1617 for (struct SharedSecret *ss = receiver->ss_head; NULL != ss; ss = ss->next)
1618 {
1619 if (0 == memcmp (&ack->cmac, &ss->cmac, sizeof(struct GNUNET_HashCode)))
1620 {
1621
1623 "Found matching cmac\n");
1624
1625 allowed = ntohl (ack->sequence_ack);
1626
1627 if (allowed <= ss->sequence_allowed)
1628 {
1630 "Ignoring ack, not giving us increased window\n.");
1631 return GNUNET_NO;
1632 }
1633 acks_to_add = (allowed - ss->sequence_allowed);
1634 GNUNET_assert (0 != acks_to_add);
1635 receiver->acks_available += (allowed - ss->sequence_allowed);
1636 ss->sequence_allowed = allowed;
1637 add_acks (ss, acks_to_add);
1639 "New sequence allows until %u (+%u). Acks available to us: %u. For secret %s\n",
1640 allowed,
1641 acks_to_add,
1642 receiver->acks_available,
1643 GNUNET_sh2s (&ss->master));
1644 return GNUNET_NO;
1645 }
1646 }
1648 "Matching cmac not found for ack!\n");
1649 return GNUNET_YES;
1650}
1651
1652
1661static void
1662consider_ss_ack (struct SharedSecret *ss)
1663{
1664 struct UDPAck ack;
1665 GNUNET_assert (NULL != ss->sender);
1667 "Considering SS UDPAck %s\n",
1668 GNUNET_i2s_full (&ss->sender->target));
1669
1671 "Sender has %u acks available.\n",
1672 ss->sender->acks_available);
1673 /* drop ancient KeyCacheEntries */
1674 while ((NULL != ss->kce_head) &&
1675 (MAX_SQN_DELTA <
1677 kce_destroy (ss->kce_tail);
1678
1679
1681 ack.header.size = htons (sizeof(ack));
1682 ack.sequence_ack = htonl (ss->sequence_allowed);
1683 ack.cmac = ss->cmac;
1685 "Notifying transport with UDPAck %s, sequence %u and master %s\n",
1687 ss->sequence_allowed,
1688 GNUNET_sh2s (&(ss->master)));
1690 &ss->sender->target,
1692 &ack.header);
1693}
1694
1695
1696static void
1697kce_generate_cb (void *cls)
1698{
1699 struct SharedSecret *ss = cls;
1700 ss->sender->kce_task = NULL;
1701
1703 "Precomputing %u keys for master %s\n",
1705 GNUNET_sh2s (&ss->master));
1706 if ((ss->override_available_acks != GNUNET_YES) &&
1707 (KCN_TARGET < ss->sender->acks_available))
1708 return;
1709 for (int i = 0; i < GENERATE_AT_ONCE; i++)
1710 kce_generate (ss, ++ss->sequence_allowed);
1711
1716 if (KCN_TARGET > ss->sender->acks_available)
1717 {
1721 ss);
1722 return;
1723 }
1725 "We have enough keys (ACKs: %u).\n", ss->sender->acks_available);
1729 consider_ss_ack (ss);
1730}
1731
1732
1741static void
1743 const void *buf,
1744 size_t buf_size)
1745{
1746 const struct GNUNET_MessageHeader *hdr;
1747 const struct UDPAck *ack;
1748 const struct UDPRekey *rekey;
1749 struct SharedSecret *ss_rekey;
1750 const char *buf_pos = buf;
1751 size_t bytes_remaining = buf_size;
1752 uint16_t type;
1753
1754 hdr = (struct GNUNET_MessageHeader*) buf_pos;
1755 if (sizeof(*hdr) > bytes_remaining)
1756 {
1757 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Plaintext too short, dropping...\n");
1758 return; /* no data left */
1759 }
1761 "try_handle_plaintext of size %llu (%u %lu) and type %u\n",
1762 (unsigned long long) bytes_remaining,
1763 ntohs (hdr->size),
1764 sizeof(*hdr),
1765 ntohs (hdr->type));
1766 if (ntohs (hdr->size) > bytes_remaining)
1767 return; /* buffer too short for indicated message length */
1768 type = ntohs (hdr->type);
1769 switch (type)
1770 {
1772 rekey = (struct UDPRekey*) buf_pos;
1773 ss_rekey = setup_shared_secret_dec (&rekey->ephemeral);
1774 ss_rekey->sender = sender;
1775 GNUNET_CONTAINER_DLL_insert (sender->ss_head, sender->ss_tail, ss_rekey);
1776 sender->num_secrets++;
1778 "Received rekey secret with cmac %s\n",
1779 GNUNET_h2s (&(ss_rekey->cmac)));
1781 "Received secret with master %s.\n",
1782 GNUNET_sh2s (&(ss_rekey->master)));
1784 "We have %u sequence_allowed.\n",
1785 ss_rekey->sequence_allowed);
1787 "We have a sender %p\n",
1788 ss_rekey->sender);
1790 "We have %u acks available.\n",
1791 ss_rekey->sender->acks_available);
1793 "# rekeying successful",
1794 1,
1795 GNUNET_NO);
1798 // FIXME
1799 kce_generate_cb (ss_rekey);
1800 /* ss_rekey->sender->kce_task = GNUNET_SCHEDULER_add_delayed (
1801 WORKING_QUEUE_INTERVALL,
1802 kce_generate_cb,
1803 ss_rekey);*/
1804 // FIXME: Theoretically, this could be an Ack
1805 buf_pos += ntohs (hdr->size);
1806 bytes_remaining -= ntohs (hdr->size);
1807 pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
1808 if (0 == purge_secrets (sender->ss_tail))
1809 {
1810 // No secret purged. Delete oldest.
1811 if (sender->num_secrets > MAX_SECRETS)
1812 {
1813 secret_destroy (sender->ss_tail);
1814 }
1815 }
1816 break;
1818 /* lookup master secret by 'cmac', then update sequence_max */
1819 ack = (struct UDPAck*) buf_pos;
1821 &sender->key,
1822 &handle_ack,
1823 (void *) ack);
1824 /* There could be more messages after the ACK, handle those as well */
1825 buf_pos += ntohs (hdr->size);
1826 bytes_remaining -= ntohs (hdr->size);
1827 pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
1828 break;
1829
1831 /* skip padding */
1832 break;
1833
1834 default:
1835 pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
1836 }
1837 return;
1838}
1839
1840
1848static void
1849decrypt_box (const struct UDPBox *box,
1850 size_t box_len,
1851 struct KeyCacheEntry *kce)
1852{
1853 struct SharedSecret *ss = kce->ss;
1854 struct SharedSecret *ss_c = ss->sender->ss_tail;
1855 struct SharedSecret *ss_tmp;
1856 int ss_destroyed = 0;
1857 char out_buf[box_len - sizeof(*box)];
1858
1859 GNUNET_assert (NULL != ss->sender);
1860 if (GNUNET_OK != try_decrypt (ss,
1861 box->gcm_tag,
1862 kce->sequence_number,
1863 (const char *) &box[1],
1864 sizeof(out_buf),
1865 out_buf))
1866 {
1867 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed decryption.\n");
1869 "# Decryption failures with valid KCE",
1870 1,
1871 GNUNET_NO);
1872 kce_destroy (kce);
1873 ss->sender->acks_available--;
1874 return;
1875 }
1876 kce_destroy (kce);
1877 kce = NULL;
1878 ss->bytes_sent += box_len;
1879 ss->sender->acks_available--;
1880 ss->sequence_used++;
1882 "# bytes decrypted with BOX",
1883 sizeof(out_buf),
1884 GNUNET_NO);
1886 "# messages decrypted with BOX",
1887 1,
1888 GNUNET_NO);
1890 "decrypted UDPBox with kid %s\n",
1891 GNUNET_sh2s (&box->kid));
1892 try_handle_plaintext (ss->sender, out_buf, sizeof(out_buf));
1893
1894 while (NULL != ss_c)
1895 {
1896 if (ss_c->bytes_sent >= rekey_max_bytes)
1897 {
1899 "Removing SS because rekey bytes reached.\n");
1900 ss_tmp = ss_c->prev;
1901 if (ss == ss_c)
1902 ss_destroyed = 1;
1903 secret_destroy (ss_c);
1904 ss_c = ss_tmp;
1905 continue;
1906 }
1907 ss_c = ss_c->prev;
1908 }
1909 if (1 == ss_destroyed)
1910 return;
1912 "Sender has %u ack left.\n",
1913 ss->sender->acks_available);
1914 if ((KCN_THRESHOLD > ss->sender->acks_available) &&
1915 (NULL == ss->sender->kce_task) &&
1917 {
1919 "Sender has %u ack left which is under threshold.\n",
1920 ss->sender->acks_available);
1924 ss);
1925 }
1926}
1927
1928
1932struct SearchContext
1933{
1937 const struct sockaddr *address;
1938
1942 socklen_t address_len;
1943
1947 struct SenderAddress *sender;
1948};
1949
1950
1962static struct SenderAddress *
1964 const struct sockaddr *address,
1965 socklen_t address_len)
1966{
1967 struct SenderAddress *sender;
1968 struct GNUNET_HashContext *hsh;
1969 struct GNUNET_HashCode sender_key;
1970
1972 GNUNET_CRYPTO_hash_context_read (hsh, address, address_len);
1973 GNUNET_CRYPTO_hash_context_read (hsh, target, sizeof(*target));
1974 GNUNET_CRYPTO_hash_context_finish (hsh, &sender_key);
1975
1976 sender = GNUNET_CONTAINER_multihashmap_get (senders, &sender_key);
1977 if (NULL != sender)
1978 {
1980 return sender;
1981 }
1982 sender = GNUNET_new (struct SenderAddress);
1983 sender->key = sender_key;
1984 sender->target = *target;
1985 sender->address = GNUNET_memdup (address, address_len);
1986 sender->address_len = address_len;
1988 senders,
1989 &sender->key,
1990 sender,
1993 "# senders active",
1995 GNUNET_NO);
1996 sender->timeout =
1999 sender,
2000 sender->timeout.abs_value_us);
2001 sender->nt = GNUNET_NT_scanner_get_type (is, address, address_len);
2002 if (NULL == timeout_task)
2004 return sender;
2005}
2006
2007
2015static int
2017 const struct UDPConfirmation *uc)
2018{
2019 const struct GNUNET_PeerIdentity *my_identity;
2020 struct UdpHandshakeSignature uhs;
2021
2024
2025 uhs.purpose.purpose = htonl (
2027 uhs.purpose.size = htonl (sizeof(uhs));
2028 uhs.sender = uc->sender;
2029 uhs.receiver = *my_identity;
2030 uhs.enc = *enc;
2031 uhs.monotonic_time = uc->monotonic_time;
2034 &uhs,
2035 &uc->sender_sig,
2036 &uc->sender.public_key);
2037}
2038
2039
2048static char *
2049sockaddr_to_udpaddr_string (const struct sockaddr *address,
2050 socklen_t address_len)
2051{
2052 char *ret;
2053
2054 switch (address->sa_family)
2055 {
2056 case AF_INET:
2058 "%s-%s",
2060 GNUNET_a2s (address, address_len));
2061 break;
2062
2063 case AF_INET6:
2065 "%s-%s",
2067 GNUNET_a2s (address, address_len));
2068 break;
2069
2070 default:
2071 GNUNET_assert (0);
2072 }
2073 return ret;
2074}
2075
2076
2077static struct GNUNET_NETWORK_Handle *
2079{
2081
2082 if (NULL == receiver->udp_sock)
2083 {
2084 if (AF_INET6 == receiver->address->sa_family)
2086 else
2088 }
2089 else
2090 udp_sock = receiver->udp_sock;
2091
2092 return udp_sock;
2093}
2094
2095
2104static struct sockaddr *
2105udp_address_to_sockaddr (const char *bindto,
2106 sa_family_t family,
2107 socklen_t *sock_len)
2108{
2109 struct sockaddr *in;
2110 unsigned int port;
2111 char dummy[2];
2112 char *colon;
2113 char *cp;
2114
2115 if (1 == sscanf (bindto, "%u%1s", &port, dummy))
2116 {
2117 /* interpreting value as just a PORT number */
2118 if (port > UINT16_MAX)
2119 {
2121 "BINDTO specification `%s' invalid: value too large for port\n",
2122 bindto);
2123 return NULL;
2124 }
2125 if ((AF_INET == family) || (GNUNET_YES == disable_v6))
2126 {
2127 struct sockaddr_in *i4;
2128
2129 i4 = GNUNET_malloc (sizeof(struct sockaddr_in));
2130 i4->sin_family = AF_INET;
2131 i4->sin_port = htons ((uint16_t) port);
2132 *sock_len = sizeof(struct sockaddr_in);
2133 in = (struct sockaddr *) i4;
2134 }
2135 else
2136 {
2137 struct sockaddr_in6 *i6;
2138
2139 i6 = GNUNET_malloc (sizeof(struct sockaddr_in6));
2140 i6->sin6_family = AF_INET6;
2141 i6->sin6_port = htons ((uint16_t) port);
2142 *sock_len = sizeof(struct sockaddr_in6);
2143 in = (struct sockaddr *) i6;
2144 }
2145 return in;
2146 }
2147 cp = GNUNET_strdup (bindto);
2148 colon = strrchr (cp, ':');
2149 if (NULL != colon)
2150 {
2151 /* interpret value after colon as port */
2152 *colon = '\0';
2153 colon++;
2154 if (1 == sscanf (colon, "%u%1s", &port, dummy))
2155 {
2156 /* interpreting value as just a PORT number */
2157 if (port > UINT16_MAX)
2158 {
2160 "BINDTO specification `%s' invalid: value too large for port\n",
2161 bindto);
2162 GNUNET_free (cp);
2163 return NULL;
2164 }
2165 }
2166 else
2167 {
2168 GNUNET_log (
2170 "BINDTO specification `%s' invalid: last ':' not followed by number\n",
2171 bindto);
2172 GNUNET_free (cp);
2173 return NULL;
2174 }
2175 }
2176 else
2177 {
2178 /* interpret missing port as 0, aka pick any free one */
2179 port = 0;
2180 }
2181 if (AF_INET6 != family)
2182 {
2183 /* try IPv4 */
2184 struct sockaddr_in v4;
2185
2186 memset (&v4, 0, sizeof(v4));
2187 if (1 == inet_pton (AF_INET, cp, &v4.sin_addr))
2188 {
2189 v4.sin_family = AF_INET;
2190 v4.sin_port = htons ((uint16_t) port);
2191#if HAVE_SOCKADDR_IN_SIN_LEN
2192 v4.sin_len = sizeof(struct sockaddr_in);
2193#endif
2194 in = GNUNET_memdup (&v4, sizeof(struct sockaddr_in));
2195 *sock_len = sizeof(struct sockaddr_in);
2196 GNUNET_free (cp);
2197 return in;
2198 }
2199 }
2200 if (AF_INET != family)
2201 {
2202 /* try IPv6 */
2203 struct sockaddr_in6 v6;
2204 const char *start;
2205
2206 memset (&v6, 0, sizeof(v6));
2207 start = cp;
2208 if (('[' == *cp) && (']' == cp[strlen (cp) - 1]))
2209 {
2210 start++; /* skip over '[' */
2211 cp[strlen (cp) - 1] = '\0'; /* eat ']' */
2212 }
2213 if (1 == inet_pton (AF_INET6, start, &v6.sin6_addr))
2214 {
2215 v6.sin6_family = AF_INET6;
2216 v6.sin6_port = htons ((uint16_t) port);
2217#if HAVE_SOCKADDR_IN_SIN_LEN
2218 v6.sin6_len = sizeof(struct sockaddr_in6);
2219#endif
2220 in = GNUNET_memdup (&v6, sizeof(v6));
2221 *sock_len = sizeof(v6);
2222 GNUNET_free (cp);
2223 return in;
2224 }
2225 }
2226 /* #5528 FIXME (feature!): maybe also try getnameinfo()? */
2227 GNUNET_free (cp);
2228 return NULL;
2229}
2230
2231
2232static void
2233sock_read (void *cls);
2234
2235
2236static enum GNUNET_GenericReturnValue
2237create_receiver (const struct GNUNET_PeerIdentity *peer,
2238 const char *address,
2240{
2241 struct GNUNET_HashContext *hsh;
2242 struct ReceiverAddress *receiver;
2243 struct GNUNET_HashCode receiver_key;
2244 const char *path;
2245 struct sockaddr *in;
2246 socklen_t in_len;
2247
2248 if (0 != strncmp (address,
2250 strlen (COMMUNICATOR_ADDRESS_PREFIX "-")))
2251 {
2252 GNUNET_break_op (0);
2253 return GNUNET_SYSERR;
2254 }
2255 path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")];
2256 in = udp_address_to_sockaddr (path, AF_UNSPEC, &in_len);
2257
2258 if (NULL == in)
2259 {
2261 "Failed to setup UDP socket address\n");
2262 return GNUNET_SYSERR;
2263 }
2264 if ((AF_INET6 == in->sa_family) &&
2266 {
2268 "IPv6 disabled, skipping %s\n", address);
2269 GNUNET_free (in);
2270 return GNUNET_SYSERR;
2271 }
2272 else if (AF_INET == in->sa_family)
2273 {
2274 struct sockaddr_in *sin = (struct sockaddr_in *) in;
2275 if (0 == sin->sin_port)
2276 {
2277 GNUNET_free (in);
2278 return GNUNET_NO;
2279 }
2280 }
2281
2283 GNUNET_CRYPTO_hash_context_read (hsh, in, in_len);
2284 GNUNET_CRYPTO_hash_context_read (hsh, peer, sizeof(*peer));
2285 GNUNET_CRYPTO_hash_context_finish (hsh, &receiver_key);
2286
2288 if (NULL != receiver)
2289 {
2291 "receiver %s already exist or is being connected to\n",
2292 address);
2293 return GNUNET_NO;
2294 }
2295
2297 receiver->udp_sock = udp_sock;
2298 receiver->key = receiver_key;
2299 receiver->address = in;
2300 receiver->address_len = in_len;
2301 receiver->target = *peer;
2302 eddsa_pub_to_hpke_key (&receiver->target.public_key,
2303 &receiver->target_hpke_key);
2304 receiver->nt = GNUNET_NT_scanner_get_type (is, in, in_len);
2306 receivers,
2307 &receiver->key,
2308 receiver,
2311 "Added %s to receivers with address %s and sock %p\n",
2312 GNUNET_i2s_full (&receiver->target),
2313 address,
2314 udp_sock);
2315 receiver->timeout =
2318 receiver,
2319 receiver->timeout.abs_value_us);
2321 "# receivers active",
2323 GNUNET_NO);
2324 receiver->foreign_addr =
2325 sockaddr_to_udpaddr_string (receiver->address, receiver->address_len);
2326 if (NULL != udp_sock)
2329 udp_sock,
2330 &sock_read,
2331 udp_sock);
2333 if (NULL == timeout_task)
2335 return GNUNET_OK;
2336}
2337
2338
2344static void
2345sock_read (void *cls)
2346{
2347 struct sockaddr_storage sa;
2348 struct sockaddr_in *addr_verify;
2349 socklen_t salen = sizeof(sa);
2350 char buf[UINT16_MAX];
2351 ssize_t rcvd;
2352
2353 struct GNUNET_NETWORK_Handle *udp_sock = cls;
2354
2357 udp_sock,
2358 &sock_read,
2359 udp_sock);
2362 udp_sock,
2363 &sock_read,
2364 udp_sock);
2365 while (1)
2366 {
2368 buf,
2369 sizeof(buf),
2370 (struct sockaddr *) &sa,
2371 &salen);
2372 if (-1 == rcvd)
2373 {
2374 struct sockaddr *addr = (struct sockaddr*) &sa;
2375
2376 if (EAGAIN == errno)
2377 break; // We are done reading data
2379 "Failed to recv from %s family %d failed sock %p\n",
2380 GNUNET_a2s ((struct sockaddr*) &sa,
2381 sizeof (*addr)),
2382 addr->sa_family,
2383 udp_sock);
2385 return;
2386 }
2388 "Read %llu bytes\n",
2389 (unsigned long long) rcvd);
2390 if (0 == rcvd)
2391 {
2392 GNUNET_break_op (0);
2394 "Read 0 bytes from UDP socket\n");
2395 return;
2396 }
2397
2398 /* first, see if it is a GNUNET_BurstMessage */
2399 if (rcvd == sizeof (struct GNUNET_BurstMessage))
2400 {
2401 struct GNUNET_BurstMessage *bm = (struct GNUNET_BurstMessage *) buf;
2402 struct sockaddr *addr = (struct sockaddr*) &sa;
2403 char *address = sockaddr_to_udpaddr_string (addr, sizeof (*addr));
2404
2405 GNUNET_assert (0 == bm->local_port);
2407 "Received a burst message for default port\n");
2408 create_receiver (&bm->peer,
2409 address,
2410 NULL);
2411 if (AF_INET6 == addr->sa_family)
2413 else
2417 return;
2418 }
2419 /* second, see if it is a UDPBox */
2420 if (rcvd > sizeof(struct UDPBox))
2421 {
2422 const struct UDPBox *box;
2423 struct KeyCacheEntry *kce;
2424
2425 box = (const struct UDPBox *) buf;
2427 if (NULL != kce)
2428 {
2430 "Found KCE with kid %s\n",
2431 GNUNET_sh2s (&box->kid));
2432 decrypt_box (box, (size_t) rcvd, kce);
2433 continue;
2434 }
2435 }
2436
2437 /* next, check if it is a broadcast */
2438 if (sizeof(struct UDPBroadcast) == rcvd)
2439 {
2440 const struct GNUNET_PeerIdentity *my_identity;
2441 const struct UDPBroadcast *ub;
2442 struct UdpBroadcastSignature uhs;
2443 struct GNUNET_PeerIdentity sender;
2444
2447
2448 addr_verify = GNUNET_memdup (&sa, salen);
2449 addr_verify->sin_port = 0;
2451 "received UDPBroadcast from %s\n",
2452 GNUNET_a2s ((const struct sockaddr *) addr_verify, salen));
2453 ub = (const struct UDPBroadcast *) buf;
2454 uhs.purpose.purpose = htonl (
2456 uhs.purpose.size = htonl (sizeof(uhs));
2457 uhs.sender = ub->sender;
2458 sender = ub->sender;
2459 if (0 == memcmp (&sender, my_identity, sizeof (struct
2461 {
2463 "Received our own broadcast\n");
2464 GNUNET_free (addr_verify);
2465 continue;
2466 }
2468 "checking UDPBroadcastSignature for %s\n",
2469 GNUNET_i2s (&sender));
2470 GNUNET_CRYPTO_hash ((struct sockaddr *) addr_verify, salen,
2471 &uhs.h_address);
2472 if (GNUNET_OK ==
2475 &uhs,
2476 &ub->sender_sig,
2477 &ub->sender.public_key))
2478 {
2479 char *addr_s;
2481
2482 addr_s =
2483 sockaddr_to_udpaddr_string ((const struct sockaddr *) &sa, salen);
2484 GNUNET_STATISTICS_update (stats, "# broadcasts received", 1, GNUNET_NO);
2485 /* use our own mechanism to determine network type */
2486 nt =
2487 GNUNET_NT_scanner_get_type (is, (const struct sockaddr *) &sa, salen);
2489 "validating address %s received from UDPBroadcast\n",
2490 GNUNET_i2s (&sender));
2492 GNUNET_free (addr_s);
2493 GNUNET_free (addr_verify);
2494 continue;
2495 }
2496 else
2497 {
2499 "VerifyingPeer %s is verifying UDPBroadcast\n",
2502 "Verifying UDPBroadcast from %s failed\n",
2503 GNUNET_i2s (&ub->sender));
2504 }
2505 GNUNET_free (addr_verify);
2506 /* continue with KX, mostly for statistics... */
2507 }
2508
2509
2510 /* finally, test if it is a KX */
2511 if (rcvd < sizeof(struct UDPConfirmation) + sizeof(struct InitialKX))
2512 {
2514 "# messages dropped (no kid, too small for KX)",
2515 1,
2516 GNUNET_NO);
2517 continue;
2518 }
2520 "Got KX\n");
2521 {
2522 const struct InitialKX *kx;
2523 struct SharedSecret *ss;
2524 char pbuf[rcvd - sizeof(struct InitialKX)];
2525 const struct UDPConfirmation *uc;
2526 struct SenderAddress *sender;
2527
2528 kx = (const struct InitialKX *) buf;
2531 "Before DEC\n");
2532
2533 if (GNUNET_OK != try_decrypt (ss,
2534 kx->gcm_tag,
2535 0,
2536 &buf[sizeof(*kx)],
2537 sizeof(pbuf),
2538 pbuf))
2539 {
2541 "Unable to decrypt tag, dropping...\n");
2542 GNUNET_free (ss);
2544 stats,
2545 "# messages dropped (no kid, AEAD decryption failed)",
2546 1,
2547 GNUNET_NO);
2548 continue;
2549 }
2551 "Before VERIFY\n");
2552
2553 uc = (const struct UDPConfirmation *) pbuf;
2554
2555 if (GNUNET_OK != verify_confirmation (&kx->enc, uc)) // TODO: need ephemeral instead of representative
2556 {
2557 GNUNET_break_op (0);
2558 GNUNET_free (ss);
2560 "# messages dropped (sender signature invalid)",
2561 1,
2562 GNUNET_NO);
2563 continue;
2564 }
2566 "Before SETUP_SENDER\n");
2567
2568 calculate_cmac (ss);
2569 sender = setup_sender (&uc->sender, (const struct sockaddr *) &sa, salen);
2570 ss->sender = sender;
2571 GNUNET_CONTAINER_DLL_insert (sender->ss_head, sender->ss_tail, ss);
2572 if ((KCN_THRESHOLD > ss->sender->acks_available) &&
2573 (NULL == ss->sender->kce_task) &&
2575 {
2576 // 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.
2580 ss);
2581 }
2582 sender->num_secrets++;
2583 GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
2585 "# messages decrypted without BOX",
2586 1,
2587 GNUNET_NO);
2588 try_handle_plaintext (sender, &uc[1], sizeof(pbuf) - sizeof(*uc));
2589 if (0 == purge_secrets (sender->ss_tail))
2590 {
2591 // No secret purged. Delete oldest.
2592 if (sender->num_secrets > MAX_SECRETS)
2593 {
2594 secret_destroy (sender->ss_tail);
2595 }
2596 }
2597 }
2598 }
2599}
2600
2601
2609static void
2610do_pad (gcry_cipher_hd_t out_cipher, char *dgram, size_t pad_size)
2611{
2612 char pad[pad_size];
2613
2615 if (sizeof(pad) > sizeof(struct GNUNET_MessageHeader))
2616 {
2617 struct GNUNET_MessageHeader hdr =
2618 { .size = htons (sizeof(pad)),
2620
2621 memcpy (pad, &hdr, sizeof(hdr));
2622 }
2624 0 ==
2625 gcry_cipher_encrypt (out_cipher, dgram, sizeof(pad), pad, sizeof(pad)));
2626}
2627
2628
2629static void
2630send_msg_with_kx (const struct GNUNET_MessageHeader *msg, struct
2632 struct GNUNET_MQ_Handle *mq)
2633{
2634 const struct GNUNET_PeerIdentity *my_identity;
2636 uint16_t msize = ntohs (msg->size);
2637 struct UdpHandshakeSignature uhs;
2638 struct UDPConfirmation uc;
2639 struct InitialKX kx;
2640 char dgram[receiver->kx_mtu + sizeof(uc) + sizeof(kx)];
2641 size_t dpos;
2642 gcry_cipher_hd_t out_cipher;
2643 struct SharedSecret *ss;
2644
2648
2649 if (msize > receiver->kx_mtu)
2650 {
2651 GNUNET_break (0);
2652 if (GNUNET_YES != receiver->receiver_destroy_called)
2654 return;
2655 }
2657
2658 /* setup key material */
2660
2661 if (0 == purge_secrets (receiver->ss_tail))
2662 {
2663 // No secret purged. Delete oldest.
2664 if (receiver->num_secrets > MAX_SECRETS)
2665 {
2666 secret_destroy (receiver->ss_tail);
2667 }
2668 }
2669
2670 setup_cipher (&ss->master, 0, &out_cipher);
2671 /* compute 'uc' */
2672 uc.sender = *my_identity;
2673 uc.monotonic_time =
2675 uhs.purpose.purpose = htonl (
2677 uhs.purpose.size = htonl (sizeof(uhs));
2678 uhs.sender = *my_identity;
2679 uhs.receiver = receiver->target;
2680 uhs.monotonic_time = uc.monotonic_time;
2682 &uhs,
2683 &uc.sender_sig);
2684 /* Leave space for kx */
2685 dpos = sizeof(kx);
2686 /* Append encrypted uc to dgram */
2687 GNUNET_assert (0 == gcry_cipher_encrypt (out_cipher,
2688 &dgram[dpos],
2689 sizeof(uc),
2690 &uc,
2691 sizeof(uc)));
2692 dpos += sizeof(uc);
2693 /* Append encrypted payload to dgram */
2695 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], msize, msg, msize));
2696 dpos += msize;
2697 do_pad (out_cipher, &dgram[dpos], sizeof(dgram) - dpos);
2698 /* Datagram starts with kx */
2699 kx.enc = uhs.enc;
2701 0 == gcry_cipher_gettag (out_cipher, kx.gcm_tag, sizeof(kx.gcm_tag)));
2702 gcry_cipher_close (out_cipher);
2703 memcpy (dgram, &kx, sizeof(kx));
2705 dgram,
2706 sizeof(dgram),
2707 receiver->address,
2708 receiver->address_len))
2709 {
2712 "Sending KX with payload size %u to %s family %d failed sock %p\n",
2713 msize,
2714 GNUNET_a2s (receiver->address,
2715 receiver->address_len),
2716 receiver->address->sa_family,
2720 return;
2721 }
2723 "Sending KX with payload size %u to %s with socket %p\n",
2724 msize,
2725 GNUNET_a2s (receiver->address,
2726 receiver->address_len),
2729}
2730
2731
2740static void
2742 const struct GNUNET_MessageHeader *msg,
2743 void *impl_state)
2744{
2745 struct ReceiverAddress *receiver = impl_state;
2746
2747 GNUNET_assert (mq == receiver->kx_mq);
2749}
2750
2751
2752static void
2753create_rekey (struct ReceiverAddress *receiver, struct SharedSecret *ss, struct
2754 UDPRekey *rekey)
2755{
2756 struct SharedSecret *ss_rekey;
2757
2759 /* setup key material */
2760 ss_rekey = setup_shared_secret_ephemeral (&rekey->ephemeral,
2761 receiver);
2762 ss_rekey->sequence_allowed = 0;
2764 "Setup secret with k = %s\n",
2765 GNUNET_sh2s (&ss_rekey->master));
2767 "Setup secret with H(k) = %s\n",
2768 GNUNET_h2s (&(ss_rekey->cmac)));
2769
2770 /* Append encrypted payload to dgram */
2772 rekey->header.size = htons (sizeof (struct UDPRekey));
2773}
2774
2775
2784static void
2786 const struct GNUNET_MessageHeader *msg,
2787 void *impl_state)
2788{
2789 struct ReceiverAddress *receiver = impl_state;
2790 struct UDPRekey rekey;
2791 struct SharedSecret *ss;
2792 int inject_rekey = GNUNET_NO;
2793 uint16_t msize = ntohs (msg->size);
2794
2795 GNUNET_assert (mq == receiver->d_mq);
2796 if ((msize > receiver->d_mtu) ||
2797 (0 == receiver->acks_available))
2798 {
2800 "msize: %u, mtu: %llu, acks: %u\n",
2801 (unsigned int) msize,
2802 (unsigned long long) receiver->d_mtu,
2803 receiver->acks_available);
2804
2805 GNUNET_break (0);
2806 if (GNUNET_YES != receiver->receiver_destroy_called)
2808 return;
2809 }
2811
2812 if (receiver->num_secrets > MAX_SECRETS)
2813 {
2814 if ((0 == purge_secrets (receiver->ss_tail)) &&
2815 (NULL != receiver->ss_tail))
2816 {
2817 // No secret purged. Delete oldest.
2818 secret_destroy (receiver->ss_tail);
2819 }
2820 }
2821 /* begin "BOX" encryption method, scan for ACKs from tail! */
2822 ss = receiver->ss_tail;
2823 while (NULL != ss)
2824 {
2825 size_t payload_len = sizeof(struct UDPBox) + receiver->d_mtu;
2827 "Considering SS %s sequence used: %u sequence allowed: %u bytes sent: %lu.\n",
2828 GNUNET_sh2s (&ss->master), ss->sequence_used,
2829 ss->sequence_allowed, ss->bytes_sent);
2830 if (ss->sequence_used >= ss->sequence_allowed)
2831 {
2832 // GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2833 // "Skipping ss because no acks to use.\n");
2834 ss = ss->prev;
2835 continue;
2836 }
2837 if (ss->bytes_sent >= rekey_max_bytes)
2838 {
2839 struct SharedSecret *ss_tmp;
2841 "Skipping ss because rekey bytes reached.\n");
2842 // FIXME cleanup ss with too many bytes sent!
2843 ss_tmp = ss->prev;
2844 secret_destroy (ss);
2845 ss = ss_tmp;
2846 continue;
2847 }
2848 if (ss->bytes_sent > rekey_max_bytes * 0.7)
2849 {
2850 if (ss->rekey_initiated == GNUNET_NO)
2851 {
2853 "Injecting rekey for ss with byte sent %lu\n",
2854 (unsigned long) ss->bytes_sent);
2855 create_rekey (receiver, ss, &rekey);
2857 payload_len += sizeof (rekey);
2859 }
2860 }
2861 if (0 < ss->sequence_used)
2863 "Trying to send UDPBox with shared secret %s sequence_used %u and ss->sequence_allowed %u\n",
2864 GNUNET_sh2s (&ss->master),
2865 ss->sequence_used,
2866 ss->sequence_allowed);
2867 {
2868 char dgram[payload_len];
2869 struct UDPBox *box;
2870 gcry_cipher_hd_t out_cipher;
2871 size_t dpos;
2872
2873 box = (struct UDPBox *) dgram;
2874 ss->sequence_used++;
2875 get_kid (&ss->master, ss->sequence_used, &box->kid);
2876 setup_cipher (&ss->master, ss->sequence_used, &out_cipher);
2877 /* Append encrypted payload to dgram */
2878 dpos = sizeof(struct UDPBox);
2879 if (GNUNET_YES == inject_rekey)
2880 {
2882 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], sizeof (rekey),
2883 &rekey, sizeof (rekey)));
2884 dpos += sizeof (rekey);
2885 }
2887 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], msize, msg, msize));
2888 dpos += msize;
2889 do_pad (out_cipher, &dgram[dpos], sizeof(dgram) - dpos);
2890 GNUNET_assert (0 == gcry_cipher_gettag (out_cipher,
2891 box->gcm_tag,
2892 sizeof(box->gcm_tag)));
2893 gcry_cipher_close (out_cipher);
2894
2896 dgram,
2897 payload_len, // FIXME why always send sizeof dgram?
2898 receiver->address,
2899 receiver->address_len))
2900 {
2903 "Sending UDPBox to %s family %d failed sock %p failed\n",
2904 GNUNET_a2s (receiver->address,
2905 receiver->address_len),
2906 receiver->address->sa_family,
2909 return;
2910 }
2912 "Sending UDPBox with payload size %u, %u acks left, %lu bytes sent with socket %p\n",
2913 msize,
2914 receiver->acks_available,
2915 (unsigned long) ss->bytes_sent,
2917 ss->bytes_sent += sizeof (dgram);
2918 receiver->acks_available--;
2920 return;
2921 }
2922 }
2924 "No suitable ss found, sending as KX...\n");
2926}
2927
2928
2937static void
2938mq_destroy_d (struct GNUNET_MQ_Handle *mq, void *impl_state)
2939{
2940 struct ReceiverAddress *receiver = impl_state;
2942 "Default MQ destroyed\n");
2943 if (mq == receiver->d_mq)
2944 {
2945 receiver->d_mq = NULL;
2946 if (GNUNET_YES != receiver->receiver_destroy_called)
2948 }
2949}
2950
2951
2960static void
2961mq_destroy_kx (struct GNUNET_MQ_Handle *mq, void *impl_state)
2962{
2963 struct ReceiverAddress *receiver = impl_state;
2965 "KX MQ destroyed\n");
2966 if (mq == receiver->kx_mq)
2967 {
2968 receiver->kx_mq = NULL;
2969 if (GNUNET_YES != receiver->receiver_destroy_called)
2971 }
2972}
2973
2974
2981static void
2982mq_cancel (struct GNUNET_MQ_Handle *mq, void *impl_state)
2983{
2984 /* Cancellation is impossible with UDP; bail */
2985 GNUNET_assert (0);
2986}
2987
2988
2998static void
2999mq_error (void *cls, enum GNUNET_MQ_Error error)
3000{
3001 struct ReceiverAddress *receiver = cls;
3002
3004 "MQ error in queue to %s: %d\n",
3005 GNUNET_i2s (&receiver->target),
3006 (int) error);
3008}
3009
3010
3018static void
3020{
3021 size_t base_mtu;
3022
3023 switch (receiver->address->sa_family)
3024 {
3025 case AF_INET:
3026 base_mtu = 1480 /* Ethernet MTU, 1500 - Ethernet header - VLAN tag */
3027 - sizeof(struct GNUNET_TUN_IPv4Header) /* 20 */
3028 - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */;
3029 break;
3030
3031 case AF_INET6:
3032 base_mtu = 1280 /* Minimum MTU required by IPv6 */
3033 - sizeof(struct GNUNET_TUN_IPv6Header) /* 40 */
3034 - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */;
3035 break;
3036
3037 default:
3038 GNUNET_assert (0);
3039 break;
3040 }
3041 /* MTU based on full KX messages */
3042 receiver->kx_mtu = base_mtu - sizeof(struct InitialKX) /* 48 */
3043 - sizeof(struct UDPConfirmation); /* 104 */
3044 /* MTU based on BOXed messages */
3045 receiver->d_mtu = base_mtu - sizeof(struct UDPBox);
3046
3048 "Setting up MQs and QHs\n");
3049 /* => Effective MTU for CORE will range from 1080 (IPv6 + KX) to
3050 1404 (IPv4 + Box) bytes, depending on circumstances... */
3051 if (NULL == receiver->kx_mq)
3054 &mq_cancel,
3055 receiver,
3056 NULL,
3057 &mq_error,
3058 receiver);
3059 if (NULL == receiver->d_mq)
3061 &mq_destroy_d,
3062 &mq_cancel,
3063 receiver,
3064 NULL,
3065 &mq_error,
3066 receiver);
3067
3068 receiver->kx_qh =
3070 &receiver->target,
3071 receiver->foreign_addr,
3072 receiver->kx_mtu,
3074 0, /* Priority */
3075 receiver->nt,
3077 receiver->kx_mq);
3078}
3079
3080
3099static int
3100mq_init (void *cls, const struct GNUNET_PeerIdentity *peer, const char *address)
3101{
3102 (void) cls;
3104 "create receiver for mq_init\n");
3105 return create_receiver (peer,
3106 address,
3107 NULL);
3108}
3109
3110
3119static int
3120get_receiver_delete_it (void *cls,
3121 const struct GNUNET_HashCode *target,
3122 void *value)
3123{
3124 struct ReceiverAddress *receiver = value;
3125
3126 (void) cls;
3127 (void) target;
3129 return GNUNET_OK;
3130}
3131
3132
3141static int
3142get_sender_delete_it (void *cls,
3143 const struct GNUNET_HashCode *target,
3144 void *value)
3145{
3146 struct SenderAddress *sender = value;
3147
3148 (void) cls;
3149 (void) target;
3150
3151
3152 sender_destroy (sender);
3153 return GNUNET_OK;
3154}
3155
3156
3162static void
3163do_shutdown (void *cls)
3164{
3166 "do_shutdown\n");
3167 GNUNET_stop_burst (NULL);
3168 if (NULL != nat)
3169 {
3171 nat = NULL;
3172 }
3173 while (NULL != bi_head)
3175 if (NULL != broadcast_task)
3176 {
3178 broadcast_task = NULL;
3179 }
3180 if (NULL != timeout_task)
3181 {
3183 timeout_task = NULL;
3184 }
3185 if (NULL != read_v6_task)
3186 {
3188 read_v6_task = NULL;
3189 }
3190 if (NULL != read_v4_task)
3191 {
3193 read_v4_task = NULL;
3194 }
3195 if (NULL != default_v6_sock)
3196 {
3199 default_v6_sock = NULL;
3200 }
3201 if (NULL != default_v4_sock)
3202 {
3205 default_v4_sock = NULL;
3206 }
3209 NULL);
3213 NULL);
3218 if (NULL != timeout_task)
3219 {
3221 timeout_task = NULL;
3222 }
3223 if (NULL != ch)
3224 {
3227 ch = NULL;
3228 }
3229 if (NULL != ah)
3230 {
3232 ah = NULL;
3233 }
3234 if (NULL != pils)
3235 {
3237 pils = NULL;
3238 }
3239 if (NULL != key_ring)
3240 {
3242 key_ring = NULL;
3243 }
3244 if (NULL != stats)
3245 {
3247 stats = NULL;
3248 }
3249 if (NULL != is)
3250 {
3252 is = NULL;
3253 }
3255 "do_shutdown finished\n");
3256}
3257
3258
3259struct AckInfo
3260{
3261 const struct UDPAck *ack;
3262
3263 const struct GNUNET_PeerIdentity *sender;
3264};
3265
3266static int
3267handle_ack_by_sender (void *cls, const struct GNUNET_HashCode *key, void *value)
3268{
3269 struct ReceiverAddress *receiver = value;
3270 struct AckInfo *ai = cls;
3271
3272 if (0 != GNUNET_memcmp (ai->sender, &receiver->target))
3273 {
3274 return GNUNET_YES;
3275 }
3276 handle_ack ((void*) ai->ack, key, receiver);
3277 return GNUNET_YES;
3278}
3279
3280
3290static void
3291enc_notify_cb (void *cls,
3292 const struct GNUNET_PeerIdentity *sender,
3293 const struct GNUNET_MessageHeader *msg)
3294{
3295 struct AckInfo ai;
3296
3297 (void) cls;
3299 "Storing UDPAck received from backchannel from %s\n",
3302 (ntohs (msg->size) != sizeof(struct UDPAck)))
3303 {
3304 GNUNET_break_op (0);
3305 return;
3306 }
3307 ai.ack = (const struct UDPAck *) msg;
3308 ai.sender = sender;
3311 &ai);
3312}
3313
3314
3328static void
3329nat_address_cb (void *cls,
3330 void **app_ctx,
3331 int add_remove,
3333 const struct sockaddr *addr,
3334 socklen_t addrlen)
3335{
3336 char *my_addr;
3338
3339 if (GNUNET_YES == add_remove)
3340 {
3342
3343 GNUNET_asprintf (&my_addr,
3344 "%s-%s",
3346 GNUNET_a2s (addr, addrlen));
3347 nt = GNUNET_NT_scanner_get_type (is, addr, addrlen);
3348 ai =
3350 my_addr,
3351 nt,
3353 GNUNET_free (my_addr);
3354 *app_ctx = ai;
3355 }
3356 else
3357 {
3358 ai = *app_ctx;
3360 *app_ctx = NULL;
3361 }
3362}
3363
3364
3370static void
3371ifc_broadcast (void *cls)
3372{
3373 struct BroadcastInterface *bi = cls;
3374 struct GNUNET_TIME_Relative delay;
3375
3376 delay = BROADCAST_FREQUENCY;
3377 delay.rel_value_us =
3379 bi->broadcast_task =
3381
3382 switch (bi->sa->sa_family)
3383 {
3384 case AF_INET: {
3385 static int yes = 1;
3386 static int no = 0;
3387 ssize_t sent;
3388
3389 if (GNUNET_OK !=
3391 SOL_SOCKET,
3392 SO_BROADCAST,
3393 &yes,
3394 sizeof(int)))
3396 "setsockopt");
3398 "creating UDPBroadcast from %s\n",
3399 GNUNET_i2s (&(bi->bcm.sender)));
3401 "sending UDPBroadcast to add %s\n",
3402 GNUNET_a2s (bi->ba, bi->salen));
3404 &bi->bcm,
3405 sizeof(bi->bcm),
3406 bi->ba,
3407 bi->salen);
3408 if (-1 == sent)
3410 "sendto");
3412 SOL_SOCKET,
3413 SO_BROADCAST,
3414 &no,
3415 sizeof(int)))
3417 "setsockopt");
3418 break;
3419 }
3420
3421 case AF_INET6: {
3422 ssize_t sent;
3423 struct sockaddr_in6 dst;
3424
3425 dst.sin6_family = AF_INET6;
3426 dst.sin6_port = htons (my_port);
3427 dst.sin6_addr = bi->mcreq.ipv6mr_multiaddr;
3428 dst.sin6_scope_id = ((struct sockaddr_in6 *) bi->ba)->sin6_scope_id;
3429
3431 "sending UDPBroadcast\n");
3433 &bi->bcm,
3434 sizeof(bi->bcm),
3435 (const struct sockaddr *) &dst,
3436 sizeof(dst));
3437 if (-1 == sent)
3439 break;
3440 }
3441
3442 default:
3443 GNUNET_break (0);
3444 break;
3445 }
3446}
3447
3448
3463static int
3464iface_proc (void *cls,
3465 const char *name,
3466 int isDefault,
3467 const struct sockaddr *addr,
3468 const struct sockaddr *broadcast_addr,
3469 const struct sockaddr *netmask,
3470 socklen_t addrlen)
3471{
3472 const struct GNUNET_PeerIdentity *my_identity;
3474 struct BroadcastInterface *bi;
3475 enum GNUNET_NetworkType network;
3476 struct UdpBroadcastSignature ubs;
3477
3478 (void) cls;
3479 (void) netmask;
3480
3483
3484 if ((NULL == my_identity) || (NULL == my_private_key))
3485 return GNUNET_YES;
3486 if (NULL == addr)
3487 return GNUNET_YES; /* need to know our address! */
3488 network = GNUNET_NT_scanner_get_type (is, addr, addrlen);
3489 if (GNUNET_NT_LOOPBACK == network)
3490 {
3491 /* Broadcasting on loopback does not make sense */
3492 return GNUNET_YES;
3493 }
3494 for (bi = bi_head; NULL != bi; bi = bi->next)
3495 {
3496 if ((bi->salen == addrlen) && (0 == memcmp (addr, bi->sa, addrlen)))
3497 {
3498 bi->found = GNUNET_YES;
3499 return GNUNET_OK;
3500 }
3501 }
3502
3503 if ((AF_INET6 == addr->sa_family) && (NULL == broadcast_addr))
3504 return GNUNET_OK; /* broadcast_addr is required for IPv6! */
3505 if ((AF_INET6 == addr->sa_family) && (NULL != default_v6_sock))
3506 return GNUNET_OK; /* not using IPv6 */
3507
3508 bi = GNUNET_new (struct BroadcastInterface);
3509 bi->sa = GNUNET_memdup (addr,
3510 addrlen);
3511 if ( (NULL != broadcast_addr) &&
3512 (addrlen == sizeof (struct sockaddr_in)) )
3513 {
3514 struct sockaddr_in *ba;
3515
3516 ba = GNUNET_memdup (broadcast_addr,
3517 addrlen);
3518 ba->sin_port = htons (2086); /* always GNUnet port, ignore configuration! */
3519 bi->ba = (struct sockaddr *) ba;
3520 }
3521 bi->salen = addrlen;
3522 bi->found = GNUNET_YES;
3523 bi->bcm.sender = *my_identity;
3524 ubs.purpose.purpose = htonl (
3526 ubs.purpose.size = htonl (sizeof(ubs));
3527 ubs.sender = *my_identity;
3529 "creating UDPBroadcastSignature for %s\n",
3530 GNUNET_a2s (addr, addrlen));
3531 GNUNET_CRYPTO_hash (addr, addrlen, &ubs.h_address);
3533 &ubs,
3534 &bi->bcm.sender_sig);
3535 if (NULL != bi->ba)
3536 {
3539 }
3540 if ((AF_INET6 == addr->sa_family) && (NULL != broadcast_addr))
3541 {
3542 /* Create IPv6 multicast request */
3543 const struct sockaddr_in6 *s6 =
3544 (const struct sockaddr_in6 *) broadcast_addr;
3545
3547 1 == inet_pton (AF_INET6, "FF05::13B", &bi->mcreq.ipv6mr_multiaddr));
3548
3549 /* http://tools.ietf.org/html/rfc2553#section-5.2:
3550 *
3551 * IPV6_JOIN_GROUP
3552 *
3553 * Join a multicast group on a specified local interface. If the
3554 * interface index is specified as 0, the kernel chooses the local
3555 * interface. For example, some kernels look up the multicast
3556 * group in the normal IPv6 routing table and using the resulting
3557 * interface; we do this for each interface, so no need to use
3558 * zero (anymore...).
3559 */
3560 bi->mcreq.ipv6mr_interface = s6->sin6_scope_id;
3561
3562 /* Join the multicast group */
3564 IPPROTO_IPV6,
3565 IPV6_JOIN_GROUP,
3566 &bi->mcreq,
3567 sizeof(bi->mcreq)))
3568 {
3570 }
3571 }
3572 return GNUNET_OK;
3573}
3574
3575
3581static void
3582do_broadcast (void *cls)
3583{
3584 struct BroadcastInterface *bin;
3585
3586 (void) cls;
3587 for (struct BroadcastInterface *bi = bi_head; NULL != bi; bi = bi->next)
3588 bi->found = GNUNET_NO;
3590 for (struct BroadcastInterface *bi = bi_head; NULL != bi; bi = bin)
3591 {
3592 bin = bi->next;
3593 if (GNUNET_NO == bi->found)
3594 bi_destroy (bi);
3595 }
3597 &do_broadcast,
3598 NULL);
3599}
3600
3601
3602static void
3603try_connection_reversal (void *cls,
3604 const struct sockaddr *addr,
3605 socklen_t addrlen)
3606{
3607 /* FIXME: support reversal: #5529 */
3609 "No connection reversal implemented!\n");
3610}
3611
3612
3613static void
3614udp_socket_notify (struct GNUNET_UdpSocketInfo *sock_info)
3615{
3617 sizeof (*sock_info->actual_address
3618 ));
3619 create_receiver (sock_info->pid,
3620 address,
3621 default_v4_sock == sock_info->udp_sock ||
3622 default_v6_sock == sock_info->udp_sock ?
3623 NULL : sock_info->udp_sock);
3625 GNUNET_free (sock_info);
3626}
3627
3628
3629static void
3630start_burst (const char *addr,
3631 struct GNUNET_TIME_Relative rtt,
3632 struct GNUNET_PeerIdentity *pid)
3633{
3634 struct GNUNET_UdpSocketInfo *sock_info;
3635
3637 "Communicator was called to start burst to address %s from %s\n",
3638 addr,
3639 my_ipv4);
3640
3641 GNUNET_stop_burst (NULL);
3642
3643 sock_info = GNUNET_new (struct GNUNET_UdpSocketInfo);
3644 sock_info->pid = GNUNET_new (struct GNUNET_PeerIdentity);
3645 sock_info->address = GNUNET_strdup (addr);
3646 sock_info->bind_address = my_ipv4;
3647 sock_info->has_port = GNUNET_YES;
3648 sock_info->udp_sock = default_v4_sock;
3649 sock_info->rtt = rtt;
3650 GNUNET_memcpy (sock_info->pid, pid, sizeof (struct GNUNET_PeerIdentity));
3651 sock_info->std_port = my_port;
3653 "1 sock addr %s addr %s rtt %lu %u\n",
3654 sock_info->address,
3655 addr,
3656 (unsigned long) sock_info->rtt.rel_value_us,
3657 my_port);
3658 burst_task = GNUNET_get_udp_socket (sock_info,
3660 GNUNET_free (sock_info);
3661}
3662
3663
3664static struct GNUNET_NETWORK_Handle*
3665create_udp_socket (const char *bindto,
3666 sa_family_t family,
3667 struct sockaddr **out,
3668 socklen_t *out_len)
3669{
3670 struct GNUNET_NETWORK_Handle *sock;
3671 struct sockaddr *in;
3672 socklen_t in_len;
3673 struct sockaddr_storage in_sto;
3674 socklen_t sto_len;
3675
3676 in = udp_address_to_sockaddr (bindto, family, &in_len);
3677 if (NULL == in)
3678 {
3680 "Failed to setup UDP socket address with path `%s'\n",
3681 bindto);
3682 return NULL;
3683 }
3684
3685 if ((AF_UNSPEC != family) && (in->sa_family != family))
3686 {
3688 "Invalid UDP socket address setup with path `%s'\n",
3689 bindto);
3690 GNUNET_free (in);
3691 return NULL;
3692 }
3693
3694 sock =
3695 GNUNET_NETWORK_socket_create (in->sa_family,
3696 SOCK_DGRAM,
3697 IPPROTO_UDP);
3698 if (NULL == sock)
3699 {
3702 "Failed to create socket for %s family %d\n",
3703 GNUNET_a2s (in,
3704 in_len),
3705 in->sa_family);
3706 GNUNET_free (in);
3707 return NULL;
3708 }
3709 if (GNUNET_OK !=
3711 in,
3712 in_len))
3713 {
3715 "bind",
3716 bindto);
3718 "Failed to bind socket for %s family %d sock %p\n",
3719 GNUNET_a2s (in,
3720 in_len),
3721 in->sa_family,
3722 sock);
3724 sock = NULL;
3725 GNUNET_free (in);
3726 return NULL;
3727 }
3728
3729 /* We might have bound to port 0, allowing the OS to figure it out;
3730 thus, get the real IN-address from the socket */
3731 sto_len = sizeof(in_sto);
3732 if (0 != getsockname (GNUNET_NETWORK_get_fd (sock),
3733 (struct sockaddr *) &in_sto,
3734 &sto_len))
3735 {
3736 memcpy (&in_sto, in, in_len);
3737 sto_len = in_len;
3738 }
3739 GNUNET_free (in);
3740 *out = GNUNET_malloc (sto_len);
3741 memcpy (*out, (struct sockaddr *) &in_sto, sto_len);
3742 *out_len = sto_len;
3743 return sock;
3744}
3745
3746
3747static void
3748shutdown_run (struct sockaddr *addrs[2])
3749{
3750 if (NULL != addrs[0])
3751 GNUNET_free (addrs[0]);
3752 if (NULL != addrs[1])
3753 GNUNET_free (addrs[1]);
3755}
3756
3757
3758static void
3759run (void *cls,
3760 char *const *args,
3761 const char *cfgfile,
3762 const struct GNUNET_CONFIGURATION_Handle *c)
3763{
3764 const struct sockaddr_in *v4;
3765 char *bindto;
3766 char *bindto6;
3767 struct sockaddr *in[2];
3768 socklen_t in_len[2];
3769
3771 "Entering the run method of udp communicator.\n");
3772
3773 cfg = c;
3775 if ((GNUNET_NO == GNUNET_NETWORK_test_pf (PF_INET6)) ||
3776 (GNUNET_YES ==
3779 "DISABLE_V6")))
3780 {
3782 }
3783
3784 if (GNUNET_OK !=
3787 "BINDTO",
3788 &bindto))
3789 {
3792 "BINDTO");
3793 return;
3794 }
3796 "The udp communicator will bind to %s for IPv4\n",
3797 bindto);
3798 if (GNUNET_YES != disable_v6)
3799 {
3800 if (GNUNET_OK !=
3803 "BINDTO6",
3804 &bindto6))
3805 {
3808 "BINDTO6");
3809 return;
3810 }
3811
3813 "The udp communicator will bind to %s for IPv6\n",
3814 bindto6);
3815 }
3816 else
3817 bindto6 = NULL;
3818 if (GNUNET_OK !=
3821 "REKEY_INTERVAL",
3824
3825 if (GNUNET_OK !=
3828 "REKEY_MAX_BYTES",
3830 {
3832 }
3833
3834 memset (in, 0, sizeof(struct sockaddr*) * 2);
3835 memset (in_len, 0, sizeof(socklen_t) * 2);
3836
3837 GNUNET_assert (bindto);
3839 bindto, AF_INET, &(in[0]), &(in_len[0]));
3840 GNUNET_free (bindto);
3841
3842 if (GNUNET_YES != disable_v6)
3843 {
3844 GNUNET_assert (bindto6);
3846 bindto6, AF_INET6, &(in[1]), &(in_len[1]));
3847 GNUNET_free (bindto6);
3848 }
3849 else
3850 default_v6_sock = NULL;
3851
3852 if ((NULL == default_v4_sock) && (NULL == default_v6_sock))
3853 return;
3854
3855 my_port = 0;
3856 if (NULL != default_v4_sock)
3857 {
3858 GNUNET_assert (in[0]);
3860 "transport",
3861 "Bound to `%s' sock %p\n",
3862 GNUNET_a2s ((const struct sockaddr *) in[0],
3863 in_len[0]),
3865
3866 v4 = (const struct sockaddr_in *) in[0];
3867
3868 my_ipv4 = GNUNET_malloc (INET_ADDRSTRLEN);
3869 my_port = ntohs (((struct sockaddr_in *) in[0])->sin_port);
3870 inet_ntop (AF_INET, &v4->sin_addr, my_ipv4, in_len[0]);
3871 }
3872 if (NULL != default_v6_sock)
3873 {
3874 GNUNET_assert (in[1]);
3876 "transport",
3877 "Bound to `%s' sock %p\n",
3878 GNUNET_a2s ((const struct sockaddr *) in[1],
3879 in_len[1]),
3881 my_port = ntohs (((struct sockaddr_in6 *) in[1])->sin6_port);
3882 }
3883 stats = GNUNET_STATISTICS_create ("communicator-udp", cfg);
3892 /* start reading */
3893 if (NULL != default_v4_sock)
3896 &sock_read,
3898 else
3899 read_v4_task = NULL;
3900 if (NULL != default_v6_sock)
3903 &sock_read,
3905 else
3906 read_v6_task = NULL;
3911 &mq_init,
3912 NULL,
3914 NULL,
3915 &start_burst);
3916 if (NULL == ch)
3917 {
3918 GNUNET_break (0);
3919 shutdown_run (in);
3920 return;
3921 }
3923 if (NULL == ah)
3924 {
3925 GNUNET_break (0);
3926 shutdown_run (in);
3927 return;
3928 }
3929 /* start broadcasting */
3930 if (GNUNET_YES !=
3933 "DISABLE_BROADCAST"))
3934 {
3936 }
3938 GNUNET_assert (NULL != key_ring);
3939 pils = GNUNET_PILS_connect (cfg, NULL, NULL);
3940 GNUNET_assert (NULL != pils);
3941
3944 IPPROTO_UDP,
3945 (NULL != in[0]? 1 : 0)
3946 + (NULL != in[1]? 1 : 0),
3947 (const struct sockaddr**)
3948 (NULL != in[0]? in : &(in[1])),
3949 NULL != in[0]? in_len : &(in_len[1]),
3952 NULL /* closure */);
3953 if (NULL != in[0])
3954 GNUNET_free (in[0]);
3955 if (NULL != in[1])
3956 GNUNET_free (in[1]);
3957}
3958
3959
3960GNUNET_DAEMON_MAIN ("gnunet-communicator-udp",
3961 _ ("GNUnet UDP communicator"),
3962 &run)
3963/* 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.
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 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 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 void eddsa_pub_to_hpke_key(const struct GNUNET_CRYPTO_EddsaPublicKey *edpk, struct GNUNET_CRYPTO_HpkePublicKey *pk)
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 void eddsa_priv_to_hpke_key(const struct GNUNET_CRYPTO_EddsaPrivateKey *edpk, struct GNUNET_CRYPTO_HpkePrivateKey *pk)
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_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 try_handle_plaintext(struct SenderAddress *sender, const void *buf, size_t buf_size)
Test if we have received a valid message in plaintext.
static struct GNUNET_PILS_KeyRing * key_ring
For PILS.
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 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 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 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 my_identity
Identity of this peer.
struct GNUNET_CRYPTO_EddsaPrivateKey my_private_key
The current private key.
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:465
void GNUNET_PILS_disconnect(struct GNUNET_PILS_Handle *handle)
Disconnect from the PILS service.
Definition pils_api.c:488
struct GNUNET_PILS_KeyRing * GNUNET_PILS_create_key_ring(const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_SCHEDULER_TaskCallback init_cb, void *cls)
Create a key ring handle to use the current peer identity key.
Definition pils_api.c:804
void GNUNET_PILS_destroy_key_ring(struct GNUNET_PILS_KeyRing *key_ring)
Destroy a key ring handle and free its memory.
Definition pils_api.c:864
const struct GNUNET_PeerIdentity * GNUNET_PILS_get_identity(const struct GNUNET_PILS_Handle *handle)
Return the current peer identity of a given handle.
Definition pils_api.c:727
const struct GNUNET_CRYPTO_EddsaPrivateKey * GNUNET_PILS_key_ring_get_private_key(const struct GNUNET_PILS_KeyRing *key_ring)
Return the current private key of a given key ring handle.
Definition pils_api.c:887
#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.
void GNUNET_TRANSPORT_communicator_address_remove_all(struct GNUNET_TRANSPORT_CommunicatorHandle *ch)
Notify transport service that this communicator no longer provides all its addresses 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_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...
void GNUNET_CRYPTO_random_block(enum GNUNET_CRYPTO_Quality mode, void *buffer, size_t length)
Fill block with a random values.
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
#define GNUNET_CRYPTO_hkdf_expand(result, out_len, 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.
#define GNUNET_CRYPTO_kdf_arg_string(d)
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_CRYPTO_kdf_arg_auto(d)
#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:1000
ssize_t GNUNET_NETWORK_socket_recvfrom(const struct GNUNET_NETWORK_Handle *desc, void *buffer, size_t length, struct sockaddr *src_addr, socklen_t *addrlen)
Read data from a socket (always non-blocking).
Definition network.c:687
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition network.c:832
enum GNUNET_GenericReturnValue GNUNET_NETWORK_test_pf(int pf)
Test if the given protocol family is supported by this system.
Definition network.c:79
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_bind(struct GNUNET_NETWORK_Handle *desc, const struct sockaddr *address, socklen_t address_len)
Bind a socket to a particular address.
Definition network.c:439
int GNUNET_NETWORK_socket_setsockopt(struct GNUNET_NETWORK_Handle *fd, int level, int option_name, const void *option_value, socklen_t option_len)
Set socket option.
Definition network.c:805
ssize_t GNUNET_NETWORK_socket_sendto(const struct GNUNET_NETWORK_Handle *desc, const void *message, size_t length, const struct sockaddr *dest_addr, socklen_t dest_len)
Send data to a particular destination (always non-blocking).
Definition network.c:771
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:572
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:1517
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:1345
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition scheduler.c:986
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:1310
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:1283
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...
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
A simplified handle for using the peer identity key.
Definition pils_api.c:132
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:141
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.

◆ 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 ( const struct GNUNET_CRYPTO_EddsaPrivateKey edpk,
struct GNUNET_CRYPTO_HpkePrivateKey pk 
)
static

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

894{
896 key.type = htonl (GNUNET_PUBLIC_KEY_TYPE_EDDSA);
897 key.eddsa_key = *edpk;
899 pk);
900}

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

Referenced by setup_initial_shared_secret_dec().

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 ( const struct GNUNET_CRYPTO_EddsaPublicKey edpk,
struct GNUNET_CRYPTO_HpkePublicKey pk 
)
static

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

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

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

922{
923 if (AF_INET6 == bi->sa->sa_family)
924 {
925 /* Leave the multicast group */
927 IPPROTO_IPV6,
928 IPV6_LEAVE_GROUP,
929 &bi->mcreq,
930 sizeof(bi->mcreq)))
931 {
933 }
934 }
937 GNUNET_free (bi->sa);
938 GNUNET_free (bi->ba);
939 GNUNET_free (bi);
940}

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

1085{
1086 struct SenderAddress *sender;
1087 struct ReceiverAddress *receiver;
1088 struct KeyCacheEntry *kce;
1089
1091 "secret %s destroy %u\n",
1092 GNUNET_sh2s (&ss->master),
1094 if (NULL != (sender = ss->sender))
1095 {
1096 GNUNET_CONTAINER_DLL_remove (sender->ss_head, sender->ss_tail, ss);
1097 sender->num_secrets--;
1099 "%u sender->num_secrets %u allowed %u used, %u available\n",
1101 sender->acks_available);
1103 if (NULL != ss->sender->kce_task)
1104 {
1106 ss->sender->kce_task = NULL;
1107 }
1108 }
1109 if (NULL != (receiver = ss->receiver))
1110 {
1111 GNUNET_CONTAINER_DLL_remove (receiver->ss_head, receiver->ss_tail, ss);
1112 receiver->num_secrets--;
1113 receiver->acks_available -= (ss->sequence_allowed - ss->sequence_used);
1115 "%u receiver->num_secrets\n",
1116 receiver->num_secrets);
1117 }
1118 while (NULL != (kce = ss->kce_head))
1119 kce_destroy (kce);
1120 GNUNET_STATISTICS_update (stats, "# Secrets active", -1, GNUNET_NO);
1122 "# KIDs active",
1124 GNUNET_NO);
1125 GNUNET_free (ss);
1126 return GNUNET_YES;
1127}

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

953{
954 struct SharedSecret *ss;
955 receiver->receiver_destroy_called = GNUNET_YES;
956
958 "Disconnecting receiver for peer `%s'\n",
959 GNUNET_i2s (&receiver->target));
960 if (NULL != receiver->kx_qh)
961 {
963 receiver->kx_qh = NULL;
964 receiver->kx_mq = NULL;
965 }
966 if (NULL != receiver->d_qh)
967 {
969 receiver->d_qh = NULL;
970 }
971 else if (NULL != receiver->d_mq)
972 {
974 receiver->d_mq = NULL;
975 }
976 if (NULL != receiver->udp_sock)
977 {
980 receiver->udp_sock = NULL;
981 }
984 &receiver->key,
985 receiver));
988 "# receivers active",
990 GNUNET_NO);
991 while (NULL != (ss = receiver->ss_head))
992 {
993 secret_destroy (ss);
994 }
995 GNUNET_free (receiver->address);
996 GNUNET_free (receiver->foreign_addr);
998}

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

1008{
1009 struct SharedSecret *ss = kce->ss;
1010
1011 ss->active_kce_count--;
1014 &kce->kid,
1015 kce));
1016 GNUNET_free (kce);
1017}

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

1031{
1032 uint32_t sid = htonl (serial);
1033 struct GNUNET_ShortHashCode prk;
1035 &sid, sizeof (sid),
1036 msec, sizeof (*msec));
1037
1039 kid,
1040 sizeof(*kid),
1041 &prk,
1042 GNUNET_CRYPTO_kdf_arg_string ("gnunet-communicator-udp-kid"));
1043}

References GNUNET_CRYPTO_hkdf_expand, GNUNET_CRYPTO_hkdf_extract(), and GNUNET_CRYPTO_kdf_arg_string.

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

1054{
1055 struct KeyCacheEntry *kce;
1056
1057 GNUNET_assert (0 < seq);
1058 kce = GNUNET_new (struct KeyCacheEntry);
1059 kce->ss = ss;
1060 kce->sequence_number = seq;
1061 get_kid (&ss->master, seq, &kce->kid);
1066 key_cache,
1067 &kce->kid,
1068 kce,
1071 "# KIDs active",
1073 GNUNET_NO);
1074}

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

1138{
1139 struct SharedSecret *ss;
1142 GNUNET_YES ==
1146 "# senders active",
1148 GNUNET_NO);
1149 while (NULL != (ss = sender->ss_head))
1150 {
1151 secret_destroy (ss);
1152 }
1155}

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

1171{
1172 uint32_t sid = htonl (serial);
1173
1175 key,
1177 msec,
1178 GNUNET_CRYPTO_kdf_arg_string ("gnunet-communicator-udp-key"),
1181 iv,
1183 msec,
1184 GNUNET_CRYPTO_kdf_arg_string ("gnunet-communicator-udp-iv"),
1186}

References AES_IV_SIZE, AES_KEY_SIZE, GNUNET_CRYPTO_hkdf_expand, GNUNET_CRYPTO_kdf_arg_auto, GNUNET_CRYPTO_kdf_arg_string, and key.

Referenced by setup_cipher().

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 1195 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 1209 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 1224 of file gnunet-communicator-udp.c.

1225{
1226 struct GNUNET_TIME_Relative st;
1227 struct GNUNET_TIME_Relative rt;
1228 struct GNUNET_TIME_Relative delay;
1229 struct ReceiverAddress *receiver;
1230 struct SenderAddress *sender;
1231
1232 (void) cls;
1233 timeout_task = NULL;
1236 {
1238 if (0 != rt.rel_value_us)
1239 break;
1241 "Receiver timed out\n");
1243 }
1245 while (NULL != (sender = GNUNET_CONTAINER_heap_peek (senders_heap)))
1246 {
1247 if (GNUNET_YES != sender->sender_destroy_called)
1248 {
1250 if (0 != st.rel_value_us)
1251 break;
1252 sender_destroy (sender);
1253 }
1254 }
1255 delay = GNUNET_TIME_relative_min (rt, st);
1256 if (delay.rel_value_us < GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
1258}

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

1268{
1270 &ss->cmac,
1271 sizeof(ss->cmac),
1272 &ss->master,
1273 GNUNET_CRYPTO_kdf_arg_string ("gnunet-communicator-udp-cmac"));
1274}

References SharedSecret::cmac, GNUNET_CRYPTO_hkdf_expand, GNUNET_CRYPTO_kdf_arg_string, 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 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 1286 of file gnunet-communicator-udp.c.

1289{
1290 const struct GNUNET_MessageHeader *hdr = plaintext;
1291 const char *pos = plaintext;
1292
1293 while (ntohs (hdr->size) <= plaintext_len)
1294 {
1296 "# bytes given to core",
1297 ntohs (hdr->size),
1298 GNUNET_NO);
1300 "Giving %u bytes to TNG\n", ntohs (hdr->size));
1303 &sender->target,
1304 hdr,
1306 NULL /* no flow control possible */
1307 ,
1308 NULL));
1309 /* move on to next message, if any */
1310 plaintext_len -= ntohs (hdr->size);
1311 if (plaintext_len < sizeof(*hdr))
1312 break;
1313 pos += ntohs (hdr->size);
1314 hdr = (const struct GNUNET_MessageHeader *) pos;
1315 // TODO for now..., we do not actually sen >1msg or have a way of telling
1316 // if we are done
1317 break;
1318 }
1320 "# bytes padding discarded",
1321 plaintext_len,
1322 GNUNET_NO);
1323}

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

1338{
1339 char key[AES_KEY_SIZE];
1340 char iv[AES_IV_SIZE];
1341 int rc;
1342
1343 GNUNET_assert (0 ==
1344 gcry_cipher_open (cipher,
1345 GCRY_CIPHER_AES256 /* low level: go for speed */
1346 ,
1347 GCRY_CIPHER_MODE_GCM,
1348 0 /* flags */));
1349 get_iv_key (msec, serial, key, iv);
1350 rc = gcry_cipher_setkey (*cipher, key, sizeof(key));
1351 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
1352 rc = gcry_cipher_setiv (*cipher, iv, sizeof(iv));
1353 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
1354}

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

1376{
1377 gcry_cipher_hd_t cipher;
1378
1379 setup_cipher (&ss->master, serial, &cipher);
1381 0 ==
1382 gcry_cipher_decrypt (cipher, out_buf, in_buf_size, in_buf, in_buf_size));
1383 if (0 != gcry_cipher_checktag (cipher, tag, GCM_TAG_SIZE))
1384 {
1385 gcry_cipher_close (cipher);
1387 "# AEAD authentication failures",
1388 1,
1389 GNUNET_NO);
1390 return GNUNET_SYSERR;
1391 }
1392 gcry_cipher_close (cipher);
1393 return GNUNET_OK;
1394}

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

1406{
1408 struct SharedSecret *ss;
1409
1412
1413 ss = GNUNET_new (struct SharedSecret);
1415 ephemeral,
1416 &ss->master);
1417 calculate_cmac (ss);
1418 return ss;
1419}

References calculate_cmac(), GNUNET_assert, GNUNET_CRYPTO_eddsa_kem_decaps(), GNUNET_new, GNUNET_PILS_key_ring_get_private_key(), key_ring, 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 1429 of file gnunet-communicator-udp.c.

1431{
1433 struct GNUNET_CRYPTO_HpkePrivateKey my_hpke_key;
1434 struct SharedSecret *ss;
1435
1438
1439 eddsa_priv_to_hpke_key (my_private_key, &my_hpke_key);
1440
1441 ss = GNUNET_new (struct SharedSecret);
1443 &ss->master);
1445 "New receiver SS master: %s\n", GNUNET_sh2s (&ss->master));
1446 calculate_cmac (ss);
1447 return ss;
1448}

References calculate_cmac(), eddsa_priv_to_hpke_key(), GNUNET_assert, GNUNET_CRYPTO_hpke_elligator_kem_decaps(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_new, GNUNET_PILS_key_ring_get_private_key(), GNUNET_sh2s(), key_ring, SharedSecret::master, and my_private_key.

Referenced by sock_read().

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

◆ setup_shared_secret_ephemeral()

static struct SharedSecret * setup_shared_secret_ephemeral ( struct GNUNET_CRYPTO_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 1459 of file gnunet-communicator-udp.c.

1462{
1463 struct SharedSecret *ss;
1464
1465 ss = GNUNET_new (struct SharedSecret);
1466 GNUNET_CRYPTO_eddsa_kem_encaps (&receiver->target.public_key,
1467 ephemeral,
1468 &ss->master);
1469 calculate_cmac (ss);
1470 ss->receiver = receiver;
1471 GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss);
1472 receiver->num_secrets++;
1473 GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
1474 return ss;
1475}

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

1489{
1490 struct SharedSecret *ss;
1491
1492 ss = GNUNET_new (struct SharedSecret);
1494 c, &ss->master);
1496 "New sender SS master: %s\n", GNUNET_sh2s (&ss->master));
1497 calculate_cmac (ss);
1498 ss->receiver = receiver;
1499 GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss);
1500 receiver->num_secrets++;
1501 GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
1502 return ss;
1503}

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

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

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

1526{
1527 struct SharedSecret *pos;
1528 struct SharedSecret *ss_to_purge;
1529 unsigned int deleted = 0;
1530
1532 "Purging secrets.\n");
1533 pos = ss_list_tail;
1534 while (NULL != pos)
1535 {
1536 ss_to_purge = pos;
1537 pos = pos->prev;
1538
1539 // FIXME we may also want to purge old unacked.
1540 if (rekey_max_bytes <= ss_to_purge->bytes_sent)
1541 {
1542 secret_destroy (ss_to_purge);
1543 deleted++;
1544 }
1545 }
1547 "Finished purging all, deleted %u.\n", deleted);
1548 return deleted;
1549}

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

1554{
1555
1556 struct ReceiverAddress *receiver = ss->receiver;
1557
1558 GNUNET_assert (NULL != ss);
1559 GNUNET_assert (NULL != receiver);
1560
1561 if (NULL == receiver->d_qh)
1562 {
1563 receiver->d_qh =
1565 &receiver->target,
1566 receiver->foreign_addr,
1567 receiver->d_mtu,
1568 acks_to_add,
1569 1, /* Priority */
1570 receiver->nt,
1572 receiver->d_mq);
1573 }
1574 else
1575 {
1577 receiver->d_qh,
1578 acks_to_add,
1579 1);
1580 }
1581
1583 "Tell transport we have %u more acks!\n",
1584 acks_to_add);
1585
1586 // Until here for alternative 1
1587
1588 /* move ss to head to avoid discarding it anytime soon! */
1589
1590 // GNUNET_CONTAINER_DLL_remove (receiver->ss_head, receiver->ss_tail, ss);
1591 // GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss);
1592}

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

1607{
1608 const struct UDPAck *ack = cls;
1609 struct ReceiverAddress *receiver = value;
1610 uint32_t acks_to_add;
1611 uint32_t allowed;
1612
1614 "in handle ack with cmac %s\n",
1615 GNUNET_h2s (&ack->cmac));
1616
1617 (void) key;
1618 for (struct SharedSecret *ss = receiver->ss_head; NULL != ss; ss = ss->next)
1619 {
1620 if (0 == memcmp (&ack->cmac, &ss->cmac, sizeof(struct GNUNET_HashCode)))
1621 {
1622
1624 "Found matching cmac\n");
1625
1626 allowed = ntohl (ack->sequence_ack);
1627
1628 if (allowed <= ss->sequence_allowed)
1629 {
1631 "Ignoring ack, not giving us increased window\n.");
1632 return GNUNET_NO;
1633 }
1634 acks_to_add = (allowed - ss->sequence_allowed);
1635 GNUNET_assert (0 != acks_to_add);
1636 receiver->acks_available += (allowed - ss->sequence_allowed);
1637 ss->sequence_allowed = allowed;
1638 add_acks (ss, acks_to_add);
1640 "New sequence allows until %u (+%u). Acks available to us: %u. For secret %s\n",
1641 allowed,
1642 acks_to_add,
1643 receiver->acks_available,
1644 GNUNET_sh2s (&ss->master));
1645 return GNUNET_NO;
1646 }
1647 }
1649 "Matching cmac not found for ack!\n");
1650 return GNUNET_YES;
1651}

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

1664{
1665 struct UDPAck ack;
1666 GNUNET_assert (NULL != ss->sender);
1668 "Considering SS UDPAck %s\n",
1669 GNUNET_i2s_full (&ss->sender->target));
1670
1672 "Sender has %u acks available.\n",
1673 ss->sender->acks_available);
1674 /* drop ancient KeyCacheEntries */
1675 while ((NULL != ss->kce_head) &&
1676 (MAX_SQN_DELTA <
1678 kce_destroy (ss->kce_tail);
1679
1680
1681 ack.header.type = htons (GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK);
1682 ack.header.size = htons (sizeof(ack));
1683 ack.sequence_ack = htonl (ss->sequence_allowed);
1684 ack.cmac = ss->cmac;
1686 "Notifying transport with UDPAck %s, sequence %u and master %s\n",
1688 ss->sequence_allowed,
1689 GNUNET_sh2s (&(ss->master)));
1691 &ss->sender->target,
1693 &ack.header);
1694}

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

1699{
1700 struct SharedSecret *ss = cls;
1701 ss->sender->kce_task = NULL;
1702
1704 "Precomputing %u keys for master %s\n",
1706 GNUNET_sh2s (&ss->master));
1707 if ((ss->override_available_acks != GNUNET_YES) &&
1708 (KCN_TARGET < ss->sender->acks_available))
1709 return;
1710 for (int i = 0; i < GENERATE_AT_ONCE; i++)
1711 kce_generate (ss, ++ss->sequence_allowed);
1712
1717 if (KCN_TARGET > ss->sender->acks_available)
1718 {
1722 ss);
1723 return;
1724 }
1726 "We have enough keys (ACKs: %u).\n", ss->sender->acks_available);
1730 consider_ss_ack (ss);
1731}

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

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

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

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

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

1967{
1968 struct SenderAddress *sender;
1969 struct GNUNET_HashContext *hsh;
1970 struct GNUNET_HashCode sender_key;
1971
1973 GNUNET_CRYPTO_hash_context_read (hsh, address, address_len);
1974 GNUNET_CRYPTO_hash_context_read (hsh, target, sizeof(*target));
1975 GNUNET_CRYPTO_hash_context_finish (hsh, &sender_key);
1976
1977 sender = GNUNET_CONTAINER_multihashmap_get (senders, &sender_key);
1978 if (NULL != sender)
1979 {
1981 return sender;
1982 }
1983 sender = GNUNET_new (struct SenderAddress);
1984 sender->key = sender_key;
1985 sender->target = *target;
1986 sender->address = GNUNET_memdup (address, address_len);
1987 sender->address_len = address_len;
1989 senders,
1990 &sender->key,
1991 sender,
1994 "# senders active",
1996 GNUNET_NO);
1997 sender->timeout =
2000 sender,
2001 sender->timeout.abs_value_us);
2002 sender->nt = GNUNET_NT_scanner_get_type (is, address, address_len);
2003 if (NULL == timeout_task)
2005 return sender;
2006}

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

2019{
2020 const struct GNUNET_PeerIdentity *my_identity;
2021 struct UdpHandshakeSignature uhs;
2022
2025
2026 uhs.purpose.purpose = htonl (
2028 uhs.purpose.size = htonl (sizeof(uhs));
2029 uhs.sender = uc->sender;
2030 uhs.receiver = *my_identity;
2031 uhs.enc = *enc;
2032 uhs.monotonic_time = uc->monotonic_time;
2035 &uhs,
2036 &uc->sender_sig,
2037 &uc->sender.public_key);
2038}

References enc, UdpHandshakeSignature::enc, GNUNET_assert, GNUNET_CRYPTO_eddsa_verify, GNUNET_PILS_get_identity(), GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_HANDSHAKE, UdpHandshakeSignature::monotonic_time, my_identity, pils, GNUNET_CRYPTO_SignaturePurpose::purpose, UdpHandshakeSignature::purpose, UdpHandshakeSignature::receiver, UdpHandshakeSignature::sender, GNUNET_CRYPTO_SignaturePurpose::size, and uc.

Referenced by sock_read().

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

2052{
2053 char *ret;
2054
2055 switch (address->sa_family)
2056 {
2057 case AF_INET:
2059 "%s-%s",
2061 GNUNET_a2s (address, address_len));
2062 break;
2063
2064 case AF_INET6:
2066 "%s-%s",
2068 GNUNET_a2s (address, address_len));
2069 break;
2070
2071 default:
2072 GNUNET_assert (0);
2073 }
2074 return ret;
2075}

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

2080{
2082
2083 if (NULL == receiver->udp_sock)
2084 {
2085 if (AF_INET6 == receiver->address->sa_family)
2087 else
2089 }
2090 else
2091 udp_sock = receiver->udp_sock;
2092
2093 return udp_sock;
2094}

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

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

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

2347{
2348 struct sockaddr_storage sa;
2349 struct sockaddr_in *addr_verify;
2350 socklen_t salen = sizeof(sa);
2351 char buf[UINT16_MAX];
2352 ssize_t rcvd;
2353
2354 struct GNUNET_NETWORK_Handle *udp_sock = cls;
2355
2358 udp_sock,
2359 &sock_read,
2360 udp_sock);
2363 udp_sock,
2364 &sock_read,
2365 udp_sock);
2366 while (1)
2367 {
2369 buf,
2370 sizeof(buf),
2371 (struct sockaddr *) &sa,
2372 &salen);
2373 if (-1 == rcvd)
2374 {
2375 struct sockaddr *addr = (struct sockaddr*) &sa;
2376
2377 if (EAGAIN == errno)
2378 break; // We are done reading data
2380 "Failed to recv from %s family %d failed sock %p\n",
2381 GNUNET_a2s ((struct sockaddr*) &sa,
2382 sizeof (*addr)),
2383 addr->sa_family,
2384 udp_sock);
2386 return;
2387 }
2389 "Read %llu bytes\n",
2390 (unsigned long long) rcvd);
2391 if (0 == rcvd)
2392 {
2393 GNUNET_break_op (0);
2395 "Read 0 bytes from UDP socket\n");
2396 return;
2397 }
2398
2399 /* first, see if it is a GNUNET_BurstMessage */
2400 if (rcvd == sizeof (struct GNUNET_BurstMessage))
2401 {
2402 struct GNUNET_BurstMessage *bm = (struct GNUNET_BurstMessage *) buf;
2403 struct sockaddr *addr = (struct sockaddr*) &sa;
2404 char *address = sockaddr_to_udpaddr_string (addr, sizeof (*addr));
2405
2406 GNUNET_assert (0 == bm->local_port);
2408 "Received a burst message for default port\n");
2409 create_receiver (&bm->peer,
2410 address,
2411 NULL);
2412 if (AF_INET6 == addr->sa_family)
2414 else
2418 return;
2419 }
2420 /* second, see if it is a UDPBox */
2421 if (rcvd > sizeof(struct UDPBox))
2422 {
2423 const struct UDPBox *box;
2424 struct KeyCacheEntry *kce;
2425
2426 box = (const struct UDPBox *) buf;
2428 if (NULL != kce)
2429 {
2431 "Found KCE with kid %s\n",
2432 GNUNET_sh2s (&box->kid));
2433 decrypt_box (box, (size_t) rcvd, kce);
2434 continue;
2435 }
2436 }
2437
2438 /* next, check if it is a broadcast */
2439 if (sizeof(struct UDPBroadcast) == rcvd)
2440 {
2441 const struct GNUNET_PeerIdentity *my_identity;
2442 const struct UDPBroadcast *ub;
2443 struct UdpBroadcastSignature uhs;
2444 struct GNUNET_PeerIdentity sender;
2445
2448
2449 addr_verify = GNUNET_memdup (&sa, salen);
2450 addr_verify->sin_port = 0;
2452 "received UDPBroadcast from %s\n",
2453 GNUNET_a2s ((const struct sockaddr *) addr_verify, salen));
2454 ub = (const struct UDPBroadcast *) buf;
2455 uhs.purpose.purpose = htonl (
2457 uhs.purpose.size = htonl (sizeof(uhs));
2458 uhs.sender = ub->sender;
2459 sender = ub->sender;
2460 if (0 == memcmp (&sender, my_identity, sizeof (struct
2462 {
2464 "Received our own broadcast\n");
2465 GNUNET_free (addr_verify);
2466 continue;
2467 }
2469 "checking UDPBroadcastSignature for %s\n",
2470 GNUNET_i2s (&sender));
2471 GNUNET_CRYPTO_hash ((struct sockaddr *) addr_verify, salen,
2472 &uhs.h_address);
2473 if (GNUNET_OK ==
2476 &uhs,
2477 &ub->sender_sig,
2478 &ub->sender.public_key))
2479 {
2480 char *addr_s;
2482
2483 addr_s =
2484 sockaddr_to_udpaddr_string ((const struct sockaddr *) &sa, salen);
2485 GNUNET_STATISTICS_update (stats, "# broadcasts received", 1, GNUNET_NO);
2486 /* use our own mechanism to determine network type */
2487 nt =
2488 GNUNET_NT_scanner_get_type (is, (const struct sockaddr *) &sa, salen);
2490 "validating address %s received from UDPBroadcast\n",
2491 GNUNET_i2s (&sender));
2493 GNUNET_free (addr_s);
2494 GNUNET_free (addr_verify);
2495 continue;
2496 }
2497 else
2498 {
2500 "VerifyingPeer %s is verifying UDPBroadcast\n",
2503 "Verifying UDPBroadcast from %s failed\n",
2504 GNUNET_i2s (&ub->sender));
2505 }
2506 GNUNET_free (addr_verify);
2507 /* continue with KX, mostly for statistics... */
2508 }
2509
2510
2511 /* finally, test if it is a KX */
2512 if (rcvd < sizeof(struct UDPConfirmation) + sizeof(struct InitialKX))
2513 {
2515 "# messages dropped (no kid, too small for KX)",
2516 1,
2517 GNUNET_NO);
2518 continue;
2519 }
2521 "Got KX\n");
2522 {
2523 const struct InitialKX *kx;
2524 struct SharedSecret *ss;
2525 char pbuf[rcvd - sizeof(struct InitialKX)];
2526 const struct UDPConfirmation *uc;
2527 struct SenderAddress *sender;
2528
2529 kx = (const struct InitialKX *) buf;
2532 "Before DEC\n");
2533
2534 if (GNUNET_OK != try_decrypt (ss,
2535 kx->gcm_tag,
2536 0,
2537 &buf[sizeof(*kx)],
2538 sizeof(pbuf),
2539 pbuf))
2540 {
2542 "Unable to decrypt tag, dropping...\n");
2543 GNUNET_free (ss);
2545 stats,
2546 "# messages dropped (no kid, AEAD decryption failed)",
2547 1,
2548 GNUNET_NO);
2549 continue;
2550 }
2552 "Before VERIFY\n");
2553
2554 uc = (const struct UDPConfirmation *) pbuf;
2555
2556 if (GNUNET_OK != verify_confirmation (&kx->enc, uc)) // TODO: need ephemeral instead of representative
2557 {
2558 GNUNET_break_op (0);
2559 GNUNET_free (ss);
2561 "# messages dropped (sender signature invalid)",
2562 1,
2563 GNUNET_NO);
2564 continue;
2565 }
2567 "Before SETUP_SENDER\n");
2568
2569 calculate_cmac (ss);
2570 sender = setup_sender (&uc->sender, (const struct sockaddr *) &sa, salen);
2571 ss->sender = sender;
2572 GNUNET_CONTAINER_DLL_insert (sender->ss_head, sender->ss_tail, ss);
2573 if ((KCN_THRESHOLD > ss->sender->acks_available) &&
2574 (NULL == ss->sender->kce_task) &&
2576 {
2577 // 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.
2581 ss);
2582 }
2583 sender->num_secrets++;
2584 GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
2586 "# messages decrypted without BOX",
2587 1,
2588 GNUNET_NO);
2589 try_handle_plaintext (sender, &uc[1], sizeof(pbuf) - sizeof(*uc));
2590 if (0 == purge_secrets (sender->ss_tail))
2591 {
2592 // No secret purged. Delete oldest.
2593 if (sender->num_secrets > MAX_SECRETS)
2594 {
2595 secret_destroy (sender->ss_tail);
2596 }
2597 }
2598 }
2599 }
2600}

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_PILS_get_identity(), 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, pils, 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 2238 of file gnunet-communicator-udp.c.

2241{
2242 struct GNUNET_HashContext *hsh;
2243 struct ReceiverAddress *receiver;
2244 struct GNUNET_HashCode receiver_key;
2245 const char *path;
2246 struct sockaddr *in;
2247 socklen_t in_len;
2248
2249 if (0 != strncmp (address,
2251 strlen (COMMUNICATOR_ADDRESS_PREFIX "-")))
2252 {
2253 GNUNET_break_op (0);
2254 return GNUNET_SYSERR;
2255 }
2256 path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")];
2257 in = udp_address_to_sockaddr (path, AF_UNSPEC, &in_len);
2258
2259 if (NULL == in)
2260 {
2262 "Failed to setup UDP socket address\n");
2263 return GNUNET_SYSERR;
2264 }
2265 if ((AF_INET6 == in->sa_family) &&
2267 {
2269 "IPv6 disabled, skipping %s\n", address);
2270 GNUNET_free (in);
2271 return GNUNET_SYSERR;
2272 }
2273 else if (AF_INET == in->sa_family)
2274 {
2275 struct sockaddr_in *sin = (struct sockaddr_in *) in;
2276 if (0 == sin->sin_port)
2277 {
2278 GNUNET_free (in);
2279 return GNUNET_NO;
2280 }
2281 }
2282
2284 GNUNET_CRYPTO_hash_context_read (hsh, in, in_len);
2285 GNUNET_CRYPTO_hash_context_read (hsh, peer, sizeof(*peer));
2286 GNUNET_CRYPTO_hash_context_finish (hsh, &receiver_key);
2287
2289 if (NULL != receiver)
2290 {
2292 "receiver %s already exist or is being connected to\n",
2293 address);
2294 return GNUNET_NO;
2295 }
2296
2298 receiver->udp_sock = udp_sock;
2299 receiver->key = receiver_key;
2300 receiver->address = in;
2301 receiver->address_len = in_len;
2302 receiver->target = *peer;
2303 eddsa_pub_to_hpke_key (&receiver->target.public_key,
2304 &receiver->target_hpke_key);
2305 receiver->nt = GNUNET_NT_scanner_get_type (is, in, in_len);
2307 receivers,
2308 &receiver->key,
2309 receiver,
2312 "Added %s to receivers with address %s and sock %p\n",
2313 GNUNET_i2s_full (&receiver->target),
2314 address,
2315 udp_sock);
2316 receiver->timeout =
2319 receiver,
2320 receiver->timeout.abs_value_us);
2322 "# receivers active",
2324 GNUNET_NO);
2325 receiver->foreign_addr =
2326 sockaddr_to_udpaddr_string (receiver->address, receiver->address_len);
2327 if (NULL != udp_sock)
2330 udp_sock,
2331 &sock_read,
2332 udp_sock);
2334 if (NULL == timeout_task)
2336 return GNUNET_OK;
2337}

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

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

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

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

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_WARNING, GNUNET_log, GNUNET_log_strerror, GNUNET_MQ_impl_send_continue(), GNUNET_NETWORK_socket_sendto(), GNUNET_PILS_get_identity(), GNUNET_PILS_key_ring_get_private_key(), GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_HANDSHAKE, GNUNET_TIME_absolute_get_monotonic(), GNUNET_TIME_absolute_hton(), GNUNET_YES, key_ring, SharedSecret::master, MAX_SECRETS, UdpHandshakeSignature::monotonic_time, mq, msg, my_identity, my_private_key, pils, 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 2742 of file gnunet-communicator-udp.c.

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

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

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

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

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

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

2940{
2941 struct ReceiverAddress *receiver = impl_state;
2943 "Default MQ destroyed\n");
2944 if (mq == receiver->d_mq)
2945 {
2946 receiver->d_mq = NULL;
2947 if (GNUNET_YES != receiver->receiver_destroy_called)
2949 }
2950}

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

2963{
2964 struct ReceiverAddress *receiver = impl_state;
2966 "KX MQ destroyed\n");
2967 if (mq == receiver->kx_mq)
2968 {
2969 receiver->kx_mq = NULL;
2970 if (GNUNET_YES != receiver->receiver_destroy_called)
2972 }
2973}

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

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

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

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

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

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

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

3124{
3125 struct ReceiverAddress *receiver = value;
3126
3127 (void) cls;
3128 (void) target;
3130 return GNUNET_OK;
3131}

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

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

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

3165{
3167 "do_shutdown\n");
3168 GNUNET_stop_burst (NULL);
3169 if (NULL != nat)
3170 {
3172 nat = NULL;
3173 }
3174 while (NULL != bi_head)
3176 if (NULL != broadcast_task)
3177 {
3179 broadcast_task = NULL;
3180 }
3181 if (NULL != timeout_task)
3182 {
3184 timeout_task = NULL;
3185 }
3186 if (NULL != read_v6_task)
3187 {
3189 read_v6_task = NULL;
3190 }
3191 if (NULL != read_v4_task)
3192 {
3194 read_v4_task = NULL;
3195 }
3196 if (NULL != default_v6_sock)
3197 {
3200 default_v6_sock = NULL;
3201 }
3202 if (NULL != default_v4_sock)
3203 {
3206 default_v4_sock = NULL;
3207 }
3210 NULL);
3214 NULL);
3219 if (NULL != timeout_task)
3220 {
3222 timeout_task = NULL;
3223 }
3224 if (NULL != ch)
3225 {
3228 ch = NULL;
3229 }
3230 if (NULL != ah)
3231 {
3233 ah = NULL;
3234 }
3235 if (NULL != pils)
3236 {
3238 pils = NULL;
3239 }
3240 if (NULL != key_ring)
3241 {
3243 key_ring = NULL;
3244 }
3245 if (NULL != stats)
3246 {
3248 stats = NULL;
3249 }
3250 if (NULL != is)
3251 {
3253 is = NULL;
3254 }
3256 "do_shutdown finished\n");
3257}

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_log, GNUNET_NAT_unregister(), GNUNET_NETWORK_socket_close(), GNUNET_NT_scanner_done(), GNUNET_OK, GNUNET_PILS_destroy_key_ring(), GNUNET_PILS_disconnect(), GNUNET_SCHEDULER_cancel(), GNUNET_STATISTICS_destroy(), GNUNET_stop_burst(), GNUNET_TRANSPORT_application_done(), GNUNET_TRANSPORT_communicator_address_remove_all(), GNUNET_TRANSPORT_communicator_disconnect(), GNUNET_YES, is, key_cache, key_ring, 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 3268 of file gnunet-communicator-udp.c.

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

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

3295{
3296 struct AckInfo ai;
3297
3298 (void) cls;
3300 "Storing UDPAck received from backchannel from %s\n",
3303 (ntohs (msg->size) != sizeof(struct UDPAck)))
3304 {
3305 GNUNET_break_op (0);
3306 return;
3307 }
3308 ai.ack = (const struct UDPAck *) msg;
3309 ai.sender = sender;
3312 &ai);
3313}

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

3336{
3337 char *my_addr;
3339
3340 if (GNUNET_YES == add_remove)
3341 {
3343
3344 GNUNET_asprintf (&my_addr,
3345 "%s-%s",
3347 GNUNET_a2s (addr, addrlen));
3348 nt = GNUNET_NT_scanner_get_type (is, addr, addrlen);
3349 ai =
3351 my_addr,
3352 nt,
3354 GNUNET_free (my_addr);
3355 *app_ctx = ai;
3356 }
3357 else
3358 {
3359 ai = *app_ctx;
3361 *app_ctx = NULL;
3362 }
3363}

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

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

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

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

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_PILS_get_identity(), GNUNET_PILS_key_ring_get_private_key(), GNUNET_SCHEDULER_add_now(), GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_BROADCAST, GNUNET_YES, UdpBroadcastSignature::h_address, ifc_broadcast(), is, key_ring, BroadcastInterface::mcreq, my_identity, my_private_key, BroadcastInterface::next, pils, 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 3583 of file gnunet-communicator-udp.c.

3584{
3585 struct BroadcastInterface *bin;
3586
3587 (void) cls;
3588 for (struct BroadcastInterface *bi = bi_head; NULL != bi; bi = bi->next)
3589 bi->found = GNUNET_NO;
3591 for (struct BroadcastInterface *bi = bi_head; NULL != bi; bi = bin)
3592 {
3593 bin = bi->next;
3594 if (GNUNET_NO == bi->found)
3595 bi_destroy (bi);
3596 }
3598 &do_broadcast,
3599 NULL);
3600}

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

Referenced by do_broadcast(), and run().

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

◆ try_connection_reversal()

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

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

3607{
3608 /* FIXME: support reversal: #5529 */
3610 "No connection reversal implemented!\n");
3611}

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

3616{
3618 sizeof (*sock_info->actual_address
3619 ));
3620 create_receiver (sock_info->pid,
3621 address,
3622 default_v4_sock == sock_info->udp_sock ||
3623 default_v6_sock == sock_info->udp_sock ?
3624 NULL : sock_info->udp_sock);
3626 GNUNET_free (sock_info);
3627}

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

3634{
3635 struct GNUNET_UdpSocketInfo *sock_info;
3636
3638 "Communicator was called to start burst to address %s from %s\n",
3639 addr,
3640 my_ipv4);
3641
3642 GNUNET_stop_burst (NULL);
3643
3644 sock_info = GNUNET_new (struct GNUNET_UdpSocketInfo);
3645 sock_info->pid = GNUNET_new (struct GNUNET_PeerIdentity);
3646 sock_info->address = GNUNET_strdup (addr);
3647 sock_info->bind_address = my_ipv4;
3648 sock_info->has_port = GNUNET_YES;
3649 sock_info->udp_sock = default_v4_sock;
3650 sock_info->rtt = rtt;
3651 GNUNET_memcpy (sock_info->pid, pid, sizeof (struct GNUNET_PeerIdentity));
3652 sock_info->std_port = my_port;
3654 "1 sock addr %s addr %s rtt %lu %u\n",
3655 sock_info->address,
3656 addr,
3657 (unsigned long) sock_info->rtt.rel_value_us,
3658 my_port);
3659 burst_task = GNUNET_get_udp_socket (sock_info,
3661 GNUNET_free (sock_info);
3662}

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

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

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

3750{
3751 if (NULL != addrs[0])
3752 GNUNET_free (addrs[0]);
3753 if (NULL != addrs[1])
3754 GNUNET_free (addrs[1]);
3756}

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:

◆ run()

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

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

3764{
3765 const struct sockaddr_in *v4;
3766 char *bindto;
3767 char *bindto6;
3768 struct sockaddr *in[2];
3769 socklen_t in_len[2];
3770
3772 "Entering the run method of udp communicator.\n");
3773
3774 cfg = c;
3776 if ((GNUNET_NO == GNUNET_NETWORK_test_pf (PF_INET6)) ||
3777 (GNUNET_YES ==
3780 "DISABLE_V6")))
3781 {
3783 }
3784
3785 if (GNUNET_OK !=
3788 "BINDTO",
3789 &bindto))
3790 {
3793 "BINDTO");
3794 return;
3795 }
3797 "The udp communicator will bind to %s for IPv4\n",
3798 bindto);
3799 if (GNUNET_YES != disable_v6)
3800 {
3801 if (GNUNET_OK !=
3804 "BINDTO6",
3805 &bindto6))
3806 {
3809 "BINDTO6");
3810 return;
3811 }
3812
3814 "The udp communicator will bind to %s for IPv6\n",
3815 bindto6);
3816 }
3817 else
3818 bindto6 = NULL;
3819 if (GNUNET_OK !=
3822 "REKEY_INTERVAL",
3825
3826 if (GNUNET_OK !=
3829 "REKEY_MAX_BYTES",
3831 {
3833 }
3834
3835 memset (in, 0, sizeof(struct sockaddr*) * 2);
3836 memset (in_len, 0, sizeof(socklen_t) * 2);
3837
3838 GNUNET_assert (bindto);
3840 bindto, AF_INET, &(in[0]), &(in_len[0]));
3841 GNUNET_free (bindto);
3842
3843 if (GNUNET_YES != disable_v6)
3844 {
3845 GNUNET_assert (bindto6);
3847 bindto6, AF_INET6, &(in[1]), &(in_len[1]));
3848 GNUNET_free (bindto6);
3849 }
3850 else
3851 default_v6_sock = NULL;
3852
3853 if ((NULL == default_v4_sock) && (NULL == default_v6_sock))
3854 return;
3855
3856 my_port = 0;
3857 if (NULL != default_v4_sock)
3858 {
3859 GNUNET_assert (in[0]);
3861 "transport",
3862 "Bound to `%s' sock %p\n",
3863 GNUNET_a2s ((const struct sockaddr *) in[0],
3864 in_len[0]),
3866
3867 v4 = (const struct sockaddr_in *) in[0];
3868
3869 my_ipv4 = GNUNET_malloc (INET_ADDRSTRLEN);
3870 my_port = ntohs (((struct sockaddr_in *) in[0])->sin_port);
3871 inet_ntop (AF_INET, &v4->sin_addr, my_ipv4, in_len[0]);
3872 }
3873 if (NULL != default_v6_sock)
3874 {
3875 GNUNET_assert (in[1]);
3877 "transport",
3878 "Bound to `%s' sock %p\n",
3879 GNUNET_a2s ((const struct sockaddr *) in[1],
3880 in_len[1]),
3882 my_port = ntohs (((struct sockaddr_in6 *) in[1])->sin6_port);
3883 }
3884 stats = GNUNET_STATISTICS_create ("communicator-udp", cfg);
3893 /* start reading */
3894 if (NULL != default_v4_sock)
3897 &sock_read,
3899 else
3900 read_v4_task = NULL;
3901 if (NULL != default_v6_sock)
3904 &sock_read,
3906 else
3907 read_v6_task = NULL;
3912 &mq_init,
3913 NULL,
3915 NULL,
3916 &start_burst);
3917 if (NULL == ch)
3918 {
3919 GNUNET_break (0);
3920 shutdown_run (in);
3921 return;
3922 }
3924 if (NULL == ah)
3925 {
3926 GNUNET_break (0);
3927 shutdown_run (in);
3928 return;
3929 }
3930 /* start broadcasting */
3931 if (GNUNET_YES !=
3934 "DISABLE_BROADCAST"))
3935 {
3937 }
3939 GNUNET_assert (NULL != key_ring);
3940 pils = GNUNET_PILS_connect (cfg, NULL, NULL);
3941 GNUNET_assert (NULL != pils);
3942
3945 IPPROTO_UDP,
3946 (NULL != in[0]? 1 : 0)
3947 + (NULL != in[1]? 1 : 0),
3948 (const struct sockaddr**)
3949 (NULL != in[0]? in : &(in[1])),
3950 NULL != in[0]? in_len : &(in_len[1]),
3953 NULL /* closure */);
3954 if (NULL != in[0])
3955 GNUNET_free (in[0]);
3956 if (NULL != in[1])
3957 GNUNET_free (in[1]);
3958}

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_PILS_create_key_ring(), 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, key_ring, mq_init(), my_ipv4, my_port, nat, nat_address_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

◆ key_ring

◆ pils

struct GNUNET_PILS_Handle* pils
static

◆ 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(), 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

◆ cfg

const struct GNUNET_CONFIGURATION_Handle* cfg
static

Our configuration.

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

Referenced by run(), and send_msg_with_kx().

◆ ah

Our handle to report addresses for validation to TRANSPORT.

Definition at line 861 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 866 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 871 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 876 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 881 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 886 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 888 of file gnunet-communicator-udp.c.

Referenced by start_burst().