* 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 (#)
+ * - support other UDP-specific NAT traversal methods (#)
*/
#include "platform.h"
#include "gnunet_util_lib.h"
#include "gnunet_nt_lib.h"
#include "gnunet_nat_service.h"
#include "gnunet_statistics_service.h"
+#include "gnunet_transport_application_service.h"
#include "gnunet_transport_communication_service.h"
/**
* How often do we rekey based on time (at least)
- */
+ */
#define REKEY_TIME_INTERVAL GNUNET_TIME_UNIT_DAYS
/**
* How long do we wait until we must have received the initial KX?
- */
+ */
#define PROTO_QUEUE_TIMEOUT GNUNET_TIME_UNIT_MINUTES
/**
* How often do we broadcast our presence on the LAN?
- */
+ */
#define BROADCAST_FREQUENCY GNUNET_TIME_UNIT_MINUTES
/**
* How often do we scan for changes to our network interfaces?
- */
+ */
#define INTERFACE_SCAN_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)
/**
* #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
+ * arrive before the sender runs out. So really this
* should ideally be based on the RTT.
*/
#define KCN_THRESHOLD 92
#define MAX_SQN_DELTA 160
/**
- * How many shared master secrets do we keep around
- * at most per sender? Should be large enough so
+ * 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
/**
* How often do we rekey based on number of bytes transmitted?
* (additionally randomized).
- */
+ */
#define REKEY_MAX_BYTES (1024LLU * 1024 * 1024 * 4LLU)
/**
/**
* Identity of the inititor of the UDP connection (UDP client).
- */
+ */
struct GNUNET_PeerIdentity sender;
/**
* Presumed identity of the target of the UDP connection (UDP server)
- */
+ */
struct GNUNET_PeerIdentity receiver;
/**
* Ephemeral key used by the @e sender.
- */
+ */
struct GNUNET_CRYPTO_EcdhePublicKey ephemeral;
/**
* Monotonic time of @e sender, to possibly help detect replay attacks
* (if receiver persists times by sender).
- */
+ */
struct GNUNET_TIME_AbsoluteNBO monotonic_time;
};
/**
* Ephemeral key for KX.
- */
+ */
struct GNUNET_CRYPTO_EcdhePublicKey ephemeral;
/**
* HMAC for the following encrypted message, using GCM. HMAC uses
* key derived from the handshake with sequence number zero.
- */
+ */
char gcm_tag[GCM_TAG_SIZE];
};
/**
* Monotonic time of @e sender, to possibly help detect replay attacks
* (if receiver persists times by sender).
- */
+ */
struct GNUNET_TIME_AbsoluteNBO monotonic_time;
/* followed by messages */
/**
* UDP key acknowledgement. May be sent via backchannel. Allows the
* sender to use `struct UDPBox` with the acknowledge key henceforth.
- */
+ */
struct UDPAck
{
/**
* Type is #GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK.
- */
+ */
struct GNUNET_MessageHeader header;
/**
* Sequence acknowledgement limit. Specifies current maximum sequence
* number supported by receiver.
- */
+ */
uint32_t sequence_max GNUNET_PACKED;
-
+
/**
* CMAC of the base key being acknowledged.
- */
+ */
struct GNUNET_HashCode cmac;
};
* Signature we use to verify that the broadcast was really made by
* the peer that claims to have made it. Basically, affirms that the
* peer is really using this IP address (albeit possibly not in _our_
- * LAN). Makes it difficult for peers in the LAN to claim to
+ * LAN). Makes it difficult for peers in the LAN to claim to
* be just any global peer -- an attacker must have at least
* shared a LAN with the peer they're pretending to be here.
*/
/**
* Identity of the inititor of the UDP broadcast.
- */
+ */
struct GNUNET_PeerIdentity sender;
/**
* Hash of the sender's UDP address.
- */
+ */
struct GNUNET_HashCode h_address;
};
* Sender's signature of type
* #GNUNET_SIGNATURE_COMMUNICATOR_UDP_BROADCAST
*/
- struct GNUNET_CRYPTO_EddsaSignature sender_sig;
-
+ struct GNUNET_CRYPTO_EddsaSignature sender_sig;
+
};
/**
* UDP message box. Always sent encrypted, only allowed after
* the receiver sent a `struct UDPAck` for the base key!
- */
+ */
struct UDPBox
{
/**
* Key and IV identification code. KDF applied to an acknowledged
* base key and a sequence number. Sequence numbers must be used
- * monotonically increasing up to the maximum specified in
+ * monotonically increasing up to the maximum specified in
* `struct UDPAck`. Without further `struct UDPAck`s, the sender
* must fall back to sending handshakes!
*/
* extends until the end of the UDP payload. If the @e hmac is
* wrong, the receiver should check if the message might be a
* `struct UdpHandshakeSignature`.
- */
+ */
char gcm_tag[GCM_TAG_SIZE];
-
+
};
* Kept in a DLL.
*/
struct KeyCacheEntry *next;
-
+
/**
* Kept in a DLL.
*/
/**
* Key and IV identification code. KDF applied to an acknowledged
* base key and a sequence number. Sequence numbers must be used
- * monotonically increasing up to the maximum specified in
+ * monotonically increasing up to the maximum specified in
* `struct UDPAck`. Without further `struct UDPAck`s, the sender
* must fall back to sending handshakes!
*/
/**
* Sequence number used to derive this entry from master key.
- */
+ */
uint32_t sequence_number;
};
* Kept in a DLL, sorted by sequence number. Only if we are decrypting.
*/
struct KeyCacheEntry *kce_head;
-
+
/**
* Kept in a DLL, sorted by sequence number. Only if we are decrypting.
*/
* Receiver we use this shared secret with, or NULL.
*/
struct ReceiverAddress *receiver;
-
+
/**
* Master shared secret.
- */
+ */
struct GNUNET_HashCode master;
/**
* CMAC is used to identify @e master in ACKs.
- */
+ */
struct GNUNET_HashCode cmac;
/**
* Up to which sequence number did we use this @e master already?
* (for encrypting only)
- */
+ */
uint32_t sequence_used;
/**
/**
* Number of active KCN entries.
- */
+ */
unsigned int active_kce_count;
};
/**
* To whom are we talking to.
*/
- struct GNUNET_PeerIdentity target;
+ struct GNUNET_PeerIdentity target;
/**
* Entry in sender expiration heap.
- */
+ */
struct GNUNET_CONTAINER_HeapNode *hn;
/**
* Shared secrets we used with @e target, last used is tail.
*/
struct SharedSecret *ss_tail;
-
+
/**
* Address of the other peer.
*/
struct sockaddr *address;
-
+
/**
* Length of the address.
*/
/**
* Length of the DLL at @a ss_head.
- */
+ */
unsigned int num_secrets;
-
+
/**
* Which network type does this queue use?
*/
enum GNUNET_NetworkType nt;
-
+
};
/**
* To whom are we talking to.
*/
- struct GNUNET_PeerIdentity target;
-
+ struct GNUNET_PeerIdentity target;
+
/**
* Shared secrets we received from @e target, first used is head.
*/
/**
* Address of the receiver in the human-readable format
* with the #COMMUNICATOR_ADDRESS_PREFIX.
- */
+ */
char *foreign_addr;
/**
* Address of the other peer.
*/
struct sockaddr *address;
-
+
/**
* Length of the address.
*/
/**
* Entry in sender expiration heap.
- */
+ */
struct GNUNET_CONTAINER_HeapNode *hn;
/**
* MTU we allowed transport for this receiver right now.
*/
size_t mtu;
-
+
/**
* Length of the DLL at @a ss_head.
- */
+ */
unsigned int num_secrets;
/**
- * Number of BOX keys from ACKs we have currently
+ * Number of BOX keys from ACKs we have currently
* available for this receiver.
- */
+ */
unsigned int acks_available;
-
+
/**
* Which network type does this queue use?
*/
enum GNUNET_NetworkType nt;
-
+
};
* Task for this broadcast interface.
*/
struct GNUNET_SCHEDULER_Task *broadcast_task;
-
+
/**
* Sender's address of the interface.
*/
struct sockaddr *sa;
-
+
/**
* Broadcast address to use on the interface.
*/
/**
* Message we broadcast on this interface.
- */
+ */
struct UDPBroadcast bcm;
-
+
/**
* If this is an IPv6 interface, this is the request
* we use to join/leave the group.
*/
struct ipv6_mreq mcreq;
-
+
/**
* Number of bytes in @e sa.
- */
+ */
socklen_t salen;
/**
*/
static struct GNUNET_NETWORK_Handle *udp_sock;
-/**
+/**
* #GNUNET_YES if #udp_sock supports IPv6.
- */
+ */
static int have_v6_socket;
/**
*/
static const struct GNUNET_CONFIGURATION_Handle *cfg;
+/**
+ * Our handle to report addresses for validation to TRANSPORT.
+ */
+static struct GNUNET_TRANSPORT_ApplicationHandle *ah;
+
/**
* Network scanner to determine network types.
*/
/**
* Port number to which we are actually bound.
- */
+ */
static uint16_t my_port;
receiver_destroy (struct ReceiverAddress *receiver)
{
struct GNUNET_MQ_Handle *mq;
-
+
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Disconnecting receiver for peer `%s'\n",
GNUNET_i2s (&receiver->target));
* Free memory used by key cache entry.
*
* @param kce the key cache entry
- */
+ */
static void
kce_destroy (struct KeyCacheEntry *kce)
{
struct GNUNET_TIME_Relative delay;
struct ReceiverAddress *receiver;
struct SenderAddress *sender;
-
+
(void) cls;
timeout_task = NULL;
rt = GNUNET_TIME_UNIT_FOREVER_REL;
if (delay.rel_value_us < GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
timeout_task = GNUNET_SCHEDULER_add_delayed (delay,
&check_timeouts,
- NULL);
+ NULL);
}
-
+
/**
* Calcualte cmac from master in @a ss.
/**
* We received @a plaintext_len bytes of @a plaintext from a @a sender.
- * Pass it on to CORE.
+ * Pass it on to CORE.
*
* @param queue the queue that received the plaintext
* @param plaintext the plaintext that was received
* @param plaintext_len number of bytes of plaintext received
- */
+ */
static void
pass_plaintext_to_core (struct SenderAddress *sender,
const void *plaintext,
/**
- * Try to decrypt @a buf using shared secret @a ss and key/iv
+ * Try to decrypt @a buf using shared secret @a ss and key/iv
* derived using @a serial.
*
* @param ss shared secret
* recalculated and a fresh queue is initialized.
*
* @param receiver receiver to setup MQ for
- */
+ */
static void
setup_receiver_mq (struct ReceiverAddress *receiver);
sizeof (struct GNUNET_HashCode)))
{
uint32_t allowed;
-
+
allowed = ntohl (ack->sequence_max);
-
+
if (allowed > ss->sequence_allowed)
{
receiver->acks_available += (allowed - ss->sequence_allowed);
* @param sender peer to process inbound plaintext for
* @param buf buffer we received
* @param buf_size number of bytes in @a buf
- */
+ */
static void
try_handle_plaintext (struct SenderAddress *sender,
const void *buf,
ack.sequence_max = htonl (ss->sequence_allowed);
ack.cmac = ss->cmac;
GNUNET_TRANSPORT_communicator_notify (ch,
- &ss->sender->target,
- COMMUNICATOR_ADDRESS_PREFIX,
- &ack.header);
+ &ss->sender->target,
+ COMMUNICATOR_ADDRESS_PREFIX,
+ &ack.header);
}
}
* @param box the data we received
* @param box_len number of bytes in @a box
* @param kce key index to decrypt @a box
- */
+ */
static void
decrypt_box (const struct UDPBox *box,
size_t box_len,
* if one does not yet exist for @a address.
*
* @param target peer to generate address for
- * @param address target address
+ * @param address target address
* @param address_len number of bytes in @a address
* @return data structure to keep track of key material for
* decrypting data from @a target
*/
static int
verify_confirmation (const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral,
- const struct UDPConfirmation *uc)
+ const struct UDPConfirmation *uc)
{
struct UdpHandshakeSignature uhs;
-
+
uhs.purpose.purpose = htonl (GNUNET_SIGNATURE_COMMUNICATOR_UDP_HANDSHAKE);
uhs.purpose.size = htonl (sizeof (uhs));
uhs.sender = uc->sender;
uhs.ephemeral = *ephemeral;
uhs.monotonic_time = uc->monotonic_time;
return GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_COMMUNICATOR_UDP_HANDSHAKE,
- &uhs.purpose,
- &uc->sender_sig,
- &uc->sender.public_key);
+ &uhs.purpose,
+ &uc->sender_sig,
+ &uc->sender.public_key);
+}
+
+
+/**
+ * Converts @a address to the address string format used by this
+ * communicator in HELLOs.
+ *
+ * @param address the address to convert, must be AF_INET or AF_INET6.
+ * @param address_len number of bytes in @a address
+ * @return string representation of @a address
+ */
+static char *
+sockaddr_to_udpaddr_string (const struct sockaddr *address,
+ socklen_t address_len)
+{
+ char *ret;
+
+ switch (address->sa_family)
+ {
+ case AF_INET:
+ GNUNET_asprintf (&ret,
+ "%s-%s",
+ COMMUNICATOR_ADDRESS_PREFIX,
+ GNUNET_a2s (address,
+ address_len));
+ break;
+ case AF_INET6:
+ GNUNET_asprintf (&ret,
+ "%s-%s",
+ COMMUNICATOR_ADDRESS_PREFIX,
+ GNUNET_a2s (address,
+ address_len));
+ break;
+ default:
+ GNUNET_assert (0);
+ }
+ return ret;
}
/**
- * Socket read task.
+ * Socket read task.
*
* @param cls NULL
*/
(void) cls;
read_task
= GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
- udp_sock,
- &sock_read,
- NULL);
+ udp_sock,
+ &sock_read,
+ NULL);
rcvd = GNUNET_NETWORK_socket_recvfrom (udp_sock,
- buf,
- sizeof (buf),
- (struct sockaddr *) &sa,
- &salen);
+ buf,
+ sizeof (buf),
+ (struct sockaddr *) &sa,
+ &salen);
if (-1 == rcvd)
{
GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG,
- "recv");
+ "recv");
return;
}
box = (const struct UDPBox *) buf;
kce = GNUNET_CONTAINER_multishortmap_get (key_cache,
- &box->kid);
+ &box->kid);
if (NULL != kce)
{
decrypt_box (box,
- (size_t) rcvd,
- kce);
+ (size_t) rcvd,
+ kce);
return;
}
}
uhs.purpose.size = htonl (sizeof (uhs));
uhs.sender = ub->sender;
GNUNET_CRYPTO_hash (&sa,
- salen,
- &uhs.h_address);
+ salen,
+ &uhs.h_address);
if (GNUNET_OK ==
- GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_COMMUNICATOR_UDP_BROADCAST,
- &uhs.purpose,
- &ub->sender_sig,
- &ub->sender.public_key))
+ GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_COMMUNICATOR_UDP_BROADCAST,
+ &uhs.purpose,
+ &ub->sender_sig,
+ &ub->sender.public_key))
{
+ char *addr_s;
+ struct GNUNET_TIME_Absolute expiration;
+ enum GNUNET_NetworkType nt;
+
+ addr_s = sockaddr_to_udpaddr_string ((const struct sockaddr *) &sa,
+ salen);
GNUNET_STATISTICS_update (stats,
- "# broadcasts received",
- 1,
- GNUNET_NO);
- // FIXME #5551: we effectively just got a HELLO!
- // trigger verification NOW!
+ "# broadcasts received",
+ 1,
+ GNUNET_NO);
+ /* expire at the broadcast frequency, as then we'll get the next one anyway */
+ expiration = GNUNET_TIME_relative_to_absolute (BROADCAST_FREQUENCY);
+ /* use our own mechanism to determine network type */
+ nt = GNUNET_NT_scanner_get_type (is,
+ (const struct sockaddr *) &sa,
+ salen);
+ GNUNET_TRANSPORT_application_validate (ah,
+ &ub->sender,
+ expiration,
+ nt,
+ addr_s);
+ GNUNET_free (addr_s);
return;
}
/* continue with KX, mostly for statistics... */
}
-
+
/* finally, test if it is a KX */
if (rcvd < sizeof (struct UDPConfirmation) + sizeof (struct InitialKX))
char dummy[2];
char *colon;
char *cp;
-
+
if (1 == SSCANF (bindto,
"%u%1s",
&port,
"DISABLE_V6")) )
{
struct sockaddr_in *i4;
-
+
i4 = GNUNET_malloc (sizeof (struct sockaddr_in));
i4->sin_family = AF_INET;
i4->sin_port = htons ((uint16_t) port);
else
{
struct sockaddr_in6 *i6;
-
+
i6 = GNUNET_malloc (sizeof (struct sockaddr_in6));
i6->sin6_family = AF_INET6;
i6->sin6_port = htons ((uint16_t) port);
.size = htons (sizeof (pad)),
.type = htons (GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_PAD)
};
-
+
memcpy (pad,
&hdr,
sizeof (hdr));
return;
}
reschedule_receiver_timeout (receiver);
-
+
if (0 == receiver->acks_available)
{
/* use KX encryption method */
* recalculated and a fresh queue is initialized.
*
* @param receiver receiver to setup MQ for
- */
+ */
static void
setup_receiver_mq (struct ReceiverAddress *receiver)
{
size_t base_mtu;
-
+
if (NULL != receiver->qh)
{
GNUNET_TRANSPORT_communicator_mq_del (receiver->qh);
/**
* Setup a receiver for transmission. Setup the MQ processing and
- * inform transport that the queue is ready.
+ * inform transport that the queue is ready.
*
- * @param
- */
+ * @param
+ */
static struct ReceiverAddress *
receiver_setup (const struct GNUNET_PeerIdentity *target,
- const struct sockaddr *address,
- socklen_t address_len)
+ const struct sockaddr *address,
+ socklen_t address_len)
{
struct ReceiverAddress *receiver;
receiver = GNUNET_new (struct ReceiverAddress);
receiver->address = GNUNET_memdup (address,
- address_len);
+ address_len);
receiver->address_len = address_len;
receiver->target = *target;
receiver->nt = GNUNET_NT_scanner_get_type (is,
address,
address_len);
(void) GNUNET_CONTAINER_multipeermap_put (receivers,
- &receiver->target,
- receiver,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
+ &receiver->target,
+ receiver,
+ GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
receiver->timeout
= GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
receiver->hn = GNUNET_CONTAINER_heap_insert (receivers_heap,
- receiver,
- receiver->timeout.abs_value_us);
+ receiver,
+ receiver->timeout.abs_value_us);
GNUNET_STATISTICS_set (stats,
- "# receivers active",
- GNUNET_CONTAINER_multipeermap_size (receivers),
- GNUNET_NO);
- switch (address->sa_family)
- {
- case AF_INET:
- GNUNET_asprintf (&receiver->foreign_addr,
- "%s-%s",
- COMMUNICATOR_ADDRESS_PREFIX,
- GNUNET_a2s (receiver->address,
- receiver->address_len));
- break;
- case AF_INET6:
- GNUNET_asprintf (&receiver->foreign_addr,
- "%s-%s",
- COMMUNICATOR_ADDRESS_PREFIX,
- GNUNET_a2s (receiver->address,
- receiver->address_len));
- break;
- default:
- GNUNET_assert (0);
- }
-
+ "# receivers active",
+ GNUNET_CONTAINER_multipeermap_size (receivers),
+ GNUNET_NO);
+ receiver->foreign_addr = sockaddr_to_udpaddr_string (receiver->address,
+ receiver->address_len);
setup_receiver_mq (receiver);
if (NULL == timeout_task)
const char *path;
struct sockaddr *in;
socklen_t in_len;
-
+
if (0 != strncmp (address,
COMMUNICATOR_ADDRESS_PREFIX "-",
strlen (COMMUNICATOR_ADDRESS_PREFIX "-")))
}
path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")];
in = udp_address_to_sockaddr (path,
- &in_len);
+ &in_len);
receiver = receiver_setup (peer,
in,
in_len);
(void) receiver;
- return GNUNET_OK;
+ return GNUNET_OK;
}
GNUNET_TRANSPORT_communicator_disconnect (ch);
ch = NULL;
}
+ if (NULL != ah)
+ {
+ GNUNET_TRANSPORT_application_done (ah);
+ ah = NULL;
+ }
if (NULL != stats)
{
GNUNET_STATISTICS_destroy (stats,
const struct GNUNET_MessageHeader *msg)
{
const struct UDPAck *ack;
-
+
(void) cls;
if ( (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK) ||
(ntohs (msg->size) != sizeof (struct UDPAck)) )
* @param cls closure
* @param app_ctx[in,out] location where the app can store stuff
* on add and retrieve it on remove
- * @param add_remove #GNUNET_YES to add a new public IP address,
+ * @param add_remove #GNUNET_YES to add a new public IP address,
* #GNUNET_NO to remove a previous (now invalid) one
* @param ac address class the address belongs to
* @param addr either the previous or the new public IP address
enum GNUNET_NetworkType nt;
GNUNET_asprintf (&my_addr,
- "%s-%s",
- COMMUNICATOR_ADDRESS_PREFIX,
- GNUNET_a2s (addr,
- addrlen));
+ "%s-%s",
+ COMMUNICATOR_ADDRESS_PREFIX,
+ GNUNET_a2s (addr,
+ addrlen));
nt = GNUNET_NT_scanner_get_type (is,
- addr,
- addrlen);
+ addr,
+ addrlen);
ai = GNUNET_TRANSPORT_communicator_address_add (ch,
my_addr,
nt,
= GNUNET_SCHEDULER_add_delayed (INTERFACE_SCAN_FREQUENCY,
&ifc_broadcast,
bi);
-
+
switch (bi->sa->sa_family) {
case AF_INET:
{
static int yes = 1;
static int no = 0;
ssize_t sent;
-
+
if (GNUNET_OK !=
GNUNET_NETWORK_socket_setsockopt (udp_sock,
SOL_SOCKET,
if ( (AF_INET6 == addr->sa_family) &&
(GNUNET_YES != have_v6_socket) )
return GNUNET_OK; /* not using IPv6 */
-
+
bi = GNUNET_new (struct BroadcastInterface);
bi->sa = GNUNET_memdup (addr,
addrlen);
inet_pton (AF_INET6,
"FF05::13B",
&bi->mcreq.ipv6mr_multiaddr));
-
+
/* http://tools.ietf.org/html/rfc2553#section-5.2:
*
* IPV6_JOIN_GROUP
do_broadcast (void *cls)
{
struct BroadcastInterface *bin;
-
+
(void) cls;
for (struct BroadcastInterface *bi = bi_head;
NULL != bi;
socklen_t in_len;
struct sockaddr_storage in_sto;
socklen_t sto_len;
-
+
(void) cls;
cfg = c;
if (GNUNET_OK !=
}
in = udp_address_to_sockaddr (bindto,
- &in_len);
+ &in_len);
if (NULL == in)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
return;
}
udp_sock = GNUNET_NETWORK_socket_create (in->sa_family,
- SOCK_DGRAM,
- IPPROTO_UDP);
+ SOCK_DGRAM,
+ IPPROTO_UDP);
if (NULL == udp_sock)
{
GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
if (GNUNET_OK !=
GNUNET_NETWORK_socket_bind (udp_sock,
in,
- in_len))
+ in_len))
{
GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
"bind",
thus, get the real IN-address from the socket */
sto_len = sizeof (in_sto);
if (0 != getsockname (GNUNET_NETWORK_get_fd (udp_sock),
- (struct sockaddr *) &in_sto,
- &sto_len))
+ (struct sockaddr *) &in_sto,
+ &sto_len))
{
memcpy (&in_sto,
- in,
- in_len);
+ in,
+ in_len);
sto_len = in_len;
}
GNUNET_free (in);
in = (struct sockaddr *) &in_sto;
in_len = sto_len;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Bound to `%s'\n",
- GNUNET_a2s ((const struct sockaddr *) &in_sto,
- sto_len));
+ "Bound to `%s'\n",
+ GNUNET_a2s ((const struct sockaddr *) &in_sto,
+ sto_len));
switch (in->sa_family)
{
case AF_INET:
my_port = 0;
}
stats = GNUNET_STATISTICS_create ("C-UDP",
- cfg);
+ cfg);
senders = GNUNET_CONTAINER_multipeermap_create (32,
- GNUNET_YES);
+ GNUNET_YES);
receivers = GNUNET_CONTAINER_multipeermap_create (32,
- GNUNET_YES);
+ GNUNET_YES);
senders_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
receivers_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
key_cache = GNUNET_CONTAINER_multishortmap_create (1024,
- GNUNET_YES);
+ GNUNET_YES);
GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
- NULL);
+ NULL);
is = GNUNET_NT_scanner_init ();
my_private_key = GNUNET_CRYPTO_eddsa_key_create_from_configuration (cfg);
if (NULL == my_private_key)
&my_identity.public_key);
/* start reading */
read_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
- udp_sock,
- &sock_read,
- NULL);
+ udp_sock,
+ &sock_read,
+ NULL);
ch = GNUNET_TRANSPORT_communicator_connect (cfg,
- COMMUNICATOR_CONFIG_SECTION,
- COMMUNICATOR_ADDRESS_PREFIX,
+ COMMUNICATOR_CONFIG_SECTION,
+ COMMUNICATOR_ADDRESS_PREFIX,
GNUNET_TRANSPORT_CC_UNRELIABLE,
- &mq_init,
- NULL,
+ &mq_init,
+ NULL,
&enc_notify_cb,
NULL);
if (NULL == ch)
GNUNET_SCHEDULER_shutdown ();
return;
}
+ ah = GNUNET_TRANSPORT_application_init (cfg);
+ if (NULL == ah)
+ {
+ GNUNET_break (0);
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ }
/* start broadcasting */
if (GNUNET_YES !=
GNUNET_CONFIGURATION_get_value_yesno (cfg,
- COMMUNICATOR_CONFIG_SECTION,
- "DISABLE_BROADCAST"))
+ COMMUNICATOR_CONFIG_SECTION,
+ "DISABLE_BROADCAST"))
{
broadcast_task = GNUNET_SCHEDULER_add_now (&do_broadcast,
- NULL);
- }
+ NULL);
+ }
nat = GNUNET_NAT_register (cfg,
- COMMUNICATOR_CONFIG_SECTION,
- IPPROTO_UDP,
- 1 /* one address */,
- (const struct sockaddr **) &in,
- &in_len,
- &nat_address_cb,
- NULL /* FIXME: support reversal: #5529 */,
- NULL /* closure */);
+ COMMUNICATOR_CONFIG_SECTION,
+ IPPROTO_UDP,
+ 1 /* one address */,
+ (const struct sockaddr **) &in,
+ &in_len,
+ &nat_address_cb,
+ NULL /* FIXME: support reversal: #5529 */,
+ NULL /* closure */);
}
* Implement next:
* - address validation: what is our plan here?
* #1 Peerstore only gets 'validated' addresses
- * #2 transport needs another API to "trigger" validation!
- * API may be used by core/application or communicators;
- * => use yet another lib/MQ/connection?
- * #3 transport should use validation to also establish
+ * #2 transport should use validation to also establish
* effective flow control (for uni-directional transports!)
- * #4 UDP broadcasting logic must be extended to use the new API
- * #5 only validated addresses are selected for scheduling; that
+ * #3 only validated addresses are selected for scheduling; that
* also ensures we know the RTT
- * #6 to ensure flow control and RTT are OK, we always do the
+ * #4 to ensure flow control and RTT are OK, we always do the
* 'validation', even if address comes from PEERSTORE
- * #7
* - ACK handling / retransmission
* - address verification
* - track RTT, distance, loss, etc.
* - backchannel message encryption & decryption
* -
*
- * Easy:
- * - figure out how to call XXX_suggestion_cb!
- *
* Later:
* - change transport-core API to provide proper flow control in both
* directions, allow multiple messages per peer simultaneously (tag
continue;
}
ephemeral_task = GNUNET_SCHEDULER_add_at (ece->ephemeral_validity,
- &expire_ephemerals,
- NULL);
+ &expire_ephemerals,
+ NULL);
return;
}
}
struct EphemeralConfirmation ec;
ece = GNUNET_CONTAINER_multipeermap_get (ephemeral_map,
- pid);
+ pid);
if ( (NULL != ece) &&
(0 == GNUNET_TIME_absolute_get_remaining (ece->ephemeral_validity).rel_value_us) )
{
ece = GNUNET_new (struct EphemeralCacheEntry);
ece->target = *pid;
ece->ephemeral_validity = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get_monotonic (GST_cfg),
- EPHEMERAL_VALIDITY);
+ EPHEMERAL_VALIDITY);
GNUNET_assert (GNUNET_OK ==
- GNUNET_CRYPTO_ecdhe_key_create2 (&ece->private_key));
+ GNUNET_CRYPTO_ecdhe_key_create2 (&ece->private_key));
GNUNET_CRYPTO_ecdhe_key_get_public (&ece->private_key,
- &ece->ephemeral_key);
+ &ece->ephemeral_key);
ec.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_EPHEMERAL);
ec.purpose.size = htonl (sizeof (ec));
ec.target = *pid;
ec.ephemeral_key = ece->ephemeral_key;
GNUNET_assert (GNUNET_OK ==
- GNUNET_CRYPTO_eddsa_sign (GST_my_private_key,
- &ec.purpose,
- &ece->sender_sig));
+ GNUNET_CRYPTO_eddsa_sign (GST_my_private_key,
+ &ec.purpose,
+ &ece->sender_sig));
ece->hn = GNUNET_CONTAINER_heap_insert (ephemeral_heap,
ece,
ece->ephemeral_validity.abs_value_us);
GNUNET_assert (GNUNET_OK ==
- GNUNET_CONTAINER_multipeermap_put (ephemeral_map,
- &ece->target,
- ece,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
+ GNUNET_CONTAINER_multipeermap_put (ephemeral_map,
+ &ece->target,
+ ece,
+ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
if (NULL == ephemeral_task)
ephemeral_task = GNUNET_SCHEDULER_add_at (ece->ephemeral_validity,
&expire_ephemerals,
// FIXME: setup 'iv'
#if FIXME
dh_key_derive (&private_key,
- &cb->pid,
- &enc->iv,
- &key);
+ &cb->pid,
+ &enc->iv,
+ &key);
#endif
ppay.ephemeral_validity = GNUNET_TIME_absolute_hton (ephemeral_validity);
ppay.monotonic_time = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_monotonic (GST_cfg));
mpos = (char *) &enc[1];
#if FIXME
encrypt (key,
- &ppay,
- &mpos,
- sizeof (ppay));
+ &ppay,
+ &mpos,
+ sizeof (ppay));
encrypt (key,
- &cb[1],
- &mpos,
- ntohs (cb->header.size) - sizeof (*cb));
+ &cb[1],
+ &mpos,
+ ntohs (cb->header.size) - sizeof (*cb));
hmac (key,
- &enc->hmac);
+ &enc->hmac);
#endif
route_message (&cb->pid,
- &enc->header);
+ &enc->header);
GNUNET_SERVICE_client_continue (tc->client);
}
cqm->request_id = htonl (idgen++);
cqm->receiver = *pid;
memcpy (&cqm[1],
- address,
- alen);
+ address,
+ alen);
GNUNET_MQ_send (tc->mq,
- env);
+ env);
}
pr->wc = GNUNET_PEERSTORE_watch (peerstore,
"transport",
&pr->pid,
- "hello",
+ GNUNET_HELLO_PEERSTORE_KEY,
&handle_hello,
pr);
GNUNET_SERVICE_client_continue (tc->client);
}
+/**
+ * Check #GNUNET_MESSAGE_TYPE_TRANSPORT_REQUEST_HELLO_VALIDATION
+ * messages.
+ *
+ * @param cls a `struct TransportClient *`
+ * @param m message to verify
+ * @return #GNUNET_OK on success
+ */
+static int
+check_request_hello_validation (void *cls,
+ const struct RequestHelloValidationMessage *m)
+{
+ GNUNET_MQ_check_zero_termination (m);
+ return GNUNET_OK;
+}
+
+
+/**
+ * A client encountered an address of another peer. Consider validating it,
+ * and if validation succeeds, persist it to PEERSTORE.
+ *
+ * @param cls a `struct TransportClient *`
+ * @param m message to verify
+ */
+static void
+handle_request_hello_validation (void *cls,
+ const struct RequestHelloValidationMessage *m)
+{
+ // FIXME: implement validation!
+}
+
+
/**
* Free neighbour entry.
*
GNUNET_MESSAGE_TYPE_TRANSPORT_SUGGEST_CANCEL,
struct ExpressPreferenceMessage,
NULL),
+ GNUNET_MQ_hd_var_size (request_hello_validation,
+ GNUNET_MESSAGE_TYPE_TRANSPORT_REQUEST_HELLO_VALIDATION,
+ struct RequestHelloValidationMessage,
+ NULL),
/* communication with core */
GNUNET_MQ_hd_fixed_size (client_start,
GNUNET_MESSAGE_TYPE_TRANSPORT_START,