GNUnet 0.28.0-dev.3-20-gf1136b0b8
 
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 if (ntohs (hdr->size) < sizeof (struct UDPRekey))
1774 {
1775 GNUNET_break_op (0);
1776 return;
1777 }
1778 ss_rekey = setup_shared_secret_dec (&rekey->ephemeral);
1779 ss_rekey->sender = sender;
1780 GNUNET_CONTAINER_DLL_insert (sender->ss_head, sender->ss_tail, ss_rekey);
1781 sender->num_secrets++;
1783 "Received rekey secret with cmac %s\n",
1784 GNUNET_h2s (&(ss_rekey->cmac)));
1786 "Received secret with master %s.\n",
1787 GNUNET_sh2s (&(ss_rekey->master)));
1789 "We have %u sequence_allowed.\n",
1790 ss_rekey->sequence_allowed);
1792 "We have a sender %p\n",
1793 ss_rekey->sender);
1795 "We have %u acks available.\n",
1796 ss_rekey->sender->acks_available);
1798 "# rekeying successful",
1799 1,
1800 GNUNET_NO);
1803 // FIXME
1804 kce_generate_cb (ss_rekey);
1805 /* ss_rekey->sender->kce_task = GNUNET_SCHEDULER_add_delayed (
1806 WORKING_QUEUE_INTERVALL,
1807 kce_generate_cb,
1808 ss_rekey);*/
1809 // FIXME: Theoretically, this could be an Ack
1810 buf_pos += ntohs (hdr->size);
1811 bytes_remaining -= ntohs (hdr->size);
1812 pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
1813 if (0 == purge_secrets (sender->ss_tail))
1814 {
1815 // No secret purged. Delete oldest.
1816 if (sender->num_secrets > MAX_SECRETS)
1817 {
1818 secret_destroy (sender->ss_tail);
1819 }
1820 }
1821 break;
1823 /* lookup master secret by 'cmac', then update sequence_max */
1824 ack = (struct UDPAck*) buf_pos;
1825 if (ntohs (hdr->size) < sizeof (struct UDPAck))
1826 {
1827 GNUNET_break_op (0);
1828 return;
1829 }
1831 &sender->key,
1832 &handle_ack,
1833 (void *) ack);
1834 /* There could be more messages after the ACK, handle those as well */
1835 buf_pos += ntohs (hdr->size);
1836 bytes_remaining -= ntohs (hdr->size);
1837 pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
1838 break;
1839
1841 /* skip padding */
1842 break;
1843
1844 default:
1845 pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
1846 }
1847 return;
1848}
1849
1850
1858static void
1859decrypt_box (const struct UDPBox *box,
1860 size_t box_len,
1861 struct KeyCacheEntry *kce)
1862{
1863 struct SharedSecret *ss = kce->ss;
1864 struct SharedSecret *ss_c = ss->sender->ss_tail;
1865 struct SharedSecret *ss_tmp;
1866 int ss_destroyed = 0;
1867 char out_buf[box_len - sizeof(*box)];
1868
1869 GNUNET_assert (NULL != ss->sender);
1870 if (GNUNET_OK != try_decrypt (ss,
1871 box->gcm_tag,
1872 kce->sequence_number,
1873 (const char *) &box[1],
1874 sizeof(out_buf),
1875 out_buf))
1876 {
1877 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed decryption.\n");
1879 "# Decryption failures with valid KCE",
1880 1,
1881 GNUNET_NO);
1882 kce_destroy (kce);
1883 ss->sender->acks_available--;
1884 return;
1885 }
1886 kce_destroy (kce);
1887 kce = NULL;
1888 ss->bytes_sent += box_len;
1889 ss->sender->acks_available--;
1890 ss->sequence_used++;
1892 "# bytes decrypted with BOX",
1893 sizeof(out_buf),
1894 GNUNET_NO);
1896 "# messages decrypted with BOX",
1897 1,
1898 GNUNET_NO);
1900 "decrypted UDPBox with kid %s\n",
1901 GNUNET_sh2s (&box->kid));
1902 try_handle_plaintext (ss->sender, out_buf, sizeof(out_buf));
1903
1904 while (NULL != ss_c)
1905 {
1906 if (ss_c->bytes_sent >= rekey_max_bytes)
1907 {
1909 "Removing SS because rekey bytes reached.\n");
1910 ss_tmp = ss_c->prev;
1911 if (ss == ss_c)
1912 ss_destroyed = 1;
1913 secret_destroy (ss_c);
1914 ss_c = ss_tmp;
1915 continue;
1916 }
1917 ss_c = ss_c->prev;
1918 }
1919 if (1 == ss_destroyed)
1920 return;
1922 "Sender has %u ack left.\n",
1923 ss->sender->acks_available);
1924 if ((KCN_THRESHOLD > ss->sender->acks_available) &&
1925 (NULL == ss->sender->kce_task) &&
1927 {
1929 "Sender has %u ack left which is under threshold.\n",
1930 ss->sender->acks_available);
1934 ss);
1935 }
1936}
1937
1938
1942struct SearchContext
1943{
1947 const struct sockaddr *address;
1948
1952 socklen_t address_len;
1953
1957 struct SenderAddress *sender;
1958};
1959
1960
1972static struct SenderAddress *
1974 const struct sockaddr *address,
1975 socklen_t address_len)
1976{
1977 struct SenderAddress *sender;
1978 struct GNUNET_HashContext *hsh;
1979 struct GNUNET_HashCode sender_key;
1980
1982 GNUNET_CRYPTO_hash_context_read (hsh, address, address_len);
1983 GNUNET_CRYPTO_hash_context_read (hsh, target, sizeof(*target));
1984 GNUNET_CRYPTO_hash_context_finish (hsh, &sender_key);
1985
1986 sender = GNUNET_CONTAINER_multihashmap_get (senders, &sender_key);
1987 if (NULL != sender)
1988 {
1990 return sender;
1991 }
1992 sender = GNUNET_new (struct SenderAddress);
1993 sender->key = sender_key;
1994 sender->target = *target;
1995 sender->address = GNUNET_memdup (address, address_len);
1996 sender->address_len = address_len;
1998 senders,
1999 &sender->key,
2000 sender,
2003 "# senders active",
2005 GNUNET_NO);
2006 sender->timeout =
2009 sender,
2010 sender->timeout.abs_value_us);
2011 sender->nt = GNUNET_NT_scanner_get_type (is, address, address_len);
2012 if (NULL == timeout_task)
2014 return sender;
2015}
2016
2017
2025static int
2027 const struct UDPConfirmation *uc)
2028{
2029 const struct GNUNET_PeerIdentity *my_identity;
2030 struct UdpHandshakeSignature uhs;
2031
2034
2035 uhs.purpose.purpose = htonl (
2037 uhs.purpose.size = htonl (sizeof(uhs));
2038 uhs.sender = uc->sender;
2039 uhs.receiver = *my_identity;
2040 uhs.enc = *enc;
2041 uhs.monotonic_time = uc->monotonic_time;
2044 &uhs,
2045 &uc->sender_sig,
2046 &uc->sender.public_key);
2047}
2048
2049
2058static char *
2059sockaddr_to_udpaddr_string (const struct sockaddr *address,
2060 socklen_t address_len)
2061{
2062 char *ret;
2063
2064 switch (address->sa_family)
2065 {
2066 case AF_INET:
2068 "%s-%s",
2070 GNUNET_a2s (address, address_len));
2071 break;
2072
2073 case AF_INET6:
2075 "%s-%s",
2077 GNUNET_a2s (address, address_len));
2078 break;
2079
2080 default:
2081 GNUNET_assert (0);
2082 }
2083 return ret;
2084}
2085
2086
2087static struct GNUNET_NETWORK_Handle *
2089{
2091
2092 if (NULL == receiver->udp_sock)
2093 {
2094 if (AF_INET6 == receiver->address->sa_family)
2096 else
2098 }
2099 else
2100 udp_sock = receiver->udp_sock;
2101
2102 return udp_sock;
2103}
2104
2105
2114static struct sockaddr *
2115udp_address_to_sockaddr (const char *bindto,
2116 sa_family_t family,
2117 socklen_t *sock_len)
2118{
2119 struct sockaddr *in;
2120 unsigned int port;
2121 char dummy[2];
2122 char *colon;
2123 char *cp;
2124
2125 if (1 == sscanf (bindto, "%u%1s", &port, dummy))
2126 {
2127 /* interpreting value as just a PORT number */
2128 if (port > UINT16_MAX)
2129 {
2131 "BINDTO specification `%s' invalid: value too large for port\n",
2132 bindto);
2133 return NULL;
2134 }
2135 if ((AF_INET == family) || (GNUNET_YES == disable_v6))
2136 {
2137 struct sockaddr_in *i4;
2138
2139 i4 = GNUNET_malloc (sizeof(struct sockaddr_in));
2140 i4->sin_family = AF_INET;
2141 i4->sin_port = htons ((uint16_t) port);
2142 *sock_len = sizeof(struct sockaddr_in);
2143 in = (struct sockaddr *) i4;
2144 }
2145 else
2146 {
2147 struct sockaddr_in6 *i6;
2148
2149 i6 = GNUNET_malloc (sizeof(struct sockaddr_in6));
2150 i6->sin6_family = AF_INET6;
2151 i6->sin6_port = htons ((uint16_t) port);
2152 *sock_len = sizeof(struct sockaddr_in6);
2153 in = (struct sockaddr *) i6;
2154 }
2155 return in;
2156 }
2157 cp = GNUNET_strdup (bindto);
2158 colon = strrchr (cp, ':');
2159 if (NULL != colon)
2160 {
2161 /* interpret value after colon as port */
2162 *colon = '\0';
2163 colon++;
2164 if (1 == sscanf (colon, "%u%1s", &port, dummy))
2165 {
2166 /* interpreting value as just a PORT number */
2167 if (port > UINT16_MAX)
2168 {
2170 "BINDTO specification `%s' invalid: value too large for port\n",
2171 bindto);
2172 GNUNET_free (cp);
2173 return NULL;
2174 }
2175 }
2176 else
2177 {
2178 GNUNET_log (
2180 "BINDTO specification `%s' invalid: last ':' not followed by number\n",
2181 bindto);
2182 GNUNET_free (cp);
2183 return NULL;
2184 }
2185 }
2186 else
2187 {
2188 /* interpret missing port as 0, aka pick any free one */
2189 port = 0;
2190 }
2191 if (AF_INET6 != family)
2192 {
2193 /* try IPv4 */
2194 struct sockaddr_in v4;
2195
2196 memset (&v4, 0, sizeof(v4));
2197 if (1 == inet_pton (AF_INET, cp, &v4.sin_addr))
2198 {
2199 v4.sin_family = AF_INET;
2200 v4.sin_port = htons ((uint16_t) port);
2201#if HAVE_SOCKADDR_IN_SIN_LEN
2202 v4.sin_len = sizeof(struct sockaddr_in);
2203#endif
2204 in = GNUNET_memdup (&v4, sizeof(struct sockaddr_in));
2205 *sock_len = sizeof(struct sockaddr_in);
2206 GNUNET_free (cp);
2207 return in;
2208 }
2209 }
2210 if (AF_INET != family)
2211 {
2212 /* try IPv6 */
2213 struct sockaddr_in6 v6;
2214 const char *start;
2215
2216 memset (&v6, 0, sizeof(v6));
2217 start = cp;
2218 if (('[' == *cp) && (']' == cp[strlen (cp) - 1]))
2219 {
2220 start++; /* skip over '[' */
2221 cp[strlen (cp) - 1] = '\0'; /* eat ']' */
2222 }
2223 if (1 == inet_pton (AF_INET6, start, &v6.sin6_addr))
2224 {
2225 v6.sin6_family = AF_INET6;
2226 v6.sin6_port = htons ((uint16_t) port);
2227#if HAVE_SOCKADDR_IN_SIN_LEN
2228 v6.sin6_len = sizeof(struct sockaddr_in6);
2229#endif
2230 in = GNUNET_memdup (&v6, sizeof(v6));
2231 *sock_len = sizeof(v6);
2232 GNUNET_free (cp);
2233 return in;
2234 }
2235 }
2236 /* #5528 FIXME (feature!): maybe also try getnameinfo()? */
2237 GNUNET_free (cp);
2238 return NULL;
2239}
2240
2241
2242static void
2243sock_read (void *cls);
2244
2245
2246static enum GNUNET_GenericReturnValue
2247create_receiver (const struct GNUNET_PeerIdentity *peer,
2248 const char *address,
2250{
2251 struct GNUNET_HashContext *hsh;
2252 struct ReceiverAddress *receiver;
2253 struct GNUNET_HashCode receiver_key;
2254 const char *path;
2255 struct sockaddr *in;
2256 socklen_t in_len;
2257
2258 if (0 != strncmp (address,
2260 strlen (COMMUNICATOR_ADDRESS_PREFIX "-")))
2261 {
2262 GNUNET_break_op (0);
2263 return GNUNET_SYSERR;
2264 }
2265 path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")];
2266 in = udp_address_to_sockaddr (path, AF_UNSPEC, &in_len);
2267
2268 if (NULL == in)
2269 {
2271 "Failed to setup UDP socket address\n");
2272 return GNUNET_SYSERR;
2273 }
2274 if ((AF_INET6 == in->sa_family) &&
2276 {
2278 "IPv6 disabled, skipping %s\n", address);
2279 GNUNET_free (in);
2280 return GNUNET_SYSERR;
2281 }
2282 else if (AF_INET == in->sa_family)
2283 {
2284 struct sockaddr_in *sin = (struct sockaddr_in *) in;
2285 if (0 == sin->sin_port)
2286 {
2287 GNUNET_free (in);
2288 return GNUNET_NO;
2289 }
2290 }
2291
2293 GNUNET_CRYPTO_hash_context_read (hsh, in, in_len);
2294 GNUNET_CRYPTO_hash_context_read (hsh, peer, sizeof(*peer));
2295 GNUNET_CRYPTO_hash_context_finish (hsh, &receiver_key);
2296
2298 if (NULL != receiver)
2299 {
2301 "receiver %s already exist or is being connected to\n",
2302 address);
2303 return GNUNET_NO;
2304 }
2305
2307 receiver->udp_sock = udp_sock;
2308 receiver->key = receiver_key;
2309 receiver->address = in;
2310 receiver->address_len = in_len;
2311 receiver->target = *peer;
2312 eddsa_pub_to_hpke_key (&receiver->target.public_key,
2313 &receiver->target_hpke_key);
2314 receiver->nt = GNUNET_NT_scanner_get_type (is, in, in_len);
2316 receivers,
2317 &receiver->key,
2318 receiver,
2321 "Added %s to receivers with address %s and sock %p\n",
2322 GNUNET_i2s_full (&receiver->target),
2323 address,
2324 udp_sock);
2325 receiver->timeout =
2328 receiver,
2329 receiver->timeout.abs_value_us);
2331 "# receivers active",
2333 GNUNET_NO);
2334 receiver->foreign_addr =
2335 sockaddr_to_udpaddr_string (receiver->address, receiver->address_len);
2336 if (NULL != udp_sock)
2339 udp_sock,
2340 &sock_read,
2341 udp_sock);
2343 if (NULL == timeout_task)
2345 return GNUNET_OK;
2346}
2347
2348
2354static void
2355sock_read (void *cls)
2356{
2357 struct sockaddr_storage sa;
2358 struct sockaddr_in *addr_verify;
2359 socklen_t salen = sizeof(sa);
2360 char buf[UINT16_MAX];
2361 ssize_t rcvd;
2362
2363 struct GNUNET_NETWORK_Handle *udp_sock = cls;
2364
2367 udp_sock,
2368 &sock_read,
2369 udp_sock);
2372 udp_sock,
2373 &sock_read,
2374 udp_sock);
2375 while (1)
2376 {
2378 buf,
2379 sizeof(buf),
2380 (struct sockaddr *) &sa,
2381 &salen);
2382 if (-1 == rcvd)
2383 {
2384 struct sockaddr *addr = (struct sockaddr*) &sa;
2385
2386 if (EAGAIN == errno)
2387 break; // We are done reading data
2389 "Failed to recv from %s family %d failed sock %p\n",
2390 GNUNET_a2s ((struct sockaddr*) &sa,
2391 sizeof (*addr)),
2392 addr->sa_family,
2393 udp_sock);
2395 return;
2396 }
2398 "Read %llu bytes\n",
2399 (unsigned long long) rcvd);
2400 if (0 == rcvd)
2401 {
2402 GNUNET_break_op (0);
2404 "Read 0 bytes from UDP socket\n");
2405 return;
2406 }
2407
2408 /* first, see if it is a GNUNET_BurstMessage */
2409 if (rcvd == sizeof (struct GNUNET_BurstMessage))
2410 {
2411 struct GNUNET_BurstMessage *bm = (struct GNUNET_BurstMessage *) buf;
2412 struct sockaddr *addr = (struct sockaddr*) &sa;
2413 char *address = sockaddr_to_udpaddr_string (addr, sizeof (*addr));
2414
2415 if (0 != bm->local_port)
2416 {
2417 GNUNET_break_op (0);
2419 "Received a burst message on port %u\n",
2420 bm->local_port);
2421 return;
2422 }
2424 "Received a burst message for default port\n");
2425 create_receiver (&bm->peer,
2426 address,
2427 NULL);
2428 if (AF_INET6 == addr->sa_family)
2430 else
2434 return;
2435 }
2436 /* second, see if it is a UDPBox */
2437 if (rcvd > sizeof(struct UDPBox))
2438 {
2439 const struct UDPBox *box;
2440 struct KeyCacheEntry *kce;
2441
2442 box = (const struct UDPBox *) buf;
2444 if (NULL != kce)
2445 {
2447 "Found KCE with kid %s\n",
2448 GNUNET_sh2s (&box->kid));
2449 decrypt_box (box, (size_t) rcvd, kce);
2450 continue;
2451 }
2452 }
2453
2454 /* next, check if it is a broadcast */
2455 if (sizeof(struct UDPBroadcast) == rcvd)
2456 {
2457 const struct GNUNET_PeerIdentity *my_identity;
2458 const struct UDPBroadcast *ub;
2459 struct UdpBroadcastSignature uhs;
2460 struct GNUNET_PeerIdentity sender;
2461
2464
2465 addr_verify = GNUNET_memdup (&sa, salen);
2466 addr_verify->sin_port = 0;
2468 "received UDPBroadcast from %s\n",
2469 GNUNET_a2s ((const struct sockaddr *) addr_verify, salen));
2470 ub = (const struct UDPBroadcast *) buf;
2471 uhs.purpose.purpose = htonl (
2473 uhs.purpose.size = htonl (sizeof(uhs));
2474 uhs.sender = ub->sender;
2475 sender = ub->sender;
2476 if (0 == memcmp (&sender, my_identity, sizeof (struct
2478 {
2480 "Received our own broadcast\n");
2481 GNUNET_free (addr_verify);
2482 continue;
2483 }
2485 "checking UDPBroadcastSignature for %s\n",
2486 GNUNET_i2s (&sender));
2487 GNUNET_CRYPTO_hash ((struct sockaddr *) addr_verify, salen,
2488 &uhs.h_address);
2489 if (GNUNET_OK ==
2492 &uhs,
2493 &ub->sender_sig,
2494 &ub->sender.public_key))
2495 {
2496 char *addr_s;
2498
2499 addr_s =
2500 sockaddr_to_udpaddr_string ((const struct sockaddr *) &sa, salen);
2501 GNUNET_STATISTICS_update (stats, "# broadcasts received", 1, GNUNET_NO);
2502 /* use our own mechanism to determine network type */
2503 nt =
2504 GNUNET_NT_scanner_get_type (is, (const struct sockaddr *) &sa, salen);
2506 "validating address %s received from UDPBroadcast\n",
2507 GNUNET_i2s (&sender));
2509 GNUNET_free (addr_s);
2510 GNUNET_free (addr_verify);
2511 continue;
2512 }
2513 else
2514 {
2516 "VerifyingPeer %s is verifying UDPBroadcast\n",
2519 "Verifying UDPBroadcast from %s failed\n",
2520 GNUNET_i2s (&ub->sender));
2521 }
2522 GNUNET_free (addr_verify);
2523 /* continue with KX, mostly for statistics... */
2524 }
2525
2526
2527 /* finally, test if it is a KX */
2528 if (rcvd < sizeof(struct UDPConfirmation) + sizeof(struct InitialKX))
2529 {
2531 "# messages dropped (no kid, too small for KX)",
2532 1,
2533 GNUNET_NO);
2534 continue;
2535 }
2537 "Got KX\n");
2538 {
2539 const struct InitialKX *kx;
2540 struct SharedSecret *ss;
2541 char pbuf[rcvd - sizeof(struct InitialKX)];
2542 const struct UDPConfirmation *uc;
2543 struct SenderAddress *sender;
2544
2545 kx = (const struct InitialKX *) buf;
2548 "Before DEC\n");
2549
2550 if (GNUNET_OK != try_decrypt (ss,
2551 kx->gcm_tag,
2552 0,
2553 &buf[sizeof(*kx)],
2554 sizeof(pbuf),
2555 pbuf))
2556 {
2558 "Unable to decrypt tag, dropping...\n");
2559 GNUNET_free (ss);
2561 stats,
2562 "# messages dropped (no kid, AEAD decryption failed)",
2563 1,
2564 GNUNET_NO);
2565 continue;
2566 }
2568 "Before VERIFY\n");
2569
2570 uc = (const struct UDPConfirmation *) pbuf;
2571
2572 if (GNUNET_OK != verify_confirmation (&kx->enc, uc)) // TODO: need ephemeral instead of representative
2573 {
2574 GNUNET_break_op (0);
2575 GNUNET_free (ss);
2577 "# messages dropped (sender signature invalid)",
2578 1,
2579 GNUNET_NO);
2580 continue;
2581 }
2583 "Before SETUP_SENDER\n");
2584
2585 calculate_cmac (ss);
2586 sender = setup_sender (&uc->sender, (const struct sockaddr *) &sa, salen);
2587 ss->sender = sender;
2588 GNUNET_CONTAINER_DLL_insert (sender->ss_head, sender->ss_tail, ss);
2589 if ((KCN_THRESHOLD > ss->sender->acks_available) &&
2590 (NULL == ss->sender->kce_task) &&
2592 {
2593 // 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.
2597 ss);
2598 }
2599 sender->num_secrets++;
2600 GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
2602 "# messages decrypted without BOX",
2603 1,
2604 GNUNET_NO);
2605 try_handle_plaintext (sender, &uc[1], sizeof(pbuf) - sizeof(*uc));
2606 if (0 == purge_secrets (sender->ss_tail))
2607 {
2608 // No secret purged. Delete oldest.
2609 if (sender->num_secrets > MAX_SECRETS)
2610 {
2611 secret_destroy (sender->ss_tail);
2612 }
2613 }
2614 }
2615 }
2616}
2617
2618
2626static void
2627do_pad (gcry_cipher_hd_t out_cipher, char *dgram, size_t pad_size)
2628{
2629 char pad[pad_size];
2630
2632 sizeof(pad));
2633 if (sizeof(pad) > sizeof(struct GNUNET_MessageHeader))
2634 {
2635 struct GNUNET_MessageHeader hdr =
2636 { .size = htons (sizeof(pad)),
2638
2639 memcpy (pad, &hdr, sizeof(hdr));
2640 }
2642 0 ==
2643 gcry_cipher_encrypt (out_cipher, dgram, sizeof(pad), pad, sizeof(pad)));
2644}
2645
2646
2647static void
2648send_msg_with_kx (const struct GNUNET_MessageHeader *msg, struct
2650 struct GNUNET_MQ_Handle *mq)
2651{
2652 const struct GNUNET_PeerIdentity *my_identity;
2654 uint16_t msize = ntohs (msg->size);
2655 struct UdpHandshakeSignature uhs;
2656 struct UDPConfirmation uc;
2657 struct InitialKX kx;
2658 char dgram[receiver->kx_mtu + sizeof(uc) + sizeof(kx)];
2659 size_t dpos;
2660 gcry_cipher_hd_t out_cipher;
2661 struct SharedSecret *ss;
2662
2666
2667 if (msize > receiver->kx_mtu)
2668 {
2669 GNUNET_break (0);
2670 if (GNUNET_YES != receiver->receiver_destroy_called)
2672 return;
2673 }
2675
2676 /* setup key material */
2678
2679 if (0 == purge_secrets (receiver->ss_tail))
2680 {
2681 // No secret purged. Delete oldest.
2682 if (receiver->num_secrets > MAX_SECRETS)
2683 {
2684 secret_destroy (receiver->ss_tail);
2685 }
2686 }
2687
2688 setup_cipher (&ss->master, 0, &out_cipher);
2689 /* compute 'uc' */
2690 uc.sender = *my_identity;
2691 uc.monotonic_time =
2693 uhs.purpose.purpose = htonl (
2695 uhs.purpose.size = htonl (sizeof(uhs));
2696 uhs.sender = *my_identity;
2697 uhs.receiver = receiver->target;
2698 uhs.monotonic_time = uc.monotonic_time;
2700 &uhs,
2701 &uc.sender_sig);
2702 /* Leave space for kx */
2703 dpos = sizeof(kx);
2704 /* Append encrypted uc to dgram */
2705 GNUNET_assert (0 == gcry_cipher_encrypt (out_cipher,
2706 &dgram[dpos],
2707 sizeof(uc),
2708 &uc,
2709 sizeof(uc)));
2710 dpos += sizeof(uc);
2711 /* Append encrypted payload to dgram */
2713 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], msize, msg, msize));
2714 dpos += msize;
2715 do_pad (out_cipher, &dgram[dpos], sizeof(dgram) - dpos);
2716 /* Datagram starts with kx */
2717 kx.enc = uhs.enc;
2719 0 == gcry_cipher_gettag (out_cipher, kx.gcm_tag, sizeof(kx.gcm_tag)));
2720 gcry_cipher_close (out_cipher);
2721 memcpy (dgram, &kx, sizeof(kx));
2723 dgram,
2724 sizeof(dgram),
2725 receiver->address,
2726 receiver->address_len))
2727 {
2730 "Sending KX with payload size %u to %s family %d failed sock %p\n",
2731 msize,
2732 GNUNET_a2s (receiver->address,
2733 receiver->address_len),
2734 receiver->address->sa_family,
2738 return;
2739 }
2741 "Sending KX with payload size %u to %s with socket %p\n",
2742 msize,
2743 GNUNET_a2s (receiver->address,
2744 receiver->address_len),
2747}
2748
2749
2758static void
2760 const struct GNUNET_MessageHeader *msg,
2761 void *impl_state)
2762{
2763 struct ReceiverAddress *receiver = impl_state;
2764
2765 GNUNET_assert (mq == receiver->kx_mq);
2767}
2768
2769
2770static void
2771create_rekey (struct ReceiverAddress *receiver, struct SharedSecret *ss, struct
2772 UDPRekey *rekey)
2773{
2774 struct SharedSecret *ss_rekey;
2775
2777 /* setup key material */
2778 ss_rekey = setup_shared_secret_ephemeral (&rekey->ephemeral,
2779 receiver);
2780 ss_rekey->sequence_allowed = 0;
2782 "Setup secret with k = %s\n",
2783 GNUNET_sh2s (&ss_rekey->master));
2785 "Setup secret with H(k) = %s\n",
2786 GNUNET_h2s (&(ss_rekey->cmac)));
2787
2788 /* Append encrypted payload to dgram */
2790 rekey->header.size = htons (sizeof (struct UDPRekey));
2791}
2792
2793
2802static void
2804 const struct GNUNET_MessageHeader *msg,
2805 void *impl_state)
2806{
2807 struct ReceiverAddress *receiver = impl_state;
2808 struct UDPRekey rekey;
2809 struct SharedSecret *ss;
2810 int inject_rekey = GNUNET_NO;
2811 uint16_t msize = ntohs (msg->size);
2812
2813 GNUNET_assert (mq == receiver->d_mq);
2814 if ((msize > receiver->d_mtu) ||
2815 (0 == receiver->acks_available))
2816 {
2818 "msize: %u, mtu: %llu, acks: %u\n",
2819 (unsigned int) msize,
2820 (unsigned long long) receiver->d_mtu,
2821 receiver->acks_available);
2822
2823 GNUNET_break (0);
2824 if (GNUNET_YES != receiver->receiver_destroy_called)
2826 return;
2827 }
2829
2830 if (receiver->num_secrets > MAX_SECRETS)
2831 {
2832 if ((0 == purge_secrets (receiver->ss_tail)) &&
2833 (NULL != receiver->ss_tail))
2834 {
2835 // No secret purged. Delete oldest.
2836 secret_destroy (receiver->ss_tail);
2837 }
2838 }
2839 /* begin "BOX" encryption method, scan for ACKs from tail! */
2840 ss = receiver->ss_tail;
2841 while (NULL != ss)
2842 {
2843 size_t payload_len = sizeof(struct UDPBox) + receiver->d_mtu;
2845 "Considering SS %s sequence used: %u sequence allowed: %u bytes sent: %lu.\n",
2846 GNUNET_sh2s (&ss->master), ss->sequence_used,
2847 ss->sequence_allowed, ss->bytes_sent);
2848 if (ss->sequence_used >= ss->sequence_allowed)
2849 {
2850 // GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2851 // "Skipping ss because no acks to use.\n");
2852 ss = ss->prev;
2853 continue;
2854 }
2855 if (ss->bytes_sent >= rekey_max_bytes)
2856 {
2857 struct SharedSecret *ss_tmp;
2859 "Skipping ss because rekey bytes reached.\n");
2860 // FIXME cleanup ss with too many bytes sent!
2861 ss_tmp = ss->prev;
2862 secret_destroy (ss);
2863 ss = ss_tmp;
2864 continue;
2865 }
2866 if (ss->bytes_sent > rekey_max_bytes * 0.7)
2867 {
2868 if (ss->rekey_initiated == GNUNET_NO)
2869 {
2871 "Injecting rekey for ss with byte sent %lu\n",
2872 (unsigned long) ss->bytes_sent);
2873 create_rekey (receiver, ss, &rekey);
2875 payload_len += sizeof (rekey);
2877 }
2878 }
2879 if (0 < ss->sequence_used)
2881 "Trying to send UDPBox with shared secret %s sequence_used %u and ss->sequence_allowed %u\n",
2882 GNUNET_sh2s (&ss->master),
2883 ss->sequence_used,
2884 ss->sequence_allowed);
2885 {
2886 char dgram[payload_len];
2887 struct UDPBox *box;
2888 gcry_cipher_hd_t out_cipher;
2889 size_t dpos;
2890
2891 box = (struct UDPBox *) dgram;
2892 ss->sequence_used++;
2893 get_kid (&ss->master, ss->sequence_used, &box->kid);
2894 setup_cipher (&ss->master, ss->sequence_used, &out_cipher);
2895 /* Append encrypted payload to dgram */
2896 dpos = sizeof(struct UDPBox);
2897 if (GNUNET_YES == inject_rekey)
2898 {
2900 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], sizeof (rekey),
2901 &rekey, sizeof (rekey)));
2902 dpos += sizeof (rekey);
2903 }
2905 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], msize, msg, msize));
2906 dpos += msize;
2907 do_pad (out_cipher, &dgram[dpos], sizeof(dgram) - dpos);
2908 GNUNET_assert (0 == gcry_cipher_gettag (out_cipher,
2909 box->gcm_tag,
2910 sizeof(box->gcm_tag)));
2911 gcry_cipher_close (out_cipher);
2912
2914 dgram,
2915 payload_len, // FIXME why always send sizeof dgram?
2916 receiver->address,
2917 receiver->address_len))
2918 {
2921 "Sending UDPBox to %s family %d failed sock %p failed\n",
2922 GNUNET_a2s (receiver->address,
2923 receiver->address_len),
2924 receiver->address->sa_family,
2927 return;
2928 }
2930 "Sending UDPBox with payload size %u, %u acks left, %lu bytes sent with socket %p\n",
2931 msize,
2932 receiver->acks_available,
2933 (unsigned long) ss->bytes_sent,
2935 ss->bytes_sent += sizeof (dgram);
2936 receiver->acks_available--;
2938 return;
2939 }
2940 }
2942 "No suitable ss found, sending as KX...\n");
2944}
2945
2946
2955static void
2956mq_destroy_d (struct GNUNET_MQ_Handle *mq, void *impl_state)
2957{
2958 struct ReceiverAddress *receiver = impl_state;
2960 "Default MQ destroyed\n");
2961 if (mq == receiver->d_mq)
2962 {
2963 receiver->d_mq = NULL;
2964 if (GNUNET_YES != receiver->receiver_destroy_called)
2966 }
2967}
2968
2969
2978static void
2979mq_destroy_kx (struct GNUNET_MQ_Handle *mq, void *impl_state)
2980{
2981 struct ReceiverAddress *receiver = impl_state;
2983 "KX MQ destroyed\n");
2984 if (mq == receiver->kx_mq)
2985 {
2986 receiver->kx_mq = NULL;
2987 if (GNUNET_YES != receiver->receiver_destroy_called)
2989 }
2990}
2991
2992
2999static void
3000mq_cancel (struct GNUNET_MQ_Handle *mq, void *impl_state)
3001{
3002 /* Cancellation is impossible with UDP; bail */
3003 GNUNET_assert (0);
3004}
3005
3006
3016static void
3017mq_error (void *cls, enum GNUNET_MQ_Error error)
3018{
3019 struct ReceiverAddress *receiver = cls;
3020
3022 "MQ error in queue to %s: %d\n",
3023 GNUNET_i2s (&receiver->target),
3024 (int) error);
3026}
3027
3028
3036static void
3038{
3039 size_t base_mtu;
3040
3041 switch (receiver->address->sa_family)
3042 {
3043 case AF_INET:
3044 base_mtu = 1480 /* Ethernet MTU, 1500 - Ethernet header - VLAN tag */
3045 - sizeof(struct GNUNET_TUN_IPv4Header) /* 20 */
3046 - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */;
3047 break;
3048
3049 case AF_INET6:
3050 base_mtu = 1280 /* Minimum MTU required by IPv6 */
3051 - sizeof(struct GNUNET_TUN_IPv6Header) /* 40 */
3052 - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */;
3053 break;
3054
3055 default:
3056 GNUNET_assert (0);
3057 break;
3058 }
3059 /* MTU based on full KX messages */
3060 receiver->kx_mtu = base_mtu - sizeof(struct InitialKX) /* 48 */
3061 - sizeof(struct UDPConfirmation); /* 104 */
3062 /* MTU based on BOXed messages */
3063 receiver->d_mtu = base_mtu - sizeof(struct UDPBox);
3064
3066 "Setting up MQs and QHs\n");
3067 /* => Effective MTU for CORE will range from 1080 (IPv6 + KX) to
3068 1404 (IPv4 + Box) bytes, depending on circumstances... */
3069 if (NULL == receiver->kx_mq)
3072 &mq_cancel,
3073 receiver,
3074 NULL,
3075 &mq_error,
3076 receiver);
3077 if (NULL == receiver->d_mq)
3079 &mq_destroy_d,
3080 &mq_cancel,
3081 receiver,
3082 NULL,
3083 &mq_error,
3084 receiver);
3085
3086 receiver->kx_qh =
3088 &receiver->target,
3089 receiver->foreign_addr,
3090 receiver->kx_mtu,
3092 0, /* Priority */
3093 receiver->nt,
3095 receiver->kx_mq);
3096}
3097
3098
3117static int
3118mq_init (void *cls, const struct GNUNET_PeerIdentity *peer, const char *address)
3119{
3120 (void) cls;
3122 "create receiver for mq_init\n");
3123 return create_receiver (peer,
3124 address,
3125 NULL);
3126}
3127
3128
3137static int
3138get_receiver_delete_it (void *cls,
3139 const struct GNUNET_HashCode *target,
3140 void *value)
3141{
3142 struct ReceiverAddress *receiver = value;
3143
3144 (void) cls;
3145 (void) target;
3147 return GNUNET_OK;
3148}
3149
3150
3159static int
3160get_sender_delete_it (void *cls,
3161 const struct GNUNET_HashCode *target,
3162 void *value)
3163{
3164 struct SenderAddress *sender = value;
3165
3166 (void) cls;
3167 (void) target;
3168
3169
3170 sender_destroy (sender);
3171 return GNUNET_OK;
3172}
3173
3174
3180static void
3181do_shutdown (void *cls)
3182{
3184 "do_shutdown\n");
3185 GNUNET_stop_burst (NULL);
3186 if (NULL != nat)
3187 {
3189 nat = NULL;
3190 }
3191 while (NULL != bi_head)
3193 if (NULL != broadcast_task)
3194 {
3196 broadcast_task = NULL;
3197 }
3198 if (NULL != timeout_task)
3199 {
3201 timeout_task = NULL;
3202 }
3203 if (NULL != read_v6_task)
3204 {
3206 read_v6_task = NULL;
3207 }
3208 if (NULL != read_v4_task)
3209 {
3211 read_v4_task = NULL;
3212 }
3213 if (NULL != default_v6_sock)
3214 {
3217 default_v6_sock = NULL;
3218 }
3219 if (NULL != default_v4_sock)
3220 {
3223 default_v4_sock = NULL;
3224 }
3227 NULL);
3231 NULL);
3236 if (NULL != timeout_task)
3237 {
3239 timeout_task = NULL;
3240 }
3241 if (NULL != ch)
3242 {
3245 ch = NULL;
3246 }
3247 if (NULL != ah)
3248 {
3250 ah = NULL;
3251 }
3252 if (NULL != pils)
3253 {
3255 pils = NULL;
3256 }
3257 if (NULL != key_ring)
3258 {
3260 key_ring = NULL;
3261 }
3262 if (NULL != stats)
3263 {
3265 stats = NULL;
3266 }
3267 if (NULL != is)
3268 {
3270 is = NULL;
3271 }
3273 "do_shutdown finished\n");
3274}
3275
3276
3277struct AckInfo
3278{
3279 const struct UDPAck *ack;
3280
3281 const struct GNUNET_PeerIdentity *sender;
3282};
3283
3284static int
3285handle_ack_by_sender (void *cls, const struct GNUNET_HashCode *key, void *value)
3286{
3287 struct ReceiverAddress *receiver = value;
3288 struct AckInfo *ai = cls;
3289
3290 if (0 != GNUNET_memcmp (ai->sender, &receiver->target))
3291 {
3292 return GNUNET_YES;
3293 }
3294 handle_ack ((void*) ai->ack, key, receiver);
3295 return GNUNET_YES;
3296}
3297
3298
3308static void
3309enc_notify_cb (void *cls,
3310 const struct GNUNET_PeerIdentity *sender,
3311 const struct GNUNET_MessageHeader *msg)
3312{
3313 struct AckInfo ai;
3314
3315 (void) cls;
3317 "Storing UDPAck received from backchannel from %s\n",
3320 (ntohs (msg->size) != sizeof(struct UDPAck)))
3321 {
3322 GNUNET_break_op (0);
3323 return;
3324 }
3325 ai.ack = (const struct UDPAck *) msg;
3326 ai.sender = sender;
3329 &ai);
3330}
3331
3332
3346static void
3347nat_address_cb (void *cls,
3348 void **app_ctx,
3349 int add_remove,
3351 const struct sockaddr *addr,
3352 socklen_t addrlen)
3353{
3354 char *my_addr;
3356
3357 if (GNUNET_YES == add_remove)
3358 {
3360
3361 GNUNET_asprintf (&my_addr,
3362 "%s-%s",
3364 GNUNET_a2s (addr, addrlen));
3365 nt = GNUNET_NT_scanner_get_type (is, addr, addrlen);
3366 ai =
3368 my_addr,
3369 nt,
3371 GNUNET_free (my_addr);
3372 *app_ctx = ai;
3373 }
3374 else
3375 {
3376 ai = *app_ctx;
3378 *app_ctx = NULL;
3379 }
3380}
3381
3382
3388static void
3389ifc_broadcast (void *cls)
3390{
3391 struct BroadcastInterface *bi = cls;
3392 struct GNUNET_TIME_Relative delay;
3393
3394 delay = BROADCAST_FREQUENCY;
3395 delay.rel_value_us =
3396 GNUNET_CRYPTO_random_u64 (delay.rel_value_us);
3397 bi->broadcast_task =
3399
3400 switch (bi->sa->sa_family)
3401 {
3402 case AF_INET: {
3403 static int yes = 1;
3404 static int no = 0;
3405 ssize_t sent;
3406
3407 if (GNUNET_OK !=
3409 SOL_SOCKET,
3410 SO_BROADCAST,
3411 &yes,
3412 sizeof(int)))
3414 "setsockopt");
3416 "creating UDPBroadcast from %s\n",
3417 GNUNET_i2s (&(bi->bcm.sender)));
3419 "sending UDPBroadcast to add %s\n",
3420 GNUNET_a2s (bi->ba, bi->salen));
3422 &bi->bcm,
3423 sizeof(bi->bcm),
3424 bi->ba,
3425 bi->salen);
3426 if (-1 == sent)
3428 "sendto");
3430 SOL_SOCKET,
3431 SO_BROADCAST,
3432 &no,
3433 sizeof(int)))
3435 "setsockopt");
3436 break;
3437 }
3438
3439 case AF_INET6: {
3440 ssize_t sent;
3441 struct sockaddr_in6 dst;
3442
3443 dst.sin6_family = AF_INET6;
3444 dst.sin6_port = htons (my_port);
3445 dst.sin6_addr = bi->mcreq.ipv6mr_multiaddr;
3446 dst.sin6_scope_id = ((struct sockaddr_in6 *) bi->ba)->sin6_scope_id;
3447
3449 "sending UDPBroadcast\n");
3451 &bi->bcm,
3452 sizeof(bi->bcm),
3453 (const struct sockaddr *) &dst,
3454 sizeof(dst));
3455 if (-1 == sent)
3457 break;
3458 }
3459
3460 default:
3461 GNUNET_break (0);
3462 break;
3463 }
3464}
3465
3466
3481static int
3482iface_proc (void *cls,
3483 const char *name,
3484 int isDefault,
3485 const struct sockaddr *addr,
3486 const struct sockaddr *broadcast_addr,
3487 const struct sockaddr *netmask,
3488 socklen_t addrlen)
3489{
3490 const struct GNUNET_PeerIdentity *my_identity;
3492 struct BroadcastInterface *bi;
3493 enum GNUNET_NetworkType network;
3494 struct UdpBroadcastSignature ubs;
3495
3496 (void) cls;
3497 (void) netmask;
3498
3501
3502 if ((NULL == my_identity) || (NULL == my_private_key))
3503 return GNUNET_YES;
3504 if (NULL == addr)
3505 return GNUNET_YES; /* need to know our address! */
3506 network = GNUNET_NT_scanner_get_type (is, addr, addrlen);
3507 if (GNUNET_NT_LOOPBACK == network)
3508 {
3509 /* Broadcasting on loopback does not make sense */
3510 return GNUNET_YES;
3511 }
3512 for (bi = bi_head; NULL != bi; bi = bi->next)
3513 {
3514 if ((bi->salen == addrlen) && (0 == memcmp (addr, bi->sa, addrlen)))
3515 {
3516 bi->found = GNUNET_YES;
3517 return GNUNET_OK;
3518 }
3519 }
3520
3521 if ((AF_INET6 == addr->sa_family) && (NULL == broadcast_addr))
3522 return GNUNET_OK; /* broadcast_addr is required for IPv6! */
3523 if ((AF_INET6 == addr->sa_family) && (NULL == default_v6_sock))
3524 return GNUNET_OK; /* not using IPv6 */
3525
3526 bi = GNUNET_new (struct BroadcastInterface);
3527 bi->sa = GNUNET_memdup (addr,
3528 addrlen);
3529 if ( (NULL != broadcast_addr) &&
3530 (addrlen == sizeof (struct sockaddr_in)) )
3531 {
3532 struct sockaddr_in *ba;
3533
3534 ba = GNUNET_memdup (broadcast_addr,
3535 addrlen);
3536 ba->sin_port = htons (2086); /* always GNUnet port, ignore configuration! */
3537 bi->ba = (struct sockaddr *) ba;
3538 }
3539 bi->salen = addrlen;
3540 bi->found = GNUNET_YES;
3541 bi->bcm.sender = *my_identity;
3542 ubs.purpose.purpose = htonl (
3544 ubs.purpose.size = htonl (sizeof(ubs));
3545 ubs.sender = *my_identity;
3547 "creating UDPBroadcastSignature for %s\n",
3548 GNUNET_a2s (addr, addrlen));
3549 GNUNET_CRYPTO_hash (addr, addrlen, &ubs.h_address);
3551 &ubs,
3552 &bi->bcm.sender_sig);
3553 if (NULL != bi->ba)
3554 {
3557 }
3558 if ((AF_INET6 == addr->sa_family) && (NULL != broadcast_addr))
3559 {
3560 /* Create IPv6 multicast request */
3561 const struct sockaddr_in6 *s6 =
3562 (const struct sockaddr_in6 *) broadcast_addr;
3563
3565 1 == inet_pton (AF_INET6, "FF05::13B", &bi->mcreq.ipv6mr_multiaddr));
3566
3567 /* http://tools.ietf.org/html/rfc2553#section-5.2:
3568 *
3569 * IPV6_JOIN_GROUP
3570 *
3571 * Join a multicast group on a specified local interface. If the
3572 * interface index is specified as 0, the kernel chooses the local
3573 * interface. For example, some kernels look up the multicast
3574 * group in the normal IPv6 routing table and using the resulting
3575 * interface; we do this for each interface, so no need to use
3576 * zero (anymore...).
3577 */
3578 bi->mcreq.ipv6mr_interface = s6->sin6_scope_id;
3579
3580 /* Join the multicast group */
3582 IPPROTO_IPV6,
3583 IPV6_JOIN_GROUP,
3584 &bi->mcreq,
3585 sizeof(bi->mcreq)))
3586 {
3588 }
3589 }
3590 return GNUNET_OK;
3591}
3592
3593
3599static void
3600do_broadcast (void *cls)
3601{
3602 struct BroadcastInterface *bin;
3603
3604 (void) cls;
3605 for (struct BroadcastInterface *bi = bi_head; NULL != bi; bi = bi->next)
3606 bi->found = GNUNET_NO;
3608 for (struct BroadcastInterface *bi = bi_head; NULL != bi; bi = bin)
3609 {
3610 bin = bi->next;
3611 if (GNUNET_NO == bi->found)
3612 bi_destroy (bi);
3613 }
3615 &do_broadcast,
3616 NULL);
3617}
3618
3619
3620static void
3621try_connection_reversal (void *cls,
3622 const struct sockaddr *addr,
3623 socklen_t addrlen)
3624{
3625 /* FIXME: support reversal: #5529 */
3627 "No connection reversal implemented!\n");
3628}
3629
3630
3631static void
3632udp_socket_notify (struct GNUNET_UdpSocketInfo *sock_info)
3633{
3634 // FIXME: This sizeof application truncates IPv6 addresses!
3636 sizeof (*sock_info->actual_address
3637 ));
3638 create_receiver (sock_info->pid,
3639 address,
3640 default_v4_sock == sock_info->udp_sock ||
3641 default_v6_sock == sock_info->udp_sock ?
3642 NULL : sock_info->udp_sock);
3644 GNUNET_free (sock_info);
3645}
3646
3647
3648static void
3649start_burst (const char *addr,
3650 struct GNUNET_TIME_Relative rtt,
3651 struct GNUNET_PeerIdentity *pid)
3652{
3653 struct GNUNET_UdpSocketInfo *sock_info;
3654
3656 "Communicator was called to start burst to address %s from %s\n",
3657 addr,
3658 my_ipv4);
3659
3660 GNUNET_stop_burst (NULL);
3661
3662 sock_info = GNUNET_new (struct GNUNET_UdpSocketInfo);
3663 sock_info->pid = GNUNET_new (struct GNUNET_PeerIdentity);
3664 sock_info->address = GNUNET_strdup (addr);
3665 sock_info->bind_address = my_ipv4;
3666 sock_info->has_port = GNUNET_YES;
3667 sock_info->udp_sock = default_v4_sock;
3668 sock_info->rtt = rtt;
3669 GNUNET_memcpy (sock_info->pid, pid, sizeof (struct GNUNET_PeerIdentity));
3670 sock_info->std_port = my_port;
3672 "1 sock addr %s addr %s rtt %lu %u\n",
3673 sock_info->address,
3674 addr,
3675 (unsigned long) sock_info->rtt.rel_value_us,
3676 my_port);
3677 burst_task = GNUNET_get_udp_socket (sock_info,
3679 GNUNET_free (sock_info);
3680}
3681
3682
3683static struct GNUNET_NETWORK_Handle*
3684create_udp_socket (const char *bindto,
3685 sa_family_t family,
3686 struct sockaddr **out,
3687 socklen_t *out_len)
3688{
3689 struct GNUNET_NETWORK_Handle *sock;
3690 struct sockaddr *in;
3691 socklen_t in_len;
3692 struct sockaddr_storage in_sto;
3693 socklen_t sto_len;
3694
3695 in = udp_address_to_sockaddr (bindto, family, &in_len);
3696 if (NULL == in)
3697 {
3699 "Failed to setup UDP socket address with path `%s'\n",
3700 bindto);
3701 return NULL;
3702 }
3703
3704 if ((AF_UNSPEC != family) && (in->sa_family != family))
3705 {
3707 "Invalid UDP socket address setup with path `%s'\n",
3708 bindto);
3709 GNUNET_free (in);
3710 return NULL;
3711 }
3712
3713 sock =
3714 GNUNET_NETWORK_socket_create (in->sa_family,
3715 SOCK_DGRAM,
3716 IPPROTO_UDP);
3717 if (NULL == sock)
3718 {
3721 "Failed to create socket for %s family %d\n",
3722 GNUNET_a2s (in,
3723 in_len),
3724 in->sa_family);
3725 GNUNET_free (in);
3726 return NULL;
3727 }
3728 if (GNUNET_OK !=
3730 in,
3731 in_len))
3732 {
3734 "bind",
3735 bindto);
3737 "Failed to bind socket for %s family %d sock %p\n",
3738 GNUNET_a2s (in,
3739 in_len),
3740 in->sa_family,
3741 sock);
3743 sock = NULL;
3744 GNUNET_free (in);
3745 return NULL;
3746 }
3747
3748 /* We might have bound to port 0, allowing the OS to figure it out;
3749 thus, get the real IN-address from the socket */
3750 sto_len = sizeof(in_sto);
3751 if (0 != getsockname (GNUNET_NETWORK_get_fd (sock),
3752 (struct sockaddr *) &in_sto,
3753 &sto_len))
3754 {
3755 memcpy (&in_sto, in, in_len);
3756 sto_len = in_len;
3757 }
3758 GNUNET_free (in);
3759 *out = GNUNET_malloc (sto_len);
3760 memcpy (*out, (struct sockaddr *) &in_sto, sto_len);
3761 *out_len = sto_len;
3762 return sock;
3763}
3764
3765
3766static void
3767shutdown_run (struct sockaddr *addrs[2])
3768{
3769 if (NULL != addrs[0])
3770 GNUNET_free (addrs[0]);
3771 if (NULL != addrs[1])
3772 GNUNET_free (addrs[1]);
3774}
3775
3776
3777static void
3778run (void *cls,
3779 char *const *args,
3780 const char *cfgfile,
3781 const struct GNUNET_CONFIGURATION_Handle *c)
3782{
3783 const struct sockaddr_in *v4;
3784 char *bindto;
3785 char *bindto6;
3786 struct sockaddr *in[2];
3787 socklen_t in_len[2];
3788
3790 "Entering the run method of udp communicator.\n");
3791
3792 cfg = c;
3794 if ((GNUNET_NO == GNUNET_NETWORK_test_pf (PF_INET6)) ||
3795 (GNUNET_YES ==
3798 "DISABLE_V6")))
3799 {
3801 }
3802
3803 if (GNUNET_OK !=
3806 "BINDTO",
3807 &bindto))
3808 {
3811 "BINDTO");
3812 return;
3813 }
3815 "The udp communicator will bind to %s for IPv4\n",
3816 bindto);
3817 if (GNUNET_YES != disable_v6)
3818 {
3819 if (GNUNET_OK !=
3822 "BINDTO6",
3823 &bindto6))
3824 {
3827 "BINDTO6");
3828 return;
3829 }
3830
3832 "The udp communicator will bind to %s for IPv6\n",
3833 bindto6);
3834 }
3835 else
3836 bindto6 = NULL;
3837 if (GNUNET_OK !=
3840 "REKEY_INTERVAL",
3843
3844 if (GNUNET_OK !=
3847 "REKEY_MAX_BYTES",
3849 {
3851 }
3852
3853 memset (in, 0, sizeof(struct sockaddr*) * 2);
3854 memset (in_len, 0, sizeof(socklen_t) * 2);
3855
3856 GNUNET_assert (bindto);
3858 bindto, AF_INET, &(in[0]), &(in_len[0]));
3859 GNUNET_free (bindto);
3860
3861 if (GNUNET_YES != disable_v6)
3862 {
3863 GNUNET_assert (bindto6);
3865 bindto6, AF_INET6, &(in[1]), &(in_len[1]));
3866 GNUNET_free (bindto6);
3867 }
3868 else
3869 default_v6_sock = NULL;
3870
3871 if ((NULL == default_v4_sock) && (NULL == default_v6_sock))
3872 return;
3873
3874 my_port = 0;
3875 if (NULL != default_v4_sock)
3876 {
3877 GNUNET_assert (in[0]);
3879 "transport",
3880 "Bound to `%s' sock %p\n",
3881 GNUNET_a2s ((const struct sockaddr *) in[0],
3882 in_len[0]),
3884
3885 v4 = (const struct sockaddr_in *) in[0];
3886
3887 my_ipv4 = GNUNET_malloc (INET_ADDRSTRLEN);
3888 my_port = ntohs (((struct sockaddr_in *) in[0])->sin_port);
3889 inet_ntop (AF_INET, &v4->sin_addr, my_ipv4, in_len[0]);
3890 }
3891 if (NULL != default_v6_sock)
3892 {
3893 GNUNET_assert (in[1]);
3895 "transport",
3896 "Bound to `%s' sock %p\n",
3897 GNUNET_a2s ((const struct sockaddr *) in[1],
3898 in_len[1]),
3900 my_port = ntohs (((struct sockaddr_in6 *) in[1])->sin6_port);
3901 }
3902 stats = GNUNET_STATISTICS_create ("communicator-udp", cfg);
3911 /* start reading */
3912 if (NULL != default_v4_sock)
3915 &sock_read,
3917 else
3918 read_v4_task = NULL;
3919 if (NULL != default_v6_sock)
3922 &sock_read,
3924 else
3925 read_v6_task = NULL;
3930 &mq_init,
3931 NULL,
3933 NULL,
3934 &start_burst);
3935 if (NULL == ch)
3936 {
3937 GNUNET_break (0);
3938 shutdown_run (in);
3939 return;
3940 }
3942 if (NULL == ah)
3943 {
3944 GNUNET_break (0);
3945 shutdown_run (in);
3946 return;
3947 }
3948 /* start broadcasting */
3949 if (GNUNET_YES !=
3952 "DISABLE_BROADCAST"))
3953 {
3955 }
3957 GNUNET_assert (NULL != key_ring);
3958 pils = GNUNET_PILS_connect (cfg, NULL, NULL);
3959 GNUNET_assert (NULL != pils);
3960
3963 IPPROTO_UDP,
3964 (NULL != in[0]? 1 : 0)
3965 + (NULL != in[1]? 1 : 0),
3966 (const struct sockaddr**)
3967 (NULL != in[0]? in : &(in[1])),
3968 NULL != in[0]? in_len : &(in_len[1]),
3971 NULL /* closure */);
3972 if (NULL != in[0])
3973 GNUNET_free (in[0]);
3974 if (NULL != in[1])
3975 GNUNET_free (in[1]);
3976}
3977
3978
3979GNUNET_DAEMON_MAIN ("gnunet-communicator-udp",
3980 _ ("GNUnet UDP communicator"),
3981 &run)
3982/* 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(uint64_t max)
Generate a random unsigned 64-bit value.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hpke_elligator_kem_encaps(const struct GNUNET_CRYPTO_HpkePublicKey *pkR, struct GNUNET_CRYPTO_HpkeEncapsulation *c, struct GNUNET_ShortHashCode *shared_secret)
Carries out ecdh encapsulation with given public key and the private key from a freshly created ephem...
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_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...
void GNUNET_CRYPTO_random_block(void *buffer, size_t length)
Fill block with a random values.
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.
#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:40
#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:513
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:568
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.
static 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 3038 of file gnunet-communicator-udp.c.

3039{
3040 size_t base_mtu;
3041
3042 switch (receiver->address->sa_family)
3043 {
3044 case AF_INET:
3045 base_mtu = 1480 /* Ethernet MTU, 1500 - Ethernet header - VLAN tag */
3046 - sizeof(struct GNUNET_TUN_IPv4Header) /* 20 */
3047 - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */;
3048 break;
3049
3050 case AF_INET6:
3051 base_mtu = 1280 /* Minimum MTU required by IPv6 */
3052 - sizeof(struct GNUNET_TUN_IPv6Header) /* 40 */
3053 - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */;
3054 break;
3055
3056 default:
3057 GNUNET_assert (0);
3058 break;
3059 }
3060 /* MTU based on full KX messages */
3061 receiver->kx_mtu = base_mtu - sizeof(struct InitialKX) /* 48 */
3062 - sizeof(struct UDPConfirmation); /* 104 */
3063 /* MTU based on BOXed messages */
3064 receiver->d_mtu = base_mtu - sizeof(struct UDPBox);
3065
3067 "Setting up MQs and QHs\n");
3068 /* => Effective MTU for CORE will range from 1080 (IPv6 + KX) to
3069 1404 (IPv4 + Box) bytes, depending on circumstances... */
3070 if (NULL == receiver->kx_mq)
3073 &mq_cancel,
3074 receiver,
3075 NULL,
3076 &mq_error,
3077 receiver);
3078 if (NULL == receiver->d_mq)
3080 &mq_destroy_d,
3081 &mq_cancel,
3082 receiver,
3083 NULL,
3084 &mq_error,
3085 receiver);
3086
3087 receiver->kx_qh =
3089 &receiver->target,
3090 receiver->foreign_addr,
3091 receiver->kx_mtu,
3093 0, /* Priority */
3094 receiver->nt,
3096 receiver->kx_mq);
3097}

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 if (ntohs (hdr->size) < sizeof (struct UDPRekey))
1775 {
1776 GNUNET_break_op (0);
1777 return;
1778 }
1779 ss_rekey = setup_shared_secret_dec (&rekey->ephemeral);
1780 ss_rekey->sender = sender;
1781 GNUNET_CONTAINER_DLL_insert (sender->ss_head, sender->ss_tail, ss_rekey);
1782 sender->num_secrets++;
1784 "Received rekey secret with cmac %s\n",
1785 GNUNET_h2s (&(ss_rekey->cmac)));
1787 "Received secret with master %s.\n",
1788 GNUNET_sh2s (&(ss_rekey->master)));
1790 "We have %u sequence_allowed.\n",
1791 ss_rekey->sequence_allowed);
1793 "We have a sender %p\n",
1794 ss_rekey->sender);
1796 "We have %u acks available.\n",
1797 ss_rekey->sender->acks_available);
1799 "# rekeying successful",
1800 1,
1801 GNUNET_NO);
1804 // FIXME
1805 kce_generate_cb (ss_rekey);
1806 /* ss_rekey->sender->kce_task = GNUNET_SCHEDULER_add_delayed (
1807 WORKING_QUEUE_INTERVALL,
1808 kce_generate_cb,
1809 ss_rekey);*/
1810 // FIXME: Theoretically, this could be an Ack
1811 buf_pos += ntohs (hdr->size);
1812 bytes_remaining -= ntohs (hdr->size);
1813 pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
1814 if (0 == purge_secrets (sender->ss_tail))
1815 {
1816 // No secret purged. Delete oldest.
1817 if (sender->num_secrets > MAX_SECRETS)
1818 {
1819 secret_destroy (sender->ss_tail);
1820 }
1821 }
1822 break;
1824 /* lookup master secret by 'cmac', then update sequence_max */
1825 ack = (struct UDPAck*) buf_pos;
1826 if (ntohs (hdr->size) < sizeof (struct UDPAck))
1827 {
1828 GNUNET_break_op (0);
1829 return;
1830 }
1832 &sender->key,
1833 &handle_ack,
1834 (void *) ack);
1835 /* There could be more messages after the ACK, handle those as well */
1836 buf_pos += ntohs (hdr->size);
1837 bytes_remaining -= ntohs (hdr->size);
1838 pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
1839 break;
1840
1842 /* skip padding */
1843 break;
1844
1845 default:
1846 pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
1847 }
1848 return;
1849}

