GNUnet 0.28.1-dev.4-24-g0cf3356dd
 
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  AckInfo
 
struct  SearchContext
 Closure for #find_sender_by_address() More...
 

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 PEER_LIVENESS_TIMEOUT   GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT
 How long may we keep transmitting to a peer that never acknowledges a single datagram before we conclude that it is gone and tear the queues down? A live peer that receives our datagrams answers with an GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK as soon as its key cache runs low, so silence for this long while we are actively sending means the peer is unreachable.
 
#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 enum GNUNET_GenericReturnValue check_peer_alive (struct ReceiverAddress *receiver)
 Check whether the peer behind receiver is still reacting to what we send it, and tear receiver down if it is not.
 
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 int handle_ack_by_sender (void *cls, const struct GNUNET_HashCode *key, void *value)
 Offer an ACK we received from ai->sender to the receiver in value, if that receiver is for that peer.
 
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, int *is_new)
 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 consider_reflexive_address (const struct GNUNET_PeerIdentity *target, const struct sockaddr *address, socklen_t address_len)
 Consider the address a datagram from target arrived from as a path we can send to.
 
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 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.

◆ PEER_LIVENESS_TIMEOUT

#define PEER_LIVENESS_TIMEOUT   GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT

How long may we keep transmitting to a peer that never acknowledges a single datagram before we conclude that it is gone and tear the queues down? A live peer that receives our datagrams answers with an GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK as soon as its key cache runs low, so silence for this long while we are actively sending means the peer is unreachable.

Definition at line 73 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 78 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 83 of file gnunet-communicator-udp.c.

