2 This file is part of GNUnet
3 Copyright (C) 2010-2014, 2018, 2019 GNUnet e.V.
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
18 SPDX-License-Identifier: AGPL3.0-or-later
22 * @file transport/gnunet-communicator-udp.c
23 * @brief Transport plugin using UDP.
24 * @author Christian Grothoff
27 * - consider imposing transmission limits in the absence
28 * of ACKs; or: maybe this should be done at TNG service level?
29 * (at least the receiver might want to enforce limits on
30 * KX/DH operations per sender in here) (#5552)
31 * - overall, we should look more into flow control support
32 * (either in backchannel, or general solution in TNG service)
33 * - handle addresses discovered from broadcasts (#5551)
34 * (think: what was the story again on address validation?
35 * where is the API for that!?!)
36 * - support DNS names in BINDTO option (#5528)
37 * - support NAT connection reversal method (#5529)
38 * - support other UDP-specific NAT traversal methods (#)
41 #include "gnunet_util_lib.h"
42 #include "gnunet_protocols.h"
43 #include "gnunet_signatures.h"
44 #include "gnunet_constants.h"
45 #include "gnunet_nt_lib.h"
46 #include "gnunet_nat_service.h"
47 #include "gnunet_statistics_service.h"
48 #include "gnunet_transport_application_service.h"
49 #include "gnunet_transport_communication_service.h"
52 * How often do we rekey based on time (at least)
54 #define REKEY_TIME_INTERVAL GNUNET_TIME_UNIT_DAYS
57 * How long do we wait until we must have received the initial KX?
59 #define PROTO_QUEUE_TIMEOUT GNUNET_TIME_UNIT_MINUTES
62 * How often do we broadcast our presence on the LAN?
64 #define BROADCAST_FREQUENCY GNUNET_TIME_UNIT_MINUTES
67 * How often do we scan for changes to our network interfaces?
69 #define INTERFACE_SCAN_FREQUENCY \
70 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)
73 * How long do we believe our addresses to remain up (before
74 * the other peer should revalidate).
76 #define ADDRESS_VALIDITY_PERIOD GNUNET_TIME_UNIT_HOURS
81 #define AES_KEY_SIZE (256 / 8)
86 #define AES_IV_SIZE (96 / 8)
89 * Size of the GCM tag.
91 #define GCM_TAG_SIZE (128 / 8)
94 * If we fall below this number of available KCNs,
95 * we generate additional ACKs until we reach
97 * Should be large enough that we don't generate ACKs all
98 * the time and still have enough time for the ACK to
99 * arrive before the sender runs out. So really this
100 * should ideally be based on the RTT.
102 #define KCN_THRESHOLD 92
105 * How many KCNs do we keep around *after* we hit
106 * the #KCN_THRESHOLD? Should be larger than
107 * #KCN_THRESHOLD so we do not generate just one
110 #define KCN_TARGET 128
113 * What is the maximum delta between KCN sequence numbers
114 * that we allow. Used to expire 'ancient' KCNs that likely
115 * were dropped by the network. Must be larger than
116 * KCN_TARGET (otherwise we generate new KCNs all the time),
117 * but not too large (otherwise packet loss may cause
118 * sender to fall back to KX needlessly when sender runs
119 * out of ACK'ed KCNs due to losses).
121 #define MAX_SQN_DELTA 160
124 * How many shared master secrets do we keep around
125 * at most per sender? Should be large enough so
126 * that we generally have a chance of sending an ACK
127 * before the sender already rotated out the master
128 * secret. Generally values around #KCN_TARGET make
129 * sense. Might make sense to adapt to RTT if we had
130 * a good measurement...
132 #define MAX_SECRETS 128
135 * How often do we rekey based on number of bytes transmitted?
136 * (additionally randomized).
138 #define REKEY_MAX_BYTES (1024LLU * 1024 * 1024 * 4LLU)
141 * Address prefix used by the communicator.
144 #define COMMUNICATOR_ADDRESS_PREFIX "udp"
147 * Configuration section used by the communicator.
149 #define COMMUNICATOR_CONFIG_SECTION "communicator-udp"
151 GNUNET_NETWORK_STRUCT_BEGIN
155 * Signature we use to verify that the ephemeral key was really chosen by
156 * the specified sender. If possible, the receiver should respond with
157 * a `struct UDPAck` (possibly via backchannel).
159 struct UdpHandshakeSignature
162 * Purpose must be #GNUNET_SIGNATURE_COMMUNICATOR_UDP_HANDSHAKE
164 struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
167 * Identity of the inititor of the UDP connection (UDP client).
169 struct GNUNET_PeerIdentity sender;
172 * Presumed identity of the target of the UDP connection (UDP server)
174 struct GNUNET_PeerIdentity receiver;
177 * Ephemeral key used by the @e sender.
179 struct GNUNET_CRYPTO_EcdhePublicKey ephemeral;
182 * Monotonic time of @e sender, to possibly help detect replay attacks
183 * (if receiver persists times by sender).
185 struct GNUNET_TIME_AbsoluteNBO monotonic_time;
190 * "Plaintext" header at beginning of KX message. Followed
191 * by encrypted `struct UDPConfirmation`.
196 * Ephemeral key for KX.
198 struct GNUNET_CRYPTO_EcdhePublicKey ephemeral;
201 * HMAC for the following encrypted message, using GCM. HMAC uses
202 * key derived from the handshake with sequence number zero.
204 char gcm_tag[GCM_TAG_SIZE];
209 * Encrypted continuation of UDP initial handshake, followed
210 * by message header with payload.
212 struct UDPConfirmation
217 struct GNUNET_PeerIdentity sender;
220 * Sender's signature of type #GNUNET_SIGNATURE_COMMUNICATOR_UDP_HANDSHAKE
222 struct GNUNET_CRYPTO_EddsaSignature sender_sig;
225 * Monotonic time of @e sender, to possibly help detect replay attacks
226 * (if receiver persists times by sender).
228 struct GNUNET_TIME_AbsoluteNBO monotonic_time;
230 /* followed by messages */
232 /* padding may follow actual messages */
237 * UDP key acknowledgement. May be sent via backchannel. Allows the
238 * sender to use `struct UDPBox` with the acknowledge key henceforth.
243 * Type is #GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK.
245 struct GNUNET_MessageHeader header;
248 * Sequence acknowledgement limit. Specifies current maximum sequence
249 * number supported by receiver.
251 uint32_t sequence_max GNUNET_PACKED;
254 * CMAC of the base key being acknowledged.
256 struct GNUNET_HashCode cmac;
261 * Signature we use to verify that the broadcast was really made by
262 * the peer that claims to have made it. Basically, affirms that the
263 * peer is really using this IP address (albeit possibly not in _our_
264 * LAN). Makes it difficult for peers in the LAN to claim to
265 * be just any global peer -- an attacker must have at least
266 * shared a LAN with the peer they're pretending to be here.
268 struct UdpBroadcastSignature
271 * Purpose must be #GNUNET_SIGNATURE_COMMUNICATOR_UDP_BROADCAST
273 struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
276 * Identity of the inititor of the UDP broadcast.
278 struct GNUNET_PeerIdentity sender;
281 * Hash of the sender's UDP address.
283 struct GNUNET_HashCode h_address;
288 * Broadcast by peer in LAN announcing its presence. Unusual in that
289 * we don't pad these to full MTU, as we cannot prevent being
290 * recognized in LAN as GNUnet peers if this feature is enabled
291 * anyway. Also, the entire message is in cleartext.
296 * Sender's peer identity.
298 struct GNUNET_PeerIdentity sender;
301 * Sender's signature of type
302 * #GNUNET_SIGNATURE_COMMUNICATOR_UDP_BROADCAST
304 struct GNUNET_CRYPTO_EddsaSignature sender_sig;
309 * UDP message box. Always sent encrypted, only allowed after
310 * the receiver sent a `struct UDPAck` for the base key!
315 * Key and IV identification code. KDF applied to an acknowledged
316 * base key and a sequence number. Sequence numbers must be used
317 * monotonically increasing up to the maximum specified in
318 * `struct UDPAck`. Without further `struct UDPAck`s, the sender
319 * must fall back to sending handshakes!
321 struct GNUNET_ShortHashCode kid;
324 * 128-bit authentication tag for the following encrypted message,
325 * from GCM. MAC starts at the @e body_start that follows and
326 * extends until the end of the UDP payload. If the @e hmac is
327 * wrong, the receiver should check if the message might be a
328 * `struct UdpHandshakeSignature`.
330 char gcm_tag[GCM_TAG_SIZE];
334 GNUNET_NETWORK_STRUCT_END
337 * Shared secret we generated for a particular sender or receiver.
343 * Pre-generated "kid" code (key and IV identification code) to
344 * quickly derive master key for a `struct UDPBox`.
351 struct KeyCacheEntry *next;
356 struct KeyCacheEntry *prev;
359 * Key and IV identification code. KDF applied to an acknowledged
360 * base key and a sequence number. Sequence numbers must be used
361 * monotonically increasing up to the maximum specified in
362 * `struct UDPAck`. Without further `struct UDPAck`s, the sender
363 * must fall back to sending handshakes!
365 struct GNUNET_ShortHashCode kid;
368 * Corresponding shared secret.
370 struct SharedSecret *ss;
373 * Sequence number used to derive this entry from master key.
375 uint32_t sequence_number;
380 * Information we track per sender address we have recently been
381 * in contact with (decryption from sender).
383 struct SenderAddress;
386 * Information we track per receiving address we have recently been
387 * in contact with (encryption to receiver).
389 struct ReceiverAddress;
392 * Shared secret we generated for a particular sender or receiver.
399 struct SharedSecret *next;
404 struct SharedSecret *prev;
407 * Kept in a DLL, sorted by sequence number. Only if we are decrypting.
409 struct KeyCacheEntry *kce_head;
412 * Kept in a DLL, sorted by sequence number. Only if we are decrypting.
414 struct KeyCacheEntry *kce_tail;
417 * Sender we use this shared secret with, or NULL.
419 struct SenderAddress *sender;
422 * Receiver we use this shared secret with, or NULL.
424 struct ReceiverAddress *receiver;
427 * Master shared secret.
429 struct GNUNET_HashCode master;
432 * CMAC is used to identify @e master in ACKs.
434 struct GNUNET_HashCode cmac;
437 * Up to which sequence number did we use this @e master already?
438 * (for encrypting only)
440 uint32_t sequence_used;
443 * Up to which sequence number did the other peer allow us to use
444 * this key, or up to which number did we allow the other peer to
447 uint32_t sequence_allowed;
450 * Number of active KCN entries.
452 unsigned int active_kce_count;
457 * Information we track per sender address we have recently been
458 * in contact with (we decrypt messages from the sender).
463 * To whom are we talking to.
465 struct GNUNET_PeerIdentity target;
468 * Entry in sender expiration heap.
470 struct GNUNET_CONTAINER_HeapNode *hn;
473 * Shared secrets we used with @e target, first used is head.
475 struct SharedSecret *ss_head;
478 * Shared secrets we used with @e target, last used is tail.
480 struct SharedSecret *ss_tail;
483 * Address of the other peer.
485 struct sockaddr *address;
488 * Length of the address.
490 socklen_t address_len;
493 * Timeout for this sender.
495 struct GNUNET_TIME_Absolute timeout;
498 * Length of the DLL at @a ss_head.
500 unsigned int num_secrets;
503 * Which network type does this queue use?
505 enum GNUNET_NetworkType nt;
510 * Information we track per receiving address we have recently been
511 * in contact with (encryption to receiver).
513 struct ReceiverAddress
516 * To whom are we talking to.
518 struct GNUNET_PeerIdentity target;
521 * Shared secrets we received from @e target, first used is head.
523 struct SharedSecret *ss_head;
526 * Shared secrets we received with @e target, last used is tail.
528 struct SharedSecret *ss_tail;
531 * Address of the receiver in the human-readable format
532 * with the #COMMUNICATOR_ADDRESS_PREFIX.
537 * Address of the other peer.
539 struct sockaddr *address;
542 * Length of the address.
544 socklen_t address_len;
547 * Entry in sender expiration heap.
549 struct GNUNET_CONTAINER_HeapNode *hn;
552 * Message queue we are providing for the #ch.
554 struct GNUNET_MQ_Handle *mq;
557 * handle for this queue with the #ch.
559 struct GNUNET_TRANSPORT_QueueHandle *qh;
562 * Timeout for this receiver address.
564 struct GNUNET_TIME_Absolute timeout;
567 * MTU we allowed transport for this receiver right now.
572 * Length of the DLL at @a ss_head.
574 unsigned int num_secrets;
577 * Number of BOX keys from ACKs we have currently
578 * available for this receiver.
580 unsigned int acks_available;
583 * Which network type does this queue use?
585 enum GNUNET_NetworkType nt;
590 * Interface we broadcast our presence on.
592 struct BroadcastInterface
597 struct BroadcastInterface *next;
602 struct BroadcastInterface *prev;
605 * Task for this broadcast interface.
607 struct GNUNET_SCHEDULER_Task *broadcast_task;
610 * Sender's address of the interface.
615 * Broadcast address to use on the interface.
620 * Message we broadcast on this interface.
622 struct UDPBroadcast bcm;
625 * If this is an IPv6 interface, this is the request
626 * we use to join/leave the group.
628 struct ipv6_mreq mcreq;
631 * Number of bytes in @e sa.
636 * Was this interface found in the last #iface_proc() scan?
643 * Cache of pre-generated key IDs.
645 static struct GNUNET_CONTAINER_MultiShortmap *key_cache;
650 static struct GNUNET_SCHEDULER_Task *read_task;
655 static struct GNUNET_SCHEDULER_Task *timeout_task;
658 * ID of master broadcast task
660 static struct GNUNET_SCHEDULER_Task *broadcast_task;
663 * For logging statistics.
665 static struct GNUNET_STATISTICS_Handle *stats;
670 static struct GNUNET_TRANSPORT_CommunicatorHandle *ch;
673 * Receivers (map from peer identity to `struct ReceiverAddress`)
675 static struct GNUNET_CONTAINER_MultiPeerMap *receivers;
678 * Senders (map from peer identity to `struct SenderAddress`)
680 static struct GNUNET_CONTAINER_MultiPeerMap *senders;
683 * Expiration heap for senders (contains `struct SenderAddress`)
685 static struct GNUNET_CONTAINER_Heap *senders_heap;
688 * Expiration heap for receivers (contains `struct ReceiverAddress`)
690 static struct GNUNET_CONTAINER_Heap *receivers_heap;
693 * Broadcast interface tasks. Kept in a DLL.
695 static struct BroadcastInterface *bi_head;
698 * Broadcast interface tasks. Kept in a DLL.
700 static struct BroadcastInterface *bi_tail;
705 static struct GNUNET_NETWORK_Handle *udp_sock;
708 * #GNUNET_YES if #udp_sock supports IPv6.
710 static int have_v6_socket;
715 static struct GNUNET_PeerIdentity my_identity;
720 static struct GNUNET_CRYPTO_EddsaPrivateKey *my_private_key;
725 static const struct GNUNET_CONFIGURATION_Handle *cfg;
728 * Our handle to report addresses for validation to TRANSPORT.
730 static struct GNUNET_TRANSPORT_ApplicationHandle *ah;
733 * Network scanner to determine network types.
735 static struct GNUNET_NT_InterfaceScanner *is;
738 * Connection to NAT service.
740 static struct GNUNET_NAT_Handle *nat;
743 * Port number to which we are actually bound.
745 static uint16_t my_port;
749 * An interface went away, stop broadcasting on it.
751 * @param bi entity to close down
754 bi_destroy (struct BroadcastInterface *bi)
756 if (AF_INET6 == bi->sa->sa_family)
758 /* Leave the multicast group */
759 if (GNUNET_OK != GNUNET_NETWORK_socket_setsockopt (udp_sock,
765 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "setsockopt");
768 GNUNET_CONTAINER_DLL_remove (bi_head, bi_tail, bi);
769 GNUNET_SCHEDULER_cancel (bi->broadcast_task);
770 GNUNET_free (bi->sa);
771 GNUNET_free_non_null (bi->ba);
777 * Destroys a receiving state due to timeout or shutdown.
779 * @param receiver entity to close down
782 receiver_destroy (struct ReceiverAddress *receiver)
784 struct GNUNET_MQ_Handle *mq;
786 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
787 "Disconnecting receiver for peer `%s'\n",
788 GNUNET_i2s (&receiver->target));
789 if (NULL != (mq = receiver->mq))
792 GNUNET_MQ_destroy (mq);
794 if (NULL != receiver->qh)
796 GNUNET_TRANSPORT_communicator_mq_del (receiver->qh);
799 GNUNET_assert (GNUNET_YES ==
800 GNUNET_CONTAINER_multipeermap_remove (receivers,
803 GNUNET_assert (receiver == GNUNET_CONTAINER_heap_remove_node (receiver->hn));
804 GNUNET_STATISTICS_set (stats,
805 "# receivers active",
806 GNUNET_CONTAINER_multipeermap_size (receivers),
808 GNUNET_free (receiver->address);
809 GNUNET_free (receiver->foreign_addr);
810 GNUNET_free (receiver);
815 * Free memory used by key cache entry.
817 * @param kce the key cache entry
820 kce_destroy (struct KeyCacheEntry *kce)
822 struct SharedSecret *ss = kce->ss;
824 ss->active_kce_count--;
825 GNUNET_CONTAINER_DLL_remove (ss->kce_head, ss->kce_tail, kce);
826 GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multishortmap_remove (key_cache,
836 * @param msec master secret for HMAC calculation
837 * @param serial number for the @a smac calculation
838 * @param kid[out] where to write the key ID
841 get_kid (const struct GNUNET_HashCode *msec,
843 struct GNUNET_ShortHashCode *kid)
845 uint32_t sid = htonl (serial);
847 GNUNET_CRYPTO_hkdf (kid,
863 * Setup key cache entry for sequence number @a seq and shared secret @a ss.
865 * @param ss shared secret
866 * @param seq sequence number for the key cache entry
869 kce_generate (struct SharedSecret *ss, uint32_t seq)
871 struct KeyCacheEntry *kce;
873 GNUNET_assert (0 < seq);
874 kce = GNUNET_new (struct KeyCacheEntry);
876 kce->sequence_number = seq;
877 get_kid (&ss->master, seq, &kce->kid);
878 GNUNET_CONTAINER_DLL_insert (ss->kce_head, ss->kce_tail, kce);
879 ss->active_kce_count++;
880 (void) GNUNET_CONTAINER_multishortmap_put (
884 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
885 GNUNET_STATISTICS_set (stats,
887 GNUNET_CONTAINER_multishortmap_size (key_cache),
893 * Destroy @a ss and associated key cache entries.
895 * @param ss shared secret to destroy
898 secret_destroy (struct SharedSecret *ss)
900 struct SenderAddress *sender;
901 struct ReceiverAddress *receiver;
902 struct KeyCacheEntry *kce;
904 if (NULL != (sender = ss->sender))
906 GNUNET_CONTAINER_DLL_remove (sender->ss_head, sender->ss_tail, ss);
907 sender->num_secrets--;
909 if (NULL != (receiver = ss->receiver))
911 GNUNET_CONTAINER_DLL_remove (receiver->ss_head, receiver->ss_tail, ss);
912 receiver->num_secrets--;
913 receiver->acks_available -= (ss->sequence_allowed - ss->sequence_used);
915 while (NULL != (kce = ss->kce_head))
917 GNUNET_STATISTICS_update (stats, "# Secrets active", -1, GNUNET_NO);
918 GNUNET_STATISTICS_set (stats,
920 GNUNET_CONTAINER_multishortmap_size (key_cache),
927 * Functions with this signature are called whenever we need
928 * to close a sender's state due to timeout.
930 * @param sender entity to close down
933 sender_destroy (struct SenderAddress *sender)
937 GNUNET_CONTAINER_multipeermap_remove (senders, &sender->target, sender));
938 GNUNET_assert (sender == GNUNET_CONTAINER_heap_remove_node (sender->hn));
939 GNUNET_STATISTICS_set (stats,
941 GNUNET_CONTAINER_multipeermap_size (senders),
943 GNUNET_free (sender->address);
944 GNUNET_free (sender);
949 * Compute @a key and @a iv.
951 * @param msec master secret for calculation
952 * @param serial number for the @a smac calculation
953 * @param key[out] where to write the decrption key
954 * @param iv[out] where to write the IV
957 get_iv_key (const struct GNUNET_HashCode *msec,
959 char key[AES_KEY_SIZE],
960 char iv[AES_IV_SIZE])
962 uint32_t sid = htonl (serial);
963 char res[AES_KEY_SIZE + AES_IV_SIZE];
965 GNUNET_CRYPTO_hkdf (res,
974 strlen ("UDP-IV-KEY"),
977 memcpy (key, res, AES_KEY_SIZE);
978 memcpy (iv, &res[AES_KEY_SIZE], AES_IV_SIZE);
983 * Increment sender timeout due to activity.
985 * @param sender address for which the timeout should be rescheduled
988 reschedule_sender_timeout (struct SenderAddress *sender)
991 GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
992 GNUNET_CONTAINER_heap_update_cost (sender->hn, sender->timeout.abs_value_us);
997 * Increment receiver timeout due to activity.
999 * @param receiver address for which the timeout should be rescheduled
1002 reschedule_receiver_timeout (struct ReceiverAddress *receiver)
1005 GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
1006 GNUNET_CONTAINER_heap_update_cost (receiver->hn,
1007 receiver->timeout.abs_value_us);
1012 * Task run to check #receiver_heap and #sender_heap for timeouts.
1014 * @param cls unused, NULL
1017 check_timeouts (void *cls)
1019 struct GNUNET_TIME_Relative st;
1020 struct GNUNET_TIME_Relative rt;
1021 struct GNUNET_TIME_Relative delay;
1022 struct ReceiverAddress *receiver;
1023 struct SenderAddress *sender;
1026 timeout_task = NULL;
1027 rt = GNUNET_TIME_UNIT_FOREVER_REL;
1028 while (NULL != (receiver = GNUNET_CONTAINER_heap_peek (receivers_heap)))
1030 rt = GNUNET_TIME_absolute_get_remaining (receiver->timeout);
1031 if (0 != rt.rel_value_us)
1033 receiver_destroy (receiver);
1035 st = GNUNET_TIME_UNIT_FOREVER_REL;
1036 while (NULL != (sender = GNUNET_CONTAINER_heap_peek (senders_heap)))
1038 st = GNUNET_TIME_absolute_get_remaining (sender->timeout);
1039 if (0 != st.rel_value_us)
1041 sender_destroy (sender);
1043 delay = GNUNET_TIME_relative_min (rt, st);
1044 if (delay.rel_value_us < GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
1045 timeout_task = GNUNET_SCHEDULER_add_delayed (delay, &check_timeouts, NULL);
1050 * Calcualte cmac from master in @a ss.
1052 * @param ss[in,out] data structure to complete
1055 calculate_cmac (struct SharedSecret *ss)
1057 GNUNET_CRYPTO_hkdf (&ss->cmac,
1066 strlen ("UDP-CMAC"),
1073 * We received @a plaintext_len bytes of @a plaintext from a @a sender.
1074 * Pass it on to CORE.
1076 * @param queue the queue that received the plaintext
1077 * @param plaintext the plaintext that was received
1078 * @param plaintext_len number of bytes of plaintext received
1081 pass_plaintext_to_core (struct SenderAddress *sender,
1082 const void *plaintext,
1083 size_t plaintext_len)
1085 const struct GNUNET_MessageHeader *hdr = plaintext;
1086 const char *pos = plaintext;
1088 while (ntohs (hdr->size) < plaintext_len)
1090 GNUNET_STATISTICS_update (stats,
1091 "# bytes given to core",
1094 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1095 "Giving %u bytes to TNG\n", ntohs (hdr->size));
1096 GNUNET_assert (GNUNET_SYSERR !=
1097 GNUNET_TRANSPORT_communicator_receive (ch,
1100 ADDRESS_VALIDITY_PERIOD,
1101 NULL /* no flow control possible */
1104 /* move on to next message, if any */
1105 plaintext_len -= ntohs (hdr->size);
1106 if (plaintext_len < sizeof(*hdr))
1108 pos += ntohs (hdr->size);
1109 hdr = (const struct GNUNET_MessageHeader *) pos;
1110 // TODO for now..., we do not actually sen >1msg or have a way of telling
1114 GNUNET_STATISTICS_update (stats,
1115 "# bytes padding discarded",
1122 * Setup @a cipher based on shared secret @a msec and
1123 * serial number @a serial.
1125 * @param msec master shared secret
1126 * @param serial serial number of cipher to set up
1127 * @param cipher[out] cipher to initialize
1130 setup_cipher (const struct GNUNET_HashCode *msec,
1132 gcry_cipher_hd_t *cipher)
1134 char key[AES_KEY_SIZE];
1135 char iv[AES_IV_SIZE];
1139 gcry_cipher_open (cipher,
1140 GCRY_CIPHER_AES256 /* low level: go for speed */,
1141 GCRY_CIPHER_MODE_GCM,
1143 get_iv_key (msec, serial, key, iv);
1144 rc = gcry_cipher_setkey (*cipher, key, sizeof(key));
1145 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
1146 rc = gcry_cipher_setiv (*cipher, iv, sizeof(iv));
1147 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
1152 * Try to decrypt @a buf using shared secret @a ss and key/iv
1153 * derived using @a serial.
1155 * @param ss shared secret
1156 * @param tag GCM authentication tag
1157 * @param serial serial number to use
1158 * @param in_buf input buffer to decrypt
1159 * @param in_buf_size number of bytes in @a in_buf and available in @a out_buf
1160 * @param out_buf where to write the result
1161 * @return #GNUNET_OK on success
1164 try_decrypt (const struct SharedSecret *ss,
1165 const char tag[GCM_TAG_SIZE],
1171 gcry_cipher_hd_t cipher;
1173 setup_cipher (&ss->master, serial, &cipher);
1176 gcry_cipher_decrypt (cipher, out_buf, in_buf_size, in_buf, in_buf_size));
1177 if (0 != gcry_cipher_checktag (cipher, tag, GCM_TAG_SIZE))
1179 gcry_cipher_close (cipher);
1180 GNUNET_STATISTICS_update (stats,
1181 "# AEAD authentication failures",
1184 return GNUNET_SYSERR;
1186 gcry_cipher_close (cipher);
1192 * Setup shared secret for decryption.
1194 * @param ephemeral ephemeral key we received from the other peer
1195 * @return new shared secret
1197 static struct SharedSecret *
1198 setup_shared_secret_dec (const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral)
1200 struct SharedSecret *ss;
1202 ss = GNUNET_new (struct SharedSecret);
1203 GNUNET_CRYPTO_eddsa_ecdh (my_private_key, ephemeral, &ss->master);
1209 * Setup shared secret for encryption.
1211 * @param ephemeral ephemeral key we are sending to the other peer
1212 * @param receiver[in,out] queue to initialize encryption key for
1213 * @return new shared secret
1215 static struct SharedSecret *
1216 setup_shared_secret_enc (const struct GNUNET_CRYPTO_EcdhePrivateKey *ephemeral,
1217 struct ReceiverAddress *receiver)
1219 struct SharedSecret *ss;
1221 ss = GNUNET_new (struct SharedSecret);
1222 GNUNET_CRYPTO_ecdh_eddsa (ephemeral,
1223 &receiver->target.public_key,
1225 calculate_cmac (ss);
1226 ss->receiver = receiver;
1227 GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss);
1228 receiver->num_secrets++;
1229 GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
1235 * Setup the MQ for the @a receiver. If a queue exists,
1236 * the existing one is destroyed. Then the MTU is
1237 * recalculated and a fresh queue is initialized.
1239 * @param receiver receiver to setup MQ for
1242 setup_receiver_mq (struct ReceiverAddress *receiver);
1246 * We received an ACK for @a pid. Check if it is for
1247 * the receiver in @a value and if so, handle it and
1248 * return #GNUNET_NO. Otherwise, return #GNUNET_YES.
1250 * @param cls a `const struct UDPAck`
1251 * @param pid peer the ACK is from
1252 * @param value a `struct ReceiverAddress`
1253 * @return #GNUNET_YES to continue to iterate
1256 handle_ack (void *cls, const struct GNUNET_PeerIdentity *pid, void *value)
1258 const struct UDPAck *ack = cls;
1259 struct ReceiverAddress *receiver = value;
1262 for (struct SharedSecret *ss = receiver->ss_head; NULL != ss; ss = ss->next)
1264 if (0 == memcmp (&ack->cmac, &ss->cmac, sizeof(struct GNUNET_HashCode)))
1268 allowed = ntohl (ack->sequence_max);
1270 if (allowed > ss->sequence_allowed)
1272 receiver->acks_available += (allowed - ss->sequence_allowed);
1273 if ((allowed - ss->sequence_allowed) == receiver->acks_available)
1275 /* we just incremented from zero => MTU change! */
1276 setup_receiver_mq (receiver);
1278 ss->sequence_allowed = allowed;
1279 /* move ss to head to avoid discarding it anytime soon! */
1280 GNUNET_CONTAINER_DLL_remove (receiver->ss_head, receiver->ss_tail, ss);
1281 GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss);
1291 * Test if we have received a valid message in plaintext.
1294 * @param sender peer to process inbound plaintext for
1295 * @param buf buffer we received
1296 * @param buf_size number of bytes in @a buf
1299 try_handle_plaintext (struct SenderAddress *sender,
1303 const struct GNUNET_MessageHeader *hdr =
1304 (const struct GNUNET_MessageHeader *) buf;
1305 const struct UDPAck *ack = (const struct UDPAck *) buf;
1308 if (sizeof(*hdr) > buf_size)
1309 return; /* not even a header */
1310 if (ntohs (hdr->size) > buf_size)
1311 return; /* not even a header */
1312 type = ntohs (hdr->type);
1315 case GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK:
1316 /* lookup master secret by 'cmac', then update sequence_max */
1317 GNUNET_CONTAINER_multipeermap_get_multiple (receivers,
1321 /* There could be more messages after the ACK, handle those as well */
1322 buf += ntohs (hdr->size);
1323 buf_size -= ntohs (hdr->size);
1324 pass_plaintext_to_core (sender, buf, buf_size);
1327 case GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_PAD:
1332 pass_plaintext_to_core (sender, buf, buf_size);
1338 * We established a shared secret with a sender. We should try to send
1339 * the sender an `struct UDPAck` at the next opportunity to allow the
1340 * sender to use @a ss longer (assuming we did not yet already
1343 * @param ss shared secret to generate ACKs for
1346 consider_ss_ack (struct SharedSecret *ss)
1348 GNUNET_assert (NULL != ss->sender);
1349 /* drop ancient KeyCacheEntries */
1350 while ((NULL != ss->kce_head) &&
1352 ss->kce_head->sequence_number - ss->kce_tail->sequence_number))
1353 kce_destroy (ss->kce_tail);
1354 if (ss->active_kce_count < KCN_THRESHOLD)
1358 while (ss->active_kce_count < KCN_TARGET)
1359 kce_generate (ss, ++ss->sequence_allowed);
1360 ack.header.type = htons (GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK);
1361 ack.header.size = htons (sizeof(ack));
1362 ack.sequence_max = htonl (ss->sequence_allowed);
1363 ack.cmac = ss->cmac;
1364 GNUNET_TRANSPORT_communicator_notify (ch,
1365 &ss->sender->target,
1366 COMMUNICATOR_ADDRESS_PREFIX,
1373 * We received a @a box with matching @a kce. Decrypt and process it.
1375 * @param box the data we received
1376 * @param box_len number of bytes in @a box
1377 * @param kce key index to decrypt @a box
1380 decrypt_box (const struct UDPBox *box,
1382 struct KeyCacheEntry *kce)
1384 struct SharedSecret *ss = kce->ss;
1385 char out_buf[box_len - sizeof(*box)];
1387 GNUNET_assert (NULL != ss->sender);
1388 if (GNUNET_OK != try_decrypt (ss,
1390 kce->sequence_number,
1391 (const char *) &box[1],
1395 GNUNET_STATISTICS_update (stats,
1396 "# Decryption failures with valid KCE",
1403 GNUNET_STATISTICS_update (stats,
1404 "# bytes decrypted with BOX",
1407 try_handle_plaintext (ss->sender, out_buf, sizeof(out_buf));
1408 consider_ss_ack (ss);
1413 * Closure for #find_sender_by_address()
1415 struct SearchContext
1418 * Address we are looking for.
1420 const struct sockaddr *address;
1423 * Number of bytes in @e address.
1425 socklen_t address_len;
1428 * Return value to set if we found a match.
1430 struct SenderAddress *sender;
1435 * Find existing `struct SenderAddress` by matching addresses.
1437 * @param cls a `struct SearchContext`
1438 * @param key ignored, must match already
1439 * @param value a `struct SenderAddress`
1440 * @return #GNUNET_YES if not found (continue to search), #GNUNET_NO if found
1443 find_sender_by_address (void *cls,
1444 const struct GNUNET_PeerIdentity *key,
1447 struct SearchContext *sc = cls;
1448 struct SenderAddress *sender = value;
1450 if ((sender->address_len == sc->address_len) &&
1451 (0 == memcmp (sender->address, sc->address, sender->address_len)))
1453 sc->sender = sender;
1454 return GNUNET_NO; /* stop iterating! */
1461 * Create sender address for @a target. Note that we
1462 * might already have one, so a fresh one is only allocated
1463 * if one does not yet exist for @a address.
1465 * @param target peer to generate address for
1466 * @param address target address
1467 * @param address_len number of bytes in @a address
1468 * @return data structure to keep track of key material for
1469 * decrypting data from @a target
1471 static struct SenderAddress *
1472 setup_sender (const struct GNUNET_PeerIdentity *target,
1473 const struct sockaddr *address,
1474 socklen_t address_len)
1476 struct SenderAddress *sender;
1477 struct SearchContext sc = { .address = address,
1478 .address_len = address_len,
1481 GNUNET_CONTAINER_multipeermap_get_multiple (senders,
1483 &find_sender_by_address,
1485 if (NULL != sc.sender)
1487 reschedule_sender_timeout (sc.sender);
1490 sender = GNUNET_new (struct SenderAddress);
1491 sender->target = *target;
1492 sender->address = GNUNET_memdup (address, address_len);
1493 sender->address_len = address_len;
1494 (void) GNUNET_CONTAINER_multipeermap_put (
1498 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
1499 GNUNET_STATISTICS_set (stats,
1501 GNUNET_CONTAINER_multipeermap_size (receivers),
1504 GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
1505 sender->hn = GNUNET_CONTAINER_heap_insert (senders_heap,
1507 sender->timeout.abs_value_us);
1508 sender->nt = GNUNET_NT_scanner_get_type (is, address, address_len);
1509 if (NULL == timeout_task)
1510 timeout_task = GNUNET_SCHEDULER_add_now (&check_timeouts, NULL);
1516 * Check signature from @a uc against @a ephemeral.
1518 * @param ephermal key that is signed
1519 * @param uc signature of claimant
1520 * @return #GNUNET_OK if signature is valid
1523 verify_confirmation (const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral,
1524 const struct UDPConfirmation *uc)
1526 struct UdpHandshakeSignature uhs;
1528 uhs.purpose.purpose = htonl (GNUNET_SIGNATURE_COMMUNICATOR_UDP_HANDSHAKE);
1529 uhs.purpose.size = htonl (sizeof(uhs));
1530 uhs.sender = uc->sender;
1531 uhs.receiver = my_identity;
1532 uhs.ephemeral = *ephemeral;
1533 uhs.monotonic_time = uc->monotonic_time;
1534 return GNUNET_CRYPTO_eddsa_verify (
1535 GNUNET_SIGNATURE_COMMUNICATOR_UDP_HANDSHAKE,
1538 &uc->sender.public_key);
1543 * Converts @a address to the address string format used by this
1544 * communicator in HELLOs.
1546 * @param address the address to convert, must be AF_INET or AF_INET6.
1547 * @param address_len number of bytes in @a address
1548 * @return string representation of @a address
1551 sockaddr_to_udpaddr_string (const struct sockaddr *address,
1552 socklen_t address_len)
1556 switch (address->sa_family)
1559 GNUNET_asprintf (&ret,
1561 COMMUNICATOR_ADDRESS_PREFIX,
1562 GNUNET_a2s (address, address_len));
1566 GNUNET_asprintf (&ret,
1568 COMMUNICATOR_ADDRESS_PREFIX,
1569 GNUNET_a2s (address, address_len));
1585 sock_read (void *cls)
1587 struct sockaddr_storage sa;
1588 socklen_t salen = sizeof(sa);
1589 char buf[UINT16_MAX];
1593 read_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
1597 rcvd = GNUNET_NETWORK_socket_recvfrom (udp_sock,
1600 (struct sockaddr *) &sa,
1604 GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG, "recv");
1607 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1608 "Read %lu bytes\n", rcvd);
1609 /* first, see if it is a UDPBox */
1610 if (rcvd > sizeof(struct UDPBox))
1612 const struct UDPBox *box;
1613 struct KeyCacheEntry *kce;
1615 box = (const struct UDPBox *) buf;
1616 kce = GNUNET_CONTAINER_multishortmap_get (key_cache, &box->kid);
1619 decrypt_box (box, (size_t) rcvd, kce);
1624 /* next, check if it is a broadcast */
1625 if (sizeof(struct UDPBroadcast) == rcvd)
1627 const struct UDPBroadcast *ub;
1628 struct UdpBroadcastSignature uhs;
1630 ub = (const struct UDPBroadcast *) buf;
1631 uhs.purpose.purpose = htonl (GNUNET_SIGNATURE_COMMUNICATOR_UDP_BROADCAST);
1632 uhs.purpose.size = htonl (sizeof(uhs));
1633 uhs.sender = ub->sender;
1634 GNUNET_CRYPTO_hash (&sa, salen, &uhs.h_address);
1636 GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_COMMUNICATOR_UDP_BROADCAST,
1639 &ub->sender.public_key))
1642 enum GNUNET_NetworkType nt;
1645 sockaddr_to_udpaddr_string ((const struct sockaddr *) &sa, salen);
1646 GNUNET_STATISTICS_update (stats, "# broadcasts received", 1, GNUNET_NO);
1647 /* use our own mechanism to determine network type */
1649 GNUNET_NT_scanner_get_type (is, (const struct sockaddr *) &sa, salen);
1650 GNUNET_TRANSPORT_application_validate (ah, &ub->sender, nt, addr_s);
1651 GNUNET_free (addr_s);
1654 /* continue with KX, mostly for statistics... */
1658 /* finally, test if it is a KX */
1659 if (rcvd < sizeof(struct UDPConfirmation) + sizeof(struct InitialKX))
1661 GNUNET_STATISTICS_update (stats,
1662 "# messages dropped (no kid, too small for KX)",
1667 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1670 const struct InitialKX *kx;
1671 struct SharedSecret *ss;
1672 char pbuf[rcvd - sizeof(struct InitialKX)];
1673 const struct UDPConfirmation *uc;
1674 struct SenderAddress *sender;
1676 kx = (const struct InitialKX *) buf;
1677 ss = setup_shared_secret_dec (&kx->ephemeral);
1678 if (GNUNET_OK != try_decrypt (ss,
1685 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1686 "Unable to decrypt tag, dropping...\n");
1688 GNUNET_STATISTICS_update (
1690 "# messages dropped (no kid, AEAD decryption failed)",
1695 uc = (const struct UDPConfirmation *) pbuf;
1696 if (GNUNET_OK != verify_confirmation (&kx->ephemeral, uc))
1698 GNUNET_break_op (0);
1700 GNUNET_STATISTICS_update (stats,
1701 "# messages dropped (sender signature invalid)",
1706 calculate_cmac (ss);
1707 sender = setup_sender (&uc->sender, (const struct sockaddr *) &sa, salen);
1708 ss->sender = sender;
1709 GNUNET_CONTAINER_DLL_insert (sender->ss_head, sender->ss_tail, ss);
1710 sender->num_secrets++;
1711 GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
1712 GNUNET_STATISTICS_update (stats,
1713 "# messages decrypted without BOX",
1716 try_handle_plaintext (sender, &uc[1], sizeof(pbuf) - sizeof(*uc));
1717 consider_ss_ack (ss);
1718 if (sender->num_secrets > MAX_SECRETS)
1719 secret_destroy (sender->ss_tail);
1725 * Convert UDP bind specification to a `struct sockaddr *`
1727 * @param bindto bind specification to convert
1728 * @param[out] sock_len set to the length of the address
1729 * @return converted bindto specification
1731 static struct sockaddr *
1732 udp_address_to_sockaddr (const char *bindto, socklen_t *sock_len)
1734 struct sockaddr *in;
1740 if (1 == sscanf (bindto, "%u%1s", &port, dummy))
1742 /* interpreting value as just a PORT number */
1743 if (port > UINT16_MAX)
1745 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1746 "BINDTO specification `%s' invalid: value too large for port\n",
1750 if ((GNUNET_NO == GNUNET_NETWORK_test_pf (PF_INET6)) ||
1752 GNUNET_CONFIGURATION_get_value_yesno (cfg,
1753 COMMUNICATOR_CONFIG_SECTION,
1756 struct sockaddr_in *i4;
1758 i4 = GNUNET_malloc (sizeof(struct sockaddr_in));
1759 i4->sin_family = AF_INET;
1760 i4->sin_port = htons ((uint16_t) port);
1761 *sock_len = sizeof(struct sockaddr_in);
1762 in = (struct sockaddr *) i4;
1766 struct sockaddr_in6 *i6;
1768 i6 = GNUNET_malloc (sizeof(struct sockaddr_in6));
1769 i6->sin6_family = AF_INET6;
1770 i6->sin6_port = htons ((uint16_t) port);
1771 *sock_len = sizeof(struct sockaddr_in6);
1772 in = (struct sockaddr *) i6;
1776 cp = GNUNET_strdup (bindto);
1777 colon = strrchr (cp, ':');
1780 /* interpet value after colon as port */
1783 if (1 == sscanf (colon, "%u%1s", &port, dummy))
1785 /* interpreting value as just a PORT number */
1786 if (port > UINT16_MAX)
1788 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1789 "BINDTO specification `%s' invalid: value too large for port\n",
1798 GNUNET_ERROR_TYPE_ERROR,
1799 "BINDTO specification `%s' invalid: last ':' not followed by number\n",
1807 /* interpret missing port as 0, aka pick any free one */
1812 struct sockaddr_in v4;
1813 if (1 == inet_pton (AF_INET, cp, &v4.sin_addr))
1815 v4.sin_family = AF_INET;
1816 v4.sin_port = htons ((uint16_t) port);
1817 #if HAVE_SOCKADDR_IN_SIN_LEN
1818 v4.sin_len = sizeof(struct sockaddr_in);
1820 in = GNUNET_memdup (&v4, sizeof(struct sockaddr_in));
1821 *sock_len = sizeof(struct sockaddr_in);
1828 struct sockaddr_in6 v6;
1832 if (('[' == *cp) && (']' == cp[strlen (cp) - 1]))
1834 start++; /* skip over '[' */
1835 cp[strlen (cp) - 1] = '\0'; /* eat ']' */
1837 if (1 == inet_pton (AF_INET6, start, &v6.sin6_addr))
1839 v6.sin6_family = AF_INET6;
1840 v6.sin6_port = htons ((uint16_t) port);
1841 #if HAVE_SOCKADDR_IN_SIN_LEN
1842 v6.sin6_len = sizeof(sizeof(struct sockaddr_in6));
1844 in = GNUNET_memdup (&v6, sizeof(v6));
1845 *sock_len = sizeof(v6);
1850 /* #5528 FIXME (feature!): maybe also try getnameinfo()? */
1857 * Pad @a dgram by @a pad_size using @a out_cipher.
1859 * @param out_cipher cipher to use
1860 * @param dgram datagram to pad
1861 * @param pad_size number of bytes of padding to append
1864 do_pad (gcry_cipher_hd_t out_cipher, char *dgram, size_t pad_size)
1868 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, pad, sizeof(pad));
1869 if (sizeof(pad) > sizeof(struct GNUNET_MessageHeader))
1871 struct GNUNET_MessageHeader hdr =
1872 { .size = htons (sizeof(pad)),
1873 .type = htons (GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_PAD) };
1875 memcpy (pad, &hdr, sizeof(hdr));
1879 gcry_cipher_encrypt (out_cipher, dgram, sizeof(pad), pad, sizeof(pad)));
1884 * Signature of functions implementing the sending functionality of a
1887 * @param mq the message queue
1888 * @param msg the message to send
1889 * @param impl_state our `struct ReceiverAddress`
1892 mq_send (struct GNUNET_MQ_Handle *mq,
1893 const struct GNUNET_MessageHeader *msg,
1896 struct ReceiverAddress *receiver = impl_state;
1897 uint16_t msize = ntohs (msg->size);
1899 GNUNET_assert (mq == receiver->mq);
1900 if (msize > receiver->mtu)
1903 receiver_destroy (receiver);
1906 reschedule_receiver_timeout (receiver);
1908 if (0 == receiver->acks_available)
1910 /* use KX encryption method */
1911 struct UdpHandshakeSignature uhs;
1912 struct UDPConfirmation uc;
1913 struct InitialKX kx;
1914 struct GNUNET_CRYPTO_EcdhePrivateKey epriv;
1915 char dgram[receiver->mtu + sizeof(uc) + sizeof(kx)];
1917 gcry_cipher_hd_t out_cipher;
1918 struct SharedSecret *ss;
1920 /* setup key material */
1921 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdhe_key_create2 (&epriv));
1923 ss = setup_shared_secret_enc (&epriv, receiver);
1924 setup_cipher (&ss->master, 0, &out_cipher);
1926 uc.sender = my_identity;
1928 GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_monotonic (cfg));
1929 uhs.purpose.purpose = htonl (GNUNET_SIGNATURE_COMMUNICATOR_UDP_HANDSHAKE);
1930 uhs.purpose.size = htonl (sizeof(uhs));
1931 uhs.sender = my_identity;
1932 uhs.receiver = receiver->target;
1933 GNUNET_CRYPTO_ecdhe_key_get_public (&epriv, &uhs.ephemeral);
1934 uhs.monotonic_time = uc.monotonic_time;
1935 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_eddsa_sign (my_private_key,
1938 /* Leave space for kx */
1940 /* Append encrypted uc to dgram */
1941 GNUNET_assert (0 == gcry_cipher_encrypt (out_cipher,
1947 /* Append encrypted payload to dgram */
1949 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], msize, msg, msize));
1951 do_pad (out_cipher, &dgram[dpos], sizeof(dgram) - dpos);
1952 /* Datagram starts with kx */
1953 kx.ephemeral = uhs.ephemeral;
1955 0 == gcry_cipher_gettag (out_cipher, kx.gcm_tag, sizeof(kx.gcm_tag)));
1956 gcry_cipher_close (out_cipher);
1957 memcpy (dgram, &kx, sizeof(kx));
1958 if (-1 == GNUNET_NETWORK_socket_sendto (udp_sock,
1962 receiver->address_len))
1963 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "send");
1964 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1965 "Sending KX to %s\n", GNUNET_a2s (receiver->address,
1966 receiver->address_len));
1967 GNUNET_MQ_impl_send_continue (mq);
1969 } /* End of KX encryption method */
1971 /* begin "BOX" encryption method, scan for ACKs from tail! */
1972 for (struct SharedSecret *ss = receiver->ss_tail; NULL != ss; ss = ss->prev)
1974 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1975 "In non-kx mode...\n");
1976 if (ss->sequence_used < ss->sequence_allowed)
1978 char dgram[sizeof(struct UDPBox) + receiver->mtu];
1980 gcry_cipher_hd_t out_cipher;
1983 box = (struct UDPBox *) dgram;
1984 ss->sequence_used++;
1985 get_kid (&ss->master, ss->sequence_used, &box->kid);
1986 setup_cipher (&ss->master, ss->sequence_used, &out_cipher);
1987 /* Append encrypted payload to dgram */
1988 dpos = sizeof(struct UDPBox);
1990 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], msize, msg, msize));
1992 do_pad (out_cipher, &dgram[dpos], sizeof(dgram) - dpos);
1993 GNUNET_assert (0 == gcry_cipher_gettag (out_cipher,
1995 sizeof(box->gcm_tag)));
1996 gcry_cipher_close (out_cipher);
1997 if (-1 == GNUNET_NETWORK_socket_sendto (udp_sock,
2001 receiver->address_len))
2002 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "send");
2003 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2006 GNUNET_MQ_impl_send_continue (mq);
2007 receiver->acks_available--;
2008 if (0 == receiver->acks_available)
2010 /* We have no more ACKs => MTU change! */
2011 setup_receiver_mq (receiver);
2012 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2013 "No more acks, MTU changed\n");
2023 * Signature of functions implementing the destruction of a message
2024 * queue. Implementations must not free @a mq, but should take care
2027 * @param mq the message queue to destroy
2028 * @param impl_state our `struct ReceiverAddress`
2031 mq_destroy (struct GNUNET_MQ_Handle *mq, void *impl_state)
2033 struct ReceiverAddress *receiver = impl_state;
2035 if (mq == receiver->mq)
2037 receiver->mq = NULL;
2038 receiver_destroy (receiver);
2044 * Implementation function that cancels the currently sent message.
2046 * @param mq message queue
2047 * @param impl_state our `struct RecvierAddress`
2050 mq_cancel (struct GNUNET_MQ_Handle *mq, void *impl_state)
2052 /* Cancellation is impossible with UDP; bail */
2058 * Generic error handler, called with the appropriate
2059 * error code and the same closure specified at the creation of
2060 * the message queue.
2061 * Not every message queue implementation supports an error handler.
2063 * @param cls our `struct ReceiverAddress`
2064 * @param error error code
2067 mq_error (void *cls, enum GNUNET_MQ_Error error)
2069 struct ReceiverAddress *receiver = cls;
2071 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2072 "MQ error in queue to %s: %d\n",
2073 GNUNET_i2s (&receiver->target),
2075 receiver_destroy (receiver);
2080 * Setup the MQ for the @a receiver. If a queue exists,
2081 * the existing one is destroyed. Then the MTU is
2082 * recalculated and a fresh queue is initialized.
2084 * @param receiver receiver to setup MQ for
2087 setup_receiver_mq (struct ReceiverAddress *receiver)
2091 if (NULL != receiver->qh)
2093 GNUNET_TRANSPORT_communicator_mq_del (receiver->qh);
2094 receiver->qh = NULL;
2096 GNUNET_assert (NULL == receiver->mq);
2097 switch (receiver->address->sa_family)
2100 base_mtu = 1480 /* Ethernet MTU, 1500 - Ethernet header - VLAN tag */
2101 - sizeof(struct GNUNET_TUN_IPv4Header) /* 20 */
2102 - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */;
2106 base_mtu = 1280 /* Minimum MTU required by IPv6 */
2107 - sizeof(struct GNUNET_TUN_IPv6Header) /* 40 */
2108 - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */;
2115 if (0 == receiver->acks_available)
2117 /* MTU based on full KX messages */
2118 receiver->mtu = base_mtu - sizeof(struct InitialKX) /* 48 */
2119 - sizeof(struct UDPConfirmation); /* 104 */
2123 /* MTU based on BOXed messages */
2124 receiver->mtu = base_mtu - sizeof(struct UDPBox);
2126 /* => Effective MTU for CORE will range from 1080 (IPv6 + KX) to
2127 1404 (IPv4 + Box) bytes, depending on circumstances... */
2128 if (NULL == receiver->mq)
2129 receiver->mq = GNUNET_MQ_queue_for_callbacks (&mq_send,
2137 GNUNET_TRANSPORT_communicator_mq_add (ch,
2139 receiver->foreign_addr,
2142 GNUNET_TRANSPORT_CS_OUTBOUND,
2148 * Function called by the transport service to initialize a
2149 * message queue given address information about another peer.
2150 * If and when the communication channel is established, the
2151 * communicator must call #GNUNET_TRANSPORT_communicator_mq_add()
2152 * to notify the service that the channel is now up. It is
2153 * the responsibility of the communicator to manage sane
2154 * retries and timeouts for any @a peer/@a address combination
2155 * provided by the transport service. Timeouts and retries
2156 * do not need to be signalled to the transport service.
2158 * @param cls closure
2159 * @param peer identity of the other peer
2160 * @param address where to send the message, human-readable
2161 * communicator-specific format, 0-terminated, UTF-8
2162 * @return #GNUNET_OK on success, #GNUNET_SYSERR if the provided address is
2166 mq_init (void *cls, const struct GNUNET_PeerIdentity *peer, const char *address)
2168 struct ReceiverAddress *receiver;
2170 struct sockaddr *in;
2173 if (0 != strncmp (address,
2174 COMMUNICATOR_ADDRESS_PREFIX "-",
2175 strlen (COMMUNICATOR_ADDRESS_PREFIX "-")))
2177 GNUNET_break_op (0);
2178 return GNUNET_SYSERR;
2180 path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")];
2181 in = udp_address_to_sockaddr (path, &in_len);
2183 receiver = GNUNET_new (struct ReceiverAddress);
2184 receiver->address = in;
2185 receiver->address_len = in_len;
2186 receiver->target = *peer;
2187 receiver->nt = GNUNET_NT_scanner_get_type (is, in, in_len);
2188 (void) GNUNET_CONTAINER_multipeermap_put (
2192 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
2194 GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
2195 receiver->hn = GNUNET_CONTAINER_heap_insert (receivers_heap,
2197 receiver->timeout.abs_value_us);
2198 GNUNET_STATISTICS_set (stats,
2199 "# receivers active",
2200 GNUNET_CONTAINER_multipeermap_size (receivers),
2202 receiver->foreign_addr =
2203 sockaddr_to_udpaddr_string (receiver->address, receiver->address_len);
2204 setup_receiver_mq (receiver);
2205 if (NULL == timeout_task)
2206 timeout_task = GNUNET_SCHEDULER_add_now (&check_timeouts, NULL);
2212 * Iterator over all receivers to clean up.
2215 * @param target unused
2216 * @param value the queue to destroy
2217 * @return #GNUNET_OK to continue to iterate
2220 get_receiver_delete_it (void *cls,
2221 const struct GNUNET_PeerIdentity *target,
2224 struct ReceiverAddress *receiver = value;
2228 receiver_destroy (receiver);
2234 * Iterator over all senders to clean up.
2237 * @param target unused
2238 * @param value the queue to destroy
2239 * @return #GNUNET_OK to continue to iterate
2242 get_sender_delete_it (void *cls,
2243 const struct GNUNET_PeerIdentity *target,
2246 struct SenderAddress *sender = value;
2250 sender_destroy (sender);
2256 * Shutdown the UNIX communicator.
2258 * @param cls NULL (always)
2261 do_shutdown (void *cls)
2265 GNUNET_NAT_unregister (nat);
2268 while (NULL != bi_head)
2269 bi_destroy (bi_head);
2270 if (NULL != broadcast_task)
2272 GNUNET_SCHEDULER_cancel (broadcast_task);
2273 broadcast_task = NULL;
2275 if (NULL != read_task)
2277 GNUNET_SCHEDULER_cancel (read_task);
2280 if (NULL != udp_sock)
2282 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (udp_sock));
2285 GNUNET_CONTAINER_multipeermap_iterate (receivers,
2286 &get_receiver_delete_it,
2288 GNUNET_CONTAINER_multipeermap_destroy (receivers);
2289 GNUNET_CONTAINER_multipeermap_iterate (senders, &get_sender_delete_it, NULL);
2290 GNUNET_CONTAINER_multipeermap_destroy (senders);
2291 GNUNET_CONTAINER_multishortmap_destroy (key_cache);
2292 GNUNET_CONTAINER_heap_destroy (senders_heap);
2293 GNUNET_CONTAINER_heap_destroy (receivers_heap);
2296 GNUNET_TRANSPORT_communicator_disconnect (ch);
2301 GNUNET_TRANSPORT_application_done (ah);
2306 GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
2309 if (NULL != my_private_key)
2311 GNUNET_free (my_private_key);
2312 my_private_key = NULL;
2316 GNUNET_NT_scanner_done (is);
2323 * Function called when the transport service has received a
2324 * backchannel message for this communicator (!) via a different return
2325 * path. Should be an acknowledgement.
2327 * @param cls closure, NULL
2328 * @param sender which peer sent the notification
2329 * @param msg payload
2332 enc_notify_cb (void *cls,
2333 const struct GNUNET_PeerIdentity *sender,
2334 const struct GNUNET_MessageHeader *msg)
2336 const struct UDPAck *ack;
2339 if ((ntohs (msg->type) != GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK) ||
2340 (ntohs (msg->size) != sizeof(struct UDPAck)))
2342 GNUNET_break_op (0);
2345 ack = (const struct UDPAck *) msg;
2346 GNUNET_CONTAINER_multipeermap_get_multiple (receivers,
2354 * Signature of the callback passed to #GNUNET_NAT_register() for
2355 * a function to call whenever our set of 'valid' addresses changes.
2357 * @param cls closure
2358 * @param app_ctx[in,out] location where the app can store stuff
2359 * on add and retrieve it on remove
2360 * @param add_remove #GNUNET_YES to add a new public IP address,
2361 * #GNUNET_NO to remove a previous (now invalid) one
2362 * @param ac address class the address belongs to
2363 * @param addr either the previous or the new public IP address
2364 * @param addrlen actual length of the @a addr
2367 nat_address_cb (void *cls,
2370 enum GNUNET_NAT_AddressClass ac,
2371 const struct sockaddr *addr,
2375 struct GNUNET_TRANSPORT_AddressIdentifier *ai;
2377 if (GNUNET_YES == add_remove)
2379 enum GNUNET_NetworkType nt;
2381 GNUNET_asprintf (&my_addr,
2383 COMMUNICATOR_ADDRESS_PREFIX,
2384 GNUNET_a2s (addr, addrlen));
2385 nt = GNUNET_NT_scanner_get_type (is, addr, addrlen);
2387 GNUNET_TRANSPORT_communicator_address_add (ch,
2390 GNUNET_TIME_UNIT_FOREVER_REL);
2391 GNUNET_free (my_addr);
2397 GNUNET_TRANSPORT_communicator_address_remove (ai);
2404 * Broadcast our presence on one of our interfaces.
2406 * @param cls a `struct BroadcastInterface`
2409 ifc_broadcast (void *cls)
2411 struct BroadcastInterface *bi = cls;
2412 struct GNUNET_TIME_Relative delay;
2414 delay = BROADCAST_FREQUENCY;
2415 delay.rel_value_us =
2416 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, delay.rel_value_us);
2417 bi->broadcast_task =
2418 GNUNET_SCHEDULER_add_delayed (INTERFACE_SCAN_FREQUENCY, &ifc_broadcast, bi);
2420 switch (bi->sa->sa_family)
2427 if (GNUNET_OK != GNUNET_NETWORK_socket_setsockopt (udp_sock,
2432 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "setsockopt");
2433 sent = GNUNET_NETWORK_socket_sendto (udp_sock,
2439 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "sendto");
2440 if (GNUNET_OK != GNUNET_NETWORK_socket_setsockopt (udp_sock,
2445 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "setsockopt");
2451 struct sockaddr_in6 dst;
2453 dst.sin6_family = AF_INET6;
2454 dst.sin6_port = htons (my_port);
2455 dst.sin6_addr = bi->mcreq.ipv6mr_multiaddr;
2456 dst.sin6_scope_id = ((struct sockaddr_in6 *) bi->ba)->sin6_scope_id;
2458 sent = GNUNET_NETWORK_socket_sendto (udp_sock,
2461 (const struct sockaddr *) &dst,
2464 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "sendto");
2476 * Callback function invoked for each interface found.
2477 * Activates/deactivates broadcast interfaces.
2480 * @param name name of the interface (can be NULL for unknown)
2481 * @param isDefault is this presumably the default interface
2482 * @param addr address of this interface (can be NULL for unknown or unassigned)
2483 * @param broadcast_addr the broadcast address (can be NULL for unknown or
2485 * @param netmask the network mask (can be NULL for unknown or unassigned)
2486 * @param addrlen length of the address
2487 * @return #GNUNET_OK to continue iteration, #GNUNET_SYSERR to abort
2490 iface_proc (void *cls,
2493 const struct sockaddr *addr,
2494 const struct sockaddr *broadcast_addr,
2495 const struct sockaddr *netmask,
2498 struct BroadcastInterface *bi;
2499 enum GNUNET_NetworkType network;
2500 struct UdpBroadcastSignature ubs;
2505 return GNUNET_YES; /* need to know our address! */
2506 network = GNUNET_NT_scanner_get_type (is, addr, addrlen);
2507 if (GNUNET_NT_LOOPBACK == network)
2509 /* Broadcasting on loopback does not make sense */
2512 for (bi = bi_head; NULL != bi; bi = bi->next)
2514 if ((bi->salen == addrlen) && (0 == memcmp (addr, bi->sa, addrlen)))
2516 bi->found = GNUNET_YES;
2521 if ((AF_INET6 == addr->sa_family) && (NULL == broadcast_addr))
2522 return GNUNET_OK; /* broadcast_addr is required for IPv6! */
2523 if ((AF_INET6 == addr->sa_family) && (GNUNET_YES != have_v6_socket))
2524 return GNUNET_OK; /* not using IPv6 */
2526 bi = GNUNET_new (struct BroadcastInterface);
2527 bi->sa = GNUNET_memdup (addr, addrlen);
2528 if (NULL != broadcast_addr)
2529 bi->ba = GNUNET_memdup (broadcast_addr, addrlen);
2530 bi->salen = addrlen;
2531 bi->found = GNUNET_YES;
2532 bi->bcm.sender = my_identity;
2533 ubs.purpose.purpose = htonl (GNUNET_SIGNATURE_COMMUNICATOR_UDP_BROADCAST);
2534 ubs.purpose.size = htonl (sizeof(ubs));
2535 ubs.sender = my_identity;
2536 GNUNET_CRYPTO_hash (addr, addrlen, &ubs.h_address);
2537 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_eddsa_sign (my_private_key,
2539 &bi->bcm.sender_sig));
2540 if (NULL != broadcast_addr)
2542 bi->broadcast_task = GNUNET_SCHEDULER_add_now (&ifc_broadcast, bi);
2543 GNUNET_CONTAINER_DLL_insert (bi_head, bi_tail, bi);
2545 if ((AF_INET6 == addr->sa_family) && (NULL != broadcast_addr))
2547 /* Create IPv6 multicast request */
2548 const struct sockaddr_in6 *s6 =
2549 (const struct sockaddr_in6 *) broadcast_addr;
2552 1 == inet_pton (AF_INET6, "FF05::13B", &bi->mcreq.ipv6mr_multiaddr));
2554 /* http://tools.ietf.org/html/rfc2553#section-5.2:
2558 * Join a multicast group on a specified local interface. If the
2559 * interface index is specified as 0, the kernel chooses the local
2560 * interface. For example, some kernels look up the multicast
2561 * group in the normal IPv6 routing table and using the resulting
2562 * interface; we do this for each interface, so no need to use
2563 * zero (anymore...).
2564 */bi->mcreq.ipv6mr_interface = s6->sin6_scope_id;
2566 /* Join the multicast group */
2567 if (GNUNET_OK != GNUNET_NETWORK_socket_setsockopt (udp_sock,
2573 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "setsockopt");
2581 * Scan interfaces to broadcast our presence on the LAN.
2583 * @param cls NULL, unused
2586 do_broadcast (void *cls)
2588 struct BroadcastInterface *bin;
2591 for (struct BroadcastInterface *bi = bi_head; NULL != bi; bi = bi->next)
2592 bi->found = GNUNET_NO;
2593 GNUNET_OS_network_interfaces_list (&iface_proc, NULL);
2594 for (struct BroadcastInterface *bi = bi_head; NULL != bi; bi = bin)
2597 if (GNUNET_NO == bi->found)
2600 broadcast_task = GNUNET_SCHEDULER_add_delayed (INTERFACE_SCAN_FREQUENCY,
2607 * Setup communicator and launch network interactions.
2609 * @param cls NULL (always)
2610 * @param args remaining command-line arguments
2611 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
2612 * @param c configuration
2617 const char *cfgfile,
2618 const struct GNUNET_CONFIGURATION_Handle *c)
2621 struct sockaddr *in;
2623 struct sockaddr_storage in_sto;
2629 GNUNET_CONFIGURATION_get_value_string (cfg,
2630 COMMUNICATOR_CONFIG_SECTION,
2634 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
2635 COMMUNICATOR_CONFIG_SECTION,
2640 in = udp_address_to_sockaddr (bindto, &in_len);
2643 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2644 "Failed to setup UDP socket address with path `%s'\n",
2646 GNUNET_free (bindto);
2650 GNUNET_NETWORK_socket_create (in->sa_family, SOCK_DGRAM, IPPROTO_UDP);
2651 if (NULL == udp_sock)
2653 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "socket");
2655 GNUNET_free (bindto);
2658 if (AF_INET6 == in->sa_family)
2659 have_v6_socket = GNUNET_YES;
2660 if (GNUNET_OK != GNUNET_NETWORK_socket_bind (udp_sock, in, in_len))
2662 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "bind", bindto);
2663 GNUNET_NETWORK_socket_close (udp_sock);
2666 GNUNET_free (bindto);
2670 /* We might have bound to port 0, allowing the OS to figure it out;
2671 thus, get the real IN-address from the socket */
2672 sto_len = sizeof(in_sto);
2673 if (0 != getsockname (GNUNET_NETWORK_get_fd (udp_sock),
2674 (struct sockaddr *) &in_sto,
2677 memcpy (&in_sto, in, in_len);
2681 GNUNET_free (bindto);
2682 in = (struct sockaddr *) &in_sto;
2684 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2686 GNUNET_a2s ((const struct sockaddr *) &in_sto, sto_len));
2687 switch (in->sa_family)
2690 my_port = ntohs (((struct sockaddr_in *) in)->sin_port);
2694 my_port = ntohs (((struct sockaddr_in6 *) in)->sin6_port);
2701 stats = GNUNET_STATISTICS_create ("C-UDP", cfg);
2702 senders = GNUNET_CONTAINER_multipeermap_create (32, GNUNET_YES);
2703 receivers = GNUNET_CONTAINER_multipeermap_create (32, GNUNET_YES);
2704 senders_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
2706 GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
2707 key_cache = GNUNET_CONTAINER_multishortmap_create (1024, GNUNET_YES);
2708 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
2709 is = GNUNET_NT_scanner_init ();
2710 my_private_key = GNUNET_CRYPTO_eddsa_key_create_from_configuration (cfg);
2711 if (NULL == my_private_key)
2714 GNUNET_ERROR_TYPE_ERROR,
2716 "Transport service is lacking key configuration settings. Exiting.\n"));
2717 GNUNET_SCHEDULER_shutdown ();
2720 GNUNET_CRYPTO_eddsa_key_get_public (my_private_key, &my_identity.public_key);
2722 read_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
2726 ch = GNUNET_TRANSPORT_communicator_connect (cfg,
2727 COMMUNICATOR_CONFIG_SECTION,
2728 COMMUNICATOR_ADDRESS_PREFIX,
2729 GNUNET_TRANSPORT_CC_UNRELIABLE,
2737 GNUNET_SCHEDULER_shutdown ();
2740 ah = GNUNET_TRANSPORT_application_init (cfg);
2744 GNUNET_SCHEDULER_shutdown ();
2747 /* start broadcasting */
2749 GNUNET_CONFIGURATION_get_value_yesno (cfg,
2750 COMMUNICATOR_CONFIG_SECTION,
2751 "DISABLE_BROADCAST"))
2753 broadcast_task = GNUNET_SCHEDULER_add_now (&do_broadcast, NULL);
2755 nat = GNUNET_NAT_register (cfg,
2756 COMMUNICATOR_CONFIG_SECTION,
2758 1 /* one address */,
2759 (const struct sockaddr **) &in,
2762 NULL /* FIXME: support reversal: #5529 */,
2763 NULL /* closure */);
2768 * The main function for the UNIX communicator.
2770 * @param argc number of arguments from the command line
2771 * @param argv command line arguments
2772 * @return 0 ok, 1 on error
2775 main (int argc, char *const *argv)
2777 static const struct GNUNET_GETOPT_CommandLineOption options[] = {
2778 GNUNET_GETOPT_OPTION_END
2782 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
2785 ret = (GNUNET_OK == GNUNET_PROGRAM_run (argc,
2787 "gnunet-communicator-udp",
2788 _ ("GNUnet UDP communicator"),
2794 GNUNET_free ((void *) argv);
2799 /* end of gnunet-communicator-udp.c */