References SenderAddress::acks_available, SharedSecret::cmac, UDPRekey::ephemeral, GNUNET_break_op, 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 1860 of file gnunet-communicator-udp.c.

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

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

1977{
1978 struct SenderAddress *sender;
1979 struct GNUNET_HashContext *hsh;
1980 struct GNUNET_HashCode sender_key;
1981
1983 GNUNET_CRYPTO_hash_context_read (hsh, address, address_len);
1984 GNUNET_CRYPTO_hash_context_read (hsh, target, sizeof(*target));
1985 GNUNET_CRYPTO_hash_context_finish (hsh, &sender_key);
1986
1987 sender = GNUNET_CONTAINER_multihashmap_get (senders, &sender_key);
1988 if (NULL != sender)
1989 {
1991 return sender;
1992 }
1993 sender = GNUNET_new (struct SenderAddress);
1994 sender->key = sender_key;
1995 sender->target = *target;
1996 sender->address = GNUNET_memdup (address, address_len);
1997 sender->address_len = address_len;
1999 senders,
2000 &sender->key,
2001 sender,
2004 "# senders active",
2006 GNUNET_NO);
2007 sender->timeout =
2010 sender,
2011 sender->timeout.abs_value_us);
2012 sender->nt = GNUNET_NT_scanner_get_type (is, address, address_len);
2013 if (NULL == timeout_task)
2015 return sender;
2016}

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