178{
183
187 struct GNUNET_PeerIdentity sender;
188
193
198
203 struct GNUNET_TIME_AbsoluteNBO monotonic_time;
204};
205
206
211struct InitialKX
212{
217
222 uint8_t gcm_tag[GCM_TAG_SIZE];
223
224};
225
226
231struct UDPConfirmation
232{
237
242
248
249 /* followed by messages */
250
251 /* padding may follow actual messages */
252};
253
254
259struct UDPAck
260{
265
271
275 struct GNUNET_HashCode cmac;
276};
277
278
288{
293
298
303};
304
305
312struct UDPBroadcast
313{
318
324};
325
326
331struct UDPBox
332{
341
349 uint8_t gcm_tag[GCM_TAG_SIZE];
350
351};
352
356struct UDPRekey
357{
362
367};
368
370
374struct SharedSecret;
375
376
381struct KeyCacheEntry
382{
386 struct KeyCacheEntry *next;
387
391 struct KeyCacheEntry *prev;
392
401
405 struct SharedSecret *ss;
406
410 uint32_t sequence_number;
411};
412
413
418struct SenderAddress;
419
424struct ReceiverAddress;
425
429struct SharedSecret
430{
434 struct SharedSecret *next;
435
439 struct SharedSecret *prev;
440
444 struct KeyCacheEntry *kce_head;
445
449 struct KeyCacheEntry *kce_tail;
450
454 struct SenderAddress *sender;
455
460
465
469 struct GNUNET_HashCode cmac;
470
475 uint32_t sequence_used;
476
482 uint32_t sequence_allowed;
483
487 unsigned int active_kce_count;
488
492 size_t bytes_sent;
493
497 int rekey_initiated;
498
503};
504
505
510struct SenderAddress
511{
516
521
525 struct SharedSecret *ss_head;
526
530 struct SharedSecret *ss_tail;
531
535 struct sockaddr *address;
536
540 socklen_t address_len;
541
545 struct GNUNET_HashCode key;
546
551
555 unsigned int num_secrets;
556
561 unsigned int acks_available;
562
567
572
577
582
587};
588
589
594struct ReceiverAddress
595{
600
605
610
614 struct GNUNET_HashCode key;
615
619 struct SharedSecret *ss_head;
620
624 struct SharedSecret *ss_tail;
625
630 char *foreign_addr;
631
635 struct sockaddr *address;
636
640 socklen_t address_len;
641
646
650 struct GNUNET_MQ_Handle *kx_mq;
651
655 struct GNUNET_MQ_Handle *d_mq;
656
661
666
674
682
688
693
697 size_t kx_mtu;
698
702 size_t d_mtu;
703
707 unsigned int num_secrets;
708
713 unsigned int acks_available;
714
719
724};
725
730{
734 struct BroadcastInterface *next;
735
739 struct BroadcastInterface *prev;
740
745
749 struct sockaddr *sa;
750
754 struct sockaddr *ba;
755
759 struct UDPBroadcast bcm;
760
765 struct ipv6_mreq mcreq;
766
770 socklen_t salen;
771
775 int found;
776};
777
781static struct GNUNET_PILS_KeyRing *key_ring;
782
786static struct GNUNET_PILS_Handle *pils;
787
792
796static unsigned long long rekey_max_bytes;
797
802
807
812
817
822
826static struct GNUNET_STATISTICS_Handle *stats;
827
832
837
842
847
852
856static struct BroadcastInterface *bi_head;
857
861static struct BroadcastInterface *bi_tail;
862
867
872
876static const struct GNUNET_CONFIGURATION_Handle *cfg;
877
882
886static struct GNUNET_NT_InterfaceScanner *is;
887
891static struct GNUNET_NAT_Handle *nat;
892
896static uint16_t my_port;
897
901char *my_ipv4;
902
906static int disable_v6;
907
908static struct GNUNET_SCHEDULER_Task *burst_task;
909
910
911static void
914{
916 key.type = htonl (GNUNET_PUBLIC_KEY_TYPE_EDDSA);
917 key.eddsa_key = *edpk;
919 pk);
920}
921
922
923static void
926{
928 key.type = htonl (GNUNET_PUBLIC_KEY_TYPE_EDDSA);
929 key.eddsa_key = *edpk;
931 pk);
932}
933
934
940static void
942{
943 if (AF_INET6 == bi->sa->sa_family)
944 {
945 /* Leave the multicast group */
947 IPPROTO_IPV6,
948 IPV6_LEAVE_GROUP,
949 &bi->mcreq,
950 sizeof(bi->mcreq)))
951 {
953 }
954 }
957 GNUNET_free (bi->sa);
958 GNUNET_free (bi->ba);
959 GNUNET_free (bi);
960}
961
962
963static int
964secret_destroy (struct SharedSecret *ss);
965
971static void
973{
974 struct SharedSecret *ss;
975 receiver->receiver_destroy_called = GNUNET_YES;
976
978 "Disconnecting receiver for peer `%s'\n",
979 GNUNET_i2s (&receiver->target));
980 if (NULL != receiver->kx_qh)
981 {
983 receiver->kx_qh = NULL;
984 receiver->kx_mq = NULL;
985 }
986 if (NULL != receiver->d_qh)
987 {
989 receiver->d_qh = NULL;
990 }
991 else if (NULL != receiver->d_mq)
992 {
994 receiver->d_mq = NULL;
995 }
996 if (NULL != receiver->udp_sock)
997 {
1000 receiver->udp_sock = NULL;
1001 }
1004 &receiver->key,
1005 receiver));
1008 "# receivers active",
1010 GNUNET_NO);
1011 while (NULL != (ss = receiver->ss_head))
1012 {
1013 secret_destroy (ss);
1014 }
1015 GNUNET_free (receiver->address);
1016 GNUNET_free (receiver->foreign_addr);
1018}
1019
1020
1026static void
1027kce_destroy (struct KeyCacheEntry *kce)
1028{
1029 struct SharedSecret *ss = kce->ss;
1030
1031 ss->active_kce_count--;
1032 /* @e acks_available is "how many BOX keys do we have ready for this
1033 sender", so it must be maintained here, where a key actually goes away,
1034 and nowhere else. #kce_generate() is the only place one comes into
1035 existence. */
1036 if (NULL != ss->sender)
1037 {
1039 if (0 < ss->sender->acks_available)
1040 ss->sender->acks_available--;
1041 }
1044 &kce->kid,
1045 kce));
1046 GNUNET_free (kce);
1047}
1048
1049
1057static void
1058get_kid (const struct GNUNET_ShortHashCode *msec,
1059 uint32_t serial,
1060 struct GNUNET_ShortHashCode *kid)
1061{
1062 uint32_t sid = htonl (serial);
1063 struct GNUNET_ShortHashCode prk;
1065 &sid, sizeof (sid),
1066 msec, sizeof (*msec));
1067
1069 kid,
1070 sizeof(*kid),
1071 &prk,
1072 GNUNET_CRYPTO_kdf_arg_string ("gnunet-communicator-udp-kid"));
1073}
1074
1075
1082static void
1083kce_generate (struct SharedSecret *ss, uint32_t seq)
1084{
1085 struct KeyCacheEntry *kce;
1086
1087 GNUNET_assert (0 < seq);
1088 kce = GNUNET_new (struct KeyCacheEntry);
1089 kce->ss = ss;
1090 kce->sequence_number = seq;
1091 get_kid (&ss->master, seq, &kce->kid);
1096 key_cache,
1097 &kce->kid,
1098 kce,
1101 "# KIDs active",
1103 GNUNET_NO);
1104}
1105
1106
1113static int
1115{
1116 struct SenderAddress *sender;
1117 struct ReceiverAddress *receiver;
1118 struct KeyCacheEntry *kce;
1119
1121 "secret %s destroy %u\n",
1122 GNUNET_sh2s (&ss->master),
1124 if (NULL != (sender = ss->sender))
1125 {
1126 GNUNET_CONTAINER_DLL_remove (sender->ss_head, sender->ss_tail, ss);
1127 sender->num_secrets--;
1129 "%u sender->num_secrets %u allowed %u used, %u available\n",
1131 sender->acks_available);
1132 /* NOTE: this used to subtract `sequence_allowed - sequence_used', which
1133 is not the number of keys this secret still holds. Keys also go away
1134 without @e sequence_used moving: #consider_ss_ack() drops entries past
1135 #MAX_SQN_DELTA, and #decrypt_box() destroys the entry of a datagram
1136 that failed to decrypt. Over-subtracting wraps this unsigned counter
1137 to ~4e9, after which `KCN_THRESHOLD > acks_available' is false
1138 forever: we never generate another key, never send another UDPAck,
1139 and the peer -- which can only send BOXes for sequence numbers we
1140 acknowledged -- falls back to a full key exchange per datagram for
1141 good. The #kce_destroy() loop below now accounts for exactly the keys
1142 that existed. */
1143 if (NULL != ss->sender->kce_task)
1144 {
1146 ss->sender->kce_task = NULL;
1147 }
1148 }
1149 if (NULL != (receiver = ss->receiver))
1150 {
1151 GNUNET_CONTAINER_DLL_remove (receiver->ss_head, receiver->ss_tail, ss);
1152 receiver->num_secrets--;
1153 receiver->acks_available -= (ss->sequence_allowed - ss->sequence_used);
1155 "%u receiver->num_secrets\n",
1156 receiver->num_secrets);
1157 }
1158 while (NULL != (kce = ss->kce_head))
1159 kce_destroy (kce);
1160 GNUNET_STATISTICS_update (stats, "# Secrets active", -1, GNUNET_NO);
1162 "# KIDs active",
1164 GNUNET_NO);
1165 GNUNET_free (ss);
1166 return GNUNET_YES;
1167}
1168
1169
1176static void
1177sender_destroy (struct SenderAddress *sender)
1178{
1179 struct SharedSecret *ss;
1182 GNUNET_YES ==
1186 "# senders active",
1188 GNUNET_NO);
1189 while (NULL != (ss = sender->ss_head))
1190 {
1191 secret_destroy (ss);
1192 }
1195}
1196
1197
1206static void
1207get_iv_key (const struct GNUNET_ShortHashCode *msec,
1208 uint32_t serial,
1209 char key[AES_KEY_SIZE],
1210 char iv[AES_IV_SIZE])
1211{
1212 uint32_t sid = htonl (serial);
1213
1215 key,
1217 msec,
1218 GNUNET_CRYPTO_kdf_arg_string ("gnunet-communicator-udp-key"),
1221 iv,
1223 msec,
1224 GNUNET_CRYPTO_kdf_arg_string ("gnunet-communicator-udp-iv"),
1226}
1227
1228
1234static void
1236{
1237 sender->timeout =
1240}
1241
1242
1252static void
1254{
1255 receiver->timeout =
1258 receiver->timeout.abs_value_us);
1259}
1260
1261
1278static enum GNUNET_GenericReturnValue
1280{
1283 <=,
1285 return GNUNET_YES;
1287 "Peer `%s' did not acknowledge a single datagram for %s while we "
1288 "kept transmitting, considering it disconnected\n",
1289 GNUNET_i2s (&receiver->target),
1291 GNUNET_YES));
1293 "# receivers destroyed (peer unresponsive)",
1294 1,
1295 GNUNET_NO);
1296 if (GNUNET_YES != receiver->receiver_destroy_called)
1298 return GNUNET_NO;
1299}
1300
1301
1307static void
1308check_timeouts (void *cls)
1309{
1310 struct GNUNET_TIME_Relative st;
1311 struct GNUNET_TIME_Relative rt;
1312 struct GNUNET_TIME_Relative delay;
1313 struct ReceiverAddress *receiver;
1314 struct SenderAddress *sender;
1315
1316 (void) cls;
1317 timeout_task = NULL;
1320 {
1322 if (0 != rt.rel_value_us)
1323 break;
1325 "Receiver timed out\n");
1327 }
1329 while (NULL != (sender = GNUNET_CONTAINER_heap_peek (senders_heap)))
1330 {
1331 /* NOTE: no @e sender_destroy_called check here -- #sender_destroy()
1332 removes the node from the heap, so anything we can peek at is live.
1333 Skipping instead of breaking would spin forever on the same node. */
1335 if (0 != st.rel_value_us)
1336 break;
1337 sender_destroy (sender);
1338 }
1339 delay = GNUNET_TIME_relative_min (rt, st);
1340 if (delay.rel_value_us < GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
1342}
1343
1344
1350static void
1351calculate_cmac (struct SharedSecret *ss)
1352{
1354 &ss->cmac,
1355 sizeof(ss->cmac),
1356 &ss->master,
1357 GNUNET_CRYPTO_kdf_arg_string ("gnunet-communicator-udp-cmac"));
1358}
1359
1360
1369static void
1371 const void *plaintext,
1372 size_t plaintext_len)
1373{
1374 const struct GNUNET_MessageHeader *hdr = plaintext;
1375 const char *pos = plaintext;
1376
1377 while (ntohs (hdr->size) <= plaintext_len)
1378 {
1380 "# bytes given to core",
1381 ntohs (hdr->size),
1382 GNUNET_NO);
1384 "Giving %u bytes to TNG\n", ntohs (hdr->size));
1387 &sender->target,
1388 hdr,
1390 NULL /* no flow control possible */
1391 ,
1392 NULL));
1393 /* move on to next message, if any */
1394 plaintext_len -= ntohs (hdr->size);
1395 if (plaintext_len < sizeof(*hdr))
1396 break;
1397 pos += ntohs (hdr->size);
1398 hdr = (const struct GNUNET_MessageHeader *) pos;
1399 // TODO for now..., we do not actually sen >1msg or have a way of telling
1400 // if we are done
1401 break;
1402 }
1404 "# bytes padding discarded",
1405 plaintext_len,
1406 GNUNET_NO);
1407}
1408
1409
1418static void
1419setup_cipher (const struct GNUNET_ShortHashCode *msec,
1420 uint32_t serial,
1421 gcry_cipher_hd_t *cipher)
1422{
1423 char key[AES_KEY_SIZE];
1424 char iv[AES_IV_SIZE];
1425 int rc;
1426
1427 GNUNET_assert (0 ==
1428 gcry_cipher_open (cipher,
1429 GCRY_CIPHER_AES256 /* low level: go for speed */
1430 ,
1431 GCRY_CIPHER_MODE_GCM,
1432 0 /* flags */));
1433 get_iv_key (msec, serial, key, iv);
1434 rc = gcry_cipher_setkey (*cipher, key, sizeof(key));
1435 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
1436 rc = gcry_cipher_setiv (*cipher, iv, sizeof(iv));
1437 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
1438}
1439
1440
1453static int
1454try_decrypt (const struct SharedSecret *ss,
1455 const uint8_t *tag,
1456 uint32_t serial,
1457 const char *in_buf,
1458 size_t in_buf_size,
1459 char *out_buf)
1460{
1461 gcry_cipher_hd_t cipher;
1462
1463 setup_cipher (&ss->master, serial, &cipher);
1465 0 ==
1466 gcry_cipher_decrypt (cipher, out_buf, in_buf_size, in_buf, in_buf_size));
1467 if (0 != gcry_cipher_checktag (cipher, tag, GCM_TAG_SIZE))
1468 {
1469 gcry_cipher_close (cipher);
1471 "# AEAD authentication failures",
1472 1,
1473 GNUNET_NO);
1474 return GNUNET_SYSERR;
1475 }
1476 gcry_cipher_close (cipher);
1477 return GNUNET_OK;
1478}
1479
1480
1487static struct SharedSecret *
1489 )
1490{
1492 struct SharedSecret *ss;
1493
1496
1497 ss = GNUNET_new (struct SharedSecret);
1499 ephemeral,
1500 &ss->master);
1501 calculate_cmac (ss);
1502 return ss;
1503}
1504
1505
1512static struct SharedSecret *
1515{
1517 struct GNUNET_CRYPTO_HpkePrivateKey my_hpke_key;
1518 struct SharedSecret *ss;
1519
1522
1523 eddsa_priv_to_hpke_key (my_private_key, &my_hpke_key);
1524
1525 ss = GNUNET_new (struct SharedSecret);
1527 &ss->master);
1529 "New receiver SS master: %s\n", GNUNET_sh2s (&ss->master));
1530 calculate_cmac (ss);
1531 return ss;
1532}
1533
1534
1542static struct SharedSecret *
1544 ,
1545 struct ReceiverAddress *receiver)
1546{
1547 struct SharedSecret *ss;
1548
1549 ss = GNUNET_new (struct SharedSecret);
1550 GNUNET_CRYPTO_eddsa_kem_encaps (&receiver->target.public_key,
1551 ephemeral,
1552 &ss->master);
1553 calculate_cmac (ss);
1554 ss->receiver = receiver;
1555 GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss);
1556 receiver->num_secrets++;
1557 GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
1558 return ss;
1559}
1560
1561
1569static struct SharedSecret *
1572 struct ReceiverAddress *receiver)
1573{
1574 struct SharedSecret *ss;
1575
1576 ss = GNUNET_new (struct SharedSecret);
1578 c, &ss->master);
1580 "New sender SS master: %s\n", GNUNET_sh2s (&ss->master));
1581 calculate_cmac (ss);
1582 ss->receiver = receiver;
1583 GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss);
1584 receiver->num_secrets++;
1585 GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
1586 return ss;
1587}
1588
1589
1597static void
1599
1600
1608static unsigned int
1609purge_secrets (struct SharedSecret *ss_list_tail)
1610{
1611 struct SharedSecret *pos;
1612 struct SharedSecret *ss_to_purge;
1613 unsigned int deleted = 0;
1614
1616 "Purging secrets.\n");
1617 pos = ss_list_tail;
1618 while (NULL != pos)
1619 {
1620 ss_to_purge = pos;
1621 pos = pos->prev;
1622
1623 // FIXME we may also want to purge old unacked.
1624 if (rekey_max_bytes <= ss_to_purge->bytes_sent)
1625 {
1626 secret_destroy (ss_to_purge);
1627 deleted++;
1628 }
1629 }
1631 "Finished purging all, deleted %u.\n", deleted);
1632 return deleted;
1633}
1634
1635
1636static void
1637add_acks (struct SharedSecret *ss, int acks_to_add)
1638{
1639
1640 struct ReceiverAddress *receiver = ss->receiver;
1641
1642 GNUNET_assert (NULL != ss);
1643 GNUNET_assert (NULL != receiver);
1644
1645 if (NULL == receiver->d_qh)
1646 {
1647 receiver->d_qh =
1649 &receiver->target,
1650 receiver->foreign_addr,
1651 receiver->d_mtu,
1652 acks_to_add,
1653 1, /* Priority */
1654 receiver->nt,
1656 receiver->d_mq);
1657 }
1658 else
1659 {
1661 receiver->d_qh,
1662 acks_to_add,
1663 1);
1664 }
1665
1667 "Tell transport we have %u more acks!\n",
1668 acks_to_add);
1669
1670 // Until here for alternative 1
1671
1672 /* move ss to head to avoid discarding it anytime soon! */
1673
1674 // GNUNET_CONTAINER_DLL_remove (receiver->ss_head, receiver->ss_tail, ss);
1675 // GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss);
1676}
1677
1678
1689static int
1690handle_ack (void *cls, const struct GNUNET_HashCode *key, void *value)
1691{
1692 const struct UDPAck *ack = cls;
1693 struct ReceiverAddress *receiver = value;
1694 uint32_t acks_to_add;
1695 uint32_t allowed;
1696
1698 "in handle ack with cmac %s\n",
1699 GNUNET_h2s (&ack->cmac));
1700
1701 (void) key;
1702 for (struct SharedSecret *ss = receiver->ss_head; NULL != ss; ss = ss->next)
1703 {
1704 if (0 == memcmp (&ack->cmac, &ss->cmac, sizeof(struct GNUNET_HashCode)))
1705 {
1706
1708 "Found matching cmac\n");
1709
1710 /* Whatever window it grants us, this ACK proves the peer is alive.
1711 Note that this is the *only* inbound signal tied to a receiver. */
1712 receiver->last_ack = GNUNET_TIME_absolute_get ();
1713
1714 allowed = ntohl (ack->sequence_ack);
1715
1716 if (allowed <= ss->sequence_allowed)
1717 {
1719 "Ignoring ack, not giving us increased window\n.");
1720 return GNUNET_NO;
1721 }
1722 acks_to_add = (allowed - ss->sequence_allowed);
1723 GNUNET_assert (0 != acks_to_add);
1724 receiver->acks_available += (allowed - ss->sequence_allowed);
1725 ss->sequence_allowed = allowed;
1726 add_acks (ss, acks_to_add);
1728 "New sequence allows until %u (+%u). Acks available to us: %u. For secret %s\n",
1729 allowed,
1730 acks_to_add,
1731 receiver->acks_available,
1732 GNUNET_sh2s (&ss->master));
1733 return GNUNET_NO;
1734 }
1735 }
1737 "Matching cmac not found for ack!\n");
1738 return GNUNET_YES;
1739}
1740
1741
1742struct AckInfo
1743{
1744 const struct UDPAck *ack;
1745
1746 const struct GNUNET_PeerIdentity *sender;
1747};
1748
1749
1764static int
1765handle_ack_by_sender (void *cls, const struct GNUNET_HashCode *key, void *value)
1766{
1767 struct ReceiverAddress *receiver = value;
1768 struct AckInfo *ai = cls;
1769
1770 if (0 != GNUNET_memcmp (ai->sender, &receiver->target))
1771 {
1772 return GNUNET_YES;
1773 }
1774 handle_ack ((void*) ai->ack, key, receiver);
1775 return GNUNET_YES;
1776}
1777
1778
1787static void
1788consider_ss_ack (struct SharedSecret *ss)
1789{
1790 struct UDPAck ack;
1791 GNUNET_assert (NULL != ss->sender);
1793 "Considering SS UDPAck %s\n",
1794 GNUNET_i2s_full (&ss->sender->target));
1795
1797 "Sender has %u acks available.\n",
1798 ss->sender->acks_available);
1799 /* drop ancient KeyCacheEntries */
1800 while ((NULL != ss->kce_head) &&
1801 (MAX_SQN_DELTA <
1803 kce_destroy (ss->kce_tail);
1804
1805
1807 ack.header.size = htons (sizeof(ack));
1808 ack.sequence_ack = htonl (ss->sequence_allowed);
1809 ack.cmac = ss->cmac;
1811 "Notifying transport with UDPAck %s, sequence %u and master %s\n",
1813 ss->sequence_allowed,
1814 GNUNET_sh2s (&(ss->master)));
1816 &ss->sender->target,
1818 &ack.header);
1819}
1820
1821
1822static void
1823kce_generate_cb (void *cls)
1824{
1825 struct SharedSecret *ss = cls;
1826 ss->sender->kce_task = NULL;
1827
1829 "Precomputing %u keys for master %s\n",
1831 GNUNET_sh2s (&ss->master));
1832 if ((ss->override_available_acks != GNUNET_YES) &&
1833 (KCN_TARGET < ss->sender->acks_available) &&
1834 (0 != ss->sequence_allowed))
1835 {
1836 /* Enough keys for this sender overall, and this secret already has some
1837 the peer may use.
1838 Do NOT just return: @e kce_task_finished is a latch that decides which
1839 of the two places that arm this task is allowed to do so -- the KX
1840 path only arms it while it is #GNUNET_NO, #decrypt_box() only while it
1841 is #GNUNET_YES. Leaving it #GNUNET_NO here means #decrypt_box() can
1842 never ask for more keys again, so the sender's supply runs down to
1843 zero and stays there. And the peer is waiting on the UDPAck that says
1844 how far it may count with this secret; without it, it can only reach
1845 us by doing a full key exchange per datagram. */
1849 consider_ss_ack (ss);
1850 return;
1851 }
1852 for (int i = 0; i < GENERATE_AT_ONCE; i++)
1853 kce_generate (ss, ++ss->sequence_allowed);
1854
1859 if (KCN_TARGET > ss->sender->acks_available)
1860 {
1864 ss);
1865 return;
1866 }
1868 "We have enough keys (ACKs: %u).\n", ss->sender->acks_available);
1872 consider_ss_ack (ss);
1873}
1874
1875
1884static void
1886 const void *buf,
1887 size_t buf_size)
1888{
1889 const struct GNUNET_MessageHeader *hdr;
1890 const struct UDPAck *ack;
1891 const struct UDPRekey *rekey;
1892 struct SharedSecret *ss_rekey;
1893 const char *buf_pos = buf;
1894 size_t bytes_remaining = buf_size;
1895 uint16_t type;
1896
1897 hdr = (struct GNUNET_MessageHeader*) buf_pos;
1898 if (sizeof(*hdr) > bytes_remaining)
1899 {
1900 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Plaintext too short, dropping...\n");
1901 return; /* no data left */
1902 }
1904 "try_handle_plaintext of size %llu (%u %lu) and type %u\n",
1905 (unsigned long long) bytes_remaining,
1906 ntohs (hdr->size),
1907 sizeof(*hdr),
1908 ntohs (hdr->type));
1909 if (ntohs (hdr->size) > bytes_remaining)
1910 return; /* buffer too short for indicated message length */
1911 type = ntohs (hdr->type);
1912 switch (type)
1913 {
1915 rekey = (struct UDPRekey*) buf_pos;
1916 if (ntohs (hdr->size) < sizeof (struct UDPRekey))
1917 {
1918 GNUNET_break_op (0);
1919 return;
1920 }
1921 ss_rekey = setup_shared_secret_dec (&rekey->ephemeral);
1922 ss_rekey->sender = sender;
1923 GNUNET_CONTAINER_DLL_insert (sender->ss_head, sender->ss_tail, ss_rekey);
1924 sender->num_secrets++;
1926 "Received rekey secret with cmac %s\n",
1927 GNUNET_h2s (&(ss_rekey->cmac)));
1929 "Received secret with master %s.\n",
1930 GNUNET_sh2s (&(ss_rekey->master)));
1932 "We have %u sequence_allowed.\n",
1933 ss_rekey->sequence_allowed);
1935 "We have a sender %p\n",
1936 ss_rekey->sender);
1938 "We have %u acks available.\n",
1939 ss_rekey->sender->acks_available);
1941 "# rekeying successful",
1942 1,
1943 GNUNET_NO);
1946 /* Go through @e kce_task rather than calling #kce_generate_cb() inline.
1947 That function starts with `sender->kce_task = NULL', so calling it
1948 directly dropped the handle of a task that may well have been armed
1949 for another of this sender's secrets: it still fires, but nothing can
1950 cancel it any more -- including #secret_destroy(), which then leaves
1951 it pointing at a freed `struct SharedSecret'. */
1952 if (NULL != ss_rekey->sender->kce_task)
1955 ss_rekey);
1956 // FIXME: Theoretically, this could be an Ack
1957 buf_pos += ntohs (hdr->size);
1958 bytes_remaining -= ntohs (hdr->size);
1959 pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
1960 if (0 == purge_secrets (sender->ss_tail))
1961 {
1962 // No secret purged. Delete oldest.
1963 if (sender->num_secrets > MAX_SECRETS)
1964 {
1965 secret_destroy (sender->ss_tail);
1966 }
1967 }
1968 break;
1970 /* lookup master secret by 'cmac', then update sequence_max */
1971 ack = (struct UDPAck*) buf_pos;
1972 if (ntohs (hdr->size) < sizeof (struct UDPAck))
1973 {
1974 GNUNET_break_op (0);
1975 return;
1976 }
1977 {
1978 /* NOTE: @e key of a sender is H(source address || peer), that of a
1979 receiver H(address we send to || peer). Looking @a receivers up by
1980 the sender's key therefore only ever hits when the peer reached us
1981 from exactly the address we send to -- i.e. never for a peer behind
1982 a NAT, which is the case that needs the ACK most. Match on the peer
1983 instead, the same way #enc_notify_cb() does for the backchannel. */
1984 struct AckInfo ai = {
1985 .ack = ack,
1986 .sender = &sender->target
1987 };
1988
1991 &ai);
1992 }
1993 /* There could be more messages after the ACK, handle those as well */
1994 buf_pos += ntohs (hdr->size);
1995 bytes_remaining -= ntohs (hdr->size);
1996 pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
1997 break;
1998
2000 /* skip padding */
2001 break;
2002
2003 default:
2004 pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
2005 }
2006 return;
2007}
2008
2009
2017static void
2018decrypt_box (const struct UDPBox *box,
2019 size_t box_len,
2020 struct KeyCacheEntry *kce)
2021{
2022 struct SharedSecret *ss = kce->ss;
2023 struct SharedSecret *ss_c = ss->sender->ss_tail;
2024 struct SharedSecret *ss_tmp;
2025 int ss_destroyed = 0;
2026 char out_buf[box_len - sizeof(*box)];
2027
2028 GNUNET_assert (NULL != ss->sender);
2029 if (GNUNET_OK != try_decrypt (ss,
2030 box->gcm_tag,
2031 kce->sequence_number,
2032 (const char *) &box[1],
2033 sizeof(out_buf),
2034 out_buf))
2035 {
2036 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed decryption.\n");
2038 "# Decryption failures with valid KCE",
2039 1,
2040 GNUNET_NO);
2041 /* NOTE: no `acks_available--' here or below -- #kce_destroy() does it.
2042 Doing it here as well double-counted, and on this path (decryption
2043 failure) @e sequence_used does *not* advance, so #secret_destroy()'s
2044 old `sequence_allowed - sequence_used' could not have compensated for
2045 it either. */
2046 kce_destroy (kce);
2047 return;
2048 }
2049 kce_destroy (kce);
2050 kce = NULL;
2051 ss->bytes_sent += box_len;
2052 ss->sequence_used++;
2054 "# bytes decrypted with BOX",
2055 sizeof(out_buf),
2056 GNUNET_NO);
2058 "# messages decrypted with BOX",
2059 1,
2060 GNUNET_NO);
2062 "decrypted UDPBox with kid %s\n",
2063 GNUNET_sh2s (&box->kid));
2064 try_handle_plaintext (ss->sender, out_buf, sizeof(out_buf));
2065
2066 while (NULL != ss_c)
2067 {
2068 if (ss_c->bytes_sent >= rekey_max_bytes)
2069 {
2071 "Removing SS because rekey bytes reached.\n");
2072 ss_tmp = ss_c->prev;
2073 if (ss == ss_c)
2074 ss_destroyed = 1;
2075 secret_destroy (ss_c);
2076 ss_c = ss_tmp;
2077 continue;
2078 }
2079 ss_c = ss_c->prev;
2080 }
2081 if (1 == ss_destroyed)
2082 return;
2084 "Sender has %u ack left.\n",
2085 ss->sender->acks_available);
2086 if ((KCN_THRESHOLD > ss->sender->acks_available) &&
2087 (NULL == ss->sender->kce_task) &&
2089 {
2091 "Sender has %u ack left which is under threshold.\n",
2092 ss->sender->acks_available);
2096 ss);
2097 }
2098}
2099
2100
2104struct SearchContext
2105{
2109 const struct sockaddr *address;
2110
2114 socklen_t address_len;
2115
2119 struct SenderAddress *sender;
2120};
2121
2122
2136static struct SenderAddress *
2138 const struct sockaddr *address,
2139 socklen_t address_len,
2140 int *is_new)
2141{
2142 struct SenderAddress *sender;
2143 struct GNUNET_HashContext *hsh;
2144 struct GNUNET_HashCode sender_key;
2145
2147 GNUNET_CRYPTO_hash_context_read (hsh, address, address_len);
2148 GNUNET_CRYPTO_hash_context_read (hsh, target, sizeof(*target));
2149 GNUNET_CRYPTO_hash_context_finish (hsh, &sender_key);
2150
2151 if (NULL != is_new)
2152 *is_new = GNUNET_NO;
2153 sender = GNUNET_CONTAINER_multihashmap_get (senders, &sender_key);
2154 if (NULL != sender)
2155 {
2157 return sender;
2158 }
2159 if (NULL != is_new)
2160 *is_new = GNUNET_YES;
2161 sender = GNUNET_new (struct SenderAddress);
2162 sender->key = sender_key;
2163 sender->target = *target;
2164 sender->address = GNUNET_memdup (address, address_len);
2165 sender->address_len = address_len;
2167 senders,
2168 &sender->key,
2169 sender,
2172 "# senders active",
2174 GNUNET_NO);
2175 sender->timeout =
2178 sender,
2179 sender->timeout.abs_value_us);
2180 sender->nt = GNUNET_NT_scanner_get_type (is, address, address_len);
2181 if (NULL == timeout_task)
2183 return sender;
2184}
2185
2186
2194static int
2196 const struct UDPConfirmation *uc)
2197{
2198 const struct GNUNET_PeerIdentity *my_identity;
2199 struct UdpHandshakeSignature uhs;
2200
2203
2204 uhs.purpose.purpose = htonl (
2206 uhs.purpose.size = htonl (sizeof(uhs));
2207 uhs.sender = uc->sender;
2208 uhs.receiver = *my_identity;
2209 uhs.enc = *enc;
2210 uhs.monotonic_time = uc->monotonic_time;
2213 &uhs,
2214 &uc->sender_sig,
2215 &uc->sender.public_key);
2216}
2217
2218
2227static char *
2228sockaddr_to_udpaddr_string (const struct sockaddr *address,
2229 socklen_t address_len)
2230{
2231 char *ret;
2232
2233 switch (address->sa_family)
2234 {
2235 case AF_INET:
2237 "%s-%s",
2239 GNUNET_a2s (address, address_len));
2240 break;
2241
2242 case AF_INET6:
2244 "%s-%s",
2246 GNUNET_a2s (address, address_len));
2247 break;
2248
2249 default:
2250 GNUNET_assert (0);
2251 }
2252 return ret;
2253}
2254
2255
2256static struct GNUNET_NETWORK_Handle *
2258{
2260
2261 if (NULL == receiver->udp_sock)
2262 {
2263 if (AF_INET6 == receiver->address->sa_family)
2265 else
2267 }
2268 else
2269 udp_sock = receiver->udp_sock;
2270
2271 return udp_sock;
2272}
2273
2274
2283static struct sockaddr *
2284udp_address_to_sockaddr (const char *bindto,
2285 sa_family_t family,
2286 socklen_t *sock_len)
2287{
2288 struct sockaddr *in;
2289 unsigned int port;
2290 char dummy[2];
2291 char *colon;
2292 char *cp;
2293
2294 if (1 == sscanf (bindto, "%u%1s", &port, dummy))
2295 {
2296 /* interpreting value as just a PORT number */
2297 if (port > UINT16_MAX)
2298 {
2300 "BINDTO specification `%s' invalid: value too large for port\n",
2301 bindto);
2302 return NULL;
2303 }
2304 if ((AF_INET == family) || (GNUNET_YES == disable_v6))
2305 {
2306 struct sockaddr_in *i4;
2307
2308 i4 = GNUNET_malloc (sizeof(struct sockaddr_in));
2309 i4->sin_family = AF_INET;
2310 i4->sin_port = htons ((uint16_t) port);
2311 *sock_len = sizeof(struct sockaddr_in);
2312 in = (struct sockaddr *) i4;
2313 }
2314 else
2315 {
2316 struct sockaddr_in6 *i6;
2317
2318 i6 = GNUNET_malloc (sizeof(struct sockaddr_in6));
2319 i6->sin6_family = AF_INET6;
2320 i6->sin6_port = htons ((uint16_t) port);
2321 *sock_len = sizeof(struct sockaddr_in6);
2322 in = (struct sockaddr *) i6;
2323 }
2324 return in;
2325 }
2326 cp = GNUNET_strdup (bindto);
2327 colon = strrchr (cp, ':');
2328 if (NULL != colon)
2329 {
2330 /* interpret value after colon as port */
2331 *colon = '\0';
2332 colon++;
2333 if (1 == sscanf (colon, "%u%1s", &port, dummy))
2334 {
2335 /* interpreting value as just a PORT number */
2336 if (port > UINT16_MAX)
2337 {
2339 "BINDTO specification `%s' invalid: value too large for port\n",
2340 bindto);
2341 GNUNET_free (cp);
2342 return NULL;
2343 }
2344 }
2345 else
2346 {
2347 GNUNET_log (
2349 "BINDTO specification `%s' invalid: last ':' not followed by number\n",
2350 bindto);
2351 GNUNET_free (cp);
2352 return NULL;
2353 }
2354 }
2355 else
2356 {
2357 /* interpret missing port as 0, aka pick any free one */
2358 port = 0;
2359 }
2360 if (AF_INET6 != family)
2361 {
2362 /* try IPv4 */
2363 struct sockaddr_in v4;
2364
2365 memset (&v4, 0, sizeof(v4));
2366 if (1 == inet_pton (AF_INET, cp, &v4.sin_addr))
2367 {
2368 v4.sin_family = AF_INET;
2369 v4.sin_port = htons ((uint16_t) port);
2370#if HAVE_SOCKADDR_IN_SIN_LEN
2371 v4.sin_len = sizeof(struct sockaddr_in);
2372#endif
2373 in = GNUNET_memdup (&v4, sizeof(struct sockaddr_in));
2374 *sock_len = sizeof(struct sockaddr_in);
2375 GNUNET_free (cp);
2376 return in;
2377 }
2378 }
2379 if (AF_INET != family)
2380 {
2381 /* try IPv6 */
2382 struct sockaddr_in6 v6;
2383 const char *start;
2384
2385 memset (&v6, 0, sizeof(v6));
2386 start = cp;
2387 if (('[' == *cp) && (']' == cp[strlen (cp) - 1]))
2388 {
2389 start++; /* skip over '[' */
2390 cp[strlen (cp) - 1] = '\0'; /* eat ']' */
2391 }
2392 if (1 == inet_pton (AF_INET6, start, &v6.sin6_addr))
2393 {
2394 v6.sin6_family = AF_INET6;
2395 v6.sin6_port = htons ((uint16_t) port);
2396#if HAVE_SOCKADDR_IN_SIN_LEN
2397 v6.sin6_len = sizeof(struct sockaddr_in6);
2398#endif
2399 in = GNUNET_memdup (&v6, sizeof(v6));
2400 *sock_len = sizeof(v6);
2401 GNUNET_free (cp);
2402 return in;
2403 }
2404 }
2405 /* #5528 FIXME (feature!): maybe also try getnameinfo()? */
2406 GNUNET_free (cp);
2407 return NULL;
2408}
2409
2410
2411static void
2412sock_read (void *cls);
2413
2414
2415static enum GNUNET_GenericReturnValue
2416create_receiver (const struct GNUNET_PeerIdentity *peer,
2417 const char *address,
2419{
2420 struct GNUNET_HashContext *hsh;
2421 struct ReceiverAddress *receiver;
2422 struct GNUNET_HashCode receiver_key;
2423 const char *path;
2424 struct sockaddr *in;
2425 socklen_t in_len;
2426
2427 if (0 != strncmp (address,
2429 strlen (COMMUNICATOR_ADDRESS_PREFIX "-")))
2430 {
2431 GNUNET_break_op (0);
2432 return GNUNET_SYSERR;
2433 }
2434 path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")];
2435 in = udp_address_to_sockaddr (path, AF_UNSPEC, &in_len);
2436
2437 if (NULL == in)
2438 {
2440 "Failed to setup UDP socket address\n");
2441 return GNUNET_SYSERR;
2442 }
2443 if ((AF_INET6 == in->sa_family) &&
2445 {
2447 "IPv6 disabled, skipping %s\n", address);
2448 GNUNET_free (in);
2449 return GNUNET_SYSERR;
2450 }
2451 else if (AF_INET == in->sa_family)
2452 {
2453 struct sockaddr_in *sin = (struct sockaddr_in *) in;
2454 if (0 == sin->sin_port)
2455 {
2456 GNUNET_free (in);
2457 return GNUNET_NO;
2458 }
2459 }
2460
2462 GNUNET_CRYPTO_hash_context_read (hsh, in, in_len);
2463 GNUNET_CRYPTO_hash_context_read (hsh, peer, sizeof(*peer));
2464 GNUNET_CRYPTO_hash_context_finish (hsh, &receiver_key);
2465
2467 if (NULL != receiver)
2468 {
2470 "receiver %s already exist or is being connected to\n",
2471 address);
2472 /* Only the new-receiver path below takes ownership of @a in. */
2473 GNUNET_free (in);
2474 return GNUNET_NO;
2475 }
2476
2478 receiver->udp_sock = udp_sock;
2479 receiver->key = receiver_key;
2480 receiver->address = in;
2481 receiver->address_len = in_len;
2482 receiver->target = *peer;
2483 eddsa_pub_to_hpke_key (&receiver->target.public_key,
2484 &receiver->target_hpke_key);
2485 receiver->nt = GNUNET_NT_scanner_get_type (is, in, in_len);
2487 receivers,
2488 &receiver->key,
2489 receiver,
2492 "Added %s to receivers with address %s and sock %p\n",
2493 GNUNET_i2s_full (&receiver->target),
2494 address,
2495 udp_sock);
2496 receiver->timeout =
2498 /* Give a fresh receiver a full window to produce its first ACK. */
2499 receiver->last_ack = GNUNET_TIME_absolute_get ();
2501 receiver,
2502 receiver->timeout.abs_value_us);
2504 "# receivers active",
2506 GNUNET_NO);
2507 receiver->foreign_addr =
2508 sockaddr_to_udpaddr_string (receiver->address, receiver->address_len);
2509 if (NULL != udp_sock)
2512 udp_sock,
2513 &sock_read,
2514 udp_sock);
2516 if (NULL == timeout_task)
2518 return GNUNET_OK;
2519}
2520
2521
2550static void
2552 const struct sockaddr *address,
2553 socklen_t address_len)
2554{
2555 char *addr_s;
2556
2557 addr_s = sockaddr_to_udpaddr_string (address, address_len);
2558 /* #create_receiver() is keyed by (address, peer), so this is a cheap
2559 no-op whenever the peer reached us from an address we already have. */
2560 if (GNUNET_OK == create_receiver (target, addr_s, NULL))
2561 {
2563 "Learned return path %s for peer `%s' from the source of an "
2564 "authenticated datagram\n",
2565 addr_s,
2566 GNUNET_i2s (target));
2568 "# receivers added (reflexive address)",
2569 1,
2570 GNUNET_NO);
2571 }
2572 GNUNET_free (addr_s);
2573}
2574
2575
2581static void
2582sock_read (void *cls)
2583{
2584 struct sockaddr_storage sa;
2585 struct sockaddr_in *addr_verify;
2586 socklen_t salen = sizeof(sa);
2587 char buf[UINT16_MAX];
2588 ssize_t rcvd;
2589
2590 struct GNUNET_NETWORK_Handle *udp_sock = cls;
2591
2594 udp_sock,
2595 &sock_read,
2596 udp_sock);
2599 udp_sock,
2600 &sock_read,
2601 udp_sock);
2602 while (1)
2603 {
2605 buf,
2606 sizeof(buf),
2607 (struct sockaddr *) &sa,
2608 &salen);
2609 if (-1 == rcvd)
2610 {
2611 struct sockaddr *addr = (struct sockaddr*) &sa;
2612
2613 if (EAGAIN == errno)
2614 break; // We are done reading data
2616 "Failed to recv from %s family %d failed sock %p\n",
2617 GNUNET_a2s ((struct sockaddr*) &sa,
2618 salen),
2619 addr->sa_family,
2620 udp_sock);
2622 return;
2623 }
2625 "Read %llu bytes\n",
2626 (unsigned long long) rcvd);
2627 if (0 == rcvd)
2628 {
2629 GNUNET_break_op (0);
2631 "Read 0 bytes from UDP socket\n");
2632 return;
2633 }
2634
2635 /* first, see if it is a GNUNET_BurstMessage */
2636 if (rcvd == sizeof (struct GNUNET_BurstMessage))
2637 {
2638 struct GNUNET_BurstMessage *bm = (struct GNUNET_BurstMessage *) buf;
2639 struct sockaddr *addr = (struct sockaddr*) &sa;
2640 /* NOTE: @a salen, not `sizeof (*addr)' -- the latter is 16, which
2641 truncates an IPv6 source to the point where #GNUNET_a2s() renders
2642 "<invalid v6 address>" and #create_receiver() then fails to parse
2643 it, silently breaking burst NAT traversal over IPv6. */
2644 char *address = sockaddr_to_udpaddr_string (addr, salen);
2645
2646 if (0 != bm->local_port)
2647 {
2648 GNUNET_break_op (0);
2650 "Received a burst message on port %u\n",
2651 bm->local_port);
2652 return;
2653 }
2655 "Received a burst message for default port\n");
2656 create_receiver (&bm->peer,
2657 address,
2658 NULL);
2659 if (AF_INET6 == addr->sa_family)
2661 else
2665 return;
2666 }
2667 /* second, see if it is a UDPBox */
2668 if (rcvd > sizeof(struct UDPBox))
2669 {
2670 const struct UDPBox *box;
2671 struct KeyCacheEntry *kce;
2672
2673 box = (const struct UDPBox *) buf;
2675 if (NULL != kce)
2676 {
2678 "Found KCE with kid %s\n",
2679 GNUNET_sh2s (&box->kid));
2680 decrypt_box (box, (size_t) rcvd, kce);
2681 continue;
2682 }
2683 }
2684
2685 /* next, check if it is a broadcast */
2686 if (sizeof(struct UDPBroadcast) == rcvd)
2687 {
2688 const struct GNUNET_PeerIdentity *my_identity;
2689 const struct UDPBroadcast *ub;
2690 struct UdpBroadcastSignature uhs;
2691 struct GNUNET_PeerIdentity sender;
2692
2695
2696 addr_verify = GNUNET_memdup (&sa, salen);
2697 addr_verify->sin_port = 0;
2699 "received UDPBroadcast from %s\n",
2700 GNUNET_a2s ((const struct sockaddr *) addr_verify, salen));
2701 ub = (const struct UDPBroadcast *) buf;
2702 uhs.purpose.purpose = htonl (
2704 uhs.purpose.size = htonl (sizeof(uhs));
2705 uhs.sender = ub->sender;
2706 sender = ub->sender;
2707 if (0 == memcmp (&sender, my_identity, sizeof (struct
2709 {
2711 "Received our own broadcast\n");
2712 GNUNET_free (addr_verify);
2713 continue;
2714 }
2716 "checking UDPBroadcastSignature for %s\n",
2717 GNUNET_i2s (&sender));
2718 GNUNET_CRYPTO_hash ((struct sockaddr *) addr_verify, salen,
2719 &uhs.h_address);
2720 if (GNUNET_OK ==
2723 &uhs,
2724 &ub->sender_sig,
2725 &ub->sender.public_key))
2726 {
2727 char *addr_s;
2729
2730 addr_s =
2731 sockaddr_to_udpaddr_string ((const struct sockaddr *) &sa, salen);
2732 GNUNET_STATISTICS_update (stats, "# broadcasts received", 1, GNUNET_NO);
2733 /* use our own mechanism to determine network type */
2734 nt =
2735 GNUNET_NT_scanner_get_type (is, (const struct sockaddr *) &sa, salen);
2737 "validating address %s received from UDPBroadcast\n",
2738 GNUNET_i2s (&sender));
2740 GNUNET_free (addr_s);
2741 GNUNET_free (addr_verify);
2742 continue;
2743 }
2744 else
2745 {
2747 "VerifyingPeer %s is verifying UDPBroadcast\n",
2750 "Verifying UDPBroadcast from %s failed\n",
2751 GNUNET_i2s (&ub->sender));
2752 }
2753 GNUNET_free (addr_verify);
2754 /* continue with KX, mostly for statistics... */
2755 }
2756
2757
2758 /* finally, test if it is a KX */
2759 if (rcvd < sizeof(struct UDPConfirmation) + sizeof(struct InitialKX))
2760 {
2762 "# messages dropped (no kid, too small for KX)",
2763 1,
2764 GNUNET_NO);
2765 continue;
2766 }
2768 "Got KX\n");
2769 {
2770 const struct InitialKX *kx;
2771 struct SharedSecret *ss;
2772 char pbuf[rcvd - sizeof(struct InitialKX)];
2773 const struct UDPConfirmation *uc;
2774 struct SenderAddress *sender;
2775 int sender_is_new;
2776
2777 kx = (const struct InitialKX *) buf;
2780 "Before DEC\n");
2781
2782 if (GNUNET_OK != try_decrypt (ss,
2783 kx->gcm_tag,
2784 0,
2785 &buf[sizeof(*kx)],
2786 sizeof(pbuf),
2787 pbuf))
2788 {
2790 "Unable to decrypt tag, dropping...\n");
2791 GNUNET_free (ss);
2793 stats,
2794 "# messages dropped (no kid, AEAD decryption failed)",
2795 1,
2796 GNUNET_NO);
2797 continue;
2798 }
2800 "Before VERIFY\n");
2801
2802 uc = (const struct UDPConfirmation *) pbuf;
2803
2804 if (GNUNET_OK != verify_confirmation (&kx->enc, uc)) // TODO: need ephemeral instead of representative
2805 {
2806 GNUNET_break_op (0);
2807 GNUNET_free (ss);
2809 "# messages dropped (sender signature invalid)",
2810 1,
2811 GNUNET_NO);
2812 continue;
2813 }
2815 "Before SETUP_SENDER\n");
2816
2817 calculate_cmac (ss);
2818 sender = setup_sender (&uc->sender,
2819 (const struct sockaddr *) &sa,
2820 salen,
2821 &sender_is_new);
2822 ss->sender = sender;
2823 /* The signature in @a uc is verified, so we know who sent this.
2824 Only on a *new* sender: #setup_sender() is keyed on (address, peer),
2825 so this fires exactly once per source address per peer instead of on
2826 every KX datagram. A peer with no ACK credit left sends every
2827 message as a KX, and doing the string formatting plus the map lookup
2828 underneath #consider_reflexive_address() for each of those is pure
2829 waste -- and worse, it makes any address churn (a NAT rotating its
2830 mapping) add a transport queue per datagram.
2831
2832 Restricted to the shared sockets: #create_receiver() takes ownership
2833 of any socket handed to it (#receiver_destroy() closes it), so the
2834 per-receiver sockets the burst code hands out must not be passed on
2835 here, and replying from a socket other than the one the datagram
2836 arrived on would leave the peer's NAT mapping unused anyway. */
2837 if ((GNUNET_YES == sender_is_new) &&
2840 (const struct sockaddr *) &sa,
2841 salen);
2842 GNUNET_CONTAINER_DLL_insert (sender->ss_head, sender->ss_tail, ss);
2843 if ((KCN_THRESHOLD > ss->sender->acks_available) &&
2844 (NULL == ss->sender->kce_task) &&
2846 {
2847 // 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.
2851 ss);
2852 }
2853 sender->num_secrets++;
2854 GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
2856 "# messages decrypted without BOX",
2857 1,
2858 GNUNET_NO);
2859 try_handle_plaintext (sender, &uc[1], sizeof(pbuf) - sizeof(*uc));
2860 if (0 == purge_secrets (sender->ss_tail))
2861 {
2862 // No secret purged. Delete oldest.
2863 if (sender->num_secrets > MAX_SECRETS)
2864 {
2865 secret_destroy (sender->ss_tail);
2866 }
2867 }
2868 }
2869 }
2870}
2871
2872
2880static void
2881do_pad (gcry_cipher_hd_t out_cipher, char *dgram, size_t pad_size)
2882{
2883 char pad[pad_size];
2884
2886 sizeof(pad));
2887 if (sizeof(pad) > sizeof(struct GNUNET_MessageHeader))
2888 {
2889 struct GNUNET_MessageHeader hdr =
2890 { .size = htons (sizeof(pad)),
2892
2893 memcpy (pad, &hdr, sizeof(hdr));
2894 }
2896 0 ==
2897 gcry_cipher_encrypt (out_cipher, dgram, sizeof(pad), pad, sizeof(pad)));
2898}
2899
2900
2901static void
2902send_msg_with_kx (const struct GNUNET_MessageHeader *msg, struct
2904 struct GNUNET_MQ_Handle *mq)
2905{
2906 const struct GNUNET_PeerIdentity *my_identity;
2908 uint16_t msize = ntohs (msg->size);
2909 struct UdpHandshakeSignature uhs;
2910 struct UDPConfirmation uc;
2911 struct InitialKX kx;
2912 char dgram[receiver->kx_mtu + sizeof(uc) + sizeof(kx)];
2913 size_t dpos;
2914 gcry_cipher_hd_t out_cipher;
2915 struct SharedSecret *ss;
2916
2920
2921 if (msize > receiver->kx_mtu)
2922 {
2923 GNUNET_break (0);
2924 if (GNUNET_YES != receiver->receiver_destroy_called)
2926 return;
2927 }
2929
2930 /* setup key material */
2932
2933 if (0 == purge_secrets (receiver->ss_tail))
2934 {
2935 // No secret purged. Delete oldest.
2936 if (receiver->num_secrets > MAX_SECRETS)
2937 {
2938 secret_destroy (receiver->ss_tail);
2939 }
2940 }
2941
2942 setup_cipher (&ss->master, 0, &out_cipher);
2943 /* compute 'uc' */
2944 uc.sender = *my_identity;
2945 uc.monotonic_time =
2947 uhs.purpose.purpose = htonl (
2949 uhs.purpose.size = htonl (sizeof(uhs));
2950 uhs.sender = *my_identity;
2951 uhs.receiver = receiver->target;
2952 uhs.monotonic_time = uc.monotonic_time;
2954 &uhs,
2955 &uc.sender_sig);
2956 /* Leave space for kx */
2957 dpos = sizeof(kx);
2958 /* Append encrypted uc to dgram */
2959 GNUNET_assert (0 == gcry_cipher_encrypt (out_cipher,
2960 &dgram[dpos],
2961 sizeof(uc),
2962 &uc,
2963 sizeof(uc)));
2964 dpos += sizeof(uc);
2965 /* Append encrypted payload to dgram */
2967 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], msize, msg, msize));
2968 dpos += msize;
2969 do_pad (out_cipher, &dgram[dpos], sizeof(dgram) - dpos);
2970 /* Datagram starts with kx */
2971 kx.enc = uhs.enc;
2973 0 == gcry_cipher_gettag (out_cipher, kx.gcm_tag, sizeof(kx.gcm_tag)));
2974 gcry_cipher_close (out_cipher);
2975 memcpy (dgram, &kx, sizeof(kx));
2977 dgram,
2978 sizeof(dgram),
2979 receiver->address,
2980 receiver->address_len))
2981 {
2984 "Sending KX with payload size %u to %s family %d failed sock %p\n",
2985 msize,
2986 GNUNET_a2s (receiver->address,
2987 receiver->address_len),
2988 receiver->address->sa_family,
2992 return;
2993 }
2995 "Sending KX with payload size %u to %s with socket %p\n",
2996 msize,
2997 GNUNET_a2s (receiver->address,
2998 receiver->address_len),
3001}
3002
3003
3012static void
3014 const struct GNUNET_MessageHeader *msg,
3015 void *impl_state)
3016{
3017 struct ReceiverAddress *receiver = impl_state;
3018
3019 GNUNET_assert (mq == receiver->kx_mq);
3021 return; /* @a receiver has been freed */
3023}
3024
3025
3026static void
3027create_rekey (struct ReceiverAddress *receiver, struct SharedSecret *ss, struct
3028 UDPRekey *rekey)
3029{
3030 struct SharedSecret *ss_rekey;
3031
3033 /* setup key material */
3034 ss_rekey = setup_shared_secret_ephemeral (&rekey->ephemeral,
3035 receiver);
3036 ss_rekey->sequence_allowed = 0;
3038 "Setup secret with k = %s\n",
3039 GNUNET_sh2s (&ss_rekey->master));
3041 "Setup secret with H(k) = %s\n",
3042 GNUNET_h2s (&(ss_rekey->cmac)));
3043
3044 /* Append encrypted payload to dgram */
3046 rekey->header.size = htons (sizeof (struct UDPRekey));
3047}
3048
3049
3058static void
3060 const struct GNUNET_MessageHeader *msg,
3061 void *impl_state)
3062{
3063 struct ReceiverAddress *receiver = impl_state;
3064 struct UDPRekey rekey;
3065 struct SharedSecret *ss;
3066 int inject_rekey = GNUNET_NO;
3067 uint16_t msize = ntohs (msg->size);
3068
3069 GNUNET_assert (mq == receiver->d_mq);
3071 return; /* @a receiver has been freed */
3072 if (msize > receiver->d_mtu)
3073 {
3074 /* Transport handed us more than the MTU we advertised for this queue;
3075 that is a bug on its side and we cannot box it. */
3077 "msize: %u, mtu: %llu\n",
3078 (unsigned int) msize,
3079 (unsigned long long) receiver->d_mtu);
3080 GNUNET_break (0);
3081 if (GNUNET_YES != receiver->receiver_destroy_called)
3083 return;
3084 }
3085 if (0 == receiver->acks_available)
3086 {
3087 /* Out of ACK credit. This is NOT a protocol violation and must not cost
3088 us the connection. Transport's idea of our window can only ever drift
3089 *upwards*: #GNUNET_TRANSPORT_communicator_mq_update() takes an
3090 unsigned @a q_len that #handle_update_queue_message() *adds* to
3091 `q_capacity', so there is no way to hand credit back once
3092 #secret_destroy() reclaims a shared secret that still had unused
3093 sequence numbers -- which #purge_secrets() and the rekey path below do
3094 routinely. Given enough uptime the two counters therefore always
3095 diverge, and tearing the receiver down here turns that bookkeeping
3096 drift into a dropped link.
3097
3098 Fall back to KX instead, exactly as the tail of this function already
3099 does when it finds no usable shared secret. That also fixes itself:
3100 a KX makes the peer generate key cache entries and ACK them, which is
3101 what replenishes the credit. */
3103 "No ACKs available for %s, sending as KX\n",
3104 GNUNET_i2s (&receiver->target));
3106 "# messages sent via KX (no ACKs available)",
3107 1,
3108 GNUNET_NO);
3111 return;
3112 }
3114
3115 if (receiver->num_secrets > MAX_SECRETS)
3116 {
3117 if ((0 == purge_secrets (receiver->ss_tail)) &&
3118 (NULL != receiver->ss_tail))
3119 {
3120 // No secret purged. Delete oldest.
3121 secret_destroy (receiver->ss_tail);
3122 }
3123 }
3124 /* begin "BOX" encryption method, scan for ACKs from tail! */
3125 ss = receiver->ss_tail;
3126 while (NULL != ss)
3127 {
3128 size_t payload_len = sizeof(struct UDPBox) + receiver->d_mtu;
3130 "Considering SS %s sequence used: %u sequence allowed: %u bytes sent: %lu.\n",
3131 GNUNET_sh2s (&ss->master), ss->sequence_used,
3132 ss->sequence_allowed, ss->bytes_sent);
3133 if (ss->sequence_used >= ss->sequence_allowed)
3134 {
3135 // GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3136 // "Skipping ss because no acks to use.\n");
3137 ss = ss->prev;
3138 continue;
3139 }
3140 if (ss->bytes_sent >= rekey_max_bytes)
3141 {
3142 struct SharedSecret *ss_tmp;
3144 "Skipping ss because rekey bytes reached.\n");
3145 // FIXME cleanup ss with too many bytes sent!
3146 ss_tmp = ss->prev;
3147 secret_destroy (ss);
3148 ss = ss_tmp;
3149 continue;
3150 }
3151 if (ss->bytes_sent > rekey_max_bytes * 0.7)
3152 {
3153 if (ss->rekey_initiated == GNUNET_NO)
3154 {
3156 "Injecting rekey for ss with byte sent %lu\n",
3157 (unsigned long) ss->bytes_sent);
3158 create_rekey (receiver, ss, &rekey);
3160 payload_len += sizeof (rekey);
3162 }
3163 }
3164 if (0 < ss->sequence_used)
3166 "Trying to send UDPBox with shared secret %s sequence_used %u and ss->sequence_allowed %u\n",
3167 GNUNET_sh2s (&ss->master),
3168 ss->sequence_used,
3169 ss->sequence_allowed);
3170 {
3171 char dgram[payload_len];
3172 struct UDPBox *box;
3173 gcry_cipher_hd_t out_cipher;
3174 size_t dpos;
3175
3176 box = (struct UDPBox *) dgram;
3177 ss->sequence_used++;
3178 get_kid (&ss->master, ss->sequence_used, &box->kid);
3179 setup_cipher (&ss->master, ss->sequence_used, &out_cipher);
3180 /* Append encrypted payload to dgram */
3181 dpos = sizeof(struct UDPBox);
3182 if (GNUNET_YES == inject_rekey)
3183 {
3185 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], sizeof (rekey),
3186 &rekey, sizeof (rekey)));
3187 dpos += sizeof (rekey);
3188 }
3190 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], msize, msg, msize));
3191 dpos += msize;
3192 do_pad (out_cipher, &dgram[dpos], sizeof(dgram) - dpos);
3193 GNUNET_assert (0 == gcry_cipher_gettag (out_cipher,
3194 box->gcm_tag,
3195 sizeof(box->gcm_tag)));
3196 gcry_cipher_close (out_cipher);
3197
3199 dgram,
3200 payload_len, // FIXME why always send sizeof dgram?
3201 receiver->address,
3202 receiver->address_len))
3203 {
3206 "Sending UDPBox to %s family %d failed sock %p failed\n",
3207 GNUNET_a2s (receiver->address,
3208 receiver->address_len),
3209 receiver->address->sa_family,
3212 return;
3213 }
3215 "Sending UDPBox with payload size %u, %u acks left, %lu bytes sent with socket %p\n",
3216 msize,
3217 receiver->acks_available,
3218 (unsigned long) ss->bytes_sent,
3220 ss->bytes_sent += sizeof (dgram);
3221 receiver->acks_available--;
3223 return;
3224 }
3225 }
3227 "No suitable ss found, sending as KX...\n");
3229}
3230
3231
3240static void
3241mq_destroy_d (struct GNUNET_MQ_Handle *mq, void *impl_state)
3242{
3243 struct ReceiverAddress *receiver = impl_state;
3245 "Default MQ destroyed\n");
3246 if (mq == receiver->d_mq)
3247 {
3248 receiver->d_mq = NULL;
3249 if (GNUNET_YES != receiver->receiver_destroy_called)
3251 }
3252}
3253
3254
3263static void
3264mq_destroy_kx (struct GNUNET_MQ_Handle *mq, void *impl_state)
3265{
3266 struct ReceiverAddress *receiver = impl_state;
3268 "KX MQ destroyed\n");
3269 if (mq == receiver->kx_mq)
3270 {
3271 receiver->kx_mq = NULL;
3272 if (GNUNET_YES != receiver->receiver_destroy_called)
3274 }
3275}
3276
3277
3284static void
3285mq_cancel (struct GNUNET_MQ_Handle *mq, void *impl_state)
3286{
3287 /* Cancellation is impossible with UDP; bail */
3288 GNUNET_assert (0);
3289}
3290
3291
3301static void
3302mq_error (void *cls, enum GNUNET_MQ_Error error)
3303{
3304 struct ReceiverAddress *receiver = cls;
3305
3307 "MQ error in queue to %s: %d\n",
3308 GNUNET_i2s (&receiver->target),
3309 (int) error);
3311}
3312
3313
3321static void
3323{
3324 size_t base_mtu;
3325
3326 switch (receiver->address->sa_family)
3327 {
3328 case AF_INET:
3329 base_mtu = 1480 /* Ethernet MTU, 1500 - Ethernet header - VLAN tag */
3330 - sizeof(struct GNUNET_TUN_IPv4Header) /* 20 */
3331 - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */;
3332 break;
3333
3334 case AF_INET6:
3335 base_mtu = 1280 /* Minimum MTU required by IPv6 */
3336 - sizeof(struct GNUNET_TUN_IPv6Header) /* 40 */
3337 - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */;
3338 break;
3339
3340 default:
3341 GNUNET_assert (0);
3342 break;
3343 }
3344 /* MTU based on full KX messages */
3345 receiver->kx_mtu = base_mtu - sizeof(struct InitialKX) /* 48 */
3346 - sizeof(struct UDPConfirmation); /* 104 */
3347 /* MTU based on BOXed messages */
3348 receiver->d_mtu = base_mtu - sizeof(struct UDPBox);
3349
3351 "Setting up MQs and QHs\n");
3352 /* => Effective MTU for CORE will range from 1080 (IPv6 + KX) to
3353 1404 (IPv4 + Box) bytes, depending on circumstances... */
3354 if (NULL == receiver->kx_mq)
3357 &mq_cancel,
3358 receiver,
3359 NULL,
3360 &mq_error,
3361 receiver);
3362 if (NULL == receiver->d_mq)
3364 &mq_destroy_d,
3365 &mq_cancel,
3366 receiver,
3367 NULL,
3368 &mq_error,
3369 receiver);
3370
3371 receiver->kx_qh =
3373 &receiver->target,
3374 receiver->foreign_addr,
3375 receiver->kx_mtu,
3377 0, /* Priority */
3378 receiver->nt,
3380 receiver->kx_mq);
3381}
3382
3383
3402static int
3403mq_init (void *cls, const struct GNUNET_PeerIdentity *peer, const char *address)
3404{
3405 (void) cls;
3407 "create receiver for mq_init\n");
3408 return create_receiver (peer,
3409 address,
3410 NULL);
3411}
3412
3413
3422static int
3423get_receiver_delete_it (void *cls,
3424 const struct GNUNET_HashCode *target,
3425 void *value)
3426{
3427 struct ReceiverAddress *receiver = value;
3428
3429 (void) cls;
3430 (void) target;
3432 return GNUNET_OK;
3433}
3434
3435
3444static int
3445get_sender_delete_it (void *cls,
3446 const struct GNUNET_HashCode *target,
3447 void *value)
3448{
3449 struct SenderAddress *sender = value;
3450
3451 (void) cls;
3452 (void) target;
3453
3454
3455 sender_destroy (sender);
3456 return GNUNET_OK;
3457}
3458
3459
3465static void
3466do_shutdown (void *cls)
3467{
3469 "do_shutdown\n");
3470 GNUNET_stop_burst (NULL);
3471 if (NULL != nat)
3472 {
3474 nat = NULL;
3475 }
3476 while (NULL != bi_head)
3478 if (NULL != broadcast_task)
3479 {
3481 broadcast_task = NULL;
3482 }
3483 if (NULL != timeout_task)
3484 {
3486 timeout_task = NULL;
3487 }
3488 if (NULL != read_v6_task)
3489 {
3491 read_v6_task = NULL;
3492 }
3493 if (NULL != read_v4_task)
3494 {
3496 read_v4_task = NULL;
3497 }
3498 if (NULL != default_v6_sock)
3499 {
3502 default_v6_sock = NULL;
3503 }
3504 if (NULL != default_v4_sock)
3505 {
3508 default_v4_sock = NULL;
3509 }
3512 NULL);
3516 NULL);
3521 if (NULL != timeout_task)
3522 {
3524 timeout_task = NULL;
3525 }
3526 if (NULL != ch)
3527 {
3530 ch = NULL;
3531 }
3532 if (NULL != ah)
3533 {
3535 ah = NULL;
3536 }
3537 if (NULL != pils)
3538 {
3540 pils = NULL;
3541 }
3542 if (NULL != key_ring)
3543 {
3545 key_ring = NULL;
3546 }
3547 if (NULL != stats)
3548 {
3550 stats = NULL;
3551 }
3552 if (NULL != is)
3553 {
3555 is = NULL;
3556 }
3558 "do_shutdown finished\n");
3559}
3560
3561
3571static void
3572enc_notify_cb (void *cls,
3573 const struct GNUNET_PeerIdentity *sender,
3574 const struct GNUNET_MessageHeader *msg)
3575{
3576 struct AckInfo ai;
3577
3578 (void) cls;
3580 "Storing UDPAck received from backchannel from %s\n",
3583 (ntohs (msg->size) != sizeof(struct UDPAck)))
3584 {
3585 GNUNET_break_op (0);
3586 return;
3587 }
3588 ai.ack = (const struct UDPAck *) msg;
3589 ai.sender = sender;
3592 &ai);
3593}
3594
3595
3609static void
3610nat_address_cb (void *cls,
3611 void **app_ctx,
3612 int add_remove,
3614 const struct sockaddr *addr,
3615 socklen_t addrlen)
3616{
3617 char *my_addr;
3619
3620 if (GNUNET_YES == add_remove)
3621 {
3623
3624 GNUNET_asprintf (&my_addr,
3625 "%s-%s",
3627 GNUNET_a2s (addr, addrlen));
3628 nt = GNUNET_NT_scanner_get_type (is, addr, addrlen);
3629 ai =
3631 my_addr,
3632 nt,
3634 GNUNET_free (my_addr);
3635 *app_ctx = ai;
3636 }
3637 else
3638 {
3639 ai = *app_ctx;
3641 *app_ctx = NULL;
3642 }
3643}
3644
3645
3651static void
3652ifc_broadcast (void *cls)
3653{
3654 struct BroadcastInterface *bi = cls;
3655 struct GNUNET_TIME_Relative delay;
3656
3657 delay = BROADCAST_FREQUENCY;
3658 delay.rel_value_us =
3659 GNUNET_CRYPTO_random_u64 (delay.rel_value_us);
3660 bi->broadcast_task =
3662
3663 switch (bi->sa->sa_family)
3664 {
3665 case AF_INET: {
3666 static int yes = 1;
3667 static int no = 0;
3668 ssize_t sent;
3669
3670 if (GNUNET_OK !=
3672 SOL_SOCKET,
3673 SO_BROADCAST,
3674 &yes,
3675 sizeof(int)))
3677 "setsockopt");
3679 "creating UDPBroadcast from %s\n",
3680 GNUNET_i2s (&(bi->bcm.sender)));
3682 "sending UDPBroadcast to add %s\n",
3683 GNUNET_a2s (bi->ba, bi->salen));
3685 &bi->bcm,
3686 sizeof(bi->bcm),
3687 bi->ba,
3688 bi->salen);
3689 if (-1 == sent)
3691 "sendto");
3693 SOL_SOCKET,
3694 SO_BROADCAST,
3695 &no,
3696 sizeof(int)))
3698 "setsockopt");
3699 break;
3700 }
3701
3702 case AF_INET6: {
3703 ssize_t sent;
3704 struct sockaddr_in6 dst;
3705
3706 dst.sin6_family = AF_INET6;
3707 dst.sin6_port = htons (my_port);
3708 dst.sin6_addr = bi->mcreq.ipv6mr_multiaddr;
3709 dst.sin6_scope_id = ((struct sockaddr_in6 *) bi->ba)->sin6_scope_id;
3710
3712 "sending UDPBroadcast\n");
3714 &bi->bcm,
3715 sizeof(bi->bcm),
3716 (const struct sockaddr *) &dst,
3717 sizeof(dst));
3718 if (-1 == sent)
3720 break;
3721 }
3722
3723 default:
3724 GNUNET_break (0);
3725 break;
3726 }
3727}
3728
3729
3744static int
3745iface_proc (void *cls,
3746 const char *name,
3747 int isDefault,
3748 const struct sockaddr *addr,
3749 const struct sockaddr *broadcast_addr,
3750 const struct sockaddr *netmask,
3751 socklen_t addrlen)
3752{
3753 const struct GNUNET_PeerIdentity *my_identity;
3755 struct BroadcastInterface *bi;
3756 enum GNUNET_NetworkType network;
3757 struct UdpBroadcastSignature ubs;
3758
3759 (void) cls;
3760 (void) netmask;
3761
3764
3765 if ((NULL == my_identity) || (NULL == my_private_key))
3766 return GNUNET_YES;
3767 if (NULL == addr)
3768 return GNUNET_YES; /* need to know our address! */
3769 network = GNUNET_NT_scanner_get_type (is, addr, addrlen);
3770 if (GNUNET_NT_LOOPBACK == network)
3771 {
3772 /* Broadcasting on loopback does not make sense */
3773 return GNUNET_YES;
3774 }
3775 for (bi = bi_head; NULL != bi; bi = bi->next)
3776 {
3777 if ((bi->salen == addrlen) && (0 == memcmp (addr, bi->sa, addrlen)))
3778 {
3779 bi->found = GNUNET_YES;
3780 return GNUNET_OK;
3781 }
3782 }
3783
3784 if ((AF_INET6 == addr->sa_family) && (NULL == broadcast_addr))
3785 return GNUNET_OK; /* broadcast_addr is required for IPv6! */
3786 if ((AF_INET6 == addr->sa_family) && (NULL == default_v6_sock))
3787 return GNUNET_OK; /* not using IPv6 */
3788
3789 bi = GNUNET_new (struct BroadcastInterface);
3790 bi->sa = GNUNET_memdup (addr,
3791 addrlen);
3792 if ( (NULL != broadcast_addr) &&
3793 (addrlen == sizeof (struct sockaddr_in)) )
3794 {
3795 struct sockaddr_in *ba;
3796
3797 ba = GNUNET_memdup (broadcast_addr,
3798 addrlen);
3799 ba->sin_port = htons (2086); /* always GNUnet port, ignore configuration! */
3800 bi->ba = (struct sockaddr *) ba;
3801 }
3802 bi->salen = addrlen;
3803 bi->found = GNUNET_YES;
3804 bi->bcm.sender = *my_identity;
3805 ubs.purpose.purpose = htonl (
3807 ubs.purpose.size = htonl (sizeof(ubs));
3808 ubs.sender = *my_identity;
3810 "creating UDPBroadcastSignature for %s\n",
3811 GNUNET_a2s (addr, addrlen));
3812 GNUNET_CRYPTO_hash (addr, addrlen, &ubs.h_address);
3814 &ubs,
3815 &bi->bcm.sender_sig);
3816 if (NULL != bi->ba)
3817 {
3820 }
3821 if ((AF_INET6 == addr->sa_family) && (NULL != broadcast_addr))
3822 {
3823 /* Create IPv6 multicast request */
3824 const struct sockaddr_in6 *s6 =
3825 (const struct sockaddr_in6 *) broadcast_addr;
3826
3828 1 == inet_pton (AF_INET6, "FF05::13B", &bi->mcreq.ipv6mr_multiaddr));
3829
3830 /* http://tools.ietf.org/html/rfc2553#section-5.2:
3831 *
3832 * IPV6_JOIN_GROUP
3833 *
3834 * Join a multicast group on a specified local interface. If the
3835 * interface index is specified as 0, the kernel chooses the local
3836 * interface. For example, some kernels look up the multicast
3837 * group in the normal IPv6 routing table and using the resulting
3838 * interface; we do this for each interface, so no need to use
3839 * zero (anymore...).
3840 */
3841 bi->mcreq.ipv6mr_interface = s6->sin6_scope_id;
3842
3843 /* Join the multicast group */
3845 IPPROTO_IPV6,
3846 IPV6_JOIN_GROUP,
3847 &bi->mcreq,
3848 sizeof(bi->mcreq)))
3849 {
3851 }
3852 }
3853 return GNUNET_OK;
3854}
3855
3856
3862static void
3863do_broadcast (void *cls)
3864{
3865 struct BroadcastInterface *bin;
3866
3867 (void) cls;
3868 for (struct BroadcastInterface *bi = bi_head; NULL != bi; bi = bi->next)
3869 bi->found = GNUNET_NO;
3871 for (struct BroadcastInterface *bi = bi_head; NULL != bi; bi = bin)
3872 {
3873 bin = bi->next;
3874 if (GNUNET_NO == bi->found)
3875 bi_destroy (bi);
3876 }
3878 &do_broadcast,
3879 NULL);
3880}
3881
3882
3883static void
3884try_connection_reversal (void *cls,
3885 const struct sockaddr *addr,
3886 socklen_t addrlen)
3887{
3888 /* FIXME: support reversal: #5529 */
3890 "No connection reversal implemented!\n");
3891}
3892
3893
3894static void
3895udp_socket_notify (struct GNUNET_UdpSocketInfo *sock_info)
3896{
3897 // FIXME: This sizeof application truncates IPv6 addresses!
3899 sizeof (*sock_info->actual_address
3900 ));
3901 create_receiver (sock_info->pid,
3902 address,
3903 default_v4_sock == sock_info->udp_sock ||
3904 default_v6_sock == sock_info->udp_sock ?
3905 NULL : sock_info->udp_sock);
3907 GNUNET_free (sock_info);
3908}
3909
3910
3911static void
3912start_burst (const char *addr,
3913 struct GNUNET_TIME_Relative rtt,
3914 struct GNUNET_PeerIdentity *pid)
3915{
3916 struct GNUNET_UdpSocketInfo *sock_info;
3917
3919 "Communicator was called to start burst to address %s from %s\n",
3920 addr,
3921 my_ipv4);
3922
3923 GNUNET_stop_burst (NULL);
3924
3925 sock_info = GNUNET_new (struct GNUNET_UdpSocketInfo);
3926 sock_info->pid = GNUNET_new (struct GNUNET_PeerIdentity);
3927 sock_info->address = GNUNET_strdup (addr);
3928 sock_info->bind_address = my_ipv4;
3929 sock_info->has_port = GNUNET_YES;
3930 sock_info->udp_sock = default_v4_sock;
3931 sock_info->rtt = rtt;
3932 GNUNET_memcpy (sock_info->pid, pid, sizeof (struct GNUNET_PeerIdentity));
3933 sock_info->std_port = my_port;
3935 "1 sock addr %s addr %s rtt %lu %u\n",
3936 sock_info->address,
3937 addr,
3938 (unsigned long) sock_info->rtt.rel_value_us,
3939 my_port);
3940 burst_task = GNUNET_get_udp_socket (sock_info,
3942 GNUNET_free (sock_info);
3943}
3944
3945
3946static struct GNUNET_NETWORK_Handle*
3947create_udp_socket (const char *bindto,
3948 sa_family_t family,
3949 struct sockaddr **out,
3950 socklen_t *out_len)
3951{
3952 struct GNUNET_NETWORK_Handle *sock;
3953 struct sockaddr *in;
3954 socklen_t in_len;
3955 struct sockaddr_storage in_sto;
3956 socklen_t sto_len;
3957
3958 in = udp_address_to_sockaddr (bindto, family, &in_len);
3959 if (NULL == in)
3960 {
3962 "Failed to setup UDP socket address with path `%s'\n",
3963 bindto);
3964 return NULL;
3965 }
3966
3967 if ((AF_UNSPEC != family) && (in->sa_family != family))
3968 {
3970 "Invalid UDP socket address setup with path `%s'\n",
3971 bindto);
3972 GNUNET_free (in);
3973 return NULL;
3974 }
3975
3976 sock =
3977 GNUNET_NETWORK_socket_create (in->sa_family,
3978 SOCK_DGRAM,
3979 IPPROTO_UDP);
3980 if (NULL == sock)
3981 {
3984 "Failed to create socket for %s family %d\n",
3985 GNUNET_a2s (in,
3986 in_len),
3987 in->sa_family);
3988 GNUNET_free (in);
3989 return NULL;
3990 }
3991 if (GNUNET_OK !=
3993 in,
3994 in_len))
3995 {
3997 "bind",
3998 bindto);
4000 "Failed to bind socket for %s family %d sock %p\n",
4001 GNUNET_a2s (in,
4002 in_len),
4003 in->sa_family,
4004 sock);
4006 sock = NULL;
4007 GNUNET_free (in);
4008 return NULL;
4009 }
4010
4011 /* We might have bound to port 0, allowing the OS to figure it out;
4012 thus, get the real IN-address from the socket */
4013 sto_len = sizeof(in_sto);
4014 if (0 != getsockname (GNUNET_NETWORK_get_fd (sock),
4015 (struct sockaddr *) &in_sto,
4016 &sto_len))
4017 {
4018 memcpy (&in_sto, in, in_len);
4019 sto_len = in_len;
4020 }
4021 GNUNET_free (in);
4022 *out = GNUNET_malloc (sto_len);
4023 memcpy (*out, (struct sockaddr *) &in_sto, sto_len);
4024 *out_len = sto_len;
4025 return sock;
4026}
4027
4028
4029static void
4030shutdown_run (struct sockaddr *addrs[2])
4031{
4032 if (NULL != addrs[0])
4033 GNUNET_free (addrs[0]);
4034 if (NULL != addrs[1])
4035 GNUNET_free (addrs[1]);
4037}
4038
4039
4040static void
4041run (void *cls,
4042 char *const *args,
4043 const char *cfgfile,
4044 const struct GNUNET_CONFIGURATION_Handle *c)
4045{
4046 const struct sockaddr_in *v4;
4047 char *bindto;
4048 char *bindto6;
4049 struct sockaddr *in[2];
4050 socklen_t in_len[2];
4051
4053 "Entering the run method of udp communicator.\n");
4054
4055 cfg = c;
4057 if ((GNUNET_NO == GNUNET_NETWORK_test_pf (PF_INET6)) ||
4058 (GNUNET_YES ==
4061 "DISABLE_V6")))
4062 {
4064 }
4065
4066 if (GNUNET_OK !=
4069 "BINDTO",
4070 &bindto))
4071 {
4074 "BINDTO");
4075 return;
4076 }
4078 "The udp communicator will bind to %s for IPv4\n",
4079 bindto);
4080 if (GNUNET_YES != disable_v6)
4081 {
4082 if (GNUNET_OK !=
4085 "BINDTO6",
4086 &bindto6))
4087 {
4090 "BINDTO6");
4091 return;
4092 }
4093
4095 "The udp communicator will bind to %s for IPv6\n",
4096 bindto6);
4097 }
4098 else
4099 bindto6 = NULL;
4100 if (GNUNET_OK !=
4103 "REKEY_INTERVAL",
4106
4107 if (GNUNET_OK !=
4110 "REKEY_MAX_BYTES",
4112 {
4114 }
4115
4116 memset (in, 0, sizeof(struct sockaddr*) * 2);
4117 memset (in_len, 0, sizeof(socklen_t) * 2);
4118
4119 GNUNET_assert (bindto);
4121 bindto, AF_INET, &(in[0]), &(in_len[0]));
4122 GNUNET_free (bindto);
4123
4124 if (GNUNET_YES != disable_v6)
4125 {
4126 GNUNET_assert (bindto6);
4128 bindto6, AF_INET6, &(in[1]), &(in_len[1]));
4129 GNUNET_free (bindto6);
4130 }
4131 else
4132 default_v6_sock = NULL;
4133
4134 if ((NULL == default_v4_sock) && (NULL == default_v6_sock))
4135 return;
4136
4137 my_port = 0;
4138 if (NULL != default_v4_sock)
4139 {
4140 GNUNET_assert (in[0]);
4142 "transport",
4143 "Bound to `%s' sock %p\n",
4144 GNUNET_a2s ((const struct sockaddr *) in[0],
4145 in_len[0]),
4147
4148 v4 = (const struct sockaddr_in *) in[0];
4149
4150 my_ipv4 = GNUNET_malloc (INET_ADDRSTRLEN);
4151 my_port = ntohs (((struct sockaddr_in *) in[0])->sin_port);
4152 inet_ntop (AF_INET, &v4->sin_addr, my_ipv4, in_len[0]);
4153 }
4154 if (NULL != default_v6_sock)
4155 {
4156 GNUNET_assert (in[1]);
4158 "transport",
4159 "Bound to `%s' sock %p\n",
4160 GNUNET_a2s ((const struct sockaddr *) in[1],
4161 in_len[1]),
4163 my_port = ntohs (((struct sockaddr_in6 *) in[1])->sin6_port);
4164 }
4165 stats = GNUNET_STATISTICS_create ("communicator-udp", cfg);
4174 /* start reading */
4175 if (NULL != default_v4_sock)
4178 &sock_read,
4180 else
4181 read_v4_task = NULL;
4182 if (NULL != default_v6_sock)
4185 &sock_read,
4187 else
4188 read_v6_task = NULL;
4193 &mq_init,
4194 NULL,
4196 NULL,
4197 &start_burst);
4198 if (NULL == ch)
4199 {
4200 GNUNET_break (0);
4201 shutdown_run (in);
4202 return;
4203 }
4205 if (NULL == ah)
4206 {
4207 GNUNET_break (0);
4208 shutdown_run (in);
4209 return;
4210 }
4211 /* start broadcasting */
4212 if (GNUNET_YES !=
4215 "DISABLE_BROADCAST"))
4216 {
4218 }
4220 GNUNET_assert (NULL != key_ring);
4221 pils = GNUNET_PILS_connect (cfg, NULL, NULL);
4222 GNUNET_assert (NULL != pils);
4223
4226 IPPROTO_UDP,
4227 (NULL != in[0]? 1 : 0)
4228 + (NULL != in[1]? 1 : 0),
4229 (const struct sockaddr**)
4230 (NULL != in[0]? in : &(in[1])),
4231 NULL != in[0]? in_len : &(in_len[1]),
4234 NULL /* closure */);
4235 if (NULL != in[0])
4236 GNUNET_free (in[0]);
4237 if (NULL != in[1])
4238 GNUNET_free (in[1]);
4239}
4240
4241
4242GNUNET_DAEMON_MAIN ("gnunet-communicator-udp",
4243 _ ("GNUnet UDP communicator"),
4244 &run)
4245/* 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.
static enum GNUNET_GenericReturnValue check_peer_alive(struct ReceiverAddress *receiver)
Check whether the peer behind receiver is still reacting to what we send it, and tear receiver down i...
#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 void consider_reflexive_address(const struct GNUNET_PeerIdentity *target, const struct sockaddr *address, socklen_t address_len)
Consider the address a datagram from target arrived from as a path we can send to.
#define PEER_LIVENESS_TIMEOUT
How long may we keep transmitting to a peer that never acknowledges a single datagram before we concl...
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)
Offer an ACK we received from ai->sender to the receiver in value, if that receiver is for that peer.
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 struct SenderAddress * setup_sender(const struct GNUNET_PeerIdentity *target, const struct sockaddr *address, socklen_t address_len, int *is_new)
Create sender address for target.
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_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:624
void GNUNET_PILS_disconnect(struct GNUNET_PILS_Handle *handle)
Disconnect from the PILS service.
Definition pils_api.c:647
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:1008
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:1068
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:875
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:1091
#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.
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:514
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:469
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition mq.c:732
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_duration(struct GNUNET_TIME_Absolute whence)
Get the duration of an operation as the difference of the current time and the given start time "henc...
Definition time.c:438
#define GNUNET_TIME_relative_cmp(t1, op, t2)
Compare two relative times.
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
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
Definition strings.c:610
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition time.c:111
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:86
A simplified handle for using the peer identity key.
Definition pils_api.c:149
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 GNUNET_TIME_Absolute last_ack
When did we last receive a GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK that belongs to this receiver?...
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 90 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 92 of file gnunet-communicator-udp.c.

◆ AES_KEY_SIZE

#define AES_KEY_SIZE   (256 / 8)

AES key size.

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

◆ AES_IV_SIZE

#define AES_IV_SIZE   (96 / 8)

AES (GCM) IV size.

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

◆ GCM_TAG_SIZE

#define GCM_TAG_SIZE   (128 / 8)

Size of the GCM tag.

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

◆ GENERATE_AT_ONCE

#define GENERATE_AT_ONCE   64

Definition at line 110 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 121 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 129 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 140 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 151 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 157 of file gnunet-communicator-udp.c.

◆ COMMUNICATOR_ADDRESS_PREFIX

#define COMMUNICATOR_ADDRESS_PREFIX   "udp"

Address prefix used by the communicator.

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

◆ COMMUNICATOR_CONFIG_SECTION

#define COMMUNICATOR_CONFIG_SECTION   "communicator-udp"

Configuration section used by the communicator.

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

915{
917 key.type = htonl (GNUNET_PUBLIC_KEY_TYPE_EDDSA);
918 key.eddsa_key = *edpk;
920 pk);
921}

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

927{
929 key.type = htonl (GNUNET_PUBLIC_KEY_TYPE_EDDSA);
930 key.eddsa_key = *edpk;
932 pk);
933}

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

943{
944 if (AF_INET6 == bi->sa->sa_family)
945 {
946 /* Leave the multicast group */
948 IPPROTO_IPV6,
949 IPV6_LEAVE_GROUP,
950 &bi->mcreq,
951 sizeof(bi->mcreq)))
952 {
954 }
955 }
958 GNUNET_free (bi->sa);
959 GNUNET_free (bi->ba);
960 GNUNET_free (bi);
961}

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

1116{
1117 struct SenderAddress *sender;
1118 struct ReceiverAddress *receiver;
1119 struct KeyCacheEntry *kce;
1120
1122 "secret %s destroy %u\n",
1123 GNUNET_sh2s (&ss->master),
1125 if (NULL != (sender = ss->sender))
1126 {
1127 GNUNET_CONTAINER_DLL_remove (sender->ss_head, sender->ss_tail, ss);
1128 sender->num_secrets--;
1130 "%u sender->num_secrets %u allowed %u used, %u available\n",
1132 sender->acks_available);
1133 /* NOTE: this used to subtract `sequence_allowed - sequence_used', which
1134 is not the number of keys this secret still holds. Keys also go away
1135 without @e sequence_used moving: #consider_ss_ack() drops entries past
1136 #MAX_SQN_DELTA, and #decrypt_box() destroys the entry of a datagram
1137 that failed to decrypt. Over-subtracting wraps this unsigned counter
1138 to ~4e9, after which `KCN_THRESHOLD > acks_available' is false
1139 forever: we never generate another key, never send another UDPAck,
1140 and the peer -- which can only send BOXes for sequence numbers we
1141 acknowledged -- falls back to a full key exchange per datagram for
1142 good. The #kce_destroy() loop below now accounts for exactly the keys
1143 that existed. */
1144 if (NULL != ss->sender->kce_task)
1145 {
1147 ss->sender->kce_task = NULL;
1148 }
1149 }
1150 if (NULL != (receiver = ss->receiver))
1151 {
1152 GNUNET_CONTAINER_DLL_remove (receiver->ss_head, receiver->ss_tail, ss);
1153 receiver->num_secrets--;
1154 receiver->acks_available -= (ss->sequence_allowed - ss->sequence_used);
1156 "%u receiver->num_secrets\n",
1157 receiver->num_secrets);
1158 }
1159 while (NULL != (kce = ss->kce_head))
1160 kce_destroy (kce);
1161 GNUNET_STATISTICS_update (stats, "# Secrets active", -1, GNUNET_NO);
1163 "# KIDs active",
1165 GNUNET_NO);
1166 GNUNET_free (ss);
1167 return GNUNET_YES;
1168}

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