2029{
2030 const struct GNUNET_PeerIdentity *my_identity;
2031 struct UdpHandshakeSignature uhs;
2032
2035
2036 uhs.purpose.purpose = htonl (
2038 uhs.purpose.size = htonl (sizeof(uhs));
2039 uhs.sender = uc->sender;
2040 uhs.receiver = *my_identity;
2041 uhs.enc = *enc;
2042 uhs.monotonic_time = uc->monotonic_time;
2045 &uhs,
2046 &uc->sender_sig,
2047 &uc->sender.public_key);
2048}

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

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

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

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

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

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

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

2357{
2358 struct sockaddr_storage sa;
2359 struct sockaddr_in *addr_verify;
2360 socklen_t salen = sizeof(sa);
2361 char buf[UINT16_MAX];
2362 ssize_t rcvd;
2363
2364 struct GNUNET_NETWORK_Handle *udp_sock = cls;
2365
2368 udp_sock,
2369 &sock_read,
2370 udp_sock);
2373 udp_sock,
2374 &sock_read,
2375 udp_sock);
2376 while (1)
2377 {
2379 buf,
2380 sizeof(buf),
2381 (struct sockaddr *) &sa,
2382 &salen);
2383 if (-1 == rcvd)
2384 {
2385 struct sockaddr *addr = (struct sockaddr*) &sa;
2386
2387 if (EAGAIN == errno)
2388 break; // We are done reading data
2390 "Failed to recv from %s family %d failed sock %p\n",
2391 GNUNET_a2s ((struct sockaddr*) &sa,
2392 sizeof (*addr)),
2393 addr->sa_family,
2394 udp_sock);
2396 return;
2397 }
2399 "Read %llu bytes\n",
2400 (unsigned long long) rcvd);
2401 if (0 == rcvd)
2402 {
2403 GNUNET_break_op (0);
2405 "Read 0 bytes from UDP socket\n");
2406 return;
2407 }
2408
2409 /* first, see if it is a GNUNET_BurstMessage */
2410 if (rcvd == sizeof (struct GNUNET_BurstMessage))
2411 {
2412 struct GNUNET_BurstMessage *bm = (struct GNUNET_BurstMessage *) buf;
2413 struct sockaddr *addr = (struct sockaddr*) &sa;
2414 char *address = sockaddr_to_udpaddr_string (addr, sizeof (*addr));
2415
2416 if (0 != bm->local_port)
2417 {
2418 GNUNET_break_op (0);
2420 "Received a burst message on port %u\n",
2421 bm->local_port);
2422 return;
2423 }
2425 "Received a burst message for default port\n");
2426 create_receiver (&bm->peer,
2427 address,
2428 NULL);
2429 if (AF_INET6 == addr->sa_family)
2431 else
2435 return;
2436 }
2437 /* second, see if it is a UDPBox */
2438 if (rcvd > sizeof(struct UDPBox))
2439 {
2440 const struct UDPBox *box;
2441 struct KeyCacheEntry *kce;
2442
2443 box = (const struct UDPBox *) buf;
2445 if (NULL != kce)
2446 {
2448 "Found KCE with kid %s\n",
2449 GNUNET_sh2s (&box->kid));
2450 decrypt_box (box, (size_t) rcvd, kce);
2451 continue;
2452 }
2453 }
2454
2455 /* next, check if it is a broadcast */
2456 if (sizeof(struct UDPBroadcast) == rcvd)
2457 {
2458 const struct GNUNET_PeerIdentity *my_identity;
2459 const struct UDPBroadcast *ub;
2460 struct UdpBroadcastSignature uhs;
2461 struct GNUNET_PeerIdentity sender;
2462
2465
2466 addr_verify = GNUNET_memdup (&sa, salen);
2467 addr_verify->sin_port = 0;
2469 "received UDPBroadcast from %s\n",
2470 GNUNET_a2s ((const struct sockaddr *) addr_verify, salen));
2471 ub = (const struct UDPBroadcast *) buf;
2472 uhs.purpose.purpose = htonl (
2474 uhs.purpose.size = htonl (sizeof(uhs));
2475 uhs.sender = ub->sender;
2476 sender = ub->sender;
2477 if (0 == memcmp (&sender, my_identity, sizeof (struct
2479 {
2481 "Received our own broadcast\n");
2482 GNUNET_free (addr_verify);
2483 continue;
2484 }
2486 "checking UDPBroadcastSignature for %s\n",
2487 GNUNET_i2s (&sender));
2488 GNUNET_CRYPTO_hash ((struct sockaddr *) addr_verify, salen,
2489 &uhs.h_address);
2490 if (GNUNET_OK ==
2493 &uhs,
2494 &ub->sender_sig,
2495 &ub->sender.public_key))
2496 {
2497 char *addr_s;
2499
2500 addr_s =
2501 sockaddr_to_udpaddr_string ((const struct sockaddr *) &sa, salen);
2502 GNUNET_STATISTICS_update (stats, "# broadcasts received", 1, GNUNET_NO);
2503 /* use our own mechanism to determine network type */
2504 nt =
2505 GNUNET_NT_scanner_get_type (is, (const struct sockaddr *) &sa, salen);
2507 "validating address %s received from UDPBroadcast\n",
2508 GNUNET_i2s (&sender));
2510 GNUNET_free (addr_s);
2511 GNUNET_free (addr_verify);
2512 continue;
2513 }
2514 else
2515 {
2517 "VerifyingPeer %s is verifying UDPBroadcast\n",
2520 "Verifying UDPBroadcast from %s failed\n",
2521 GNUNET_i2s (&ub->sender));
2522 }
2523 GNUNET_free (addr_verify);
2524 /* continue with KX, mostly for statistics... */
2525 }
2526
2527
2528 /* finally, test if it is a KX */
2529 if (rcvd < sizeof(struct UDPConfirmation) + sizeof(struct InitialKX))
2530 {
2532 "# messages dropped (no kid, too small for KX)",
2533 1,
2534 GNUNET_NO);
2535 continue;
2536 }
2538 "Got KX\n");
2539 {
2540 const struct InitialKX *kx;
2541 struct SharedSecret *ss;
2542 char pbuf[rcvd - sizeof(struct InitialKX)];
2543 const struct UDPConfirmation *uc;
2544 struct SenderAddress *sender;
2545
2546 kx = (const struct InitialKX *) buf;
2549 "Before DEC\n");
2550
2551 if (GNUNET_OK != try_decrypt (ss,
2552 kx->gcm_tag,
2553 0,
2554 &buf[sizeof(*kx)],
2555 sizeof(pbuf),
2556 pbuf))
2557 {
2559 "Unable to decrypt tag, dropping...\n");
2560 GNUNET_free (ss);
2562 stats,
2563 "# messages dropped (no kid, AEAD decryption failed)",
2564 1,
2565 GNUNET_NO);
2566 continue;
2567 }
2569 "Before VERIFY\n");
2570
2571 uc = (const struct UDPConfirmation *) pbuf;
2572
2573 if (GNUNET_OK != verify_confirmation (&kx->enc, uc)) // TODO: need ephemeral instead of representative
2574 {
2575 GNUNET_break_op (0);
2576 GNUNET_free (ss);
2578 "# messages dropped (sender signature invalid)",
2579 1,
2580 GNUNET_NO);
2581 continue;
2582 }
2584 "Before SETUP_SENDER\n");
2585
2586 calculate_cmac (ss);
2587 sender = setup_sender (&uc->sender, (const struct sockaddr *) &sa, salen);
2588 ss->sender = sender;
2589 GNUNET_CONTAINER_DLL_insert (sender->ss_head, sender->ss_tail, ss);
2590 if ((KCN_THRESHOLD > ss->sender->acks_available) &&
2591 (NULL == ss->sender->kce_task) &&
2593 {
2594 // 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.
2598 ss);
2599 }
2600 sender->num_secrets++;
2601 GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
2603 "# messages decrypted without BOX",
2604 1,
2605 GNUNET_NO);
2606 try_handle_plaintext (sender, &uc[1], sizeof(pbuf) - sizeof(*uc));
2607 if (0 == purge_secrets (sender->ss_tail))
2608 {
2609 // No secret purged. Delete oldest.
2610 if (sender->num_secrets > MAX_SECRETS)
2611 {
2612 secret_destroy (sender->ss_tail);
2613 }
2614 }
2615 }
2616 }
2617}

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

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

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