974{
975 struct SharedSecret *ss;
976 receiver->receiver_destroy_called = GNUNET_YES;
977
979 "Disconnecting receiver for peer `%s'\n",
980 GNUNET_i2s (&receiver->target));
981 if (NULL != receiver->kx_qh)
982 {
984 receiver->kx_qh = NULL;
985 receiver->kx_mq = NULL;
986 }
987 if (NULL != receiver->d_qh)
988 {
990 receiver->d_qh = NULL;
991 }
992 else if (NULL != receiver->d_mq)
993 {
995 receiver->d_mq = NULL;
996 }
997 if (NULL != receiver->udp_sock)
998 {
1001 receiver->udp_sock = NULL;
1002 }
1005 &receiver->key,
1006 receiver));
1009 "# receivers active",
1011 GNUNET_NO);
1012 while (NULL != (ss = receiver->ss_head))
1013 {
1014 secret_destroy (ss);
1015 }
1016 GNUNET_free (receiver->address);
1017 GNUNET_free (receiver->foreign_addr);
1019}

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

1029{
1030 struct SharedSecret *ss = kce->ss;
1031
1032 ss->active_kce_count--;
1033 /* @e acks_available is "how many BOX keys do we have ready for this
1034 sender", so it must be maintained here, where a key actually goes away,
1035 and nowhere else. #kce_generate() is the only place one comes into
1036 existence. */
1037 if (NULL != ss->sender)
1038 {
1040 if (0 < ss->sender->acks_available)
1041 ss->sender->acks_available--;
1042 }
1045 &kce->kid,
1046 kce));
1047 GNUNET_free (kce);
1048}

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

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