2629{
2630 char pad[pad_size];
2631
2633 sizeof(pad));
2634 if (sizeof(pad) > sizeof(struct GNUNET_MessageHeader))
2635 {
2636 struct GNUNET_MessageHeader hdr =
2637 { .size = htons (sizeof(pad)),
2639
2640 memcpy (pad, &hdr, sizeof(hdr));
2641 }
2643 0 ==
2644 gcry_cipher_encrypt (out_cipher, dgram, sizeof(pad), pad, sizeof(pad)));
2645}

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

2652{
2653 const struct GNUNET_PeerIdentity *my_identity;
2655 uint16_t msize = ntohs (msg->size);
2656 struct UdpHandshakeSignature uhs;
2657 struct UDPConfirmation uc;
2658 struct InitialKX kx;
2659 char dgram[receiver->kx_mtu + sizeof(uc) + sizeof(kx)];
2660 size_t dpos;
2661 gcry_cipher_hd_t out_cipher;
2662 struct SharedSecret *ss;
2663
2667
2668 if (msize > receiver->kx_mtu)
2669 {
2670 GNUNET_break (0);
2671 if (GNUNET_YES != receiver->receiver_destroy_called)
2673 return;
2674 }
2676
2677 /* setup key material */
2679
2680 if (0 == purge_secrets (receiver->ss_tail))
2681 {
2682 // No secret purged. Delete oldest.
2683 if (receiver->num_secrets > MAX_SECRETS)
2684 {
2685 secret_destroy (receiver->ss_tail);
2686 }
2687 }
2688
2689 setup_cipher (&ss->master, 0, &out_cipher);
2690 /* compute 'uc' */
2691 uc.sender = *my_identity;
2692 uc.monotonic_time =
2694 uhs.purpose.purpose = htonl (
2696 uhs.purpose.size = htonl (sizeof(uhs));
2697 uhs.sender = *my_identity;
2698 uhs.receiver = receiver->target;
2699 uhs.monotonic_time = uc.monotonic_time;
2701 &uhs,
2702 &uc.sender_sig);
2703 /* Leave space for kx */
2704 dpos = sizeof(kx);
2705 /* Append encrypted uc to dgram */
2706 GNUNET_assert (0 == gcry_cipher_encrypt (out_cipher,
2707 &dgram[dpos],
2708 sizeof(uc),
2709 &uc,
2710 sizeof(uc)));
2711 dpos += sizeof(uc);
2712 /* Append encrypted payload to dgram */
2714 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], msize, msg, msize));
2715 dpos += msize;
2716 do_pad (out_cipher, &dgram[dpos], sizeof(dgram) - dpos);
2717 /* Datagram starts with kx */
2718 kx.enc = uhs.enc;
2720 0 == gcry_cipher_gettag (out_cipher, kx.gcm_tag, sizeof(kx.gcm_tag)));
2721 gcry_cipher_close (out_cipher);
2722 memcpy (dgram, &kx, sizeof(kx));
2724 dgram,
2725 sizeof(dgram),
2726 receiver->address,
2727 receiver->address_len))
2728 {
2731 "Sending KX with payload size %u to %s family %d failed sock %p\n",
2732 msize,
2733 GNUNET_a2s (receiver->address,
2734 receiver->address_len),
2735 receiver->address->sa_family,
2739 return;
2740 }
2742 "Sending KX with payload size %u to %s with socket %p\n",
2743 msize,
2744 GNUNET_a2s (receiver->address,
2745 receiver->address_len),
2748}

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

2763{
2764 struct ReceiverAddress *receiver = impl_state;
2765
2766 GNUNET_assert (mq == receiver->kx_mq);
2768}

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

2774{
2775 struct SharedSecret *ss_rekey;
2776
2778 /* setup key material */
2779 ss_rekey = setup_shared_secret_ephemeral (&rekey->ephemeral,
2780 receiver);
2781 ss_rekey->sequence_allowed = 0;
2783 "Setup secret with k = %s\n",
2784 GNUNET_sh2s (&ss_rekey->master));
2786 "Setup secret with H(k) = %s\n",
2787 GNUNET_h2s (&(ss_rekey->cmac)));
2788
2789 /* Append encrypted payload to dgram */
2791 rekey->header.size = htons (sizeof (struct UDPRekey));
2792}

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

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

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

2958{
2959 struct ReceiverAddress *receiver = impl_state;
2961 "Default MQ destroyed\n");
2962 if (mq == receiver->d_mq)
2963 {
2964 receiver->d_mq = NULL;
2965 if (GNUNET_YES != receiver->receiver_destroy_called)
2967 }
2968}

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

2981{
2982 struct ReceiverAddress *receiver = impl_state;
2984 "KX MQ destroyed\n");
2985 if (mq == receiver->kx_mq)
2986 {
2987 receiver->kx_mq = NULL;
2988 if (GNUNET_YES != receiver->receiver_destroy_called)
2990 }
2991}

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