1062{
1063 uint32_t sid = htonl (serial);
1064 struct GNUNET_ShortHashCode prk;
1066 &sid, sizeof (sid),
1067 msec, sizeof (*msec));
1068
1070 kid,
1071 sizeof(*kid),
1072 &prk,
1073 GNUNET_CRYPTO_kdf_arg_string ("gnunet-communicator-udp-kid"));
1074}

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

1085{
1086 struct KeyCacheEntry *kce;
1087
1088 GNUNET_assert (0 < seq);
1089 kce = GNUNET_new (struct KeyCacheEntry);
1090 kce->ss = ss;
1091 kce->sequence_number = seq;
1092 get_kid (&ss->master, seq, &kce->kid);
1097 key_cache,
1098 &kce->kid,
1099 kce,
1102 "# KIDs active",
1104 GNUNET_NO);
1105}

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

1179{
1180 struct SharedSecret *ss;
1183 GNUNET_YES ==
1187 "# senders active",
1189 GNUNET_NO);
1190 while (NULL != (ss = sender->ss_head))
1191 {
1192 secret_destroy (ss);
1193 }
1196}

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

1212{
1213 uint32_t sid = htonl (serial);
1214
1216 key,
1218 msec,
1219 GNUNET_CRYPTO_kdf_arg_string ("gnunet-communicator-udp-key"),
1222 iv,
1224 msec,
1225 GNUNET_CRYPTO_kdf_arg_string ("gnunet-communicator-udp-iv"),
1227}

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 1236 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.

NOTE: this is called when we transmit, so timeout tracks our own activity, not the peer's. It must not be mistaken for a liveness check; see check_peer_alive().

Parameters
receiveraddress for which the timeout should be rescheduled

Definition at line 1254 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_peer_alive()

static enum GNUNET_GenericReturnValue check_peer_alive ( struct ReceiverAddress receiver)
static

Check whether the peer behind receiver is still reacting to what we send it, and tear receiver down if it is not.

Called before each transmission. reschedule_receiver_timeout() pushes timeout forward on every send, so check_timeouts() can never expire a receiver we keep transmitting to – and the KX queue is registered with GNUNET_TRANSPORT_QUEUE_LENGTH_UNLIMITED, so transport always has one to transmit on. Without this check a peer that vanished would keep its queues (and hence transport's virtual link, and hence CORE's idea of the connection) alive forever.

Parameters
receiverreceiver we are about to transmit to
Returns
GNUNET_YES if receiver is alive, GNUNET_NO if it was destroyed and must not be touched again by the caller

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

1281{
1284 <=,
1286 return GNUNET_YES;
1288 "Peer `%s' did not acknowledge a single datagram for %s while we "
1289 "kept transmitting, considering it disconnected\n",
1290 GNUNET_i2s (&receiver->target),
1292 GNUNET_YES));
1294 "# receivers destroyed (peer unresponsive)",
1295 1,
1296 GNUNET_NO);
1297 if (GNUNET_YES != receiver->receiver_destroy_called)
1299 return GNUNET_NO;
1300}

References GNUNET_ERROR_TYPE_INFO, GNUNET_i2s(), GNUNET_log, GNUNET_NO, GNUNET_STATISTICS_update(), GNUNET_STRINGS_relative_time_to_string(), GNUNET_TIME_absolute_get_duration(), GNUNET_TIME_relative_cmp, GNUNET_YES, PEER_LIVENESS_TIMEOUT, receiver(), receiver_destroy(), and stats.

Referenced by mq_send_d(), and mq_send_kx().

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

◆ check_timeouts()

static void check_timeouts ( void *  cls)
static

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

Parameters
clsunused, NULL

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

1310{
1311 struct GNUNET_TIME_Relative st;
1312 struct GNUNET_TIME_Relative rt;
1313 struct GNUNET_TIME_Relative delay;
1314 struct ReceiverAddress *receiver;
1315 struct SenderAddress *sender;
1316
1317 (void) cls;
1318 timeout_task = NULL;
1321 {
1323 if (0 != rt.rel_value_us)
1324 break;
1326 "Receiver timed out\n");
1328 }
1330 while (NULL != (sender = GNUNET_CONTAINER_heap_peek (senders_heap)))
1331 {
1332 /* NOTE: no @e sender_destroy_called check here -- #sender_destroy()
1333 removes the node from the heap, so anything we can peek at is live.
1334 Skipping instead of breaking would spin forever on the same node. */
1336 if (0 != st.rel_value_us)
1337 break;
1338 sender_destroy (sender);
1339 }
1340 delay = GNUNET_TIME_relative_min (rt, st);
1341 if (delay.rel_value_us < GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
1343}

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, receiver(), receiver_destroy(), receivers_heap, GNUNET_TIME_Relative::rel_value_us, sender_destroy(), 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 1352 of file gnunet-communicator-udp.c.

1353{
1355 &ss->cmac,
1356 sizeof(ss->cmac),
1357 &ss->master,
1358 GNUNET_CRYPTO_kdf_arg_string ("gnunet-communicator-udp-cmac"));
1359}

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

1374{
1375 const struct GNUNET_MessageHeader *hdr = plaintext;
1376 const char *pos = plaintext;
1377
1378 while (ntohs (hdr->size) <= plaintext_len)
1379 {
1381 "# bytes given to core",
1382 ntohs (hdr->size),
1383 GNUNET_NO);
1385 "Giving %u bytes to TNG\n", ntohs (hdr->size));
1388 &sender->target,
1389 hdr,
1391 NULL /* no flow control possible */
1392 ,
1393 NULL));
1394 /* move on to next message, if any */
1395 plaintext_len -= ntohs (hdr->size);
1396 if (plaintext_len < sizeof(*hdr))
1397 break;
1398 pos += ntohs (hdr->size);
1399 hdr = (const struct GNUNET_MessageHeader *) pos;
1400 // TODO for now..., we do not actually sen >1msg or have a way of telling
1401 // if we are done
1402 break;
1403 }
1405 "# bytes padding discarded",
1406 plaintext_len,
1407 GNUNET_NO);
1408}

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

1423{
1424 char key[AES_KEY_SIZE];
1425 char iv[AES_IV_SIZE];
1426 int rc;
1427
1428 GNUNET_assert (0 ==
1429 gcry_cipher_open (cipher,
1430 GCRY_CIPHER_AES256 /* low level: go for speed */
1431 ,
1432 GCRY_CIPHER_MODE_GCM,
1433 0 /* flags */));
1434 get_iv_key (msec, serial, key, iv);
1435 rc = gcry_cipher_setkey (*cipher, key, sizeof(key));
1436 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
1437 rc = gcry_cipher_setiv (*cipher, iv, sizeof(iv));
1438 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
1439}

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

1461{
1462 gcry_cipher_hd_t cipher;
1463
1464 setup_cipher (&ss->master, serial, &cipher);
1466 0 ==
1467 gcry_cipher_decrypt (cipher, out_buf, in_buf_size, in_buf, in_buf_size));
1468 if (0 != gcry_cipher_checktag (cipher, tag, GCM_TAG_SIZE))
1469 {
1470 gcry_cipher_close (cipher);
1472 "# AEAD authentication failures",
1473 1,
1474 GNUNET_NO);
1475 return GNUNET_SYSERR;
1476 }
1477 gcry_cipher_close (cipher);
1478 return GNUNET_OK;
1479}

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

1491{
1493 struct SharedSecret *ss;
1494
1497
1498 ss = GNUNET_new (struct SharedSecret);
1500 ephemeral,
1501 &ss->master);
1502 calculate_cmac (ss);
1503 return ss;
1504}

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

1516{
1518 struct GNUNET_CRYPTO_HpkePrivateKey my_hpke_key;
1519 struct SharedSecret *ss;
1520
1523
1524 eddsa_priv_to_hpke_key (my_private_key, &my_hpke_key);
1525
1526 ss = GNUNET_new (struct SharedSecret);
1528 &ss->master);
1530 "New receiver SS master: %s\n", GNUNET_sh2s (&ss->master));
1531 calculate_cmac (ss);
1532 return ss;
1533}

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

1547{
1548 struct SharedSecret *ss;
1549
1550 ss = GNUNET_new (struct SharedSecret);
1551 GNUNET_CRYPTO_eddsa_kem_encaps (&receiver->target.public_key,
1552 ephemeral,
1553 &ss->master);
1554 calculate_cmac (ss);
1555 ss->receiver = receiver;
1556 GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss);
1557 receiver->num_secrets++;
1558 GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
1559 return ss;
1560}

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

1574{
1575 struct SharedSecret *ss;
1576
1577 ss = GNUNET_new (struct SharedSecret);
1579 c, &ss->master);
1581 "New sender SS master: %s\n", GNUNET_sh2s (&ss->master));
1582 calculate_cmac (ss);
1583 ss->receiver = receiver;
1584 GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss);
1585 receiver->num_secrets++;
1586 GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
1587 return ss;
1588}

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

3324{
3325 size_t base_mtu;
3326
3327 switch (receiver->address->sa_family)
3328 {
3329 case AF_INET:
3330 base_mtu = 1480 /* Ethernet MTU, 1500 - Ethernet header - VLAN tag */
3331 - sizeof(struct GNUNET_TUN_IPv4Header) /* 20 */
3332 - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */;
3333 break;
3334
3335 case AF_INET6:
3336 base_mtu = 1280 /* Minimum MTU required by IPv6 */
3337 - sizeof(struct GNUNET_TUN_IPv6Header) /* 40 */
3338 - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */;
3339 break;
3340
3341 default:
3342 GNUNET_assert (0);
3343 break;
3344 }
3345 /* MTU based on full KX messages */
3346 receiver->kx_mtu = base_mtu - sizeof(struct InitialKX) /* 48 */
3347 - sizeof(struct UDPConfirmation); /* 104 */
3348 /* MTU based on BOXed messages */
3349 receiver->d_mtu = base_mtu - sizeof(struct UDPBox);
3350
3352 "Setting up MQs and QHs\n");
3353 /* => Effective MTU for CORE will range from 1080 (IPv6 + KX) to
3354 1404 (IPv4 + Box) bytes, depending on circumstances... */
3355 if (NULL == receiver->kx_mq)
3358 &mq_cancel,
3359 receiver,
3360 NULL,
3361 &mq_error,
3362 receiver);
3363 if (NULL == receiver->d_mq)
3365 &mq_destroy_d,
3366 &mq_cancel,
3367 receiver,
3368 NULL,
3369 &mq_error,
3370 receiver);
3371
3372 receiver->kx_qh =
3374 &receiver->target,
3375 receiver->foreign_addr,
3376 receiver->kx_mtu,
3378 0, /* Priority */
3379 receiver->nt,
3381 receiver->kx_mq);
3382}

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

1611{
1612 struct SharedSecret *pos;
1613 struct SharedSecret *ss_to_purge;
1614 unsigned int deleted = 0;
1615
1617 "Purging secrets.\n");
1618 pos = ss_list_tail;
1619 while (NULL != pos)
1620 {
1621 ss_to_purge = pos;
1622 pos = pos->prev;
1623
1624 // FIXME we may also want to purge old unacked.
1625 if (rekey_max_bytes <= ss_to_purge->bytes_sent)
1626 {
1627 secret_destroy (ss_to_purge);
1628 deleted++;
1629 }
1630 }
1632 "Finished purging all, deleted %u.\n", deleted);
1633 return deleted;
1634}

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

1639{
1640
1641 struct ReceiverAddress *receiver = ss->receiver;
1642
1643 GNUNET_assert (NULL != ss);
1644 GNUNET_assert (NULL != receiver);
1645
1646 if (NULL == receiver->d_qh)
1647 {
1648 receiver->d_qh =
1650 &receiver->target,
1651 receiver->foreign_addr,
1652 receiver->d_mtu,
1653 acks_to_add,
1654 1, /* Priority */
1655 receiver->nt,
1657 receiver->d_mq);
1658 }
1659 else
1660 {
1662 receiver->d_qh,
1663 acks_to_add,
1664 1);
1665 }
1666
1668 "Tell transport we have %u more acks!\n",
1669 acks_to_add);
1670
1671 // Until here for alternative 1
1672
1673 /* move ss to head to avoid discarding it anytime soon! */
1674
1675 // GNUNET_CONTAINER_DLL_remove (receiver->ss_head, receiver->ss_tail, ss);
1676 // GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss);
1677}

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