3002{
3003 /* Cancellation is impossible with UDP; bail */
3004 GNUNET_assert (0);
3005}

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

3019{
3020 struct ReceiverAddress *receiver = cls;
3021
3023 "MQ error in queue to %s: %d\n",
3024 GNUNET_i2s (&receiver->target),
3025 (int) error);
3027}

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

3120{
3121 (void) cls;
3123 "create receiver for mq_init\n");
3124 return create_receiver (peer,
3125 address,
3126 NULL);
3127}

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

3142{
3143 struct ReceiverAddress *receiver = value;
3144
3145 (void) cls;
3146 (void) target;
3148 return GNUNET_OK;
3149}

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

3164{
3165 struct SenderAddress *sender = value;
3166
3167 (void) cls;
3168 (void) target;
3169
3170
3171 sender_destroy (sender);
3172 return GNUNET_OK;
3173}

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

3183{
3185 "do_shutdown\n");
3186 GNUNET_stop_burst (NULL);
3187 if (NULL != nat)
3188 {
3190 nat = NULL;
3191 }
3192 while (NULL != bi_head)
3194 if (NULL != broadcast_task)
3195 {
3197 broadcast_task = NULL;
3198 }
3199 if (NULL != timeout_task)
3200 {
3202 timeout_task = NULL;
3203 }
3204 if (NULL != read_v6_task)
3205 {
3207 read_v6_task = NULL;
3208 }
3209 if (NULL != read_v4_task)
3210 {
3212 read_v4_task = NULL;
3213 }
3214 if (NULL != default_v6_sock)
3215 {
3218 default_v6_sock = NULL;
3219 }
3220 if (NULL != default_v4_sock)
3221 {
3224 default_v4_sock = NULL;
3225 }
3228 NULL);
3232 NULL);
3237 if (NULL != timeout_task)
3238 {
3240 timeout_task = NULL;
3241 }
3242 if (NULL != ch)
3243 {
3246 ch = NULL;
3247 }
3248 if (NULL != ah)
3249 {
3251 ah = NULL;
3252 }
3253 if (NULL != pils)
3254 {
3256 pils = NULL;
3257 }
3258 if (NULL != key_ring)
3259 {
3261 key_ring = NULL;
3262 }
3263 if (NULL != stats)
3264 {
3266 stats = NULL;
3267 }
3268 if (NULL != is)
3269 {
3271 is = NULL;
3272 }
3274 "do_shutdown finished\n");
3275}

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