1692{
1693 const struct UDPAck *ack = cls;
1694 struct ReceiverAddress *receiver = value;
1695 uint32_t acks_to_add;
1696 uint32_t allowed;
1697
1699 "in handle ack with cmac %s\n",
1700 GNUNET_h2s (&ack->cmac));
1701
1702 (void) key;
1703 for (struct SharedSecret *ss = receiver->ss_head; NULL != ss; ss = ss->next)
1704 {
1705 if (0 == memcmp (&ack->cmac, &ss->cmac, sizeof(struct GNUNET_HashCode)))
1706 {
1707
1709 "Found matching cmac\n");
1710
1711 /* Whatever window it grants us, this ACK proves the peer is alive.
1712 Note that this is the *only* inbound signal tied to a receiver. */
1713 receiver->last_ack = GNUNET_TIME_absolute_get ();
1714
1715 allowed = ntohl (ack->sequence_ack);
1716
1717 if (allowed <= ss->sequence_allowed)
1718 {
1720 "Ignoring ack, not giving us increased window\n.");
1721 return GNUNET_NO;
1722 }
1723 acks_to_add = (allowed - ss->sequence_allowed);
1724 GNUNET_assert (0 != acks_to_add);
1725 receiver->acks_available += (allowed - ss->sequence_allowed);
1726 ss->sequence_allowed = allowed;
1727 add_acks (ss, acks_to_add);
1729 "New sequence allows until %u (+%u). Acks available to us: %u. For secret %s\n",
1730 allowed,
1731 acks_to_add,
1732 receiver->acks_available,
1733 GNUNET_sh2s (&ss->master));
1734 return GNUNET_NO;
1735 }
1736 }
1738 "Matching cmac not found for ack!\n");
1739 return GNUNET_YES;
1740}

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

Referenced by handle_ack_by_sender().

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

◆ handle_ack_by_sender()

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

Offer an ACK we received from ai->sender to the receiver in value, if that receiver is for that peer.

Matching on the peer identity (and letting handle_ack() sort out which shared secret the ACK is for) is the only workable test: the ACK reaches us over whatever path transport chose, which tells us nothing about which of the addresses we hold for that peer it belongs to.

Parameters
clsa struct AckInfo *
keyhash of the receiver, unused
valuea struct ReceiverAddress *
Returns
GNUNET_YES to continue to iterate

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

1767{
1768 struct ReceiverAddress *receiver = value;
1769 struct AckInfo *ai = cls;
1770
1771 if (0 != GNUNET_memcmp (ai->sender, &receiver->target))
1772 {
1773 return GNUNET_YES;
1774 }
1775 handle_ack ((void*) ai->ack, key, receiver);
1776 return GNUNET_YES;
1777}

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

Referenced by enc_notify_cb(), and try_handle_plaintext().

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

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

1790{
1791 struct UDPAck ack;
1792 GNUNET_assert (NULL != ss->sender);
1794 "Considering SS UDPAck %s\n",
1795 GNUNET_i2s_full (&ss->sender->target));
1796
1798 "Sender has %u acks available.\n",
1799 ss->sender->acks_available);
1800 /* drop ancient KeyCacheEntries */
1801 while ((NULL != ss->kce_head) &&
1802 (MAX_SQN_DELTA <
1804 kce_destroy (ss->kce_tail);
1805
1806
1807 ack.header.type = htons (GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK);
1808 ack.header.size = htons (sizeof(ack));
1809 ack.sequence_ack = htonl (ss->sequence_allowed);
1810 ack.cmac = ss->cmac;
1812 "Notifying transport with UDPAck %s, sequence %u and master %s\n",
1814 ss->sequence_allowed,
1815 GNUNET_sh2s (&(ss->master)));
1817 &ss->sender->target,
1819 &ack.header);
1820}

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

1825{
1826 struct SharedSecret *ss = cls;
1827 ss->sender->kce_task = NULL;
1828
1830 "Precomputing %u keys for master %s\n",
1832 GNUNET_sh2s (&ss->master));
1833 if ((ss->override_available_acks != GNUNET_YES) &&
1834 (KCN_TARGET < ss->sender->acks_available) &&
1835 (0 != ss->sequence_allowed))
1836 {
1837 /* Enough keys for this sender overall, and this secret already has some
1838 the peer may use.
1839 Do NOT just return: @e kce_task_finished is a latch that decides which
1840 of the two places that arm this task is allowed to do so -- the KX
1841 path only arms it while it is #GNUNET_NO, #decrypt_box() only while it
1842 is #GNUNET_YES. Leaving it #GNUNET_NO here means #decrypt_box() can
1843 never ask for more keys again, so the sender's supply runs down to
1844 zero and stays there. And the peer is waiting on the UDPAck that says
1845 how far it may count with this secret; without it, it can only reach
1846 us by doing a full key exchange per datagram. */
1850 consider_ss_ack (ss);
1851 return;
1852 }
1853 for (int i = 0; i < GENERATE_AT_ONCE; i++)
1854 kce_generate (ss, ++ss->sequence_allowed);
1855
1860 if (KCN_TARGET > ss->sender->acks_available)
1861 {
1865 ss);
1866 return;
1867 }
1869 "We have enough keys (ACKs: %u).\n", ss->sender->acks_available);
1873 consider_ss_ack (ss);
1874}

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

1889{
1890 const struct GNUNET_MessageHeader *hdr;
1891 const struct UDPAck *ack;
1892 const struct UDPRekey *rekey;
1893 struct SharedSecret *ss_rekey;
1894 const char *buf_pos = buf;
1895 size_t bytes_remaining = buf_size;
1896 uint16_t type;
1897
1898 hdr = (struct GNUNET_MessageHeader*) buf_pos;
1899 if (sizeof(*hdr) > bytes_remaining)
1900 {
1901 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Plaintext too short, dropping...\n");
1902 return; /* no data left */
1903 }
1905 "try_handle_plaintext of size %llu (%u %lu) and type %u\n",
1906 (unsigned long long) bytes_remaining,
1907 ntohs (hdr->size),
1908 sizeof(*hdr),
1909 ntohs (hdr->type));
1910 if (ntohs (hdr->size) > bytes_remaining)
1911 return; /* buffer too short for indicated message length */
1912 type = ntohs (hdr->type);
1913 switch (type)
1914 {
1916 rekey = (struct UDPRekey*) buf_pos;
1917 if (ntohs (hdr->size) < sizeof (struct UDPRekey))
1918 {
1919 GNUNET_break_op (0);
1920 return;
1921 }
1922 ss_rekey = setup_shared_secret_dec (&rekey->ephemeral);
1923 ss_rekey->sender = sender;
1924 GNUNET_CONTAINER_DLL_insert (sender->ss_head, sender->ss_tail, ss_rekey);
1925 sender->num_secrets++;
1927 "Received rekey secret with cmac %s\n",
1928 GNUNET_h2s (&(ss_rekey->cmac)));
1930 "Received secret with master %s.\n",
1931 GNUNET_sh2s (&(ss_rekey->master)));
1933 "We have %u sequence_allowed.\n",
1934 ss_rekey->sequence_allowed);
1936 "We have a sender %p\n",
1937 ss_rekey->sender);
1939 "We have %u acks available.\n",
1940 ss_rekey->sender->acks_available);
1942 "# rekeying successful",
1943 1,
1944 GNUNET_NO);
1947 /* Go through @e kce_task rather than calling #kce_generate_cb() inline.
1948 That function starts with `sender->kce_task = NULL', so calling it
1949 directly dropped the handle of a task that may well have been armed
1950 for another of this sender's secrets: it still fires, but nothing can
1951 cancel it any more -- including #secret_destroy(), which then leaves
1952 it pointing at a freed `struct SharedSecret'. */
1953 if (NULL != ss_rekey->sender->kce_task)
1956 ss_rekey);
1957 // FIXME: Theoretically, this could be an Ack
1958 buf_pos += ntohs (hdr->size);
1959 bytes_remaining -= ntohs (hdr->size);
1960 pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
1961 if (0 == purge_secrets (sender->ss_tail))
1962 {
1963 // No secret purged. Delete oldest.
1964 if (sender->num_secrets > MAX_SECRETS)
1965 {
1966 secret_destroy (sender->ss_tail);
1967 }
1968 }
1969 break;
1971 /* lookup master secret by 'cmac', then update sequence_max */
1972 ack = (struct UDPAck*) buf_pos;
1973 if (ntohs (hdr->size) < sizeof (struct UDPAck))
1974 {
1975 GNUNET_break_op (0);
1976 return;
1977 }
1978 {
1979 /* NOTE: @e key of a sender is H(source address || peer), that of a
1980 receiver H(address we send to || peer). Looking @a receivers up by
1981 the sender's key therefore only ever hits when the peer reached us
1982 from exactly the address we send to -- i.e. never for a peer behind
1983 a NAT, which is the case that needs the ACK most. Match on the peer
1984 instead, the same way #enc_notify_cb() does for the backchannel. */
1985 struct AckInfo ai = {
1986 .ack = ack,
1987 .sender = &sender->target
1988 };
1989
1992 &ai);
1993 }
1994 /* There could be more messages after the ACK, handle those as well */
1995 buf_pos += ntohs (hdr->size);
1996 bytes_remaining -= ntohs (hdr->size);
1997 pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
1998 break;
1999
2001 /* skip padding */
2002 break;
2003
2004 default:
2005 pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
2006 }
2007 return;
2008}

References AckInfo::ack, SenderAddress::acks_available, ai, SharedSecret::cmac, UDPRekey::ephemeral, GNUNET_break_op, GNUNET_CONTAINER_DLL_insert, GNUNET_CONTAINER_multihashmap_iterate(), 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_SCHEDULER_add_now(), GNUNET_SCHEDULER_cancel(), GNUNET_sh2s(), GNUNET_STATISTICS_update(), GNUNET_YES, handle_ack_by_sender(), kce_generate_cb(), SenderAddress::kce_send_ack_on_finish, SenderAddress::kce_task, SharedSecret::master, MAX_SECRETS, SenderAddress::num_secrets, SharedSecret::override_available_acks, pass_plaintext_to_core(), purge_secrets(), receivers, secret_destroy(), SharedSecret::sender, AckInfo::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 2019 of file gnunet-communicator-udp.c.

2022{
2023 struct SharedSecret *ss = kce->ss;
2024 struct SharedSecret *ss_c = ss->sender->ss_tail;
2025 struct SharedSecret *ss_tmp;
2026 int ss_destroyed = 0;
2027 char out_buf[box_len - sizeof(*box)];
2028
2029 GNUNET_assert (NULL != ss->sender);
2030 if (GNUNET_OK != try_decrypt (ss,
2031 box->gcm_tag,
2032 kce->sequence_number,
2033 (const char *) &box[1],
2034 sizeof(out_buf),
2035 out_buf))
2036 {
2037 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed decryption.\n");
2039 "# Decryption failures with valid KCE",
2040 1,
2041 GNUNET_NO);
2042 /* NOTE: no `acks_available--' here or below -- #kce_destroy() does it.
2043 Doing it here as well double-counted, and on this path (decryption
2044 failure) @e sequence_used does *not* advance, so #secret_destroy()'s
2045 old `sequence_allowed - sequence_used' could not have compensated for
2046 it either. */
2047 kce_destroy (kce);
2048 return;
2049 }
2050 kce_destroy (kce);
2051 kce = NULL;
2052 ss->bytes_sent += box_len;
2053 ss->sequence_used++;
2055 "# bytes decrypted with BOX",
2056 sizeof(out_buf),
2057 GNUNET_NO);
2059 "# messages decrypted with BOX",
2060 1,
2061 GNUNET_NO);
2063 "decrypted UDPBox with kid %s\n",
2064 GNUNET_sh2s (&box->kid));
2065 try_handle_plaintext (ss->sender, out_buf, sizeof(out_buf));
2066
2067 while (NULL != ss_c)
2068 {
2069 if (ss_c->bytes_sent >= rekey_max_bytes)
2070 {
2072 "Removing SS because rekey bytes reached.\n");
2073 ss_tmp = ss_c->prev;
2074 if (ss == ss_c)
2075 ss_destroyed = 1;
2076 secret_destroy (ss_c);
2077 ss_c = ss_tmp;
2078 continue;
2079 }
2080 ss_c = ss_c->prev;
2081 }
2082 if (1 == ss_destroyed)
2083 return;
2085 "Sender has %u ack left.\n",
2086 ss->sender->acks_available);
2087 if ((KCN_THRESHOLD > ss->sender->acks_available) &&
2088 (NULL == ss->sender->kce_task) &&
2090 {
2092 "Sender has %u ack left which is under threshold.\n",
2093 ss->sender->acks_available);
2097 ss);
2098 }
2099}

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,
int *  is_new 
)
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
[out]is_newset to GNUNET_YES if this is the first time we see target at address, may be NULL
Returns
data structure to keep track of key material for decrypting data from target

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

2142{
2143 struct SenderAddress *sender;
2144 struct GNUNET_HashContext *hsh;
2145 struct GNUNET_HashCode sender_key;
2146
2148 GNUNET_CRYPTO_hash_context_read (hsh, address, address_len);
2149 GNUNET_CRYPTO_hash_context_read (hsh, target, sizeof(*target));
2150 GNUNET_CRYPTO_hash_context_finish (hsh, &sender_key);
2151
2152 if (NULL != is_new)
2153 *is_new = GNUNET_NO;
2154 sender = GNUNET_CONTAINER_multihashmap_get (senders, &sender_key);
2155 if (NULL != sender)
2156 {
2158 return sender;
2159 }
2160 if (NULL != is_new)
2161 *is_new = GNUNET_YES;
2162 sender = GNUNET_new (struct SenderAddress);
2163 sender->key = sender_key;
2164 sender->target = *target;
2165 sender->address = GNUNET_memdup (address, address_len);
2166 sender->address_len = address_len;
2168 senders,
2169 &sender->key,
2170 sender,
2173 "# senders active",
2175 GNUNET_NO);
2176 sender->timeout =
2179 sender,
2180 sender->timeout.abs_value_us);
2181 sender->nt = GNUNET_NT_scanner_get_type (is, address, address_len);
2182 if (NULL == timeout_task)
2184 return sender;
2185}

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(), GNUNET_YES, 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 2196 of file gnunet-communicator-udp.c.

2198{
2199 const struct GNUNET_PeerIdentity *my_identity;
2200 struct UdpHandshakeSignature uhs;
2201
2204
2205 uhs.purpose.purpose = htonl (
2207 uhs.purpose.size = htonl (sizeof(uhs));
2208 uhs.sender = uc->sender;
2209 uhs.receiver = *my_identity;
2210 uhs.enc = *enc;
2211 uhs.monotonic_time = uc->monotonic_time;
2214 &uhs,
2215 &uc->sender_sig,
2216 &uc->sender.public_key);
2217}

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

2231{
2232 char *ret;
2233
2234 switch (address->sa_family)
2235 {
2236 case AF_INET:
2238 "%s-%s",
2240 GNUNET_a2s (address, address_len));
2241 break;
2242
2243 case AF_INET6:
2245 "%s-%s",
2247 GNUNET_a2s (address, address_len));
2248 break;
2249
2250 default:
2251 GNUNET_assert (0);
2252 }
2253 return ret;
2254}

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

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

2259{
2261
2262 if (NULL == receiver->udp_sock)
2263 {
2264 if (AF_INET6 == receiver->address->sa_family)
2266 else
2268 }
2269 else
2270 udp_sock = receiver->udp_sock;
2271
2272 return udp_sock;
2273}

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

2288{
2289 struct sockaddr *in;
2290 unsigned int port;
2291 char dummy[2];
2292 char *colon;
2293 char *cp;
2294
2295 if (1 == sscanf (bindto, "%u%1s", &port, dummy))
2296 {
2297 /* interpreting value as just a PORT number */
2298 if (port > UINT16_MAX)
2299 {
2301 "BINDTO specification `%s' invalid: value too large for port\n",
2302 bindto);
2303 return NULL;
2304 }
2305 if ((AF_INET == family) || (GNUNET_YES == disable_v6))
2306 {
2307 struct sockaddr_in *i4;
2308
2309 i4 = GNUNET_malloc (sizeof(struct sockaddr_in));
2310 i4->sin_family = AF_INET;
2311 i4->sin_port = htons ((uint16_t) port);
2312 *sock_len = sizeof(struct sockaddr_in);
2313 in = (struct sockaddr *) i4;
2314 }
2315 else
2316 {
2317 struct sockaddr_in6 *i6;
2318
2319 i6 = GNUNET_malloc (sizeof(struct sockaddr_in6));
2320 i6->sin6_family = AF_INET6;
2321 i6->sin6_port = htons ((uint16_t) port);
2322 *sock_len = sizeof(struct sockaddr_in6);
2323 in = (struct sockaddr *) i6;
2324 }
2325 return in;
2326 }
2327 cp = GNUNET_strdup (bindto);
2328 colon = strrchr (cp, ':');
2329 if (NULL != colon)
2330 {
2331 /* interpret value after colon as port */
2332 *colon = '\0';
2333 colon++;
2334 if (1 == sscanf (colon, "%u%1s", &port, dummy))
2335 {
2336 /* interpreting value as just a PORT number */
2337 if (port > UINT16_MAX)
2338 {
2340 "BINDTO specification `%s' invalid: value too large for port\n",
2341 bindto);
2342 GNUNET_free (cp);
2343 return NULL;
2344 }
2345 }
2346 else
2347 {
2348 GNUNET_log (
2350 "BINDTO specification `%s' invalid: last ':' not followed by number\n",
2351 bindto);
2352 GNUNET_free (cp);
2353 return NULL;
2354 }
2355 }
2356 else
2357 {
2358 /* interpret missing port as 0, aka pick any free one */
2359 port = 0;
2360 }
2361 if (AF_INET6 != family)
2362 {
2363 /* try IPv4 */
2364 struct sockaddr_in v4;
2365
2366 memset (&v4, 0, sizeof(v4));
2367 if (1 == inet_pton (AF_INET, cp, &v4.sin_addr))
2368 {
2369 v4.sin_family = AF_INET;
2370 v4.sin_port = htons ((uint16_t) port);
2371#if HAVE_SOCKADDR_IN_SIN_LEN
2372 v4.sin_len = sizeof(struct sockaddr_in);
2373#endif
2374 in = GNUNET_memdup (&v4, sizeof(struct sockaddr_in));
2375 *sock_len = sizeof(struct sockaddr_in);
2376 GNUNET_free (cp);
2377 return in;
2378 }
2379 }
2380 if (AF_INET != family)
2381 {
2382 /* try IPv6 */
2383 struct sockaddr_in6 v6;
2384 const char *start;
2385
2386 memset (&v6, 0, sizeof(v6));
2387 start = cp;
2388 if (('[' == *cp) && (']' == cp[strlen (cp) - 1]))
2389 {
2390 start++; /* skip over '[' */
2391 cp[strlen (cp) - 1] = '\0'; /* eat ']' */
2392 }
2393 if (1 == inet_pton (AF_INET6, start, &v6.sin6_addr))
2394 {
2395 v6.sin6_family = AF_INET6;
2396 v6.sin6_port = htons ((uint16_t) port);
2397#if HAVE_SOCKADDR_IN_SIN_LEN
2398 v6.sin6_len = sizeof(struct sockaddr_in6);
2399#endif
2400 in = GNUNET_memdup (&v6, sizeof(v6));
2401 *sock_len = sizeof(v6);
2402 GNUNET_free (cp);
2403 return in;
2404 }
2405 }
2406 /* #5528 FIXME (feature!): maybe also try getnameinfo()? */
2407 GNUNET_free (cp);
2408 return NULL;
2409}

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

2584{
2585 struct sockaddr_storage sa;
2586 struct sockaddr_in *addr_verify;
2587 socklen_t salen = sizeof(sa);
2588 char buf[UINT16_MAX];
2589 ssize_t rcvd;
2590
2591 struct GNUNET_NETWORK_Handle *udp_sock = cls;
2592
2595 udp_sock,
2596 &sock_read,
2597 udp_sock);
2600 udp_sock,
2601 &sock_read,
2602 udp_sock);
2603 while (1)
2604 {
2606 buf,
2607 sizeof(buf),
2608 (struct sockaddr *) &sa,
2609 &salen);
2610 if (-1 == rcvd)
2611 {
2612 struct sockaddr *addr = (struct sockaddr*) &sa;
2613
2614 if (EAGAIN == errno)
2615 break; // We are done reading data
2617 "Failed to recv from %s family %d failed sock %p\n",
2618 GNUNET_a2s ((struct sockaddr*) &sa,
2619 salen),
2620 addr->sa_family,
2621 udp_sock);
2623 return;
2624 }
2626 "Read %llu bytes\n",
2627 (unsigned long long) rcvd);
2628 if (0 == rcvd)
2629 {
2630 GNUNET_break_op (0);
2632 "Read 0 bytes from UDP socket\n");
2633 return;
2634 }
2635
2636 /* first, see if it is a GNUNET_BurstMessage */
2637 if (rcvd == sizeof (struct GNUNET_BurstMessage))
2638 {
2639 struct GNUNET_BurstMessage *bm = (struct GNUNET_BurstMessage *) buf;
2640 struct sockaddr *addr = (struct sockaddr*) &sa;
2641 /* NOTE: @a salen, not `sizeof (*addr)' -- the latter is 16, which
2642 truncates an IPv6 source to the point where #GNUNET_a2s() renders
2643 "<invalid v6 address>" and #create_receiver() then fails to parse
2644 it, silently breaking burst NAT traversal over IPv6. */
2645 char *address = sockaddr_to_udpaddr_string (addr, salen);
2646
2647 if (0 != bm->local_port)
2648 {
2649 GNUNET_break_op (0);
2651 "Received a burst message on port %u\n",
2652 bm->local_port);
2653 return;
2654 }
2656 "Received a burst message for default port\n");
2657 create_receiver (&bm->peer,
2658 address,
2659 NULL);
2660 if (AF_INET6 == addr->sa_family)
2662 else
2666 return;
2667 }
2668 /* second, see if it is a UDPBox */
2669 if (rcvd > sizeof(struct UDPBox))
2670 {
2671 const struct UDPBox *box;
2672 struct KeyCacheEntry *kce;
2673
2674 box = (const struct UDPBox *) buf;
2676 if (NULL != kce)
2677 {
2679 "Found KCE with kid %s\n",
2680 GNUNET_sh2s (&box->kid));
2681 decrypt_box (box, (size_t) rcvd, kce);
2682 continue;
2683 }
2684 }
2685
2686 /* next, check if it is a broadcast */
2687 if (sizeof(struct UDPBroadcast) == rcvd)
2688 {
2689 const struct GNUNET_PeerIdentity *my_identity;
2690 const struct UDPBroadcast *ub;
2691 struct UdpBroadcastSignature uhs;
2692 struct GNUNET_PeerIdentity sender;
2693
2696
2697 addr_verify = GNUNET_memdup (&sa, salen);
2698 addr_verify->sin_port = 0;
2700 "received UDPBroadcast from %s\n",
2701 GNUNET_a2s ((const struct sockaddr *) addr_verify, salen));
2702 ub = (const struct UDPBroadcast *) buf;
2703 uhs.purpose.purpose = htonl (
2705 uhs.purpose.size = htonl (sizeof(uhs));
2706 uhs.sender = ub->sender;
2707 sender = ub->sender;
2708 if (0 == memcmp (&sender, my_identity, sizeof (struct
2710 {
2712 "Received our own broadcast\n");
2713 GNUNET_free (addr_verify);
2714 continue;
2715 }
2717 "checking UDPBroadcastSignature for %s\n",
2718 GNUNET_i2s (&sender));
2719 GNUNET_CRYPTO_hash ((struct sockaddr *) addr_verify, salen,
2720 &uhs.h_address);
2721 if (GNUNET_OK ==
2724 &uhs,
2725 &ub->sender_sig,
2726 &ub->sender.public_key))
2727 {
2728 char *addr_s;
2730
2731 addr_s =
2732 sockaddr_to_udpaddr_string ((const struct sockaddr *) &sa, salen);
2733 GNUNET_STATISTICS_update (stats, "# broadcasts received", 1, GNUNET_NO);
2734 /* use our own mechanism to determine network type */
2735 nt =
2736 GNUNET_NT_scanner_get_type (is, (const struct sockaddr *) &sa, salen);
2738 "validating address %s received from UDPBroadcast\n",
2739 GNUNET_i2s (&sender));
2741 GNUNET_free (addr_s);
2742 GNUNET_free (addr_verify);
2743 continue;
2744 }
2745 else
2746 {
2748 "VerifyingPeer %s is verifying UDPBroadcast\n",
2751 "Verifying UDPBroadcast from %s failed\n",
2752 GNUNET_i2s (&ub->sender));
2753 }
2754 GNUNET_free (addr_verify);
2755 /* continue with KX, mostly for statistics... */
2756 }
2757
2758
2759 /* finally, test if it is a KX */
2760 if (rcvd < sizeof(struct UDPConfirmation) + sizeof(struct InitialKX))
2761 {
2763 "# messages dropped (no kid, too small for KX)",
2764 1,
2765 GNUNET_NO);
2766 continue;
2767 }
2769 "Got KX\n");
2770 {
2771 const struct InitialKX *kx;
2772 struct SharedSecret *ss;
2773 char pbuf[rcvd - sizeof(struct InitialKX)];
2774 const struct UDPConfirmation *uc;
2775 struct SenderAddress *sender;
2776 int sender_is_new;
2777
2778 kx = (const struct InitialKX *) buf;
2781 "Before DEC\n");
2782
2783 if (GNUNET_OK != try_decrypt (ss,
2784 kx->gcm_tag,
2785 0,
2786 &buf[sizeof(*kx)],
2787 sizeof(pbuf),
2788 pbuf))
2789 {
2791 "Unable to decrypt tag, dropping...\n");
2792 GNUNET_free (ss);
2794 stats,
2795 "# messages dropped (no kid, AEAD decryption failed)",
2796 1,
2797 GNUNET_NO);
2798 continue;
2799 }
2801 "Before VERIFY\n");
2802
2803 uc = (const struct UDPConfirmation *) pbuf;
2804
2805 if (GNUNET_OK != verify_confirmation (&kx->enc, uc)) // TODO: need ephemeral instead of representative
2806 {
2807 GNUNET_break_op (0);
2808 GNUNET_free (ss);
2810 "# messages dropped (sender signature invalid)",
2811 1,
2812 GNUNET_NO);
2813 continue;
2814 }
2816 "Before SETUP_SENDER\n");
2817
2818 calculate_cmac (ss);
2819 sender = setup_sender (&uc->sender,
2820 (const struct sockaddr *) &sa,
2821 salen,
2822 &sender_is_new);
2823 ss->sender = sender;
2824 /* The signature in @a uc is verified, so we know who sent this.
2825 Only on a *new* sender: #setup_sender() is keyed on (address, peer),
2826 so this fires exactly once per source address per peer instead of on
2827 every KX datagram. A peer with no ACK credit left sends every
2828 message as a KX, and doing the string formatting plus the map lookup
2829 underneath #consider_reflexive_address() for each of those is pure
2830 waste -- and worse, it makes any address churn (a NAT rotating its
2831 mapping) add a transport queue per datagram.
2832
2833 Restricted to the shared sockets: #create_receiver() takes ownership
2834 of any socket handed to it (#receiver_destroy() closes it), so the
2835 per-receiver sockets the burst code hands out must not be passed on
2836 here, and replying from a socket other than the one the datagram
2837 arrived on would leave the peer's NAT mapping unused anyway. */
2838 if ((GNUNET_YES == sender_is_new) &&
2841 (const struct sockaddr *) &sa,
2842 salen);
2843 GNUNET_CONTAINER_DLL_insert (sender->ss_head, sender->ss_tail, ss);
2844 if ((KCN_THRESHOLD > ss->sender->acks_available) &&
2845 (NULL == ss->sender->kce_task) &&
2847 {
2848 // 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.
2852 ss);
2853 }
2854 sender->num_secrets++;
2855 GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
2857 "# messages decrypted without BOX",
2858 1,
2859 GNUNET_NO);
2860 try_handle_plaintext (sender, &uc[1], sizeof(pbuf) - sizeof(*uc));
2861 if (0 == purge_secrets (sender->ss_tail))
2862 {
2863 // No secret purged. Delete oldest.
2864 if (sender->num_secrets > MAX_SECRETS)
2865 {
2866 secret_destroy (sender->ss_tail);
2867 }
2868 }
2869 }
2870 }
2871}

References SenderAddress::acks_available, address, ah, calculate_cmac(), ch, consider_reflexive_address(), 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 2417 of file gnunet-communicator-udp.c.

2420{
2421 struct GNUNET_HashContext *hsh;
2422 struct ReceiverAddress *receiver;
2423 struct GNUNET_HashCode receiver_key;
2424 const char *path;
2425 struct sockaddr *in;
2426 socklen_t in_len;
2427
2428 if (0 != strncmp (address,
2430 strlen (COMMUNICATOR_ADDRESS_PREFIX "-")))
2431 {
2432 GNUNET_break_op (0);
2433 return GNUNET_SYSERR;
2434 }
2435 path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")];
2436 in = udp_address_to_sockaddr (path, AF_UNSPEC, &in_len);
2437
2438 if (NULL == in)
2439 {
2441 "Failed to setup UDP socket address\n");
2442 return GNUNET_SYSERR;
2443 }
2444 if ((AF_INET6 == in->sa_family) &&
2446 {
2448 "IPv6 disabled, skipping %s\n", address);
2449 GNUNET_free (in);
2450 return GNUNET_SYSERR;
2451 }
2452 else if (AF_INET == in->sa_family)
2453 {
2454 struct sockaddr_in *sin = (struct sockaddr_in *) in;
2455 if (0 == sin->sin_port)
2456 {
2457 GNUNET_free (in);
2458 return GNUNET_NO;
2459 }
2460 }
2461
2463 GNUNET_CRYPTO_hash_context_read (hsh, in, in_len);
2464 GNUNET_CRYPTO_hash_context_read (hsh, peer, sizeof(*peer));
2465 GNUNET_CRYPTO_hash_context_finish (hsh, &receiver_key);
2466
2468 if (NULL != receiver)
2469 {
2471 "receiver %s already exist or is being connected to\n",
2472 address);
2473 /* Only the new-receiver path below takes ownership of @a in. */
2474 GNUNET_free (in);
2475 return GNUNET_NO;
2476 }
2477
2479 receiver->udp_sock = udp_sock;
2480 receiver->key = receiver_key;
2481 receiver->address = in;
2482 receiver->address_len = in_len;
2483 receiver->target = *peer;
2484 eddsa_pub_to_hpke_key (&receiver->target.public_key,
2485 &receiver->target_hpke_key);
2486 receiver->nt = GNUNET_NT_scanner_get_type (is, in, in_len);
2488 receivers,
2489 &receiver->key,
2490 receiver,
2493 "Added %s to receivers with address %s and sock %p\n",
2494 GNUNET_i2s_full (&receiver->target),
2495 address,
2496 udp_sock);
2497 receiver->timeout =
2499 /* Give a fresh receiver a full window to produce its first ACK. */
2500 receiver->last_ack = GNUNET_TIME_absolute_get ();
2502 receiver,
2503 receiver->timeout.abs_value_us);
2505 "# receivers active",
2507 GNUNET_NO);
2508 receiver->foreign_addr =
2509 sockaddr_to_udpaddr_string (receiver->address, receiver->address_len);
2510 if (NULL != udp_sock)
2513 udp_sock,
2514 &sock_read,
2515 udp_sock);
2517 if (NULL == timeout_task)
2519 return GNUNET_OK;
2520}

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_absolute_get(), 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 consider_reflexive_address(), mq_init(), sock_read(), and udp_socket_notify().

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

◆ consider_reflexive_address()

static void consider_reflexive_address ( const struct GNUNET_PeerIdentity target,
const struct sockaddr *  address,
socklen_t  address_len 
)
static

Consider the address a datagram from target arrived from as a path we can send to.

The address a peer publishes is the address it believes it has. For a peer behind a NAT that is at best the mapping its NAT happened to have when GNUNET_NAT_register() last looked, and NAT mappings do not survive an idle period anywhere near GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT (Linux netfilter drops an unreplied UDP mapping after 30s, a replied one after 120s). Once it is dropped, the peer's next datagram very possibly gets a different external port, and the published address is dead for good – while we go on sending to it, because nothing here ever looked at where the peer's datagrams actually come from.

Its reflexive address, by contrast, is in every datagram it sends us, and is by construction a mapping that is open right now.

Only call this for a datagram that carried a valid UDPConfirmation signature, so that we know which peer sent it. That signature does not cover the source address, so a replayed datagram can still point us at an address the peer never used. That costs us only the handful of KX datagrams transport spends failing to validate the resulting queue: an address that cannot answer a challenge never becomes usable.

Parameters
targetpeer that authenticated itself to us
addressaddress the datagram was received from
address_lennumber of bytes in address

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

2555{
2556 char *addr_s;
2557
2558 addr_s = sockaddr_to_udpaddr_string (address, address_len);
2559 /* #create_receiver() is keyed by (address, peer), so this is a cheap
2560 no-op whenever the peer reached us from an address we already have. */
2561 if (GNUNET_OK == create_receiver (target, addr_s, NULL))
2562 {
2564 "Learned return path %s for peer `%s' from the source of an "
2565 "authenticated datagram\n",
2566 addr_s,
2567 GNUNET_i2s (target));
2569 "# receivers added (reflexive address)",
2570 1,
2571 GNUNET_NO);
2572 }
2573 GNUNET_free (addr_s);
2574}

References address, create_receiver(), GNUNET_ERROR_TYPE_INFO, GNUNET_free, GNUNET_i2s(), GNUNET_log, GNUNET_NO, GNUNET_OK, GNUNET_STATISTICS_update(), sockaddr_to_udpaddr_string(), and stats.

Referenced by sock_read().

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

2883{
2884 char pad[pad_size];
2885
2887 sizeof(pad));
2888 if (sizeof(pad) > sizeof(struct GNUNET_MessageHeader))
2889 {
2890 struct GNUNET_MessageHeader hdr =
2891 { .size = htons (sizeof(pad)),
2893
2894 memcpy (pad, &hdr, sizeof(hdr));
2895 }
2897 0 ==
2898 gcry_cipher_encrypt (out_cipher, dgram, sizeof(pad), pad, sizeof(pad)));
2899}

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

2906{
2907 const struct GNUNET_PeerIdentity *my_identity;
2909 uint16_t msize = ntohs (msg->size);
2910 struct UdpHandshakeSignature uhs;
2911 struct UDPConfirmation uc;
2912 struct InitialKX kx;
2913 char dgram[receiver->kx_mtu + sizeof(uc) + sizeof(kx)];
2914 size_t dpos;
2915 gcry_cipher_hd_t out_cipher;
2916 struct SharedSecret *ss;
2917
2921
2922 if (msize > receiver->kx_mtu)
2923 {
2924 GNUNET_break (0);
2925 if (GNUNET_YES != receiver->receiver_destroy_called)
2927 return;
2928 }
2930
2931 /* setup key material */
2933
2934 if (0 == purge_secrets (receiver->ss_tail))
2935 {
2936 // No secret purged. Delete oldest.
2937 if (receiver->num_secrets > MAX_SECRETS)
2938 {
2939 secret_destroy (receiver->ss_tail);
2940 }
2941 }
2942
2943 setup_cipher (&ss->master, 0, &out_cipher);
2944 /* compute 'uc' */
2945 uc.sender = *my_identity;
2946 uc.monotonic_time =
2948 uhs.purpose.purpose = htonl (
2950 uhs.purpose.size = htonl (sizeof(uhs));
2951 uhs.sender = *my_identity;
2952 uhs.receiver = receiver->target;
2953 uhs.monotonic_time = uc.monotonic_time;
2955 &uhs,
2956 &uc.sender_sig);
2957 /* Leave space for kx */
2958 dpos = sizeof(kx);
2959 /* Append encrypted uc to dgram */
2960 GNUNET_assert (0 == gcry_cipher_encrypt (out_cipher,
2961 &dgram[dpos],
2962 sizeof(uc),
2963 &uc,
2964 sizeof(uc)));
2965 dpos += sizeof(uc);
2966 /* Append encrypted payload to dgram */
2968 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], msize, msg, msize));
2969 dpos += msize;
2970 do_pad (out_cipher, &dgram[dpos], sizeof(dgram) - dpos);
2971 /* Datagram starts with kx */
2972 kx.enc = uhs.enc;
2974 0 == gcry_cipher_gettag (out_cipher, kx.gcm_tag, sizeof(kx.gcm_tag)));
2975 gcry_cipher_close (out_cipher);
2976 memcpy (dgram, &kx, sizeof(kx));
2978 dgram,
2979 sizeof(dgram),
2980 receiver->address,
2981 receiver->address_len))
2982 {
2985 "Sending KX with payload size %u to %s family %d failed sock %p\n",
2986 msize,
2987 GNUNET_a2s (receiver->address,
2988 receiver->address_len),
2989 receiver->address->sa_family,
2993 return;
2994 }
2996 "Sending KX with payload size %u to %s with socket %p\n",
2997 msize,
2998 GNUNET_a2s (receiver->address,
2999 receiver->address_len),
3002}

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

3017{
3018 struct ReceiverAddress *receiver = impl_state;
3019
3020 GNUNET_assert (mq == receiver->kx_mq);
3022 return; /* @a receiver has been freed */
3024}

References check_peer_alive(), GNUNET_assert, GNUNET_NO, 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 3028 of file gnunet-communicator-udp.c.

3030{
3031 struct SharedSecret *ss_rekey;
3032
3034 /* setup key material */
3035 ss_rekey = setup_shared_secret_ephemeral (&rekey->ephemeral,
3036 receiver);
3037 ss_rekey->sequence_allowed = 0;
3039 "Setup secret with k = %s\n",
3040 GNUNET_sh2s (&ss_rekey->master));
3042 "Setup secret with H(k) = %s\n",
3043 GNUNET_h2s (&(ss_rekey->cmac)));
3044
3045 /* Append encrypted payload to dgram */
3047 rekey->header.size = htons (sizeof (struct UDPRekey));
3048}

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

3063{
3064 struct ReceiverAddress *receiver = impl_state;
3065 struct UDPRekey rekey;
3066 struct SharedSecret *ss;
3067 int inject_rekey = GNUNET_NO;
3068 uint16_t msize = ntohs (msg->size);
3069
3070 GNUNET_assert (mq == receiver->d_mq);
3072 return; /* @a receiver has been freed */
3073 if (msize > receiver->d_mtu)
3074 {
3075 /* Transport handed us more than the MTU we advertised for this queue;
3076 that is a bug on its side and we cannot box it. */
3078 "msize: %u, mtu: %llu\n",
3079 (unsigned int) msize,
3080 (unsigned long long) receiver->d_mtu);
3081 GNUNET_break (0);
3082 if (GNUNET_YES != receiver->receiver_destroy_called)
3084 return;
3085 }
3086 if (0 == receiver->acks_available)
3087 {
3088 /* Out of ACK credit. This is NOT a protocol violation and must not cost
3089 us the connection. Transport's idea of our window can only ever drift
3090 *upwards*: #GNUNET_TRANSPORT_communicator_mq_update() takes an
3091 unsigned @a q_len that #handle_update_queue_message() *adds* to
3092 `q_capacity', so there is no way to hand credit back once
3093 #secret_destroy() reclaims a shared secret that still had unused
3094 sequence numbers -- which #purge_secrets() and the rekey path below do
3095 routinely. Given enough uptime the two counters therefore always
3096 diverge, and tearing the receiver down here turns that bookkeeping
3097 drift into a dropped link.
3098
3099 Fall back to KX instead, exactly as the tail of this function already
3100 does when it finds no usable shared secret. That also fixes itself:
3101 a KX makes the peer generate key cache entries and ACK them, which is
3102 what replenishes the credit. */
3104 "No ACKs available for %s, sending as KX\n",
3105 GNUNET_i2s (&receiver->target));
3107 "# messages sent via KX (no ACKs available)",
3108 1,
3109 GNUNET_NO);
3112 return;
3113 }
3115
3116 if (receiver->num_secrets > MAX_SECRETS)
3117 {
3118 if ((0 == purge_secrets (receiver->ss_tail)) &&
3119 (NULL != receiver->ss_tail))
3120 {
3121 // No secret purged. Delete oldest.
3122 secret_destroy (receiver->ss_tail);
3123 }
3124 }
3125 /* begin "BOX" encryption method, scan for ACKs from tail! */
3126 ss = receiver->ss_tail;
3127 while (NULL != ss)
3128 {
3129 size_t payload_len = sizeof(struct UDPBox) + receiver->d_mtu;
3131 "Considering SS %s sequence used: %u sequence allowed: %u bytes sent: %lu.\n",
3132 GNUNET_sh2s (&ss->master), ss->sequence_used,
3133 ss->sequence_allowed, ss->bytes_sent);
3134 if (ss->sequence_used >= ss->sequence_allowed)
3135 {
3136 // GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3137 // "Skipping ss because no acks to use.\n");
3138 ss = ss->prev;
3139 continue;
3140 }
3141 if (ss->bytes_sent >= rekey_max_bytes)
3142 {
3143 struct SharedSecret *ss_tmp;
3145 "Skipping ss because rekey bytes reached.\n");
3146 // FIXME cleanup ss with too many bytes sent!
3147 ss_tmp = ss->prev;
3148 secret_destroy (ss);
3149 ss = ss_tmp;
3150 continue;
3151 }
3152 if (ss->bytes_sent > rekey_max_bytes * 0.7)
3153 {
3154 if (ss->rekey_initiated == GNUNET_NO)
3155 {
3157 "Injecting rekey for ss with byte sent %lu\n",
3158 (unsigned long) ss->bytes_sent);
3159 create_rekey (receiver, ss, &rekey);
3161 payload_len += sizeof (rekey);
3163 }
3164 }
3165 if (0 < ss->sequence_used)
3167 "Trying to send UDPBox with shared secret %s sequence_used %u and ss->sequence_allowed %u\n",
3168 GNUNET_sh2s (&ss->master),
3169 ss->sequence_used,
3170 ss->sequence_allowed);
3171 {
3172 char dgram[payload_len];
3173 struct UDPBox *box;
3174 gcry_cipher_hd_t out_cipher;
3175 size_t dpos;
3176
3177 box = (struct UDPBox *) dgram;
3178 ss->sequence_used++;
3179 get_kid (&ss->master, ss->sequence_used, &box->kid);
3180 setup_cipher (&ss->master, ss->sequence_used, &out_cipher);
3181 /* Append encrypted payload to dgram */
3182 dpos = sizeof(struct UDPBox);
3183 if (GNUNET_YES == inject_rekey)
3184 {
3186 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], sizeof (rekey),
3187 &rekey, sizeof (rekey)));
3188 dpos += sizeof (rekey);
3189 }
3191 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], msize, msg, msize));
3192 dpos += msize;
3193 do_pad (out_cipher, &dgram[dpos], sizeof(dgram) - dpos);
3194 GNUNET_assert (0 == gcry_cipher_gettag (out_cipher,
3195 box->gcm_tag,
3196 sizeof(box->gcm_tag)));
3197 gcry_cipher_close (out_cipher);
3198
3200 dgram,
3201 payload_len, // FIXME why always send sizeof dgram?
3202 receiver->address,
3203 receiver->address_len))
3204 {
3207 "Sending UDPBox to %s family %d failed sock %p failed\n",
3208 GNUNET_a2s (receiver->address,
3209 receiver->address_len),
3210 receiver->address->sa_family,
3213 return;
3214 }
3216 "Sending UDPBox with payload size %u, %u acks left, %lu bytes sent with socket %p\n",
3217 msize,
3218 receiver->acks_available,
3219 (unsigned long) ss->bytes_sent,
3221 ss->bytes_sent += sizeof (dgram);
3222 receiver->acks_available--;
3224 return;
3225 }
3226 }
3228 "No suitable ss found, sending as KX...\n");
3230}