3287{
3288 struct ReceiverAddress *receiver = value;
3289 struct AckInfo *ai = cls;
3290
3291 if (0 != GNUNET_memcmp (ai->sender, &receiver->target))
3292 {
3293 return GNUNET_YES;
3294 }
3295 handle_ack ((void*) ai->ack, key, receiver);
3296 return GNUNET_YES;
3297}

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

3313{
3314 struct AckInfo ai;
3315
3316 (void) cls;
3318 "Storing UDPAck received from backchannel from %s\n",
3321 (ntohs (msg->size) != sizeof(struct UDPAck)))
3322 {
3323 GNUNET_break_op (0);
3324 return;
3325 }
3326 ai.ack = (const struct UDPAck *) msg;
3327 ai.sender = sender;
3330 &ai);
3331}

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

3354{
3355 char *my_addr;
3357
3358 if (GNUNET_YES == add_remove)
3359 {
3361
3362 GNUNET_asprintf (&my_addr,
3363 "%s-%s",
3365 GNUNET_a2s (addr, addrlen));
3366 nt = GNUNET_NT_scanner_get_type (is, addr, addrlen);
3367 ai =
3369 my_addr,
3370 nt,
3372 GNUNET_free (my_addr);
3373 *app_ctx = ai;
3374 }
3375 else
3376 {
3377 ai = *app_ctx;
3379 *app_ctx = NULL;
3380 }
3381}

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

3391{
3392 struct BroadcastInterface *bi = cls;
3393 struct GNUNET_TIME_Relative delay;
3394
3395 delay = BROADCAST_FREQUENCY;
3396 delay.rel_value_us =
3397 GNUNET_CRYPTO_random_u64 (delay.rel_value_us);
3398 bi->broadcast_task =
3400
3401 switch (bi->sa->sa_family)
3402 {
3403 case AF_INET: {
3404 static int yes = 1;
3405 static int no = 0;
3406 ssize_t sent;
3407
3408 if (GNUNET_OK !=
3410 SOL_SOCKET,
3411 SO_BROADCAST,
3412 &yes,
3413 sizeof(int)))
3415 "setsockopt");
3417 "creating UDPBroadcast from %s\n",
3418 GNUNET_i2s (&(bi->bcm.sender)));
3420 "sending UDPBroadcast to add %s\n",
3421 GNUNET_a2s (bi->ba, bi->salen));
3423 &bi->bcm,
3424 sizeof(bi->bcm),
3425 bi->ba,
3426 bi->salen);
3427 if (-1 == sent)
3429 "sendto");
3431 SOL_SOCKET,
3432 SO_BROADCAST,
3433 &no,
3434 sizeof(int)))
3436 "setsockopt");
3437 break;
3438 }
3439
3440 case AF_INET6: {
3441 ssize_t sent;
3442 struct sockaddr_in6 dst;
3443
3444 dst.sin6_family = AF_INET6;
3445 dst.sin6_port = htons (my_port);
3446 dst.sin6_addr = bi->mcreq.ipv6mr_multiaddr;
3447 dst.sin6_scope_id = ((struct sockaddr_in6 *) bi->ba)->sin6_scope_id;
3448
3450 "sending UDPBroadcast\n");
3452 &bi->bcm,
3453 sizeof(bi->bcm),
3454 (const struct sockaddr *) &dst,
3455 sizeof(dst));
3456 if (-1 == sent)
3458 break;
3459 }
3460
3461 default:
3462 GNUNET_break (0);
3463 break;
3464 }
3465}

References BroadcastInterface::ba, BroadcastInterface::bcm, BROADCAST_FREQUENCY, BroadcastInterface::broadcast_task, default_v4_sock, default_v6_sock, GNUNET_a2s(), GNUNET_break, 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 3483 of file gnunet-communicator-udp.c.

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

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

3602{
3603 struct BroadcastInterface *bin;
3604
3605 (void) cls;
3606 for (struct BroadcastInterface *bi = bi_head; NULL != bi; bi = bi->next)
3607 bi->found = GNUNET_NO;
3609 for (struct BroadcastInterface *bi = bi_head; NULL != bi; bi = bin)
3610 {
3611 bin = bi->next;
3612 if (GNUNET_NO == bi->found)
3613 bi_destroy (bi);
3614 }
3616 &do_broadcast,
3617 NULL);
3618}

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

3625{
3626 /* FIXME: support reversal: #5529 */
3628 "No connection reversal implemented!\n");
3629}

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

3634{
3635 // FIXME: This sizeof application truncates IPv6 addresses!
3637 sizeof (*sock_info->actual_address
3638 ));
3639 create_receiver (sock_info->pid,
3640 address,
3641 default_v4_sock == sock_info->udp_sock ||
3642 default_v6_sock == sock_info->udp_sock ?
3643 NULL : sock_info->udp_sock);
3645 GNUNET_free (sock_info);
3646}

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

3653{
3654 struct GNUNET_UdpSocketInfo *sock_info;
3655
3657 "Communicator was called to start burst to address %s from %s\n",
3658 addr,
3659 my_ipv4);
3660
3661 GNUNET_stop_burst (NULL);
3662
3663 sock_info = GNUNET_new (struct GNUNET_UdpSocketInfo);
3664 sock_info->pid = GNUNET_new (struct GNUNET_PeerIdentity);
3665 sock_info->address = GNUNET_strdup (addr);
3666 sock_info->bind_address = my_ipv4;
3667 sock_info->has_port = GNUNET_YES;
3668 sock_info->udp_sock = default_v4_sock;
3669 sock_info->rtt = rtt;
3670 GNUNET_memcpy (sock_info->pid, pid, sizeof (struct GNUNET_PeerIdentity));
3671 sock_info->std_port = my_port;
3673 "1 sock addr %s addr %s rtt %lu %u\n",
3674 sock_info->address,
3675 addr,
3676 (unsigned long) sock_info->rtt.rel_value_us,
3677 my_port);
3678 burst_task = GNUNET_get_udp_socket (sock_info,
3680 GNUNET_free (sock_info);
3681}

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

3689{
3690 struct GNUNET_NETWORK_Handle *sock;
3691 struct sockaddr *in;
3692 socklen_t in_len;
3693 struct sockaddr_storage in_sto;
3694 socklen_t sto_len;
3695
3696 in = udp_address_to_sockaddr (bindto, family, &in_len);
3697 if (NULL == in)
3698 {
3700 "Failed to setup UDP socket address with path `%s'\n",
3701 bindto);
3702 return NULL;
3703 }
3704
3705 if ((AF_UNSPEC != family) && (in->sa_family != family))
3706 {
3708 "Invalid UDP socket address setup with path `%s'\n",
3709 bindto);
3710 GNUNET_free (in);
3711 return NULL;
3712 }
3713
3714 sock =
3715 GNUNET_NETWORK_socket_create (in->sa_family,
3716 SOCK_DGRAM,
3717 IPPROTO_UDP);
3718 if (NULL == sock)
3719 {
3722 "Failed to create socket for %s family %d\n",
3723 GNUNET_a2s (in,
3724 in_len),
3725 in->sa_family);
3726 GNUNET_free (in);
3727 return NULL;
3728 }
3729 if (GNUNET_OK !=
3731 in,
3732 in_len))
3733 {
3735 "bind",
3736 bindto);
3738 "Failed to bind socket for %s family %d sock %p\n",
3739 GNUNET_a2s (in,
3740 in_len),
3741 in->sa_family,
3742 sock);
3744 sock = NULL;
3745 GNUNET_free (in);
3746 return NULL;
3747 }
3748
3749 /* We might have bound to port 0, allowing the OS to figure it out;
3750 thus, get the real IN-address from the socket */
3751 sto_len = sizeof(in_sto);
3752 if (0 != getsockname (GNUNET_NETWORK_get_fd (sock),
3753 (struct sockaddr *) &in_sto,
3754 &sto_len))
3755 {
3756 memcpy (&in_sto, in, in_len);
3757 sto_len = in_len;
3758 }
3759 GNUNET_free (in);
3760 *out = GNUNET_malloc (sto_len);
3761 memcpy (*out, (struct sockaddr *) &in_sto, sto_len);
3762 *out_len = sto_len;
3763 return sock;
3764}

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

3769{
3770 if (NULL != addrs[0])
3771 GNUNET_free (addrs[0]);
3772 if (NULL != addrs[1])
3773 GNUNET_free (addrs[1]);
3775}

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

3783{
3784 const struct sockaddr_in *v4;
3785 char *bindto;
3786 char *bindto6;
3787 struct sockaddr *in[2];
3788 socklen_t in_len[2];
3789
3791 "Entering the run method of udp communicator.\n");
3792
3793 cfg = c;
3795 if ((GNUNET_NO == GNUNET_NETWORK_test_pf (PF_INET6)) ||
3796 (GNUNET_YES ==
3799 "DISABLE_V6")))
3800 {
3802 }
3803
3804 if (GNUNET_OK !=
3807 "BINDTO",
3808 &bindto))
3809 {
3812 "BINDTO");
3813 return;
3814 }
3816 "The udp communicator will bind to %s for IPv4\n",
3817 bindto);
3818 if (GNUNET_YES != disable_v6)
3819 {
3820 if (GNUNET_OK !=
3823 "BINDTO6",
3824 &bindto6))
3825 {
3828 "BINDTO6");
3829 return;
3830 }
3831
3833 "The udp communicator will bind to %s for IPv6\n",
3834 bindto6);
3835 }
3836 else
3837 bindto6 = NULL;
3838 if (GNUNET_OK !=
3841 "REKEY_INTERVAL",
3844
3845 if (GNUNET_OK !=
3848 "REKEY_MAX_BYTES",
3850 {
3852 }
3853
3854 memset (in, 0, sizeof(struct sockaddr*) * 2);
3855 memset (in_len, 0, sizeof(socklen_t) * 2);
3856
3857 GNUNET_assert (bindto);
3859 bindto, AF_INET, &(in[0]), &(in_len[0]));
3860 GNUNET_free (bindto);
3861
3862 if (GNUNET_YES != disable_v6)
3863 {
3864 GNUNET_assert (bindto6);
3866 bindto6, AF_INET6, &(in[1]), &(in_len[1]));
3867 GNUNET_free (bindto6);
3868 }
3869 else
3870 default_v6_sock = NULL;
3871
3872 if ((NULL == default_v4_sock) && (NULL == default_v6_sock))
3873 return;
3874
3875 my_port = 0;
3876 if (NULL != default_v4_sock)
3877 {
3878 GNUNET_assert (in[0]);
3880 "transport",
3881 "Bound to `%s' sock %p\n",
3882 GNUNET_a2s ((const struct sockaddr *) in[0],
3883 in_len[0]),
3885
3886 v4 = (const struct sockaddr_in *) in[0];
3887
3888 my_ipv4 = GNUNET_malloc (INET_ADDRSTRLEN);
3889 my_port = ntohs (((struct sockaddr_in *) in[0])->sin_port);
3890 inet_ntop (AF_INET, &v4->sin_addr, my_ipv4, in_len[0]);
3891 }
3892 if (NULL != default_v6_sock)
3893 {
3894 GNUNET_assert (in[1]);
3896 "transport",
3897 "Bound to `%s' sock %p\n",
3898 GNUNET_a2s ((const struct sockaddr *) in[1],
3899 in_len[1]),
3901 my_port = ntohs (((struct sockaddr_in6 *) in[1])->sin6_port);
3902 }
3903 stats = GNUNET_STATISTICS_create ("communicator-udp", cfg);
3912 /* start reading */
3913 if (NULL != default_v4_sock)
3916 &sock_read,
3918 else
3919 read_v4_task = NULL;
3920 if (NULL != default_v6_sock)
3923 &sock_read,
3925 else
3926 read_v6_task = NULL;
3931 &mq_init,
3932 NULL,
3934 NULL,
3935 &start_burst);
3936 if (NULL == ch)
3937 {
3938 GNUNET_break (0);
3939 shutdown_run (in);
3940 return;
3941 }
3943 if (NULL == ah)
3944 {
3945 GNUNET_break (0);
3946 shutdown_run (in);
3947 return;
3948 }
3949 /* start broadcasting */
3950 if (GNUNET_YES !=
3953 "DISABLE_BROADCAST"))
3954 {
3956 }
3958 GNUNET_assert (NULL != key_ring);
3959 pils = GNUNET_PILS_connect (cfg, NULL, NULL);
3960 GNUNET_assert (NULL != pils);
3961
3964 IPPROTO_UDP,
3965 (NULL != in[0]? 1 : 0)
3966 + (NULL != in[1]? 1 : 0),
3967 (const struct sockaddr**)
3968 (NULL != in[0]? in : &(in[1])),
3969 NULL != in[0]? in_len : &(in_len[1]),
3972 NULL /* closure */);
3973 if (NULL != in[0])
3974 GNUNET_free (in[0]);
3975 if (NULL != in[1])
3976 GNUNET_free (in[1]);
3977}

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