References SharedSecret::bytes_sent, check_peer_alive(), 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_i2s(), GNUNET_log, GNUNET_log_strerror, GNUNET_MQ_impl_send_continue(), GNUNET_NETWORK_socket_sendto(), GNUNET_NO, GNUNET_sh2s(), GNUNET_STATISTICS_update(), 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(), GNUNET_MessageHeader::size, and stats.

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

3243{
3244 struct ReceiverAddress *receiver = impl_state;
3246 "Default MQ destroyed\n");
3247 if (mq == receiver->d_mq)
3248 {
3249 receiver->d_mq = NULL;
3250 if (GNUNET_YES != receiver->receiver_destroy_called)
3252 }
3253}

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

3266{
3267 struct ReceiverAddress *receiver = impl_state;
3269 "KX MQ destroyed\n");
3270 if (mq == receiver->kx_mq)
3271 {
3272 receiver->kx_mq = NULL;
3273 if (GNUNET_YES != receiver->receiver_destroy_called)
3275 }
3276}

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

3287{
3288 /* Cancellation is impossible with UDP; bail */
3289 GNUNET_assert (0);
3290}

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

3304{
3305 struct ReceiverAddress *receiver = cls;
3306
3308 "MQ error in queue to %s: %d\n",
3309 GNUNET_i2s (&receiver->target),
3310 (int) error);
3312}

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

3405{
3406 (void) cls;
3408 "create receiver for mq_init\n");
3409 return create_receiver (peer,
3410 address,
3411 NULL);
3412}

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

3427{
3428 struct ReceiverAddress *receiver = value;
3429
3430 (void) cls;
3431 (void) target;
3433 return GNUNET_OK;
3434}

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

3449{
3450 struct SenderAddress *sender = value;
3451
3452 (void) cls;
3453 (void) target;
3454
3455
3456 sender_destroy (sender);
3457 return GNUNET_OK;
3458}

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

3468{
3470 "do_shutdown\n");
3471 GNUNET_stop_burst (NULL);
3472 if (NULL != nat)
3473 {
3475 nat = NULL;
3476 }
3477 while (NULL != bi_head)
3479 if (NULL != broadcast_task)
3480 {
3482 broadcast_task = NULL;
3483 }
3484 if (NULL != timeout_task)
3485 {
3487 timeout_task = NULL;
3488 }
3489 if (NULL != read_v6_task)
3490 {
3492 read_v6_task = NULL;
3493 }
3494 if (NULL != read_v4_task)
3495 {
3497 read_v4_task = NULL;
3498 }
3499 if (NULL != default_v6_sock)
3500 {
3503 default_v6_sock = NULL;
3504 }
3505 if (NULL != default_v4_sock)
3506 {
3509 default_v4_sock = NULL;
3510 }
3513 NULL);
3517 NULL);
3522 if (NULL != timeout_task)
3523 {
3525 timeout_task = NULL;
3526 }
3527 if (NULL != ch)
3528 {
3531 ch = NULL;
3532 }
3533 if (NULL != ah)
3534 {
3536 ah = NULL;
3537 }
3538 if (NULL != pils)
3539 {
3541 pils = NULL;
3542 }
3543 if (NULL != key_ring)
3544 {
3546 key_ring = NULL;
3547 }
3548 if (NULL != stats)
3549 {
3551 stats = NULL;
3552 }
3553 if (NULL != is)
3554 {
3556 is = NULL;
3557 }
3559 "do_shutdown finished\n");
3560}

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:

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

3576{
3577 struct AckInfo ai;
3578
3579 (void) cls;
3581 "Storing UDPAck received from backchannel from %s\n",
3584 (ntohs (msg->size) != sizeof(struct UDPAck)))
3585 {
3586 GNUNET_break_op (0);
3587 return;
3588 }
3589 ai.ack = (const struct UDPAck *) msg;
3590 ai.sender = sender;
3593 &ai);
3594}

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

3617{
3618 char *my_addr;
3620
3621 if (GNUNET_YES == add_remove)
3622 {
3624
3625 GNUNET_asprintf (&my_addr,
3626 "%s-%s",
3628 GNUNET_a2s (addr, addrlen));
3629 nt = GNUNET_NT_scanner_get_type (is, addr, addrlen);
3630 ai =
3632 my_addr,
3633 nt,
3635 GNUNET_free (my_addr);
3636 *app_ctx = ai;
3637 }
3638 else
3639 {
3640 ai = *app_ctx;
3642 *app_ctx = NULL;
3643 }
3644}

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

3654{
3655 struct BroadcastInterface *bi = cls;
3656 struct GNUNET_TIME_Relative delay;
3657
3658 delay = BROADCAST_FREQUENCY;
3659 delay.rel_value_us =
3660 GNUNET_CRYPTO_random_u64 (delay.rel_value_us);
3661 bi->broadcast_task =
3663
3664 switch (bi->sa->sa_family)
3665 {
3666 case AF_INET: {
3667 static int yes = 1;
3668 static int no = 0;
3669 ssize_t sent;
3670
3671 if (GNUNET_OK !=
3673 SOL_SOCKET,
3674 SO_BROADCAST,
3675 &yes,
3676 sizeof(int)))
3678 "setsockopt");
3680 "creating UDPBroadcast from %s\n",
3681 GNUNET_i2s (&(bi->bcm.sender)));
3683 "sending UDPBroadcast to add %s\n",
3684 GNUNET_a2s (bi->ba, bi->salen));
3686 &bi->bcm,
3687 sizeof(bi->bcm),
3688 bi->ba,
3689 bi->salen);
3690 if (-1 == sent)
3692 "sendto");
3694 SOL_SOCKET,
3695 SO_BROADCAST,
3696 &no,
3697 sizeof(int)))
3699 "setsockopt");
3700 break;
3701 }
3702
3703 case AF_INET6: {
3704 ssize_t sent;
3705 struct sockaddr_in6 dst;
3706
3707 dst.sin6_family = AF_INET6;
3708 dst.sin6_port = htons (my_port);
3709 dst.sin6_addr = bi->mcreq.ipv6mr_multiaddr;
3710 dst.sin6_scope_id = ((struct sockaddr_in6 *) bi->ba)->sin6_scope_id;
3711
3713 "sending UDPBroadcast\n");
3715 &bi->bcm,
3716 sizeof(bi->bcm),
3717 (const struct sockaddr *) &dst,
3718 sizeof(dst));
3719 if (-1 == sent)
3721 break;
3722 }
3723
3724 default:
3725 GNUNET_break (0);
3726 break;
3727 }
3728}

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

3753{
3754 const struct GNUNET_PeerIdentity *my_identity;
3756 struct BroadcastInterface *bi;
3757 enum GNUNET_NetworkType network;
3758 struct UdpBroadcastSignature ubs;
3759
3760 (void) cls;
3761 (void) netmask;
3762
3765
3766 if ((NULL == my_identity) || (NULL == my_private_key))
3767 return GNUNET_YES;
3768 if (NULL == addr)
3769 return GNUNET_YES; /* need to know our address! */
3770 network = GNUNET_NT_scanner_get_type (is, addr, addrlen);
3771 if (GNUNET_NT_LOOPBACK == network)
3772 {
3773 /* Broadcasting on loopback does not make sense */
3774 return GNUNET_YES;
3775 }
3776 for (bi = bi_head; NULL != bi; bi = bi->next)
3777 {
3778 if ((bi->salen == addrlen) && (0 == memcmp (addr, bi->sa, addrlen)))
3779 {
3780 bi->found = GNUNET_YES;
3781 return GNUNET_OK;
3782 }
3783 }
3784
3785 if ((AF_INET6 == addr->sa_family) && (NULL == broadcast_addr))
3786 return GNUNET_OK; /* broadcast_addr is required for IPv6! */
3787 if ((AF_INET6 == addr->sa_family) && (NULL == default_v6_sock))
3788 return GNUNET_OK; /* not using IPv6 */
3789
3790 bi = GNUNET_new (struct BroadcastInterface);
3791 bi->sa = GNUNET_memdup (addr,
3792 addrlen);
3793 if ( (NULL != broadcast_addr) &&
3794 (addrlen == sizeof (struct sockaddr_in)) )
3795 {
3796 struct sockaddr_in *ba;
3797
3798 ba = GNUNET_memdup (broadcast_addr,
3799 addrlen);
3800 ba->sin_port = htons (2086); /* always GNUnet port, ignore configuration! */
3801 bi->ba = (struct sockaddr *) ba;
3802 }
3803 bi->salen = addrlen;
3804 bi->found = GNUNET_YES;
3805 bi->bcm.sender = *my_identity;
3806 ubs.purpose.purpose = htonl (
3808 ubs.purpose.size = htonl (sizeof(ubs));
3809 ubs.sender = *my_identity;
3811 "creating UDPBroadcastSignature for %s\n",
3812 GNUNET_a2s (addr, addrlen));
3813 GNUNET_CRYPTO_hash (addr, addrlen, &ubs.h_address);
3815 &ubs,
3816 &bi->bcm.sender_sig);
3817 if (NULL != bi->ba)
3818 {
3821 }
3822 if ((AF_INET6 == addr->sa_family) && (NULL != broadcast_addr))
3823 {
3824 /* Create IPv6 multicast request */
3825 const struct sockaddr_in6 *s6 =
3826 (const struct sockaddr_in6 *) broadcast_addr;
3827
3829 1 == inet_pton (AF_INET6, "FF05::13B", &bi->mcreq.ipv6mr_multiaddr));
3830
3831 /* http://tools.ietf.org/html/rfc2553#section-5.2:
3832 *
3833 * IPV6_JOIN_GROUP
3834 *
3835 * Join a multicast group on a specified local interface. If the
3836 * interface index is specified as 0, the kernel chooses the local
3837 * interface. For example, some kernels look up the multicast
3838 * group in the normal IPv6 routing table and using the resulting
3839 * interface; we do this for each interface, so no need to use
3840 * zero (anymore...).
3841 */
3842 bi->mcreq.ipv6mr_interface = s6->sin6_scope_id;
3843
3844 /* Join the multicast group */
3846 IPPROTO_IPV6,
3847 IPV6_JOIN_GROUP,
3848 &bi->mcreq,
3849 sizeof(bi->mcreq)))
3850 {
3852 }
3853 }
3854 return GNUNET_OK;
3855}

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

3865{
3866 struct BroadcastInterface *bin;
3867
3868 (void) cls;
3869 for (struct BroadcastInterface *bi = bi_head; NULL != bi; bi = bi->next)
3870 bi->found = GNUNET_NO;
3872 for (struct BroadcastInterface *bi = bi_head; NULL != bi; bi = bin)
3873 {
3874 bin = bi->next;
3875 if (GNUNET_NO == bi->found)
3876 bi_destroy (bi);
3877 }
3879 &do_broadcast,
3880 NULL);
3881}

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

3888{
3889 /* FIXME: support reversal: #5529 */
3891 "No connection reversal implemented!\n");
3892}

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

3897{
3898 // FIXME: This sizeof application truncates IPv6 addresses!
3900 sizeof (*sock_info->actual_address
3901 ));
3902 create_receiver (sock_info->pid,
3903 address,
3904 default_v4_sock == sock_info->udp_sock ||
3905 default_v6_sock == sock_info->udp_sock ?
3906 NULL : sock_info->udp_sock);
3908 GNUNET_free (sock_info);
3909}

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

3916{
3917 struct GNUNET_UdpSocketInfo *sock_info;
3918
3920 "Communicator was called to start burst to address %s from %s\n",
3921 addr,
3922 my_ipv4);
3923
3924 GNUNET_stop_burst (NULL);
3925
3926 sock_info = GNUNET_new (struct GNUNET_UdpSocketInfo);
3927 sock_info->pid = GNUNET_new (struct GNUNET_PeerIdentity);
3928 sock_info->address = GNUNET_strdup (addr);
3929 sock_info->bind_address = my_ipv4;
3930 sock_info->has_port = GNUNET_YES;
3931 sock_info->udp_sock = default_v4_sock;
3932 sock_info->rtt = rtt;
3933 GNUNET_memcpy (sock_info->pid, pid, sizeof (struct GNUNET_PeerIdentity));
3934 sock_info->std_port = my_port;
3936 "1 sock addr %s addr %s rtt %lu %u\n",
3937 sock_info->address,
3938 addr,
3939 (unsigned long) sock_info->rtt.rel_value_us,
3940 my_port);
3941 burst_task = GNUNET_get_udp_socket (sock_info,
3943 GNUNET_free (sock_info);
3944}

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

3952{
3953 struct GNUNET_NETWORK_Handle *sock;
3954 struct sockaddr *in;
3955 socklen_t in_len;
3956 struct sockaddr_storage in_sto;
3957 socklen_t sto_len;
3958
3959 in = udp_address_to_sockaddr (bindto, family, &in_len);
3960 if (NULL == in)
3961 {
3963 "Failed to setup UDP socket address with path `%s'\n",
3964 bindto);
3965 return NULL;
3966 }
3967
3968 if ((AF_UNSPEC != family) && (in->sa_family != family))
3969 {
3971 "Invalid UDP socket address setup with path `%s'\n",
3972 bindto);
3973 GNUNET_free (in);
3974 return NULL;
3975 }
3976
3977 sock =
3978 GNUNET_NETWORK_socket_create (in->sa_family,
3979 SOCK_DGRAM,
3980 IPPROTO_UDP);
3981 if (NULL == sock)
3982 {
3985 "Failed to create socket for %s family %d\n",
3986 GNUNET_a2s (in,
3987 in_len),
3988 in->sa_family);
3989 GNUNET_free (in);
3990 return NULL;
3991 }
3992 if (GNUNET_OK !=
3994 in,
3995 in_len))
3996 {
3998 "bind",
3999 bindto);
4001 "Failed to bind socket for %s family %d sock %p\n",
4002 GNUNET_a2s (in,
4003 in_len),
4004 in->sa_family,
4005 sock);
4007 sock = NULL;
4008 GNUNET_free (in);
4009 return NULL;
4010 }
4011
4012 /* We might have bound to port 0, allowing the OS to figure it out;
4013 thus, get the real IN-address from the socket */
4014 sto_len = sizeof(in_sto);
4015 if (0 != getsockname (GNUNET_NETWORK_get_fd (sock),
4016 (struct sockaddr *) &in_sto,
4017 &sto_len))
4018 {
4019 memcpy (&in_sto, in, in_len);
4020 sto_len = in_len;
4021 }
4022 GNUNET_free (in);
4023 *out = GNUNET_malloc (sto_len);
4024 memcpy (*out, (struct sockaddr *) &in_sto, sto_len);
4025 *out_len = sto_len;
4026 return sock;
4027}

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

4032{
4033 if (NULL != addrs[0])
4034 GNUNET_free (addrs[0]);
4035 if (NULL != addrs[1])
4036 GNUNET_free (addrs[1]);
4038}

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

4046{
4047 const struct sockaddr_in *v4;
4048 char *bindto;
4049 char *bindto6;
4050 struct sockaddr *in[2];
4051 socklen_t in_len[2];
4052
4054 "Entering the run method of udp communicator.\n");
4055
4056 cfg = c;
4058 if ((GNUNET_NO == GNUNET_NETWORK_test_pf (PF_INET6)) ||
4059 (GNUNET_YES ==
4062 "DISABLE_V6")))
4063 {
4065 }
4066
4067 if (GNUNET_OK !=
4070 "BINDTO",
4071 &bindto))
4072 {
4075 "BINDTO");
4076 return;
4077 }
4079 "The udp communicator will bind to %s for IPv4\n",
4080 bindto);
4081 if (GNUNET_YES != disable_v6)
4082 {
4083 if (GNUNET_OK !=
4086 "BINDTO6",
4087 &bindto6))
4088 {
4091 "BINDTO6");
4092 return;
4093 }
4094
4096 "The udp communicator will bind to %s for IPv6\n",
4097 bindto6);
4098 }
4099 else
4100 bindto6 = NULL;
4101 if (GNUNET_OK !=
4104 "REKEY_INTERVAL",
4107
4108 if (GNUNET_OK !=
4111 "REKEY_MAX_BYTES",
4113 {
4115 }
4116
4117 memset (in, 0, sizeof(struct sockaddr*) * 2);
4118 memset (in_len, 0, sizeof(socklen_t) * 2);
4119
4120 GNUNET_assert (bindto);
4122 bindto, AF_INET, &(in[0]), &(in_len[0]));
4123 GNUNET_free (bindto);
4124
4125 if (GNUNET_YES != disable_v6)
4126 {
4127 GNUNET_assert (bindto6);
4129 bindto6, AF_INET6, &(in[1]), &(in_len[1]));
4130 GNUNET_free (bindto6);
4131 }
4132 else
4133 default_v6_sock = NULL;
4134
4135 if ((NULL == default_v4_sock) && (NULL == default_v6_sock))
4136 return;
4137
4138 my_port = 0;
4139 if (NULL != default_v4_sock)
4140 {
4141 GNUNET_assert (in[0]);
4143 "transport",
4144 "Bound to `%s' sock %p\n",
4145 GNUNET_a2s ((const struct sockaddr *) in[0],
4146 in_len[0]),
4148
4149 v4 = (const struct sockaddr_in *) in[0];
4150
4151 my_ipv4 = GNUNET_malloc (INET_ADDRSTRLEN);
4152 my_port = ntohs (((struct sockaddr_in *) in[0])->sin_port);
4153 inet_ntop (AF_INET, &v4->sin_addr, my_ipv4, in_len[0]);
4154 }
4155 if (NULL != default_v6_sock)
4156 {
4157 GNUNET_assert (in[1]);
4159 "transport",
4160 "Bound to `%s' sock %p\n",
4161 GNUNET_a2s ((const struct sockaddr *) in[1],
4162 in_len[1]),
4164 my_port = ntohs (((struct sockaddr_in6 *) in[1])->sin6_port);
4165 }
4166 stats = GNUNET_STATISTICS_create ("communicator-udp", cfg);
4175 /* start reading */
4176 if (NULL != default_v4_sock)
4179 &sock_read,
4181 else
4182 read_v4_task = NULL;
4183 if (NULL != default_v6_sock)
4186 &sock_read,
4188 else
4189 read_v6_task = NULL;
4194 &mq_init,
4195 NULL,
4197 NULL,
4198 &start_burst);
4199 if (NULL == ch)
4200 {
4201 GNUNET_break (0);
4202 shutdown_run (in);
4203 return;
4204 }
4206 if (NULL == ah)
4207 {
4208 GNUNET_break (0);
4209 shutdown_run (in);
4210 return;
4211 }
4212 /* start broadcasting */
4213 if (GNUNET_YES !=
4216 "DISABLE_BROADCAST"))
4217 {
4219 }
4221 GNUNET_assert (NULL != key_ring);
4222 pils = GNUNET_PILS_connect (cfg, NULL, NULL);
4223 GNUNET_assert (NULL != pils);
4224
4227 IPPROTO_UDP,
4228 (NULL != in[0]? 1 : 0)
4229 + (NULL != in[1]? 1 : 0),
4230 (const struct sockaddr**)
4231 (NULL != in[0]? in : &(in[1])),
4232 NULL != in[0]? in_len : &(in_len[1]),
4235 NULL /* closure */);
4236 if (NULL != in[0])
4237 GNUNET_free (in[0]);
4238 if (NULL != in[1])
4239 GNUNET_free (in[1]);
4240}

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 792 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 797 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 802 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 807 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 812 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 817 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 822 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 837 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 842 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 847 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 852 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 857 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 862 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 867 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 877 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 882 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 887 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 892 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 897 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 902 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 907 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 909 of file gnunet-communicator-udp.c.

Referenced by start_burst().