summaryrefslogtreecommitdiff
path: root/protocols/Tox/libtox/src
diff options
context:
space:
mode:
authordartraiden <wowemuh@gmail.com>2022-02-07 00:34:21 +0300
committerdartraiden <wowemuh@gmail.com>2022-02-07 00:35:37 +0300
commit223306302f39455970b67a97ba62e4a542224f7a (patch)
tree21da0622af231bea688b413d1238d15315d658ce /protocols/Tox/libtox/src
parent41317031f257ad6a06fa743860aff212074dc416 (diff)
Update libtox to 0.2.15
Diffstat (limited to 'protocols/Tox/libtox/src')
-rw-r--r--protocols/Tox/libtox/src/toxcore/DHT.c1120
-rw-r--r--protocols/Tox/libtox/src/toxcore/DHT.h170
-rw-r--r--protocols/Tox/libtox/src/toxcore/LAN_discovery.api.h57
-rw-r--r--protocols/Tox/libtox/src/toxcore/LAN_discovery.c153
-rw-r--r--protocols/Tox/libtox/src/toxcore/LAN_discovery.h20
-rw-r--r--protocols/Tox/libtox/src/toxcore/Messenger.c322
-rw-r--r--protocols/Tox/libtox/src/toxcore/Messenger.h200
-rw-r--r--protocols/Tox/libtox/src/toxcore/TCP_client.c429
-rw-r--r--protocols/Tox/libtox/src/toxcore/TCP_client.h44
-rw-r--r--protocols/Tox/libtox/src/toxcore/TCP_common.c291
-rw-r--r--protocols/Tox/libtox/src/toxcore/TCP_common.h97
-rw-r--r--protocols/Tox/libtox/src/toxcore/TCP_connection.c334
-rw-r--r--protocols/Tox/libtox/src/toxcore/TCP_connection.h89
-rw-r--r--protocols/Tox/libtox/src/toxcore/TCP_server.c546
-rw-r--r--protocols/Tox/libtox/src/toxcore/TCP_server.h70
-rw-r--r--protocols/Tox/libtox/src/toxcore/ccompat.h19
-rw-r--r--protocols/Tox/libtox/src/toxcore/crypto_core.api.h253
-rw-r--r--protocols/Tox/libtox/src/toxcore/crypto_core.c163
-rw-r--r--protocols/Tox/libtox/src/toxcore/crypto_core.h185
-rw-r--r--protocols/Tox/libtox/src/toxcore/crypto_core_mem.c87
-rw-r--r--protocols/Tox/libtox/src/toxcore/friend_connection.c127
-rw-r--r--protocols/Tox/libtox/src/toxcore/friend_connection.h69
-rw-r--r--protocols/Tox/libtox/src/toxcore/friend_requests.c23
-rw-r--r--protocols/Tox/libtox/src/toxcore/friend_requests.h12
-rw-r--r--protocols/Tox/libtox/src/toxcore/group.c322
-rw-r--r--protocols/Tox/libtox/src/toxcore/group.h121
-rw-r--r--protocols/Tox/libtox/src/toxcore/list.c14
-rw-r--r--protocols/Tox/libtox/src/toxcore/list.h20
-rw-r--r--protocols/Tox/libtox/src/toxcore/logger.c13
-rw-r--r--protocols/Tox/libtox/src/toxcore/logger.h2
-rw-r--r--protocols/Tox/libtox/src/toxcore/mono_time.c45
-rw-r--r--protocols/Tox/libtox/src/toxcore/mono_time.h6
-rw-r--r--protocols/Tox/libtox/src/toxcore/net_crypto.c545
-rw-r--r--protocols/Tox/libtox/src/toxcore/net_crypto.h127
-rw-r--r--protocols/Tox/libtox/src/toxcore/network.c572
-rw-r--r--protocols/Tox/libtox/src/toxcore/network.h212
-rw-r--r--protocols/Tox/libtox/src/toxcore/onion.c128
-rw-r--r--protocols/Tox/libtox/src/toxcore/onion.h36
-rw-r--r--protocols/Tox/libtox/src/toxcore/onion_announce.c108
-rw-r--r--protocols/Tox/libtox/src/toxcore/onion_announce.h29
-rw-r--r--protocols/Tox/libtox/src/toxcore/onion_client.c268
-rw-r--r--protocols/Tox/libtox/src/toxcore/onion_client.h46
-rw-r--r--protocols/Tox/libtox/src/toxcore/ping.api.h50
-rw-r--r--protocols/Tox/libtox/src/toxcore/ping.c103
-rw-r--r--protocols/Tox/libtox/src/toxcore/ping.h30
-rw-r--r--protocols/Tox/libtox/src/toxcore/ping_array.api.h66
-rw-r--r--protocols/Tox/libtox/src/toxcore/ping_array.c12
-rw-r--r--protocols/Tox/libtox/src/toxcore/ping_array.h22
-rw-r--r--protocols/Tox/libtox/src/toxcore/state.c13
-rw-r--r--protocols/Tox/libtox/src/toxcore/state.h2
-rw-r--r--protocols/Tox/libtox/src/toxcore/tox.api.h2862
-rw-r--r--protocols/Tox/libtox/src/toxcore/tox.c385
-rw-r--r--protocols/Tox/libtox/src/toxcore/tox.h1094
-rw-r--r--protocols/Tox/libtox/src/toxcore/tox_api.c16
-rw-r--r--protocols/Tox/libtox/src/toxcore/util.c8
-rw-r--r--protocols/Tox/libtox/src/toxcore/util.h6
-rw-r--r--protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/crypto_pwhash_scryptsalsa208sha256.h97
-rw-r--r--protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/crypto_scrypt-common.c257
-rw-r--r--protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/crypto_scrypt.h98
-rw-r--r--protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/export.h43
-rw-r--r--protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/nosse/pwhash_scryptsalsa208sha256_nosse.c309
-rw-r--r--protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/note_to_maintainers.txt14
-rw-r--r--protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/pbkdf2-sha256.c97
-rw-r--r--protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/pbkdf2-sha256.h57
-rw-r--r--protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/pwhash_scryptsalsa208sha256.c210
-rw-r--r--protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/runtime.c144
-rw-r--r--protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/runtime.h38
-rw-r--r--protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/scrypt_platform.c107
-rw-r--r--protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/sse/pwhash_scryptsalsa208sha256_sse.c401
-rw-r--r--protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/sysendian.h158
-rw-r--r--protocols/Tox/libtox/src/toxencryptsave/defines.h5
-rw-r--r--protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.api.h311
-rw-r--r--protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.c71
-rw-r--r--protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.h61
74 files changed, 4615 insertions, 10026 deletions
diff --git a/protocols/Tox/libtox/src/toxcore/DHT.c b/protocols/Tox/libtox/src/toxcore/DHT.c
index 267d46881e..4cc8d2002f 100644
--- a/protocols/Tox/libtox/src/toxcore/DHT.c
+++ b/protocols/Tox/libtox/src/toxcore/DHT.c
@@ -3,15 +3,15 @@
* Copyright © 2013 Tox project.
*/
-/*
+/**
* An implementation of the DHT as seen in docs/updates/DHT.md
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include "DHT.h"
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
#include "LAN_discovery.h"
#include "logger.h"
#include "mono_time.h"
@@ -20,22 +20,18 @@
#include "state.h"
#include "util.h"
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-
-/* The timeout after which a node is discarded completely. */
+/** The timeout after which a node is discarded completely. */
#define KILL_NODE_TIMEOUT (BAD_NODE_TIMEOUT + PING_INTERVAL)
-/* Ping interval in seconds for each random sending of a get nodes request. */
+/** Ping interval in seconds for each random sending of a get nodes request. */
#define GET_NODE_INTERVAL 20
#define MAX_PUNCHING_PORTS 48
-/* Interval in seconds between punching attempts*/
+/** Interval in seconds between punching attempts*/
#define PUNCH_INTERVAL 3
-/* Time in seconds after which punching parameters will be reset */
+/** Time in seconds after which punching parameters will be reset */
#define PUNCH_RESET_TIME 40
#define MAX_NORMAL_PUNCHING_TRIES 5
@@ -43,7 +39,7 @@
#define NAT_PING_REQUEST 0
#define NAT_PING_RESPONSE 1
-/* Number of get node requests to send to quickly find close nodes. */
+/** Number of get node requests to send to quickly find close nodes. */
#define MAX_BOOTSTRAP_TIMES 5
typedef struct DHT_Friend_Callback {
@@ -103,8 +99,7 @@ struct DHT {
struct Ping *ping;
Ping_Array *dht_ping_array;
- Ping_Array *dht_harden_ping_array;
- uint64_t last_run;
+ uint64_t cur_time;
Cryptopacket_Handler cryptopackethandlers[256];
@@ -178,7 +173,23 @@ static bool assoc_timeout(uint64_t cur_time, const IPPTsPng *assoc)
return (assoc->timestamp + BAD_NODE_TIMEOUT) <= cur_time;
}
-/* Compares pk1 and pk2 with pk.
+/** Converts an IPv4-in-IPv6 to IPv4 and returns the new IP_Port.
+ *
+ * If the ip_port is already IPv4 this function returns a copy of the original ip_port.
+ */
+static IP_Port ip_port_normalize(const IP_Port *ip_port)
+{
+ IP_Port res = *ip_port;
+
+ if (net_family_is_ipv6(res.ip.family) && ipv6_ipv4_in_v6(&res.ip.ip.v6)) {
+ res.ip.family = net_family_ipv4;
+ res.ip.ip.v4.uint32 = res.ip.ip.v6.uint32[3];
+ }
+
+ return res;
+}
+
+/** Compares pk1 and pk2 with pk.
*
* return 0 if both are same distance.
* return 1 if pk1 is closer.
@@ -202,7 +213,7 @@ int id_closest(const uint8_t *pk, const uint8_t *pk1, const uint8_t *pk2)
return 0;
}
-/* Return index of first unequal bit number.
+/** Return index of first unequal bit number.
*/
static unsigned int bit_by_bit_cmp(const uint8_t *pk1, const uint8_t *pk2)
{
@@ -228,11 +239,11 @@ static unsigned int bit_by_bit_cmp(const uint8_t *pk1, const uint8_t *pk2)
return i * 8 + j;
}
-/* Shared key generations are costly, it is therefore smart to store commonly used
- * ones so that they can re used later without being computed again.
+/** Shared key generations are costly, it is therefore smart to store commonly used
+ * ones so that they can be re-used later without being computed again.
*
- * If shared key is already in shared_keys, copy it to shared_key.
- * else generate it into shared_key and copy it to shared_keys
+ * If a shared key is already in shared_keys, copy it to shared_key.
+ * Otherwise generate it into shared_key and copy it to shared_keys
*/
void get_shared_key(const Mono_Time *mono_time, Shared_Keys *shared_keys, uint8_t *shared_key,
const uint8_t *secret_key, const uint8_t *public_key)
@@ -279,7 +290,7 @@ void get_shared_key(const Mono_Time *mono_time, Shared_Keys *shared_keys, uint8_
}
}
-/* Copy shared_key to encrypt/decrypt DHT packet from public_key into shared_key
+/** Copy shared_key to encrypt/decrypt DHT packet from public_key into shared_key
* for packets that we receive.
*/
void dht_get_shared_key_recv(DHT *dht, uint8_t *shared_key, const uint8_t *public_key)
@@ -287,7 +298,7 @@ void dht_get_shared_key_recv(DHT *dht, uint8_t *shared_key, const uint8_t *publi
get_shared_key(dht->mono_time, &dht->shared_keys_recv, shared_key, dht->self_secret_key, public_key);
}
-/* Copy shared_key to encrypt/decrypt DHT packet from public_key into shared_key
+/** Copy shared_key to encrypt/decrypt DHT packet from public_key into shared_key
* for packets that we send.
*/
void dht_get_shared_key_sent(DHT *dht, uint8_t *shared_key, const uint8_t *public_key)
@@ -297,7 +308,7 @@ void dht_get_shared_key_sent(DHT *dht, uint8_t *shared_key, const uint8_t *publi
#define CRYPTO_SIZE (1 + CRYPTO_PUBLIC_KEY_SIZE * 2 + CRYPTO_NONCE_SIZE)
-/* Create a request to peer.
+/** Create a request to peer.
* send_public_key and send_secret_key are the pub/secret keys of the sender.
* recv_public_key is public key of receiver.
* packet must be an array of MAX_CRYPTO_REQUEST_SIZE big.
@@ -339,7 +350,7 @@ int create_request(const uint8_t *send_public_key, const uint8_t *send_secret_ke
return len + CRYPTO_SIZE;
}
-/* Puts the senders public key in the request in public_key, the data from the request
+/** Puts the senders public key in the request in public_key, the data from the request
* in data if a friend or ping request was sent to us and returns the length of the data.
* packet is the request packet and length is its length.
*
@@ -381,7 +392,7 @@ int handle_request(const uint8_t *self_public_key, const uint8_t *self_secret_ke
#define PACKED_NODE_SIZE_IP4 (1 + SIZE_IP4 + sizeof(uint16_t) + CRYPTO_PUBLIC_KEY_SIZE)
#define PACKED_NODE_SIZE_IP6 (1 + SIZE_IP6 + sizeof(uint16_t) + CRYPTO_PUBLIC_KEY_SIZE)
-/* Return packet size of packed node with ip_family on success.
+/** Return packet size of packed node with ip_family on success.
* Return -1 on failure.
*/
int packed_node_size(Family ip_family)
@@ -398,7 +409,9 @@ int packed_node_size(Family ip_family)
}
-/* Packs an IP_Port structure into data of max size length.
+/** Packs an IP_Port structure into data of max size length.
+ *
+ * Packed_length is the offset of data currently packed.
*
* Returns size of packed IP_Port data on success
* Return -1 on failure.
@@ -455,7 +468,8 @@ int pack_ip_port(uint8_t *data, uint16_t length, const IP_Port *ip_port)
}
static int dht_create_packet(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
- const uint8_t *shared_key, const uint8_t type, uint8_t *plain, size_t plain_length, uint8_t *packet)
+ const uint8_t *shared_key, const uint8_t type,
+ const uint8_t *plain, size_t plain_length, uint8_t *packet)
{
VLA(uint8_t, encrypted, plain_length + CRYPTO_MAC_SIZE);
uint8_t nonce[CRYPTO_NONCE_SIZE];
@@ -476,7 +490,9 @@ static int dht_create_packet(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
return 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + encrypted_length;
}
-/* Unpack IP_Port structure from data of max size length into ip_port.
+/** Unpack IP_Port structure from data of max size length into ip_port.
+ *
+ * len_processed is the offset of data currently unpacked.
*
* Return size of unpacked ip_port on success.
* Return -1 on failure.
@@ -514,6 +530,10 @@ int unpack_ip_port(IP_Port *ip_port, const uint8_t *data, uint16_t length, bool
return -1;
}
+ *ip_port = (IP_Port) {
+ 0
+ };
+
if (is_ipv4) {
const uint32_t size = 1 + SIZE_IP4 + sizeof(uint16_t);
@@ -539,7 +559,7 @@ int unpack_ip_port(IP_Port *ip_port, const uint8_t *data, uint16_t length, bool
}
}
-/* Pack number of nodes into data of maxlength length.
+/** Pack number of nodes into data of maxlength length.
*
* return length of packed nodes on success.
* return -1 on failure.
@@ -573,7 +593,7 @@ int pack_nodes(uint8_t *data, uint16_t length, const Node_format *nodes, uint16_
return packed_length;
}
-/* Unpack data of length into nodes of size max_num_nodes.
+/** Unpack data of length into nodes of size max_num_nodes.
* Put the length of the data processed in processed_data_len.
* tcp_enabled sets if TCP nodes are expected (true) or not (false).
*
@@ -616,37 +636,44 @@ int unpack_nodes(Node_format *nodes, uint16_t max_num_nodes, uint16_t *processed
return num;
}
-/* Find index in an array with public_key equal to pk.
+/** Find index in an array with public_key equal to pk.
*
* return index or UINT32_MAX if not found.
*/
-#define INDEX_OF_PK(array, size, pk) \
- do { \
- for (uint32_t i = 0; i < size; ++i) { \
- if (id_equal(array[i].public_key, pk)) { \
- return i; \
- } \
- } \
- \
- return UINT32_MAX; \
- } while (0)
-
static uint32_t index_of_client_pk(const Client_data *array, uint32_t size, const uint8_t *pk)
{
- INDEX_OF_PK(array, size, pk);
+ for (uint32_t i = 0; i < size; ++i) {
+ if (id_equal(array[i].public_key, pk)) {
+ return i;
+ }
+ }
+
+ return UINT32_MAX;
}
static uint32_t index_of_friend_pk(const DHT_Friend *array, uint32_t size, const uint8_t *pk)
{
- INDEX_OF_PK(array, size, pk);
+ for (uint32_t i = 0; i < size; ++i) {
+ if (id_equal(array[i].public_key, pk)) {
+ return i;
+ }
+ }
+
+ return UINT32_MAX;
}
static uint32_t index_of_node_pk(const Node_format *array, uint32_t size, const uint8_t *pk)
{
- INDEX_OF_PK(array, size, pk);
+ for (uint32_t i = 0; i < size; ++i) {
+ if (id_equal(array[i].public_key, pk)) {
+ return i;
+ }
+ }
+
+ return UINT32_MAX;
}
-/* Find index of Client_data with ip_port equal to param ip_port.
+/** Find index of Client_data with ip_port equal to param ip_port.
*
* return index or UINT32_MAX if not found.
*/
@@ -662,43 +689,43 @@ static uint32_t index_of_client_ip_port(const Client_data *array, uint32_t size,
return UINT32_MAX;
}
-/* Update ip_port of client if it's needed.
+/** Update ip_port of client if it's needed.
*/
static void update_client(const Logger *log, const Mono_Time *mono_time, int index, Client_data *client,
- IP_Port ip_port)
+ const IP_Port *ip_port)
{
IPPTsPng *assoc;
int ip_version;
- if (net_family_is_ipv4(ip_port.ip.family)) {
+ if (net_family_is_ipv4(ip_port->ip.family)) {
assoc = &client->assoc4;
ip_version = 4;
- } else if (net_family_is_ipv6(ip_port.ip.family)) {
+ } else if (net_family_is_ipv6(ip_port->ip.family)) {
assoc = &client->assoc6;
ip_version = 6;
} else {
return;
}
- if (!ipport_equal(&assoc->ip_port, &ip_port)) {
+ if (!ipport_equal(&assoc->ip_port, ip_port)) {
char ip_str[IP_NTOA_LEN];
LOGGER_TRACE(log, "coipil[%u]: switching ipv%d from %s:%u to %s:%u",
index, ip_version,
ip_ntoa(&assoc->ip_port.ip, ip_str, sizeof(ip_str)),
net_ntohs(assoc->ip_port.port),
- ip_ntoa(&ip_port.ip, ip_str, sizeof(ip_str)),
- net_ntohs(ip_port.port));
+ ip_ntoa(&ip_port->ip, ip_str, sizeof(ip_str)),
+ net_ntohs(ip_port->port));
}
- if (!ip_is_lan(assoc->ip_port.ip) && ip_is_lan(ip_port.ip)) {
+ if (!ip_is_lan(&assoc->ip_port.ip) && ip_is_lan(&ip_port->ip)) {
return;
}
- assoc->ip_port = ip_port;
+ assoc->ip_port = *ip_port;
assoc->timestamp = mono_time_get(mono_time);
}
-/* Check if client with public_key is already in list of length length.
+/** Check if client with public_key is already in list of length length.
* If it is then set its corresponding timestamp to current time.
* If the id is already in the list with a different ip_port, update it.
* TODO(irungentoo): Maybe optimize this.
@@ -706,7 +733,7 @@ static void update_client(const Logger *log, const Mono_Time *mono_time, int ind
* return True(1) or False(0)
*/
static int client_or_ip_port_in_list(const Logger *log, const Mono_Time *mono_time, Client_data *list, uint16_t length,
- const uint8_t *public_key, IP_Port ip_port)
+ const uint8_t *public_key, const IP_Port *ip_port)
{
const uint64_t temp_time = mono_time_get(mono_time);
uint32_t index = index_of_client_pk(list, length, public_key);
@@ -722,7 +749,7 @@ static int client_or_ip_port_in_list(const Logger *log, const Mono_Time *mono_ti
* TODO(irungentoo): maybe we SHOULDN'T do that if that public_key is in a friend_list
* and the one who is the actual friend's public_key/address set?
* MAYBE: check the other address, if valid, don't nuke? */
- index = index_of_client_ip_port(list, length, &ip_port);
+ index = index_of_client_ip_port(list, length, ip_port);
if (index == UINT32_MAX) {
return 0;
@@ -731,7 +758,7 @@ static int client_or_ip_port_in_list(const Logger *log, const Mono_Time *mono_ti
IPPTsPng *assoc;
int ip_version;
- if (net_family_is_ipv4(ip_port.ip.family)) {
+ if (net_family_is_ipv4(ip_port->ip.family)) {
assoc = &list[index].assoc4;
ip_version = 4;
} else {
@@ -746,11 +773,13 @@ static int client_or_ip_port_in_list(const Logger *log, const Mono_Time *mono_ti
LOGGER_DEBUG(log, "coipil[%u]: switching public_key (ipv%d)", index, ip_version);
/* kill the other address, if it was set */
- memset(assoc, 0, sizeof(IPPTsPng));
+ *assoc = (IPPTsPng) {
+ 0
+ };
return 1;
}
-bool add_to_list(Node_format *nodes_list, uint32_t length, const uint8_t *pk, IP_Port ip_port,
+bool add_to_list(Node_format *nodes_list, uint32_t length, const uint8_t *pk, const IP_Port *ip_port,
const uint8_t *cmp_pk)
{
for (uint32_t i = 0; i < length; ++i) {
@@ -759,10 +788,10 @@ bool add_to_list(Node_format *nodes_list, uint32_t length, const uint8_t *pk, IP
memcpy(pk_bak, nodes_list[i].public_key, CRYPTO_PUBLIC_KEY_SIZE);
const IP_Port ip_port_bak = nodes_list[i].ip_port;
memcpy(nodes_list[i].public_key, pk, CRYPTO_PUBLIC_KEY_SIZE);
- nodes_list[i].ip_port = ip_port;
+ nodes_list[i].ip_port = *ip_port;
if (i != length - 1) {
- add_to_list(nodes_list, length, pk_bak, ip_port_bak, cmp_pk);
+ add_to_list(nodes_list, length, pk_bak, &ip_port_bak, cmp_pk);
}
return true;
@@ -772,25 +801,12 @@ bool add_to_list(Node_format *nodes_list, uint32_t length, const uint8_t *pk, IP
return false;
}
-/* TODO(irungentoo): change this to 7 when done*/
-#define HARDENING_ALL_OK 2
-/* return 0 if not.
- * return 1 if route request are ok
- * return 2 if it responds to send node packets correctly
- * return 4 if it can test other nodes correctly
- * return HARDENING_ALL_OK if all ok.
- */
-static uint8_t hardening_correct(const Hardening *h)
-{
- return h->routes_requests_ok + (h->send_nodes_ok << 1) + (h->testing_requests << 2);
-}
-
-/*
+/**
* helper for get_close_nodes(). argument list is a monster :D
*/
static void get_close_nodes_inner(uint64_t cur_time, const uint8_t *public_key, Node_format *nodes_list,
Family sa_family, const Client_data *client_list, uint32_t client_list_length,
- uint32_t *num_nodes_ptr, bool is_LAN, uint8_t want_good)
+ uint32_t *num_nodes_ptr, bool is_LAN)
{
if (!net_family_is_ipv4(sa_family) && !net_family_is_ipv6(sa_family) && !net_family_is_unspec(sa_family)) {
return;
@@ -824,12 +840,7 @@ static void get_close_nodes_inner(uint64_t cur_time, const uint8_t *public_key,
}
/* don't send LAN ips to non LAN peers */
- if (ip_is_lan(ipptp->ip_port.ip) && !is_LAN) {
- continue;
- }
-
- if (!ip_is_lan(ipptp->ip_port.ip) && want_good && hardening_correct(&ipptp->hardening) != HARDENING_ALL_OK
- && !id_equal(public_key, client->public_key)) {
+ if (ip_is_lan(&ipptp->ip_port.ip) && !is_LAN) {
continue;
}
@@ -838,78 +849,58 @@ static void get_close_nodes_inner(uint64_t cur_time, const uint8_t *public_key,
nodes_list[num_nodes].ip_port = ipptp->ip_port;
++num_nodes;
} else {
- add_to_list(nodes_list, MAX_SENT_NODES, client->public_key, ipptp->ip_port, public_key);
+ add_to_list(nodes_list, MAX_SENT_NODES, client->public_key, &ipptp->ip_port, public_key);
}
}
*num_nodes_ptr = num_nodes;
}
-/* Find MAX_SENT_NODES nodes closest to the public_key for the send nodes request:
+/** Find MAX_SENT_NODES nodes closest to the public_key for the send nodes request:
* put them in the nodes_list and return how many were found.
*
* TODO(irungentoo): For the love of based <your favorite deity, in doubt use
* "love"> make this function cleaner and much more efficient.
- *
- * want_good : do we want only good nodes as checked with the hardening returned or not?
*/
static int get_somewhat_close_nodes(const DHT *dht, const uint8_t *public_key, Node_format *nodes_list,
- Family sa_family, bool is_LAN, uint8_t want_good)
+ Family sa_family, bool is_LAN)
{
uint32_t num_nodes = 0;
- get_close_nodes_inner(dht->last_run, public_key, nodes_list, sa_family,
- dht->close_clientlist, LCLIENT_LIST, &num_nodes, is_LAN, 0);
-
- /* TODO(irungentoo): uncomment this when hardening is added to close friend clients */
-#if 0
+ get_close_nodes_inner(dht->cur_time, public_key, nodes_list, sa_family,
+ dht->close_clientlist, LCLIENT_LIST, &num_nodes, is_LAN);
for (uint32_t i = 0; i < dht->num_friends; ++i) {
- get_close_nodes_inner(dht->mono_time, public_key, nodes_list, sa_family,
+ get_close_nodes_inner(dht->cur_time, public_key, nodes_list, sa_family,
dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS,
- &num_nodes, is_LAN, want_good);
- }
-
-#endif
-
- for (uint32_t i = 0; i < dht->num_friends; ++i) {
- get_close_nodes_inner(dht->last_run, public_key, nodes_list, sa_family,
- dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS,
- &num_nodes, is_LAN, 0);
+ &num_nodes, is_LAN);
}
return num_nodes;
}
int get_close_nodes(const DHT *dht, const uint8_t *public_key, Node_format *nodes_list, Family sa_family,
- bool is_LAN, uint8_t want_good)
+ bool is_LAN)
{
memset(nodes_list, 0, MAX_SENT_NODES * sizeof(Node_format));
- return get_somewhat_close_nodes(dht, public_key, nodes_list, sa_family, is_LAN, want_good);
+ return get_somewhat_close_nodes(dht, public_key, nodes_list, sa_family, is_LAN);
}
-typedef struct DHT_Cmp_data {
+typedef struct DHT_Cmp_Data {
uint64_t cur_time;
const uint8_t *base_public_key;
Client_data entry;
-} DHT_Cmp_data;
-
-static bool incorrect_hardening(const IPPTsPng *assoc)
-{
- return hardening_correct(&assoc->hardening) != HARDENING_ALL_OK;
-}
+} DHT_Cmp_Data;
-static int cmp_dht_entry(const void *a, const void *b)
+static int dht_cmp_entry(const void *a, const void *b)
{
- DHT_Cmp_data cmp1;
- DHT_Cmp_data cmp2;
- memcpy(&cmp1, a, sizeof(DHT_Cmp_data));
- memcpy(&cmp2, b, sizeof(DHT_Cmp_data));
- const Client_data entry1 = cmp1.entry;
- const Client_data entry2 = cmp2.entry;
- const uint8_t *cmp_public_key = cmp1.base_public_key;
+ const DHT_Cmp_Data *cmp1 = (const DHT_Cmp_Data *)a;
+ const DHT_Cmp_Data *cmp2 = (const DHT_Cmp_Data *)b;
+ const Client_data entry1 = cmp1->entry;
+ const Client_data entry2 = cmp2->entry;
+ const uint8_t *cmp_public_key = cmp1->base_public_key;
- bool t1 = assoc_timeout(cmp1.cur_time, &entry1.assoc4) && assoc_timeout(cmp1.cur_time, &entry1.assoc6);
- bool t2 = assoc_timeout(cmp2.cur_time, &entry2.assoc4) && assoc_timeout(cmp2.cur_time, &entry2.assoc6);
+ const bool t1 = assoc_timeout(cmp1->cur_time, &entry1.assoc4) && assoc_timeout(cmp1->cur_time, &entry1.assoc6);
+ const bool t2 = assoc_timeout(cmp2->cur_time, &entry2.assoc4) && assoc_timeout(cmp2->cur_time, &entry2.assoc6);
if (t1 && t2) {
return 0;
@@ -923,17 +914,6 @@ static int cmp_dht_entry(const void *a, const void *b)
return 1;
}
- t1 = incorrect_hardening(&entry1.assoc4) && incorrect_hardening(&entry1.assoc6);
- t2 = incorrect_hardening(&entry2.assoc4) && incorrect_hardening(&entry2.assoc6);
-
- if (t1 && !t2) {
- return -1;
- }
-
- if (!t1 && t2) {
- return 1;
- }
-
const int close = id_closest(cmp_public_key, entry1.public_key, entry2.public_key);
if (close == 1) {
@@ -947,7 +927,7 @@ static int cmp_dht_entry(const void *a, const void *b)
return 0;
}
-/* Is it ok to store node with public_key in client.
+/** Is it ok to store node with public_key in client.
*
* return 0 if node can't be stored.
* return 1 if it can.
@@ -965,7 +945,7 @@ static void sort_client_list(Client_data *list, uint64_t cur_time, unsigned int
{
// Pass comp_public_key to qsort with each Client_data entry, so the
// comparison function can use it as the base of comparison.
- VLA(DHT_Cmp_data, cmp_list, length);
+ VLA(DHT_Cmp_Data, cmp_list, length);
for (uint32_t i = 0; i < length; ++i) {
cmp_list[i].cur_time = cur_time;
@@ -973,7 +953,7 @@ static void sort_client_list(Client_data *list, uint64_t cur_time, unsigned int
cmp_list[i].entry = list[i];
}
- qsort(cmp_list, length, sizeof(DHT_Cmp_data), cmp_dht_entry);
+ qsort(cmp_list, length, sizeof(DHT_Cmp_Data), dht_cmp_entry);
for (uint32_t i = 0; i < length; ++i) {
list[i] = cmp_list[i].entry;
@@ -999,12 +979,13 @@ static void update_client_with_reset(const Mono_Time *mono_time, Client_data *cl
ip_reset(&ipptp_write->ret_ip_port.ip);
ipptp_write->ret_ip_port.port = 0;
ipptp_write->ret_timestamp = 0;
+ ipptp_write->ret_ip_self = false;
/* zero out other address */
memset(ipptp_clear, 0, sizeof(*ipptp_clear));
}
-/* Replace a first bad (or empty) node with this one
+/** Replace a first bad (or empty) node with this one
* or replace a possibly bad node (tests failed or not done yet)
* that is further than any other in the list
* from the comp_public_key
@@ -1021,35 +1002,35 @@ static bool replace_all(const DHT *dht,
Client_data *list,
uint16_t length,
const uint8_t *public_key,
- IP_Port ip_port,
+ const IP_Port *ip_port,
const uint8_t *comp_public_key)
{
- if (!net_family_is_ipv4(ip_port.ip.family) && !net_family_is_ipv6(ip_port.ip.family)) {
+ if (!net_family_is_ipv4(ip_port->ip.family) && !net_family_is_ipv6(ip_port->ip.family)) {
return false;
}
- if (!store_node_ok(&list[1], dht->last_run, public_key, comp_public_key) &&
- !store_node_ok(&list[0], dht->last_run, public_key, comp_public_key)) {
+ if (!store_node_ok(&list[1], dht->cur_time, public_key, comp_public_key) &&
+ !store_node_ok(&list[0], dht->cur_time, public_key, comp_public_key)) {
return false;
}
- sort_client_list(list, dht->last_run, length, comp_public_key);
+ sort_client_list(list, dht->cur_time, length, comp_public_key);
Client_data *const client = &list[0];
id_copy(client->public_key, public_key);
- update_client_with_reset(dht->mono_time, client, &ip_port);
+ update_client_with_reset(dht->mono_time, client, ip_port);
return true;
}
-/* Add node to close list.
+/** Add node to close list.
*
* simulate is set to 1 if we want to check if a node can be added to the list without adding it.
*
* return -1 on failure.
* return 0 on success.
*/
-static int add_to_close(DHT *dht, const uint8_t *public_key, IP_Port ip_port, bool simulate)
+static int add_to_close(DHT *dht, const uint8_t *public_key, const IP_Port *ip_port, bool simulate)
{
unsigned int index = bit_by_bit_cmp(public_key, dht->self_public_key);
@@ -1062,8 +1043,8 @@ static int add_to_close(DHT *dht, const uint8_t *public_key, IP_Port ip_port, bo
* index is left as >= LCLIENT_LENGTH */
Client_data *const client = &dht->close_clientlist[(index * LCLIENT_NODES) + i];
- if (!assoc_timeout(dht->last_run, &client->assoc4) ||
- !assoc_timeout(dht->last_run, &client->assoc6)) {
+ if (!assoc_timeout(dht->cur_time, &client->assoc4) ||
+ !assoc_timeout(dht->cur_time, &client->assoc6)) {
continue;
}
@@ -1072,22 +1053,22 @@ static int add_to_close(DHT *dht, const uint8_t *public_key, IP_Port ip_port, bo
}
id_copy(client->public_key, public_key);
- update_client_with_reset(dht->mono_time, client, &ip_port);
+ update_client_with_reset(dht->mono_time, client, ip_port);
return 0;
}
return -1;
}
-/* Return 1 if node can be added to close list, 0 if it can't.
+/** Return 1 if node can be added to close list, 0 if it can't.
*/
-bool node_addable_to_close_list(DHT *dht, const uint8_t *public_key, IP_Port ip_port)
+bool node_addable_to_close_list(DHT *dht, const uint8_t *public_key, const IP_Port *ip_port)
{
return add_to_close(dht, public_key, ip_port, 1) == 0;
}
static bool is_pk_in_client_list(const Client_data *list, unsigned int client_list_length, uint64_t cur_time,
- const uint8_t *public_key, IP_Port ip_port)
+ const uint8_t *public_key, const IP_Port *ip_port)
{
const uint32_t index = index_of_client_pk(list, client_list_length, public_key);
@@ -1095,14 +1076,14 @@ static bool is_pk_in_client_list(const Client_data *list, unsigned int client_li
return 0;
}
- const IPPTsPng *assoc = net_family_is_ipv4(ip_port.ip.family)
+ const IPPTsPng *assoc = net_family_is_ipv4(ip_port->ip.family)
? &list[index].assoc4
: &list[index].assoc6;
return !assoc_timeout(cur_time, assoc);
}
-static bool is_pk_in_close_list(DHT *dht, const uint8_t *public_key, IP_Port ip_port)
+static bool is_pk_in_close_list(const DHT *dht, const uint8_t *public_key, const IP_Port *ip_port)
{
unsigned int index = bit_by_bit_cmp(public_key, dht->self_public_key);
@@ -1110,17 +1091,17 @@ static bool is_pk_in_close_list(DHT *dht, const uint8_t *public_key, IP_Port ip_
index = LCLIENT_LENGTH - 1;
}
- return is_pk_in_client_list(dht->close_clientlist + index * LCLIENT_NODES, LCLIENT_NODES, dht->last_run, public_key,
+ return is_pk_in_client_list(dht->close_clientlist + index * LCLIENT_NODES, LCLIENT_NODES, dht->cur_time, public_key,
ip_port);
}
-/* Check if the node obtained with a get_nodes with public_key should be pinged.
+/** Check if the node obtained with a get_nodes with public_key should be pinged.
* NOTE: for best results call it after addto_lists.
*
* return false if the node should not be pinged.
* return true if it should.
*/
-static bool ping_node_from_getnodes_ok(DHT *dht, const uint8_t *public_key, IP_Port ip_port)
+static bool ping_node_from_getnodes_ok(DHT *dht, const uint8_t *public_key, const IP_Port *ip_port)
{
bool ret = false;
@@ -1136,7 +1117,7 @@ static bool ping_node_from_getnodes_ok(DHT *dht, const uint8_t *public_key, IP_P
if (ret && index == UINT32_MAX && !in_close_list) {
if (*num < MAX_CLOSE_TO_BOOTSTRAP_NODES) {
memcpy(dht->to_bootstrap[*num].public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE);
- dht->to_bootstrap[*num].ip_port = ip_port;
+ dht->to_bootstrap[*num].ip_port = *ip_port;
++*num;
} else {
// TODO(irungentoo): ipv6 vs v4
@@ -1150,24 +1131,24 @@ static bool ping_node_from_getnodes_ok(DHT *dht, const uint8_t *public_key, IP_P
bool store_ok = false;
- if (store_node_ok(&dht_friend->client_list[1], dht->last_run, public_key, dht_friend->public_key)) {
+ if (store_node_ok(&dht_friend->client_list[1], dht->cur_time, public_key, dht_friend->public_key)) {
store_ok = true;
}
- if (store_node_ok(&dht_friend->client_list[0], dht->last_run, public_key, dht_friend->public_key)) {
+ if (store_node_ok(&dht_friend->client_list[0], dht->cur_time, public_key, dht_friend->public_key)) {
store_ok = true;
}
unsigned int *const friend_num = &dht_friend->num_to_bootstrap;
const uint32_t index = index_of_node_pk(dht_friend->to_bootstrap, *friend_num, public_key);
- const bool pk_in_list = is_pk_in_client_list(dht_friend->client_list, MAX_FRIEND_CLIENTS, dht->last_run, public_key,
+ const bool pk_in_list = is_pk_in_client_list(dht_friend->client_list, MAX_FRIEND_CLIENTS, dht->cur_time, public_key,
ip_port);
if (store_ok && index == UINT32_MAX && !pk_in_list) {
if (*friend_num < MAX_SENT_NODES) {
Node_format *const format = &dht_friend->to_bootstrap[*friend_num];
memcpy(format->public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE);
- format->ip_port = ip_port;
+ format->ip_port = *ip_port;
++*friend_num;
} else {
add_to_list(dht_friend->to_bootstrap, MAX_SENT_NODES, public_key, ip_port, dht_friend->public_key);
@@ -1180,41 +1161,37 @@ static bool ping_node_from_getnodes_ok(DHT *dht, const uint8_t *public_key, IP_P
return ret;
}
-/* Attempt to add client with ip_port and public_key to the friends client list
+/** Attempt to add client with ip_port and public_key to the friends client list
* and close_clientlist.
*
* returns 1+ if the item is used in any list, 0 else
*/
-uint32_t addto_lists(DHT *dht, IP_Port ip_port, const uint8_t *public_key)
+uint32_t addto_lists(DHT *dht, const IP_Port *ip_port, const uint8_t *public_key)
{
- uint32_t used = 0;
+ IP_Port ipp_copy = ip_port_normalize(ip_port);
- /* convert IPv4-in-IPv6 to IPv4 */
- if (net_family_is_ipv6(ip_port.ip.family) && ipv6_ipv4_in_v6(ip_port.ip.ip.v6)) {
- ip_port.ip.family = net_family_ipv4;
- ip_port.ip.ip.v4.uint32 = ip_port.ip.ip.v6.uint32[3];
- }
+ uint32_t used = 0;
/* NOTE: Current behavior if there are two clients with the same id is
* to replace the first ip by the second.
*/
const bool in_close_list = client_or_ip_port_in_list(dht->log, dht->mono_time, dht->close_clientlist, LCLIENT_LIST,
- public_key, ip_port);
+ public_key, &ipp_copy);
/* add_to_close should be called only if !in_list (don't extract to variable) */
- if (in_close_list || add_to_close(dht, public_key, ip_port, 0)) {
+ if (in_close_list || add_to_close(dht, public_key, &ipp_copy, 0)) {
++used;
}
- DHT_Friend *friend_foundip = nullptr;
+ const DHT_Friend *friend_foundip = nullptr;
for (uint32_t i = 0; i < dht->num_friends; ++i) {
const bool in_list = client_or_ip_port_in_list(dht->log, dht->mono_time, dht->friends_list[i].client_list,
- MAX_FRIEND_CLIENTS, public_key, ip_port);
+ MAX_FRIEND_CLIENTS, public_key, &ipp_copy);
/* replace_all should be called only if !in_list (don't extract to variable) */
if (in_list
- || replace_all(dht, dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS, public_key, ip_port,
+ || replace_all(dht, dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS, public_key, &ipp_copy,
dht->friends_list[i].public_key)) {
DHT_Friend *dht_friend = &dht->friends_list[i];
@@ -1233,15 +1210,15 @@ uint32_t addto_lists(DHT *dht, IP_Port ip_port, const uint8_t *public_key)
for (uint32_t i = 0; i < friend_foundip->lock_count; ++i) {
if (friend_foundip->callbacks[i].ip_callback) {
friend_foundip->callbacks[i].ip_callback(friend_foundip->callbacks[i].data,
- friend_foundip->callbacks[i].number, ip_port);
+ friend_foundip->callbacks[i].number, &ipp_copy);
}
}
return used;
}
-static bool update_client_data(const Mono_Time *mono_time, Client_data *array, size_t size, IP_Port ip_port,
- const uint8_t *pk)
+static bool update_client_data(const Mono_Time *mono_time, Client_data *array, size_t size, const IP_Port *ip_port,
+ const uint8_t *pk, bool node_is_self)
{
const uint64_t temp_time = mono_time_get(mono_time);
const uint32_t index = index_of_client_pk(array, size, pk);
@@ -1253,32 +1230,30 @@ static bool update_client_data(const Mono_Time *mono_time, Client_data *array, s
Client_data *const data = &array[index];
IPPTsPng *assoc;
- if (net_family_is_ipv4(ip_port.ip.family)) {
+ if (net_family_is_ipv4(ip_port->ip.family)) {
assoc = &data->assoc4;
- } else if (net_family_is_ipv6(ip_port.ip.family)) {
+ } else if (net_family_is_ipv6(ip_port->ip.family)) {
assoc = &data->assoc6;
} else {
return true;
}
- assoc->ret_ip_port = ip_port;
+ assoc->ret_ip_port = *ip_port;
assoc->ret_timestamp = temp_time;
+ assoc->ret_ip_self = node_is_self;
+
return true;
}
-/* If public_key is a friend or us, update ret_ip_port
+/** If public_key is a friend or us, update ret_ip_port
* nodepublic_key is the id of the node that sent us this info.
*/
-static void returnedip_ports(DHT *dht, IP_Port ip_port, const uint8_t *public_key, const uint8_t *nodepublic_key)
+static void returnedip_ports(DHT *dht, const IP_Port *ip_port, const uint8_t *public_key, const uint8_t *nodepublic_key)
{
- /* convert IPv4-in-IPv6 to IPv4 */
- if (net_family_is_ipv6(ip_port.ip.family) && ipv6_ipv4_in_v6(ip_port.ip.ip.v6)) {
- ip_port.ip.family = net_family_ipv4;
- ip_port.ip.ip.v4.uint32 = ip_port.ip.ip.v6.uint32[3];
- }
+ IP_Port ipp_copy = ip_port_normalize(ip_port);
if (id_equal(public_key, dht->self_public_key)) {
- update_client_data(dht->mono_time, dht->close_clientlist, LCLIENT_LIST, ip_port, nodepublic_key);
+ update_client_data(dht->mono_time, dht->close_clientlist, LCLIENT_LIST, &ipp_copy, nodepublic_key, true);
return;
}
@@ -1286,41 +1261,36 @@ static void returnedip_ports(DHT *dht, IP_Port ip_port, const uint8_t *public_ke
if (id_equal(public_key, dht->friends_list[i].public_key)) {
Client_data *const client_list = dht->friends_list[i].client_list;
- if (update_client_data(dht->mono_time, client_list, MAX_FRIEND_CLIENTS, ip_port, nodepublic_key)) {
+ if (update_client_data(dht->mono_time, client_list, MAX_FRIEND_CLIENTS, &ipp_copy, nodepublic_key, false)) {
return;
}
}
}
}
-/* Send a getnodes request.
- * sendback_node is the node that it will send back the response to (set to NULL to disable this) */
-static int getnodes(DHT *dht, IP_Port ip_port, const uint8_t *public_key, const uint8_t *client_id,
- const Node_format *sendback_node)
+bool dht_getnodes(DHT *dht, const IP_Port *ip_port, const uint8_t *public_key, const uint8_t *client_id)
{
/* Check if packet is going to be sent to ourself. */
if (id_equal(public_key, dht->self_public_key)) {
- return -1;
+ return false;
}
uint8_t plain_message[sizeof(Node_format) * 2] = {0};
Node_format receiver;
memcpy(receiver.public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE);
- receiver.ip_port = ip_port;
- memcpy(plain_message, &receiver, sizeof(receiver));
+ receiver.ip_port = *ip_port;
+
+ if (pack_nodes(plain_message, sizeof(plain_message), &receiver, 1) == -1) {
+ return false;
+ }
uint64_t ping_id = 0;
- if (sendback_node != nullptr) {
- memcpy(plain_message + sizeof(receiver), sendback_node, sizeof(Node_format));
- ping_id = ping_array_add(dht->dht_harden_ping_array, dht->mono_time, plain_message, sizeof(plain_message));
- } else {
- ping_id = ping_array_add(dht->dht_ping_array, dht->mono_time, plain_message, sizeof(receiver));
- }
+ ping_id = ping_array_add(dht->dht_ping_array, dht->mono_time, plain_message, sizeof(receiver));
if (ping_id == 0) {
- return -1;
+ return false;
}
uint8_t plain[CRYPTO_PUBLIC_KEY_SIZE + sizeof(ping_id)];
@@ -1335,15 +1305,21 @@ static int getnodes(DHT *dht, IP_Port ip_port, const uint8_t *public_key, const
const int len = dht_create_packet(dht->self_public_key, shared_key, NET_PACKET_GET_NODES,
plain, sizeof(plain), data);
+ crypto_memzero(shared_key, sizeof(shared_key));
+
if (len != sizeof(data)) {
- return -1;
+ return false;
}
- return sendpacket(dht->net, ip_port, data, len);
+ if (sendpacket(dht->net, ip_port, data, len) > 0) {
+ return true;
+ }
+
+ return false;
}
-/* Send a send nodes response: message for IPv6 nodes */
-static int sendnodes_ipv6(const DHT *dht, IP_Port ip_port, const uint8_t *public_key, const uint8_t *client_id,
+/** Send a send nodes response: message for IPv6 nodes */
+static int sendnodes_ipv6(const DHT *dht, const IP_Port *ip_port, const uint8_t *public_key, const uint8_t *client_id,
const uint8_t *sendback_data, uint16_t length, const uint8_t *shared_encryption_key)
{
/* Check if packet is going to be sent to ourself. */
@@ -1359,7 +1335,7 @@ static int sendnodes_ipv6(const DHT *dht, IP_Port ip_port, const uint8_t *public
Node_format nodes_list[MAX_SENT_NODES];
const uint32_t num_nodes =
- get_close_nodes(dht, client_id, nodes_list, net_family_unspec, ip_is_lan(ip_port.ip), 1);
+ get_close_nodes(dht, client_id, nodes_list, net_family_unspec, ip_is_lan(&ip_port->ip));
VLA(uint8_t, plain, 1 + node_format_size * MAX_SENT_NODES + length);
@@ -1391,7 +1367,7 @@ static int sendnodes_ipv6(const DHT *dht, IP_Port ip_port, const uint8_t *public
#define CRYPTO_NODE_SIZE (CRYPTO_PUBLIC_KEY_SIZE + sizeof(uint64_t))
-static int handle_getnodes(void *object, IP_Port source, const uint8_t *packet, uint16_t length, void *userdata)
+static int handle_getnodes(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length, void *userdata)
{
if (length != (CRYPTO_SIZE + CRYPTO_MAC_SIZE + sizeof(uint64_t))) {
return true;
@@ -1416,6 +1392,7 @@ static int handle_getnodes(void *object, IP_Port source, const uint8_t *packet,
plain);
if (len != CRYPTO_NODE_SIZE) {
+ crypto_memzero(shared_key, sizeof(shared_key));
return true;
}
@@ -1423,39 +1400,34 @@ static int handle_getnodes(void *object, IP_Port source, const uint8_t *packet,
ping_add(dht->ping, packet + 1, source);
+ crypto_memzero(shared_key, sizeof(shared_key));
+
return false;
}
-/* return false if no
- * return true if yes */
-static bool sent_getnode_to_node(DHT *dht, const uint8_t *public_key, IP_Port node_ip_port, uint64_t ping_id,
- Node_format *sendback_node)
+/** Return true if we sent a getnode packet to the peer associated with the supplied info. */
+static bool sent_getnode_to_node(DHT *dht, const uint8_t *public_key, const IP_Port *node_ip_port, uint64_t ping_id)
{
uint8_t data[sizeof(Node_format) * 2];
- if (ping_array_check(dht->dht_ping_array, dht->mono_time, data, sizeof(data), ping_id) == sizeof(Node_format)) {
- memset(sendback_node, 0, sizeof(Node_format));
- } else if (ping_array_check(dht->dht_harden_ping_array, dht->mono_time, data, sizeof(data), ping_id) == sizeof(data)) {
- memcpy(sendback_node, data + sizeof(Node_format), sizeof(Node_format));
- } else {
+ if (ping_array_check(dht->dht_ping_array, dht->mono_time, data, sizeof(data), ping_id) != sizeof(Node_format)) {
return false;
}
Node_format test;
- memcpy(&test, data, sizeof(Node_format));
- if (!ipport_equal(&test.ip_port, &node_ip_port) || !id_equal(test.public_key, public_key)) {
+ if (unpack_nodes(&test, 1, nullptr, data, sizeof(data), false) != 1) {
+ return false;
+ }
+
+ if (!ipport_equal(&test.ip_port, node_ip_port) || !id_equal(test.public_key, public_key)) {
return false;
}
return true;
}
-/* Function is needed in following functions. */
-static int send_hardening_getnode_res(const DHT *dht, const Node_format *sendto, const uint8_t *queried_client_id,
- const uint8_t *nodes_data, uint16_t nodes_data_length);
-
-static int handle_sendnodes_core(void *object, IP_Port source, const uint8_t *packet, uint16_t length,
+static int handle_sendnodes_core(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length,
Node_format *plain_nodes, uint16_t size_plain_nodes, uint32_t *num_nodes_out)
{
DHT *const dht = (DHT *)object;
@@ -1485,6 +1457,8 @@ static int handle_sendnodes_core(void *object, IP_Port source, const uint8_t *pa
1 + data_size + sizeof(uint64_t) + CRYPTO_MAC_SIZE,
plain);
+ crypto_memzero(shared_key, sizeof(shared_key));
+
if ((unsigned int)len != SIZEOF_VLA(plain)) {
return 1;
}
@@ -1493,12 +1467,10 @@ static int handle_sendnodes_core(void *object, IP_Port source, const uint8_t *pa
return 1;
}
- Node_format sendback_node;
-
uint64_t ping_id;
memcpy(&ping_id, plain + 1 + data_size, sizeof(ping_id));
- if (!sent_getnode_to_node(dht, packet + 1, source, ping_id, &sendback_node)) {
+ if (!sent_getnode_to_node(dht, packet + 1, source, ping_id)) {
return 1;
}
@@ -1522,11 +1494,11 @@ static int handle_sendnodes_core(void *object, IP_Port source, const uint8_t *pa
*num_nodes_out = num_nodes;
- send_hardening_getnode_res(dht, &sendback_node, packet + 1, plain + 1, data_size);
return 0;
}
-static int handle_sendnodes_ipv6(void *object, IP_Port source, const uint8_t *packet, uint16_t length, void *userdata)
+static int handle_sendnodes_ipv6(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length,
+ void *userdata)
{
DHT *const dht = (DHT *)object;
Node_format plain_nodes[MAX_SENT_NODES];
@@ -1542,8 +1514,8 @@ static int handle_sendnodes_ipv6(void *object, IP_Port source, const uint8_t *pa
for (uint32_t i = 0; i < num_nodes; ++i) {
if (ipport_isset(&plain_nodes[i].ip_port)) {
- ping_node_from_getnodes_ok(dht, plain_nodes[i].public_key, plain_nodes[i].ip_port);
- returnedip_ports(dht, plain_nodes[i].ip_port, plain_nodes[i].public_key, packet + 1);
+ ping_node_from_getnodes_ok(dht, plain_nodes[i].public_key, &plain_nodes[i].ip_port);
+ returnedip_ports(dht, &plain_nodes[i].ip_port, plain_nodes[i].public_key, packet + 1);
}
}
@@ -1553,13 +1525,25 @@ static int handle_sendnodes_ipv6(void *object, IP_Port source, const uint8_t *pa
/*----------------------------------------------------------------------------------*/
/*------------------------END of packet handling functions--------------------------*/
+static void dht_friend_lock(DHT_Friend *const dht_friend, dht_ip_cb *ip_callback,
+ void *data, int32_t number, uint16_t *lock_count)
+{
+ const uint16_t lock_num = dht_friend->lock_count;
+ ++dht_friend->lock_count;
+ dht_friend->callbacks[lock_num].ip_callback = ip_callback;
+ dht_friend->callbacks[lock_num].data = data;
+ dht_friend->callbacks[lock_num].number = number;
+
+ if (lock_count) {
+ *lock_count = lock_num + 1;
+ }
+}
+
int dht_addfriend(DHT *dht, const uint8_t *public_key, dht_ip_cb *ip_callback,
void *data, int32_t number, uint16_t *lock_count)
{
const uint32_t friend_num = index_of_friend_pk(dht->friends_list, dht->num_friends, public_key);
- uint16_t lock_num;
-
if (friend_num != UINT32_MAX) { /* Is friend already in DHT? */
DHT_Friend *const dht_friend = &dht->friends_list[friend_num];
@@ -1567,15 +1551,7 @@ int dht_addfriend(DHT *dht, const uint8_t *public_key, dht_ip_cb *ip_callback,
return -1;
}
- lock_num = dht_friend->lock_count;
- ++dht_friend->lock_count;
- dht_friend->callbacks[lock_num].ip_callback = ip_callback;
- dht_friend->callbacks[lock_num].data = data;
- dht_friend->callbacks[lock_num].number = number;
-
- if (lock_count) {
- *lock_count = lock_num + 1;
- }
+ dht_friend_lock(dht_friend, ip_callback, data, number, lock_count);
return 0;
}
@@ -1594,18 +1570,10 @@ int dht_addfriend(DHT *dht, const uint8_t *public_key, dht_ip_cb *ip_callback,
dht_friend->nat.nat_ping_id = random_u64();
++dht->num_friends;
- lock_num = dht_friend->lock_count;
- ++dht_friend->lock_count;
- dht_friend->callbacks[lock_num].ip_callback = ip_callback;
- dht_friend->callbacks[lock_num].data = data;
- dht_friend->callbacks[lock_num].number = number;
-
- if (lock_count) {
- *lock_count = lock_num + 1;
- }
+ dht_friend_lock(dht_friend, ip_callback, data, number, lock_count);
dht_friend->num_to_bootstrap = get_close_nodes(dht, dht_friend->public_key, dht_friend->to_bootstrap, net_family_unspec,
- 1, 0);
+ 1);
return 0;
}
@@ -1632,9 +1600,7 @@ int dht_delfriend(DHT *dht, const uint8_t *public_key, uint16_t lock_count)
--dht->num_friends;
if (dht->num_friends != friend_num) {
- memcpy(&dht->friends_list[friend_num],
- &dht->friends_list[dht->num_friends],
- sizeof(DHT_Friend));
+ dht->friends_list[friend_num] = dht->friends_list[dht->num_friends];
}
if (dht->num_friends == 0) {
@@ -1643,7 +1609,7 @@ int dht_delfriend(DHT *dht, const uint8_t *public_key, uint16_t lock_count)
return 0;
}
- DHT_Friend *const temp = (DHT_Friend *)realloc(dht->friends_list, sizeof(DHT_Friend) * (dht->num_friends));
+ DHT_Friend *const temp = (DHT_Friend *)realloc(dht->friends_list, sizeof(DHT_Friend) * dht->num_friends);
if (temp == nullptr) {
return -1;
@@ -1665,7 +1631,7 @@ int dht_getfriendip(const DHT *dht, const uint8_t *public_key, IP_Port *ip_port)
return -1;
}
- DHT_Friend *const frnd = &dht->friends_list[friend_index];
+ const DHT_Friend *const frnd = &dht->friends_list[friend_index];
const uint32_t client_index = index_of_client_pk(frnd->client_list, MAX_FRIEND_CLIENTS, public_key);
if (client_index == -1) {
@@ -1678,7 +1644,7 @@ int dht_getfriendip(const DHT *dht, const uint8_t *public_key, IP_Port *ip_port)
for (const IPPTsPng * const *it = assocs; *it; ++it) {
const IPPTsPng *const assoc = *it;
- if (!assoc_timeout(dht->last_run, assoc)) {
+ if (!assoc_timeout(dht->cur_time, assoc)) {
*ip_port = assoc->ip_port;
return 1;
}
@@ -1687,7 +1653,7 @@ int dht_getfriendip(const DHT *dht, const uint8_t *public_key, IP_Port *ip_port)
return -1;
}
-/* returns number of nodes not in kill-timeout */
+/** returns number of nodes not in kill-timeout */
static uint8_t do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, const uint8_t *public_key,
Client_data *list, uint32_t list_count, uint32_t *bootstrap_times, bool sortable)
{
@@ -1714,12 +1680,12 @@ static uint8_t do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, co
++not_kill;
if (mono_time_is_timeout(dht->mono_time, assoc->last_pinged, PING_INTERVAL)) {
- getnodes(dht, assoc->ip_port, client->public_key, public_key, nullptr);
+ dht_getnodes(dht, &assoc->ip_port, client->public_key, public_key);
assoc->last_pinged = temp_time;
}
/* If node is good. */
- if (!assoc_timeout(dht->last_run, assoc)) {
+ if (!assoc_timeout(dht->cur_time, assoc)) {
client_list[num_nodes] = client;
assoc_list[num_nodes] = assoc;
++num_nodes;
@@ -1736,18 +1702,18 @@ static uint8_t do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, co
}
if (sortable && sort_ok) {
- sort_client_list(list, dht->last_run, list_count, public_key);
+ sort_client_list(list, dht->cur_time, list_count, public_key);
}
if ((num_nodes != 0) && (mono_time_is_timeout(dht->mono_time, *lastgetnode, GET_NODE_INTERVAL)
|| *bootstrap_times < MAX_BOOTSTRAP_TIMES)) {
- uint32_t rand_node = random_u32() % num_nodes;
+ uint32_t rand_node = random_range_u32(num_nodes);
if ((num_nodes - 1) != rand_node) {
- rand_node += random_u32() % (num_nodes - (rand_node + 1));
+ rand_node += random_range_u32(num_nodes - (rand_node + 1));
}
- getnodes(dht, assoc_list[rand_node]->ip_port, client_list[rand_node]->public_key, public_key, nullptr);
+ dht_getnodes(dht, &assoc_list[rand_node]->ip_port, client_list[rand_node]->public_key, public_key);
*lastgetnode = temp_time;
++*bootstrap_times;
@@ -1756,7 +1722,7 @@ static uint8_t do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, co
return not_kill;
}
-/* Ping each client in the "friends" list every PING_INTERVAL seconds. Send a get nodes request
+/** Ping each client in the "friends" list every PING_INTERVAL seconds. Send a get nodes request
* every GET_NODE_INTERVAL seconds to a random good node for each "friend" in our "friends" list.
*/
static void do_dht_friends(DHT *dht)
@@ -1765,8 +1731,7 @@ static void do_dht_friends(DHT *dht)
DHT_Friend *const dht_friend = &dht->friends_list[i];
for (size_t j = 0; j < dht_friend->num_to_bootstrap; ++j) {
- getnodes(dht, dht_friend->to_bootstrap[j].ip_port, dht_friend->to_bootstrap[j].public_key, dht_friend->public_key,
- nullptr);
+ dht_getnodes(dht, &dht_friend->to_bootstrap[j].ip_port, dht_friend->to_bootstrap[j].public_key, dht_friend->public_key);
}
dht_friend->num_to_bootstrap = 0;
@@ -1777,13 +1742,13 @@ static void do_dht_friends(DHT *dht)
}
}
-/* Ping each client in the close nodes list every PING_INTERVAL seconds.
+/** Ping each client in the close nodes list every PING_INTERVAL seconds.
* Send a get nodes request every GET_NODE_INTERVAL seconds to a random good node in the list.
*/
static void do_Close(DHT *dht)
{
for (size_t i = 0; i < dht->num_to_bootstrap; ++i) {
- getnodes(dht, dht->to_bootstrap[i].ip_port, dht->to_bootstrap[i].public_key, dht->self_public_key, nullptr);
+ dht_getnodes(dht, &dht->to_bootstrap[i].ip_port, dht->to_bootstrap[i].public_key, dht->self_public_key);
}
dht->num_to_bootstrap = 0;
@@ -1819,15 +1784,11 @@ static void do_Close(DHT *dht)
}
}
-void dht_getnodes(DHT *dht, const IP_Port *from_ipp, const uint8_t *from_id, const uint8_t *which_id)
+void dht_bootstrap(DHT *dht, const IP_Port *ip_port, const uint8_t *public_key)
{
- getnodes(dht, *from_ipp, from_id, which_id, nullptr);
+ dht_getnodes(dht, ip_port, public_key, dht->self_public_key);
}
-void dht_bootstrap(DHT *dht, IP_Port ip_port, const uint8_t *public_key)
-{
- getnodes(dht, ip_port, public_key, dht->self_public_key, nullptr);
-}
int dht_bootstrap_from_address(DHT *dht, const char *address, uint8_t ipv6enabled,
uint16_t port, const uint8_t *public_key)
{
@@ -1845,11 +1806,11 @@ int dht_bootstrap_from_address(DHT *dht, const char *address, uint8_t ipv6enable
if (addr_resolve_or_parse_ip(address, &ip_port_v64.ip, ip_extra)) {
ip_port_v64.port = port;
- dht_bootstrap(dht, ip_port_v64, public_key);
+ dht_bootstrap(dht, &ip_port_v64, public_key);
if ((ip_extra != nullptr) && ip_isset(ip_extra)) {
ip_port_v4.port = port;
- dht_bootstrap(dht, ip_port_v4, public_key);
+ dht_bootstrap(dht, &ip_port_v4, public_key);
}
return 1;
@@ -1858,7 +1819,7 @@ int dht_bootstrap_from_address(DHT *dht, const char *address, uint8_t ipv6enable
return 0;
}
-/* Send the given packet to node with public_key
+/** Send the given packet to node with public_key.
*
* return -1 if failure.
*/
@@ -1873,7 +1834,7 @@ int route_packet(const DHT *dht, const uint8_t *public_key, const uint8_t *packe
const IPPTsPng *const assoc = *it;
if (ip_isset(&assoc->ip_port.ip)) {
- return sendpacket(dht->net, assoc->ip_port, packet, length);
+ return sendpacket(dht->net, &assoc->ip_port, packet, length);
}
}
@@ -1884,7 +1845,7 @@ int route_packet(const DHT *dht, const uint8_t *public_key, const uint8_t *packe
return -1;
}
-/* Puts all the different ips returned by the nodes for a friend_num into array ip_portlist.
+/** Puts all the different ips returned by the nodes for a friend_num into array ip_portlist.
* ip_portlist must be at least MAX_FRIEND_CLIENTS big.
*
* return the number of ips returned.
@@ -1920,8 +1881,8 @@ static int friend_iplist(const DHT *dht, IP_Port *ip_portlist, uint16_t friend_n
}
if (id_equal(client->public_key, dht_friend->public_key)) {
- if (!assoc_timeout(dht->last_run, &client->assoc6)
- || !assoc_timeout(dht->last_run, &client->assoc4)) {
+ if (!assoc_timeout(dht->cur_time, &client->assoc6)
+ || !assoc_timeout(dht->cur_time, &client->assoc4)) {
return 0; /* direct connectivity */
}
}
@@ -1960,12 +1921,83 @@ static int friend_iplist(const DHT *dht, IP_Port *ip_portlist, uint16_t friend_n
}
-/* Send the following packet to everyone who tells us they are connected to friend_id.
+/**
+ * Callback invoked for each IP/port of each client of a friend.
+ *
+ * For each client, the callback is invoked twice: once for IPv4 and once for
+ * IPv6. If the callback returns `false` after the IPv4 invocation, it will not
+ * be invoked for IPv6.
+ *
+ * @param dht The main DHT instance.
+ * @param ip_port The currently processed IP/port.
+ * @param n A pointer to the number that will be returned from `foreach_ip_port`.
+ * @param userdata The `userdata` pointer passed to `foreach_ip_port`.
+ */
+typedef bool foreach_ip_port_cb(const DHT *dht, const IP_Port *ip_port, uint32_t *n, void *userdata);
+
+/**
+ * Runs a callback on every active connection for a given DHT friend.
+ *
+ * This iterates over the client list of a DHT friend and invokes a callback for
+ * every non-zero IP/port (IPv4 and IPv6) that's not timed out.
+ *
+ * @param dht The main DHT instance, passed to the callback.
+ * @param dht_friend The friend over whose connections we should iterate.
+ * @param callback The callback to invoke for each IP/port.
+ * @param userdata Extra pointer passed to the callback.
+ */
+static uint32_t foreach_ip_port(const DHT *dht, const DHT_Friend *dht_friend,
+ foreach_ip_port_cb *callback, void *userdata)
+{
+ uint32_t n = 0;
+
+ /* extra legwork, because having the outside allocating the space for us
+ * is *usually* good(tm) (bites us in the behind in this case though) */
+ for (uint32_t i = 0; i < MAX_FRIEND_CLIENTS; ++i) {
+ const Client_data *const client = &dht_friend->client_list[i];
+ const IPPTsPng *const assocs[] = { &client->assoc4, &client->assoc6, nullptr };
+
+ for (const IPPTsPng * const *it = assocs; *it != nullptr; ++it) {
+ const IPPTsPng *const assoc = *it;
+
+ /* If ip is not zero and node is good. */
+ if (!ip_isset(&assoc->ret_ip_port.ip)
+ && !mono_time_is_timeout(dht->mono_time, assoc->ret_timestamp, BAD_NODE_TIMEOUT)) {
+ continue;
+ }
+
+ if (!callback(dht, &assoc->ip_port, &n, userdata)) {
+ /* If the callback is happy with just one of the assocs, we
+ * don't give it the second one. */
+ break;
+ }
+ }
+ }
+
+ return n;
+}
+
+static bool send_packet_to_friend(const DHT *dht, const IP_Port *ip_port, uint32_t *n, void *userdata)
+{
+ const Packet *packet = (const Packet *)userdata;
+ const int retval = send_packet(dht->net, ip_port, *packet);
+
+ if ((uint32_t)retval == packet->length) {
+ ++*n;
+ /* Send one packet per friend: stop the foreach on the first success. */
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * Send the following packet to everyone who tells us they are connected to friend_id.
*
* return ip for friend.
* return number of nodes the packet was sent to. (Only works if more than (MAX_FRIEND_CLIENTS / 4).
*/
-int route_tofriend(const DHT *dht, const uint8_t *friend_id, const uint8_t *packet, uint16_t length)
+uint32_t route_to_friend(const DHT *dht, const uint8_t *friend_id, const Packet *packet)
{
const uint32_t num = index_of_friend_pk(dht->friends_list, dht->num_friends, friend_id);
@@ -1973,47 +2005,33 @@ int route_tofriend(const DHT *dht, const uint8_t *friend_id, const uint8_t *pack
return 0;
}
- uint32_t sent = 0;
IP_Port ip_list[MAX_FRIEND_CLIENTS];
const int ip_num = friend_iplist(dht, ip_list, num);
- if (ip_num < (MAX_FRIEND_CLIENTS / 4)) {
+ if (ip_num < MAX_FRIEND_CLIENTS / 4) {
return 0; /* Reason for that? */
}
const DHT_Friend *const dht_friend = &dht->friends_list[num];
+ Packet packet_userdata = *packet; // Copy because it needs to be non-const.
- /* extra legwork, because having the outside allocating the space for us
- * is *usually* good(tm) (bites us in the behind in this case though) */
-
- for (uint32_t i = 0; i < MAX_FRIEND_CLIENTS; ++i) {
- const Client_data *const client = &dht_friend->client_list[i];
- const IPPTsPng *const assocs[] = { &client->assoc4, &client->assoc6, nullptr };
-
- for (const IPPTsPng * const *it = assocs; *it; ++it) {
- const IPPTsPng *const assoc = *it;
-
- /* If ip is not zero and node is good. */
- if (ip_isset(&assoc->ret_ip_port.ip) && !mono_time_is_timeout(dht->mono_time, assoc->ret_timestamp, BAD_NODE_TIMEOUT)) {
- const int retval = sendpacket(dht->net, assoc->ip_port, packet, length);
-
- if ((unsigned int)retval == length) {
- ++sent;
- break; /* Send one packet per client.*/
- }
- }
- }
- }
+ return foreach_ip_port(dht, dht_friend, send_packet_to_friend, &packet_userdata);
+}
- return sent;
+static bool get_ip_port(const DHT *dht, const IP_Port *ip_port, uint32_t *n, void *userdata)
+{
+ IP_Port *ip_list = (IP_Port *)userdata;
+ ip_list[*n] = *ip_port;
+ ++*n;
+ return true;
}
-/* Send the following packet to one random person who tells us they are connected to friend_id.
+/** Send the following packet to one random person who tells us they are connected to friend_id.
*
* return number of nodes the packet was sent to.
*/
-static int routeone_tofriend(DHT *dht, const uint8_t *friend_id, const uint8_t *packet, uint16_t length)
+static uint32_t routeone_to_friend(const DHT *dht, const uint8_t *friend_id, const Packet *packet)
{
const uint32_t num = index_of_friend_pk(dht->friends_list, dht->num_friends, friend_id);
@@ -2024,33 +2042,17 @@ static int routeone_tofriend(DHT *dht, const uint8_t *friend_id, const uint8_t *
const DHT_Friend *const dht_friend = &dht->friends_list[num];
IP_Port ip_list[MAX_FRIEND_CLIENTS * 2];
- int n = 0;
- /* extra legwork, because having the outside allocating the space for us
- * is *usually* good(tm) (bites us in the behind in this case though) */
-
- for (uint32_t i = 0; i < MAX_FRIEND_CLIENTS; ++i) {
- const Client_data *const client = &dht_friend->client_list[i];
- const IPPTsPng *const assocs[] = { &client->assoc4, &client->assoc6, nullptr };
-
- for (const IPPTsPng * const *it = assocs; *it; ++it) {
- const IPPTsPng *const assoc = *it;
-
- /* If ip is not zero and node is good. */
- if (ip_isset(&assoc->ret_ip_port.ip) && !mono_time_is_timeout(dht->mono_time, assoc->ret_timestamp, BAD_NODE_TIMEOUT)) {
- ip_list[n] = assoc->ip_port;
- ++n;
- }
- }
- }
+ const int n = foreach_ip_port(dht, dht_friend, get_ip_port, ip_list);
if (n < 1) {
return 0;
}
- const int retval = sendpacket(dht->net, ip_list[random_u32() % n], packet, length);
+ const uint32_t rand_idx = random_range_u32(n);
+ const int retval = send_packet(dht->net, &ip_list[rand_idx], *packet);
- if ((unsigned int)retval == length) {
+ if ((unsigned int)retval == packet->length) {
return 1;
}
@@ -2060,28 +2062,30 @@ static int routeone_tofriend(DHT *dht, const uint8_t *friend_id, const uint8_t *
/*----------------------------------------------------------------------------------*/
/*---------------------BEGINNING OF NAT PUNCHING FUNCTIONS--------------------------*/
-static int send_NATping(DHT *dht, const uint8_t *public_key, uint64_t ping_id, uint8_t type)
+static int send_NATping(const DHT *dht, const uint8_t *public_key, uint64_t ping_id, uint8_t type)
{
uint8_t data[sizeof(uint64_t) + 1];
- uint8_t packet[MAX_CRYPTO_REQUEST_SIZE];
-
- int num = 0;
+ uint8_t packet_data[MAX_CRYPTO_REQUEST_SIZE];
data[0] = type;
memcpy(data + 1, &ping_id, sizeof(uint64_t));
/* 254 is NAT ping request packet id */
const int len = create_request(
- dht->self_public_key, dht->self_secret_key, packet, public_key, data,
+ dht->self_public_key, dht->self_secret_key, packet_data, public_key, data,
sizeof(uint64_t) + 1, CRYPTO_PACKET_NAT_PING);
if (len == -1) {
return -1;
}
+ assert(len <= UINT16_MAX);
+ uint32_t num = 0;
+ const Packet packet = {packet_data, (uint16_t)len};
+
if (type == 0) { /* If packet is request use many people to route it. */
- num = route_tofriend(dht, public_key, packet, len);
+ num = route_to_friend(dht, public_key, &packet);
} else if (type == 1) { /* If packet is response use only one person to route it */
- num = routeone_tofriend(dht, public_key, packet, len);
+ num = routeone_to_friend(dht, public_key, &packet);
}
if (num == 0) {
@@ -2091,8 +2095,8 @@ static int send_NATping(DHT *dht, const uint8_t *public_key, uint64_t ping_id, u
return num;
}
-/* Handle a received ping request for. */
-static int handle_NATping(void *object, IP_Port source, const uint8_t *source_pubkey, const uint8_t *packet,
+/** Handle a received ping request for. */
+static int handle_NATping(void *object, const IP_Port *source, const uint8_t *source_pubkey, const uint8_t *packet,
uint16_t length, void *userdata)
{
if (length != sizeof(uint64_t) + 1) {
@@ -2129,13 +2133,13 @@ static int handle_NATping(void *object, IP_Port source, const uint8_t *source_pu
return 1;
}
-/* Get the most common ip in the ip_portlist.
+/** Get the most common ip in the ip_portlist.
* Only return ip if it appears in list min_num or more.
* len must not be bigger than MAX_FRIEND_CLIENTS.
*
* return ip of 0 if failure.
*/
-static IP nat_commonip(IP_Port *ip_portlist, uint16_t len, uint16_t min_num)
+static IP nat_commonip(const IP_Port *ip_portlist, uint16_t len, uint16_t min_num)
{
IP zero;
ip_reset(&zero);
@@ -2161,18 +2165,18 @@ static IP nat_commonip(IP_Port *ip_portlist, uint16_t len, uint16_t min_num)
return zero;
}
-/* Return all the ports for one ip in a list.
+/** Return all the ports for one ip in a list.
* portlist must be at least len long,
* where len is the length of ip_portlist.
*
* return number of ports and puts the list of ports in portlist.
*/
-static uint16_t nat_getports(uint16_t *portlist, IP_Port *ip_portlist, uint16_t len, IP ip)
+static uint16_t nat_getports(uint16_t *portlist, const IP_Port *ip_portlist, uint16_t len, const IP *ip)
{
uint16_t num = 0;
for (uint32_t i = 0; i < len; ++i) {
- if (ip_equal(&ip_portlist[i].ip, &ip)) {
+ if (ip_equal(&ip_portlist[i].ip, ip)) {
portlist[num] = net_ntohs(ip_portlist[i].port);
++num;
}
@@ -2181,7 +2185,7 @@ static uint16_t nat_getports(uint16_t *portlist, IP_Port *ip_portlist, uint16_t
return num;
}
-static void punch_holes(DHT *dht, IP ip, uint16_t *port_list, uint16_t numports, uint16_t friend_num)
+static void punch_holes(DHT *dht, const IP *ip, const uint16_t *port_list, uint16_t numports, uint16_t friend_num)
{
if (!dht->hole_punching_enabled) {
return;
@@ -2202,9 +2206,9 @@ static void punch_holes(DHT *dht, IP ip, uint16_t *port_list, uint16_t numports,
if (i == numports) { /* If all ports are the same, only try that one port. */
IP_Port pinging;
- ip_copy(&pinging.ip, &ip);
+ ip_copy(&pinging.ip, ip);
pinging.port = net_htons(first_port);
- ping_send_request(dht->ping, pinging, dht->friends_list[friend_num].public_key);
+ ping_send_request(dht->ping, &pinging, dht->friends_list[friend_num].public_key);
} else {
for (i = 0; i < MAX_PUNCHING_PORTS; ++i) {
/* TODO(irungentoo): Improve port guessing algorithm. */
@@ -2214,9 +2218,9 @@ static void punch_holes(DHT *dht, IP ip, uint16_t *port_list, uint16_t numports,
const uint32_t index = (it / 2) % numports;
const uint16_t port = port_list[index] + delta;
IP_Port pinging;
- ip_copy(&pinging.ip, &ip);
+ ip_copy(&pinging.ip, ip);
pinging.port = net_htons(port);
- ping_send_request(dht->ping, pinging, dht->friends_list[friend_num].public_key);
+ ping_send_request(dht->ping, &pinging, dht->friends_list[friend_num].public_key);
}
dht->friends_list[friend_num].nat.punching_index += i;
@@ -2225,12 +2229,12 @@ static void punch_holes(DHT *dht, IP ip, uint16_t *port_list, uint16_t numports,
if (dht->friends_list[friend_num].nat.tries > MAX_NORMAL_PUNCHING_TRIES) {
const uint16_t port = 1024;
IP_Port pinging;
- ip_copy(&pinging.ip, &ip);
+ ip_copy(&pinging.ip, ip);
for (i = 0; i < MAX_PUNCHING_PORTS; ++i) {
uint32_t it = i + dht->friends_list[friend_num].nat.punching_index2;
pinging.port = net_htons(port + it);
- ping_send_request(dht->ping, pinging, dht->friends_list[friend_num].public_key);
+ ping_send_request(dht->ping, &pinging, dht->friends_list[friend_num].public_key);
}
dht->friends_list[friend_num].nat.punching_index2 += i - (MAX_PUNCHING_PORTS / 2);
@@ -2274,8 +2278,8 @@ static void do_NAT(DHT *dht)
}
uint16_t port_list[MAX_FRIEND_CLIENTS];
- const uint16_t numports = nat_getports(port_list, ip_list, num, ip);
- punch_holes(dht, ip, port_list, numports, i);
+ const uint16_t numports = nat_getports(port_list, ip_list, num, &ip);
+ punch_holes(dht, &ip, port_list, numports, i);
dht->friends_list[i].nat.punching_timestamp = temp_time;
dht->friends_list[i].nat.hole_punching = 0;
@@ -2286,233 +2290,12 @@ static void do_NAT(DHT *dht)
/*----------------------------------------------------------------------------------*/
/*-----------------------END OF NAT PUNCHING FUNCTIONS------------------------------*/
-#define DHT_HARDENING 0
-#define HARDREQ_DATA_SIZE 384 // Attempt to prevent amplification/other attacks
-
-typedef enum Check_Type {
- CHECK_TYPE_ROUTE_REQ = 0,
- CHECK_TYPE_ROUTE_RES = 1,
- CHECK_TYPE_GETNODE_REQ = 2,
- CHECK_TYPE_GETNODE_RES = 3,
- CHECK_TYPE_TEST_REQ = 4,
- CHECK_TYPE_TEST_RES = 5,
-} Check_Type;
-
-#if DHT_HARDENING
-static int send_hardening_req(DHT *dht, Node_format *sendto, uint8_t type, uint8_t *contents, uint16_t length)
-{
- if (length > HARDREQ_DATA_SIZE - 1) {
- return -1;
- }
-
- uint8_t packet[MAX_CRYPTO_REQUEST_SIZE];
- uint8_t data[HARDREQ_DATA_SIZE] = {0};
- data[0] = type;
- memcpy(data + 1, contents, length);
- const int len = create_request(
- dht->self_public_key, dht->self_secret_key, packet, sendto->public_key,
- data, sizeof(data), CRYPTO_PACKET_HARDENING);
-
- if (len == -1) {
- return -1;
- }
-
- return sendpacket(dht->net, sendto->ip_port, packet, len);
-}
-
-/* Send a get node hardening request */
-static int send_hardening_getnode_req(DHT *dht, Node_format *dest, Node_format *node_totest, uint8_t *search_id)
-{
- uint8_t data[sizeof(Node_format) + CRYPTO_PUBLIC_KEY_SIZE];
- memcpy(data, node_totest, sizeof(Node_format));
- memcpy(data + sizeof(Node_format), search_id, CRYPTO_PUBLIC_KEY_SIZE);
- return send_hardening_req(dht, dest, CHECK_TYPE_GETNODE_REQ, data, sizeof(Node_format) + CRYPTO_PUBLIC_KEY_SIZE);
-}
-#endif
-
-/* Send a get node hardening response */
-static int send_hardening_getnode_res(const DHT *dht, const Node_format *sendto, const uint8_t *queried_client_id,
- const uint8_t *nodes_data, uint16_t nodes_data_length)
-{
- if (!ip_isset(&sendto->ip_port.ip)) {
- return -1;
- }
-
- uint8_t packet[MAX_CRYPTO_REQUEST_SIZE];
- VLA(uint8_t, data, 1 + CRYPTO_PUBLIC_KEY_SIZE + nodes_data_length);
- data[0] = CHECK_TYPE_GETNODE_RES;
- memcpy(data + 1, queried_client_id, CRYPTO_PUBLIC_KEY_SIZE);
- memcpy(data + 1 + CRYPTO_PUBLIC_KEY_SIZE, nodes_data, nodes_data_length);
- const int len = create_request(
- dht->self_public_key, dht->self_secret_key, packet, sendto->public_key,
- data, SIZEOF_VLA(data), CRYPTO_PACKET_HARDENING);
-
- if (len == -1) {
- return -1;
- }
-
- return sendpacket(dht->net, sendto->ip_port, packet, len);
-}
-
-/* TODO(irungentoo): improve */
-static IPPTsPng *get_closelist_IPPTsPng(DHT *dht, const uint8_t *public_key, Family sa_family)
-{
- for (uint32_t i = 0; i < LCLIENT_LIST; ++i) {
- if (!id_equal(dht->close_clientlist[i].public_key, public_key)) {
- continue;
- }
-
- if (net_family_is_ipv4(sa_family)) {
- return &dht->close_clientlist[i].assoc4;
- }
-
- if (net_family_is_ipv6(sa_family)) {
- return &dht->close_clientlist[i].assoc6;
- }
- }
-
- return nullptr;
-}
-
-/*
- * check how many nodes in nodes are also present in the closelist.
- * TODO(irungentoo): make this function better.
- */
-static uint32_t have_nodes_closelist(DHT *dht, Node_format *nodes, uint16_t num)
-{
- uint32_t counter = 0;
-
- for (uint32_t i = 0; i < num; ++i) {
- if (id_equal(nodes[i].public_key, dht->self_public_key)) {
- ++counter;
- continue;
- }
-
- const IPPTsPng *const temp = get_closelist_IPPTsPng(dht, nodes[i].public_key, nodes[i].ip_port.ip.family);
-
- if (temp) {
- if (!assoc_timeout(dht->last_run, temp)) {
- ++counter;
- }
- }
- }
-
- return counter;
-}
-
-/* Interval in seconds between hardening checks */
-#define HARDENING_INTERVAL 120
-
-/* Handle a received hardening packet */
-static int handle_hardening(void *object, IP_Port source, const uint8_t *source_pubkey, const uint8_t *packet,
- uint16_t length, void *userdata)
-{
- DHT *const dht = (DHT *)object;
-
- if (length < 2) {
- return 1;
- }
-
- switch (packet[0]) {
- case CHECK_TYPE_GETNODE_REQ: {
- if (length != HARDREQ_DATA_SIZE) {
- return 1;
- }
-
- Node_format node;
- Node_format tocheck_node;
- node.ip_port = source;
- memcpy(node.public_key, source_pubkey, CRYPTO_PUBLIC_KEY_SIZE);
- memcpy(&tocheck_node, packet + 1, sizeof(Node_format));
-
- if (getnodes(dht, tocheck_node.ip_port, tocheck_node.public_key, packet + 1 + sizeof(Node_format), &node) == -1) {
- return 1;
- }
-
- return 0;
- }
-
- case CHECK_TYPE_GETNODE_RES: {
- if (length <= CRYPTO_PUBLIC_KEY_SIZE + 1) {
- return 1;
- }
-
- if (length > 1 + CRYPTO_PUBLIC_KEY_SIZE + sizeof(Node_format) * MAX_SENT_NODES) {
- return 1;
- }
-
- uint16_t length_nodes = length - 1 - CRYPTO_PUBLIC_KEY_SIZE;
- Node_format nodes[MAX_SENT_NODES];
- const int num_nodes = unpack_nodes(nodes, MAX_SENT_NODES, nullptr, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE,
- length_nodes, 0);
-
- /* TODO(irungentoo): MAX_SENT_NODES nodes should be returned at all times
- * (right now we have a small network size so it could cause problems for testing and etc..) */
- if (num_nodes <= 0) {
- return 1;
- }
-
- /* NOTE: This should work for now but should be changed to something better. */
- if (have_nodes_closelist(dht, nodes, num_nodes) < (uint32_t)((num_nodes + 2) / 2)) {
- return 1;
- }
-
- IPPTsPng *const temp = get_closelist_IPPTsPng(dht, packet + 1, nodes[0].ip_port.ip.family);
-
- if (temp == nullptr) {
- return 1;
- }
-
- if (mono_time_is_timeout(dht->mono_time, temp->hardening.send_nodes_timestamp, HARDENING_INTERVAL)) {
- return 1;
- }
-
- if (!id_equal(temp->hardening.send_nodes_pingedid, source_pubkey)) {
- return 1;
- }
-
- /* If Nodes look good and the request checks out */
- temp->hardening.send_nodes_ok = 1;
- return 0;/* success*/
- }
- }
-
- return 1;
-}
-
-#if DHT_HARDENING
-#define HARDEN_TIMEOUT 1200
-
-/* Return a random node from all the nodes we are connected to.
- * TODO(irungentoo): improve this function.
- */
-static Node_format random_node(DHT *dht, Family sa_family)
-{
- uint8_t id[CRYPTO_PUBLIC_KEY_SIZE];
-
- for (uint32_t i = 0; i < CRYPTO_PUBLIC_KEY_SIZE / 4; ++i) { /* populate the id with pseudorandom bytes.*/
- const uint32_t t = random_u32();
- memcpy(id + i * sizeof(t), &t, sizeof(t));
- }
-
- Node_format nodes_list[MAX_SENT_NODES];
- memset(nodes_list, 0, sizeof(nodes_list));
- const uint32_t num_nodes = get_close_nodes(dht, id, nodes_list, sa_family, 1, 0);
-
- if (num_nodes == 0) {
- return nodes_list[0];
- }
-
- return nodes_list[random_u32() % num_nodes];
-}
-#endif
-
-/* Put up to max_num nodes in nodes from the closelist.
+/** Put up to max_num nodes in nodes from the closelist.
*
* return the number of nodes.
*/
-static uint16_t list_nodes(Client_data *list, size_t length, uint64_t cur_time, Node_format *nodes,
- uint16_t max_num)
+static uint16_t list_nodes(const Client_data *list, size_t length, uint64_t cur_time,
+ Node_format *nodes, uint16_t max_num)
{
if (max_num == 0) {
return 0;
@@ -2549,11 +2332,11 @@ static uint16_t list_nodes(Client_data *list, size_t length, uint64_t cur_time,
return count;
}
-/* Put up to max_num nodes in nodes from the random friends.
+/** Put up to max_num nodes in nodes from the random friends.
*
* return the number of nodes.
*/
-uint16_t randfriends_nodes(DHT *dht, Node_format *nodes, uint16_t max_num)
+uint16_t randfriends_nodes(const DHT *dht, Node_format *nodes, uint16_t max_num)
{
if (max_num == 0) {
return 0;
@@ -2563,7 +2346,7 @@ uint16_t randfriends_nodes(DHT *dht, Node_format *nodes, uint16_t max_num)
const uint32_t r = random_u32();
for (size_t i = 0; i < DHT_FAKE_FRIEND_NUMBER; ++i) {
- count += list_nodes(dht->friends_list[(i + r) % DHT_FAKE_FRIEND_NUMBER].client_list, MAX_FRIEND_CLIENTS, dht->last_run,
+ count += list_nodes(dht->friends_list[(i + r) % DHT_FAKE_FRIEND_NUMBER].client_list, MAX_FRIEND_CLIENTS, dht->cur_time,
nodes + count, max_num - count);
if (count >= max_num) {
@@ -2574,68 +2357,15 @@ uint16_t randfriends_nodes(DHT *dht, Node_format *nodes, uint16_t max_num)
return count;
}
-/* Put up to max_num nodes in nodes from the closelist.
+/** Put up to max_num nodes in nodes from the closelist.
*
* return the number of nodes.
*/
-uint16_t closelist_nodes(DHT *dht, Node_format *nodes, uint16_t max_num)
+uint16_t closelist_nodes(const DHT *dht, Node_format *nodes, uint16_t max_num)
{
- return list_nodes(dht->close_clientlist, LCLIENT_LIST, dht->last_run, nodes, max_num);
+ return list_nodes(dht->close_clientlist, LCLIENT_LIST, dht->cur_time, nodes, max_num);
}
-#if DHT_HARDENING
-static void do_hardening(DHT *dht)
-{
- for (uint32_t i = 0; i < LCLIENT_LIST * 2; ++i) {
- IPPTsPng *cur_iptspng;
- Family sa_family;
- const uint8_t *const public_key = dht->close_clientlist[i / 2].public_key;
-
- if (i % 2 == 0) {
- cur_iptspng = &dht->close_clientlist[i / 2].assoc4;
- sa_family = net_family_ipv4;
- } else {
- cur_iptspng = &dht->close_clientlist[i / 2].assoc6;
- sa_family = net_family_ipv6;
- }
-
- if (assoc_timeout(dht->mono_time, cur_iptspng)) {
- continue;
- }
-
- if (cur_iptspng->hardening.send_nodes_ok == 0) {
- if (mono_time_is_timeout(dht->mono_time, cur_iptspng->hardening.send_nodes_timestamp, HARDENING_INTERVAL)) {
- Node_format rand_node = random_node(dht, sa_family);
-
- if (!ipport_isset(&rand_node.ip_port)) {
- continue;
- }
-
- if (id_equal(public_key, rand_node.public_key)) {
- continue;
- }
-
- Node_format to_test;
- to_test.ip_port = cur_iptspng->ip_port;
- memcpy(to_test.public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE);
-
- // TODO(irungentoo): The search id should maybe not be ours?
- if (send_hardening_getnode_req(dht, &rand_node, &to_test, dht->self_public_key) > 0) {
- memcpy(cur_iptspng->hardening.send_nodes_pingedid, rand_node.public_key, CRYPTO_PUBLIC_KEY_SIZE);
- cur_iptspng->hardening.send_nodes_timestamp = mono_time_get(dht->mono_time);
- }
- }
- } else {
- if (mono_time_is_timeout(dht->mono_time, cur_iptspng->hardening.send_nodes_timestamp, HARDEN_TIMEOUT)) {
- cur_iptspng->hardening.send_nodes_ok = 0;
- }
- }
-
- // TODO(irungentoo): add the 2 other testers.
- }
-}
-#endif
-
/*----------------------------------------------------------------------------------*/
void cryptopacket_registerhandler(DHT *dht, uint8_t byte, cryptopacket_handler_cb *cb, void *object)
@@ -2644,7 +2374,8 @@ void cryptopacket_registerhandler(DHT *dht, uint8_t byte, cryptopacket_handler_c
dht->cryptopackethandlers[byte].object = object;
}
-static int cryptopacket_handle(void *object, IP_Port source, const uint8_t *packet, uint16_t length, void *userdata)
+static int cryptopacket_handle(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length,
+ void *userdata)
{
DHT *const dht = (DHT *)object;
@@ -2701,7 +2432,7 @@ DHT *new_dht(const Logger *log, Mono_Time *mono_time, Networking_Core *net, bool
}
dht->mono_time = mono_time;
- dht->last_run = mono_time_get(mono_time);
+ dht->cur_time = mono_time_get(mono_time);
dht->log = log;
dht->net = net;
@@ -2718,14 +2449,12 @@ DHT *new_dht(const Logger *log, Mono_Time *mono_time, Networking_Core *net, bool
networking_registerhandler(dht->net, NET_PACKET_SEND_NODES_IPV6, &handle_sendnodes_ipv6, dht);
networking_registerhandler(dht->net, NET_PACKET_CRYPTO, &cryptopacket_handle, dht);
cryptopacket_registerhandler(dht, CRYPTO_PACKET_NAT_PING, &handle_NATping, dht);
- cryptopacket_registerhandler(dht, CRYPTO_PACKET_HARDENING, &handle_hardening, dht);
crypto_new_keypair(dht->self_public_key, dht->self_secret_key);
dht->dht_ping_array = ping_array_new(DHT_PING_ARRAY_SIZE, PING_TIMEOUT);
- dht->dht_harden_ping_array = ping_array_new(DHT_PING_ARRAY_SIZE, PING_TIMEOUT);
- if (dht->dht_ping_array == nullptr || dht->dht_harden_ping_array == nullptr) {
+ if (dht->dht_ping_array == nullptr) {
kill_dht(dht);
return nullptr;
}
@@ -2749,11 +2478,11 @@ void do_dht(DHT *dht)
{
const uint64_t cur_time = mono_time_get(dht->mono_time);
- if (dht->last_run == cur_time) {
+ if (dht->cur_time == cur_time) {
return;
}
- dht->last_run = cur_time;
+ dht->cur_time = cur_time;
// Load friends/clients if first call to do_dht
if (dht->loaded_num_nodes) {
@@ -2764,9 +2493,6 @@ void do_dht(DHT *dht)
do_dht_friends(dht);
do_NAT(dht);
ping_iterate(dht->ping);
-#if DHT_HARDENING
- do_hardening(dht);
-#endif
}
void kill_dht(DHT *dht)
@@ -2774,12 +2500,13 @@ void kill_dht(DHT *dht)
networking_registerhandler(dht->net, NET_PACKET_GET_NODES, nullptr, nullptr);
networking_registerhandler(dht->net, NET_PACKET_SEND_NODES_IPV6, nullptr, nullptr);
cryptopacket_registerhandler(dht, CRYPTO_PACKET_NAT_PING, nullptr, nullptr);
- cryptopacket_registerhandler(dht, CRYPTO_PACKET_HARDENING, nullptr, nullptr);
ping_array_kill(dht->dht_ping_array);
- ping_array_kill(dht->dht_harden_ping_array);
ping_kill(dht->ping);
free(dht->friends_list);
free(dht->loaded_nodes_list);
+ crypto_memzero(&dht->shared_keys_recv, sizeof(dht->shared_keys_recv));
+ crypto_memzero(&dht->shared_keys_sent, sizeof(dht->shared_keys_sent));
+ crypto_memzero(dht->self_secret_key, sizeof(dht->self_secret_key));
free(dht);
}
@@ -2792,7 +2519,7 @@ void kill_dht(DHT *dht)
#define MAX_SAVED_DHT_NODES (((DHT_FAKE_FRIEND_NUMBER * MAX_FRIEND_CLIENTS) + LCLIENT_LIST) * 2)
-/* Get the size of the DHT (for saving). */
+/** Get the size of the DHT (for saving). */
uint32_t dht_size(const DHT *dht)
{
uint32_t numv4 = 0;
@@ -2823,7 +2550,7 @@ uint32_t dht_size(const DHT *dht)
return size32 + sizesubhead + packed_node_size(net_family_ipv4) * numv4 + packed_node_size(net_family_ipv6) * numv6;
}
-/* Save the DHT in data where data is an array of size dht_size(). */
+/** Save the DHT in data where data is an array of size dht_size(). */
void dht_save(const DHT *dht, uint8_t *data)
{
host_to_lendian_bytes32(data, DHT_STATE_COOKIE_GLOBAL);
@@ -2834,7 +2561,7 @@ void dht_save(const DHT *dht, uint8_t *data)
/* get right offset. we write the actual header later. */
data = state_write_section_header(data, DHT_STATE_COOKIE_TYPE, 0, 0);
- Node_format *clients = (Node_format *)malloc(MAX_SAVED_DHT_NODES * sizeof(Node_format));
+ Node_format *clients = (Node_format *)calloc(MAX_SAVED_DHT_NODES, sizeof(Node_format));
if (clients == nullptr) {
LOGGER_ERROR(dht->log, "could not allocate %u nodes", MAX_SAVED_DHT_NODES);
@@ -2886,10 +2613,14 @@ void dht_save(const DHT *dht, uint8_t *data)
free(clients);
}
-/* Bootstrap from this number of nodes every time dht_connect_after_load() is called */
+/** Bootstrap from this number of nodes every time dht_connect_after_load() is called */
#define SAVE_BOOTSTAP_FREQUENCY 8
-/* Start sending packets after DHT loaded_friends_list and loaded_clients_list are set */
+/** Start sending packets after DHT loaded_friends_list and loaded_clients_list are set.
+ *
+ * returns 0 if successful
+ * returns -1 otherwise
+ */
int dht_connect_after_load(DHT *dht)
{
if (dht == nullptr) {
@@ -2910,7 +2641,7 @@ int dht_connect_after_load(DHT *dht)
for (uint32_t i = 0; i < dht->loaded_num_nodes && i < SAVE_BOOTSTAP_FREQUENCY; ++i) {
const unsigned int index = dht->loaded_nodes_index % dht->loaded_num_nodes;
- dht_bootstrap(dht, dht->loaded_nodes_list[index].ip_port, dht->loaded_nodes_list[index].public_key);
+ dht_bootstrap(dht, &dht->loaded_nodes_list[index].ip_port, dht->loaded_nodes_list[index].public_key);
++dht->loaded_nodes_index;
}
@@ -2948,16 +2679,17 @@ static State_Load_Status dht_load_state_callback(void *outer, const uint8_t *dat
break;
}
- default:
+ default: {
LOGGER_ERROR(dht->log, "Load state (DHT): contains unrecognized part (len %u, type %u)",
length, type);
break;
+ }
}
return STATE_LOAD_STATUS_CONTINUE;
}
-/* Load the DHT from data of size size.
+/** Load the DHT from data of size size.
*
* return -1 if failure.
* return 0 if success.
@@ -2979,7 +2711,7 @@ int dht_load(DHT *dht, const uint8_t *data, uint32_t length)
return -1;
}
-/* return false if we are not connected to the DHT.
+/** return false if we are not connected to the DHT.
* return true if we are.
*/
bool dht_isconnected(const DHT *dht)
@@ -2987,8 +2719,8 @@ bool dht_isconnected(const DHT *dht)
for (uint32_t i = 0; i < LCLIENT_LIST; ++i) {
const Client_data *const client = &dht->close_clientlist[i];
- if (!assoc_timeout(dht->last_run, &client->assoc4) ||
- !assoc_timeout(dht->last_run, &client->assoc6)) {
+ if (!assoc_timeout(dht->cur_time, &client->assoc4) ||
+ !assoc_timeout(dht->cur_time, &client->assoc6)) {
return true;
}
}
@@ -2996,7 +2728,7 @@ bool dht_isconnected(const DHT *dht)
return false;
}
-/* return false if we are not connected or only connected to lan peers with the DHT.
+/** return false if we are not connected or only connected to lan peers with the DHT.
* return true if we are.
*/
bool dht_non_lan_connected(const DHT *dht)
@@ -3004,16 +2736,66 @@ bool dht_non_lan_connected(const DHT *dht)
for (uint32_t i = 0; i < LCLIENT_LIST; ++i) {
const Client_data *const client = &dht->close_clientlist[i];
- if (!assoc_timeout(dht->last_run, &client->assoc4)
- && !ip_is_lan(client->assoc4.ip_port.ip)) {
+ if (!assoc_timeout(dht->cur_time, &client->assoc4)
+ && !ip_is_lan(&client->assoc4.ip_port.ip)) {
return true;
}
- if (!assoc_timeout(dht->last_run, &client->assoc6)
- && !ip_is_lan(client->assoc6.ip_port.ip)) {
+ if (!assoc_timeout(dht->cur_time, &client->assoc6)
+ && !ip_is_lan(&client->assoc6.ip_port.ip)) {
return true;
}
}
return false;
}
+
+/** Copies our own ip_port structure to `dest`. WAN addresses take priority over LAN addresses.
+ *
+ * This function will zero the `dest` buffer before use.
+ *
+ * Return 0 if our ip port can't be found (this usually means we're not connected to the DHT).
+ * Return 1 if IP is a WAN address.
+ * Return 2 if IP is a LAN address.
+ */
+unsigned int ipport_self_copy(const DHT *dht, IP_Port *dest)
+{
+ ipport_reset(dest);
+
+ bool is_lan = false;
+
+ for (uint32_t i = 0; i < LCLIENT_LIST; ++i) {
+ const Client_data *client = dht_get_close_client(dht, i);
+ const IP_Port *ip_port4 = &client->assoc4.ret_ip_port;
+
+ if (client->assoc4.ret_ip_self && ipport_isset(ip_port4)) {
+ ipport_copy(dest, ip_port4);
+ is_lan = ip_is_lan(&dest->ip);
+
+ if (!is_lan) {
+ break;
+ }
+ }
+
+ const IP_Port *ip_port6 = &client->assoc6.ret_ip_port;
+
+ if (client->assoc6.ret_ip_self && ipport_isset(ip_port6)) {
+ ipport_copy(dest, ip_port6);
+ is_lan = ip_is_lan(&dest->ip);
+
+ if (!is_lan) {
+ break;
+ }
+ }
+ }
+
+ if (!ipport_isset(dest)) {
+ return 0;
+ }
+
+ if (is_lan) {
+ return 2;
+ }
+
+ return 1;
+}
diff --git a/protocols/Tox/libtox/src/toxcore/DHT.h b/protocols/Tox/libtox/src/toxcore/DHT.h
index fcc67251f6..f72ef924c9 100644
--- a/protocols/Tox/libtox/src/toxcore/DHT.h
+++ b/protocols/Tox/libtox/src/toxcore/DHT.h
@@ -3,63 +3,62 @@
* Copyright © 2013 Tox project.
*/
-/*
+/**
* An implementation of the DHT as seen in docs/updates/DHT.md
*/
#ifndef C_TOXCORE_TOXCORE_DHT_H
#define C_TOXCORE_TOXCORE_DHT_H
+#include <stdbool.h>
+
#include "crypto_core.h"
#include "logger.h"
#include "mono_time.h"
#include "network.h"
#include "ping_array.h"
-#include <stdbool.h>
-
#ifdef __cplusplus
extern "C" {
#endif
-/* Maximum number of clients stored per friend. */
+/** Maximum number of clients stored per friend. */
#define MAX_FRIEND_CLIENTS 8
#define LCLIENT_NODES MAX_FRIEND_CLIENTS
#define LCLIENT_LENGTH 128
-/* A list of the clients mathematically closest to ours. */
+/** A list of the clients mathematically closest to ours. */
#define LCLIENT_LIST (LCLIENT_LENGTH * LCLIENT_NODES)
#define MAX_CLOSE_TO_BOOTSTRAP_NODES 8
-/* The max number of nodes to send with send nodes. */
+/** The max number of nodes to send with send nodes. */
#define MAX_SENT_NODES 4
-/* Ping timeout in seconds */
+/** Ping timeout in seconds */
#define PING_TIMEOUT 5
-/* size of DHT ping arrays. */
+/** size of DHT ping arrays. */
#define DHT_PING_ARRAY_SIZE 512
-/* Ping interval in seconds for each node in our lists. */
+/** Ping interval in seconds for each node in our lists. */
#define PING_INTERVAL 60
-/* The number of seconds for a non responsive node to become bad. */
+/** The number of seconds for a non responsive node to become bad. */
#define PINGS_MISSED_NODE_GOES_BAD 1
#define PING_ROUNDTRIP 2
#define BAD_NODE_TIMEOUT (PING_INTERVAL + PINGS_MISSED_NODE_GOES_BAD * (PING_INTERVAL + PING_ROUNDTRIP))
-/* The number of "fake" friends to add (for optimization purposes and so our paths for the onion part are more random) */
+/** The number of "fake" friends to add (for optimization purposes and so our paths for the onion part are more random) */
#define DHT_FAKE_FRIEND_NUMBER 2
#define MAX_CRYPTO_REQUEST_SIZE 1024
#define CRYPTO_PACKET_FRIEND_REQ 32 // Friend request crypto packet ID.
-#define CRYPTO_PACKET_HARDENING 48 // Hardening crypto packet ID.
#define CRYPTO_PACKET_DHTPK 156
#define CRYPTO_PACKET_NAT_PING 254 // NAT ping crypto packet ID.
-/* Create a request to peer.
+/** Create a request to peer.
* send_public_key and send_secret_key are the pub/secret keys of the sender.
* recv_public_key is public key of receiver.
* packet must be an array of MAX_CRYPTO_REQUEST_SIZE big.
@@ -72,10 +71,12 @@ extern "C" {
int create_request(const uint8_t *send_public_key, const uint8_t *send_secret_key, uint8_t *packet,
const uint8_t *recv_public_key, const uint8_t *data, uint32_t length, uint8_t request_id);
-/* puts the senders public key in the request in public_key, the data from the request
+/** Puts the senders public key in the request in public_key, the data from the request
* in data if a friend or ping request was sent to us and returns the length of the data.
- * packet is the request packet and length is its length
- * return -1 if not valid request. */
+ * packet is the request packet and length is its length.
+ *
+ * return -1 if not valid request.
+ */
int handle_request(const uint8_t *self_public_key, const uint8_t *self_secret_key, uint8_t *public_key, uint8_t *data,
uint8_t *request_id, const uint8_t *packet, uint16_t length);
@@ -84,33 +85,16 @@ typedef struct IPPTs {
uint64_t timestamp;
} IPPTs;
-typedef struct Hardening {
- /* Node routes request correctly (true (1) or false/didn't check (0)) */
- uint8_t routes_requests_ok;
- /* Time which we last checked this.*/
- uint64_t routes_requests_timestamp;
- uint8_t routes_requests_pingedid[CRYPTO_PUBLIC_KEY_SIZE];
- /* Node sends correct send_node (true (1) or false/didn't check (0)) */
- uint8_t send_nodes_ok;
- /* Time which we last checked this.*/
- uint64_t send_nodes_timestamp;
- uint8_t send_nodes_pingedid[CRYPTO_PUBLIC_KEY_SIZE];
- /* Node can be used to test other nodes (true (1) or false/didn't check (0)) */
- uint8_t testing_requests;
- /* Time which we last checked this.*/
- uint64_t testing_timestamp;
- uint8_t testing_pingedid[CRYPTO_PUBLIC_KEY_SIZE];
-} Hardening;
-
typedef struct IPPTsPng {
IP_Port ip_port;
uint64_t timestamp;
uint64_t last_pinged;
- Hardening hardening;
- /* Returned by this node. Either our friend or us. */
+ /* Returned by this node */
IP_Port ret_ip_port;
uint64_t ret_timestamp;
+ /* true if this ip_port is ours */
+ bool ret_ip_self;
} IPPTsPng;
typedef struct Client_data {
@@ -146,33 +130,37 @@ typedef struct DHT_Friend DHT_Friend;
const uint8_t *dht_friend_public_key(const DHT_Friend *dht_friend);
const Client_data *dht_friend_client(const DHT_Friend *dht_friend, size_t index);
-/* Return packet size of packed node with ip_family on success.
+/** Return packet size of packed node with ip_family on success.
* Return -1 on failure.
*/
int packed_node_size(Family ip_family);
-/* Packs an IP_Port structure into data of max size length.
+/** Packs an IP_Port structure into data of max size length.
+ *
+ * Packed_length is the offset of data currently packed.
*
* Returns size of packed IP_Port data on success
* Return -1 on failure.
*/
int pack_ip_port(uint8_t *data, uint16_t length, const IP_Port *ip_port);
-/* Unpack IP_Port structure from data of max size length into ip_port.
+/** Unpack IP_Port structure from data of max size length into ip_port.
+ *
+ * len_processed is the offset of data currently unpacked.
*
* Return size of unpacked ip_port on success.
* Return -1 on failure.
*/
int unpack_ip_port(IP_Port *ip_port, const uint8_t *data, uint16_t length, bool tcp_enabled);
-/* Pack number of nodes into data of maxlength length.
+/** Pack number of nodes into data of maxlength length.
*
* return length of packed nodes on success.
* return -1 on failure.
*/
int pack_nodes(uint8_t *data, uint16_t length, const Node_format *nodes, uint16_t number);
-/* Unpack data of length into nodes of size max_num_nodes.
+/** Unpack data of length into nodes of size max_num_nodes.
* Put the length of the data processed in processed_data_len.
* tcp_enabled sets if TCP nodes are expected (true) or not (false).
*
@@ -202,10 +190,9 @@ typedef struct Shared_Keys {
/*----------------------------------------------------------------------------------*/
-typedef int cryptopacket_handler_cb(void *object, IP_Port ip_port, const uint8_t *source_pubkey,
+typedef int cryptopacket_handler_cb(void *object, const IP_Port *ip_port, const uint8_t *source_pubkey,
const uint8_t *data, uint16_t len, void *userdata);
-#define DHT_DEFINED
typedef struct DHT DHT;
const uint8_t *dht_get_self_public_key(const DHT *dht);
@@ -224,30 +211,36 @@ const uint8_t *dht_get_friend_public_key(const DHT *dht, uint32_t friend_num);
/*----------------------------------------------------------------------------------*/
-/* Shared key generations are costly, it is therefore smart to store commonly used
- * ones so that they can re used later without being computed again.
+/** Shared key generations are costly, it is therefore smart to store commonly used
+ * ones so that they can be re-used later without being computed again.
*
- * If shared key is already in shared_keys, copy it to shared_key.
- * else generate it into shared_key and copy it to shared_keys
+ * If a shared key is already in shared_keys, copy it to shared_key.
+ * Otherwise generate it into shared_key and copy it to shared_keys
*/
void get_shared_key(const Mono_Time *mono_time, Shared_Keys *shared_keys, uint8_t *shared_key,
const uint8_t *secret_key, const uint8_t *public_key);
-/* Copy shared_key to encrypt/decrypt DHT packet from public_key into shared_key
+/** Copy shared_key to encrypt/decrypt DHT packet from public_key into shared_key
* for packets that we receive.
*/
void dht_get_shared_key_recv(DHT *dht, uint8_t *shared_key, const uint8_t *public_key);
-/* Copy shared_key to encrypt/decrypt DHT packet from public_key into shared_key
+/** Copy shared_key to encrypt/decrypt DHT packet from public_key into shared_key
* for packets that we send.
*/
void dht_get_shared_key_sent(DHT *dht, uint8_t *shared_key, const uint8_t *public_key);
-void dht_getnodes(DHT *dht, const IP_Port *from_ipp, const uint8_t *from_id, const uint8_t *which_id);
-typedef void dht_ip_cb(void *object, int32_t number, IP_Port ip_port);
+/** Sends a getnodes request to `ip_port` with the public key `public_key` for nodes
+ * that are close to `client_id`.
+ *
+ * Return true on success.
+ */
+bool dht_getnodes(DHT *dht, const IP_Port *ip_port, const uint8_t *public_key, const uint8_t *client_id);
+
+typedef void dht_ip_cb(void *object, int32_t number, const IP_Port *ip_port);
-/* Add a new friend to the friends list.
+/** Add a new friend to the friends list.
* public_key must be CRYPTO_PUBLIC_KEY_SIZE bytes long.
*
* ip_callback is the callback of a function that will be called when the ip address
@@ -262,7 +255,7 @@ typedef void dht_ip_cb(void *object, int32_t number, IP_Port ip_port);
int dht_addfriend(DHT *dht, const uint8_t *public_key, dht_ip_cb *ip_callback,
void *data, int32_t number, uint16_t *lock_count);
-/* Delete a friend from the friends list.
+/** Delete a friend from the friends list.
* public_key must be CRYPTO_PUBLIC_KEY_SIZE bytes long.
*
* return 0 if success.
@@ -270,7 +263,7 @@ int dht_addfriend(DHT *dht, const uint8_t *public_key, dht_ip_cb *ip_callback,
*/
int dht_delfriend(DHT *dht, const uint8_t *public_key, uint16_t lock_count);
-/* Get ip of friend.
+/** Get ip of friend.
* public_key must be CRYPTO_PUBLIC_KEY_SIZE bytes long.
* ip must be 4 bytes long.
* port must be 2 bytes long.
@@ -281,7 +274,7 @@ int dht_delfriend(DHT *dht, const uint8_t *public_key, uint16_t lock_count);
*/
int dht_getfriendip(const DHT *dht, const uint8_t *public_key, IP_Port *ip_port);
-/* Compares pk1 and pk2 with pk.
+/** Compares pk1 and pk2 with pk.
*
* return 0 if both are same distance.
* return 1 if pk1 is closer.
@@ -289,19 +282,19 @@ int dht_getfriendip(const DHT *dht, const uint8_t *public_key, IP_Port *ip_port)
*/
int id_closest(const uint8_t *pk, const uint8_t *pk1, const uint8_t *pk2);
-/**
+/***
* Add node to the node list making sure only the nodes closest to cmp_pk are in the list.
*
* @return true iff the node was added to the list.
*/
-bool add_to_list(Node_format *nodes_list, uint32_t length, const uint8_t *pk, IP_Port ip_port,
+bool add_to_list(Node_format *nodes_list, uint32_t length, const uint8_t *pk, const IP_Port *ip_port,
const uint8_t *cmp_pk);
-/* Return 1 if node can be added to close list, 0 if it can't.
+/** Return 1 if node can be added to close list, 0 if it can't.
*/
-bool node_addable_to_close_list(DHT *dht, const uint8_t *public_key, IP_Port ip_port);
+bool node_addable_to_close_list(DHT *dht, const uint8_t *public_key, const IP_Port *ip_port);
-/* Get the (maximum MAX_SENT_NODES) closest nodes to public_key we know
+/** Get the (maximum MAX_SENT_NODES) closest nodes to public_key we know
* and put them in nodes_list (must be MAX_SENT_NODES big).
*
* sa_family = family (IPv4 or IPv6) (0 if we don't care)?
@@ -312,32 +305,33 @@ bool node_addable_to_close_list(DHT *dht, const uint8_t *public_key, IP_Port ip_
*
*/
int get_close_nodes(const DHT *dht, const uint8_t *public_key, Node_format *nodes_list, Family sa_family,
- bool is_LAN, uint8_t want_good);
+ bool is_LAN);
-/* Put up to max_num nodes in nodes from the random friends.
+/** Put up to max_num nodes in nodes from the random friends.
*
* return the number of nodes.
*/
-uint16_t randfriends_nodes(DHT *dht, Node_format *nodes, uint16_t max_num);
+uint16_t randfriends_nodes(const DHT *dht, Node_format *nodes, uint16_t max_num);
-/* Put up to max_num nodes in nodes from the closelist.
+/** Put up to max_num nodes in nodes from the closelist.
*
* return the number of nodes.
*/
-uint16_t closelist_nodes(DHT *dht, Node_format *nodes, uint16_t max_num);
+uint16_t closelist_nodes(const DHT *dht, Node_format *nodes, uint16_t max_num);
-/* Run this function at least a couple times per second (It's the main loop). */
+/** Run this function at least a couple times per second (It's the main loop). */
void do_dht(DHT *dht);
/*
* Use these two functions to bootstrap the client.
*/
-/* Sends a "get nodes" request to the given node with ip, port and public_key
+/** Sends a "get nodes" request to the given node with ip, port and public_key
* to setup connections
*/
-void dht_bootstrap(DHT *dht, IP_Port ip_port, const uint8_t *public_key);
-/* Resolves address into an IP address. If successful, sends a "get nodes"
+void dht_bootstrap(DHT *dht, const IP_Port *ip_port, const uint8_t *public_key);
+
+/** Resolves address into an IP address. If successful, sends a "get nodes"
* request to the given node with ip, port and public_key to setup connections
*
* address can be a hostname or an IP address (IPv4 or IPv6).
@@ -351,7 +345,7 @@ void dht_bootstrap(DHT *dht, IP_Port ip_port, const uint8_t *public_key);
int dht_bootstrap_from_address(DHT *dht, const char *address, uint8_t ipv6enabled,
uint16_t port, const uint8_t *public_key);
-/* Start sending packets after DHT loaded_friends_list and loaded_clients_list are set.
+/** Start sending packets after DHT loaded_friends_list and loaded_clients_list are set.
*
* returns 0 if successful
* returns -1 otherwise
@@ -360,54 +354,66 @@ int dht_connect_after_load(DHT *dht);
/* ROUTING FUNCTIONS */
-/* Send the given packet to node with public_key.
+/** Send the given packet to node with public_key.
*
* return -1 if failure.
*/
int route_packet(const DHT *dht, const uint8_t *public_key, const uint8_t *packet, uint16_t length);
-/* Send the following packet to everyone who tells us they are connected to friend_id.
+/**
+ * Send the following packet to everyone who tells us they are connected to friend_id.
*
- * return number of nodes it sent the packet to.
+ * return ip for friend.
+ * return number of nodes the packet was sent to. (Only works if more than (MAX_FRIEND_CLIENTS / 4).
*/
-int route_tofriend(const DHT *dht, const uint8_t *friend_id, const uint8_t *packet, uint16_t length);
+uint32_t route_to_friend(const DHT *dht, const uint8_t *friend_id, const Packet *packet);
-/* Function to handle crypto packets.
+/** Function to handle crypto packets.
*/
void cryptopacket_registerhandler(DHT *dht, uint8_t byte, cryptopacket_handler_cb *cb, void *object);
/* SAVE/LOAD functions */
-/* Get the size of the DHT (for saving). */
+/** Get the size of the DHT (for saving). */
uint32_t dht_size(const DHT *dht);
-/* Save the DHT in data where data is an array of size dht_size(). */
+/** Save the DHT in data where data is an array of size dht_size(). */
void dht_save(const DHT *dht, uint8_t *data);
-/* Load the DHT from data of size size.
+/** Load the DHT from data of size size.
*
* return -1 if failure.
* return 0 if success.
*/
int dht_load(DHT *dht, const uint8_t *data, uint32_t length);
-/* Initialize DHT. */
+/** Initialize DHT. */
DHT *new_dht(const Logger *log, Mono_Time *mono_time, Networking_Core *net, bool holepunching_enabled);
void kill_dht(DHT *dht);
-/* return false if we are not connected to the DHT.
+/** return false if we are not connected to the DHT.
* return true if we are.
*/
bool dht_isconnected(const DHT *dht);
-/* return false if we are not connected or only connected to lan peers with the DHT.
+/** return false if we are not connected or only connected to lan peers with the DHT.
* return true if we are.
*/
bool dht_non_lan_connected(const DHT *dht);
-uint32_t addto_lists(DHT *dht, IP_Port ip_port, const uint8_t *public_key);
+uint32_t addto_lists(DHT *dht, const IP_Port *ip_port, const uint8_t *public_key);
+
+/** Copies our own ip_port structure to `dest`. WAN addresses take priority over LAN addresses.
+ *
+ * This function will zero the `dest` buffer before use.
+ *
+ * Return 0 if our ip port can't be found (this usually means we're not connected to the DHT).
+ * Return 1 if IP is a WAN address.
+ * Return 2 if IP is a LAN address.
+ */
+unsigned int ipport_self_copy(const DHT *dht, IP_Port *dest);
#ifdef __cplusplus
} // extern "C"
diff --git a/protocols/Tox/libtox/src/toxcore/LAN_discovery.api.h b/protocols/Tox/libtox/src/toxcore/LAN_discovery.api.h
deleted file mode 100644
index ad3d60ed7a..0000000000
--- a/protocols/Tox/libtox/src/toxcore/LAN_discovery.api.h
+++ /dev/null
@@ -1,57 +0,0 @@
-%{
-/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2018 The TokTok team.
- * Copyright © 2013 Tox project.
- */
-
-/*
- * LAN discovery implementation.
- */
-#ifndef C_TOXCORE_TOXCORE_LAN_DISCOVERY_H
-#define C_TOXCORE_TOXCORE_LAN_DISCOVERY_H
-
-#include "DHT.h"
-%}
-
-class dHT { struct this; }
-class iP { struct this; }
-
-namespace lan_discovery {
-
-/**
- * Interval in seconds between LAN discovery packet sending.
- */
-#define LAN_DISCOVERY_INTERVAL 10
-
-/**
- * Send a LAN discovery pcaket to the broadcast address with port port.
- */
-static int32_t send(uint16_t port, dHT::this *dht);
-
-/**
- * Sets up packet handlers.
- */
-static void init(dHT::this *dht);
-
-/**
- * Clear packet handlers.
- */
-static void kill(dHT::this *dht);
-
-}
-
-/**
- * Is IP a local ip or not.
- */
-static bool ip_is_local(iP::this ip);
-
-/**
- * Checks if a given IP isn't routable.
- *
- * @return true if ip is a LAN ip, false if it is not.
- */
-static bool ip_is_lan(iP::this ip);
-
-%{
-#endif // C_TOXCORE_TOXCORE_LAN_DISCOVERY_H
-%}
diff --git a/protocols/Tox/libtox/src/toxcore/LAN_discovery.c b/protocols/Tox/libtox/src/toxcore/LAN_discovery.c
index 3f6951fcc7..6f9f77b6bb 100644
--- a/protocols/Tox/libtox/src/toxcore/LAN_discovery.c
+++ b/protocols/Tox/libtox/src/toxcore/LAN_discovery.c
@@ -3,17 +3,41 @@
* Copyright © 2013 Tox project.
*/
-/*
+/**
* LAN discovery implementation.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include "LAN_discovery.h"
#include <string.h>
+#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
+// The mingw32/64 Windows library warns about including winsock2.h after
+// windows.h even though with the above it's a valid thing to do. So, to make
+// mingw32 headers happy, we include winsock2.h first.
+#include <winsock2.h>
+
+#include <windows.h>
+#include <ws2tcpip.h>
+
+#include <iphlpapi.h>
+#endif
+
+#if defined(__linux__) || defined(__FreeBSD__) || defined(__DragonFly__)
+#include <netinet/in.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+#endif
+
+#ifdef __linux__
+#include <linux/netdevice.h>
+#endif
+
+#if defined(__FreeBSD__) || defined(__DragonFly__)
+#include <net/if.h>
+#endif
+
#include "util.h"
#define MAX_INTERFACES 16
@@ -29,16 +53,6 @@ static IP_Port broadcast_ip_ports[MAX_INTERFACES];
#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
-// The mingw32/64 Windows library warns about including winsock2.h after
-// windows.h even though with the above it's a valid thing to do. So, to make
-// mingw32 headers happy, we include winsock2.h first.
-#include <winsock2.h>
-
-#include <windows.h>
-#include <ws2tcpip.h>
-
-#include <iphlpapi.h>
-
static void fetch_broadcast_info(uint16_t port)
{
IP_ADAPTER_INFO *pAdapterInfo = (IP_ADAPTER_INFO *)malloc(sizeof(IP_ADAPTER_INFO));
@@ -106,21 +120,7 @@ static void fetch_broadcast_info(uint16_t port)
}
}
-#elif defined(__linux__) || defined(__FreeBSD__) || defined(__DragonFly__)
-
-#include <netinet/in.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#ifdef __linux__
-#include <linux/netdevice.h>
-#endif
-
-#if defined(__FreeBSD__) || defined(__DragonFly__)
-#include <net/if.h>
-#endif
+#elif !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && (defined(__linux__) || defined(__FreeBSD__) || defined(__DragonFly__))
static void fetch_broadcast_info(uint16_t port)
{
@@ -173,7 +173,7 @@ static void fetch_broadcast_info(uint16_t port)
continue;
}
- struct sockaddr_in *sock4 = (struct sockaddr_in *)(void *)&i_faces[i].ifr_broadaddr;
+ const struct sockaddr_in *sock4 = (const struct sockaddr_in *)(void *)&i_faces[i].ifr_broadaddr;
if (count >= MAX_INTERFACES) {
break;
@@ -208,12 +208,13 @@ static void fetch_broadcast_info(uint16_t port)
}
#endif
-/* Send packet to all IPv4 broadcast addresses
+
+/** Send packet to all IPv4 broadcast addresses
*
* return 1 if sent to at least one broadcast target.
* return 0 on failure to find any valid broadcast target.
*/
-static uint32_t send_broadcasts(Networking_Core *net, uint16_t port, const uint8_t *data, uint16_t length)
+static uint32_t send_broadcasts(const Networking_Core *net, uint16_t port, const uint8_t *data, uint16_t length)
{
/* fetch only once? on every packet? every X seconds?
* old: every packet, new: once */
@@ -226,13 +227,13 @@ static uint32_t send_broadcasts(Networking_Core *net, uint16_t port, const uint8
}
for (int i = 0; i < broadcast_count; ++i) {
- sendpacket(net, broadcast_ip_ports[i], data, length);
+ sendpacket(net, &broadcast_ip_ports[i], data, length);
}
return 1;
}
-/* Return the broadcast ip. */
+/** Return the broadcast ip. */
static IP broadcast_ip(Family family_socket, Family family_broadcast)
{
IP ip;
@@ -259,103 +260,103 @@ static IP broadcast_ip(Family family_socket, Family family_broadcast)
return ip;
}
-static bool ip4_is_local(IP4 ip4)
+static bool ip4_is_local(const IP4 *ip4)
{
/* Loopback. */
- return ip4.uint8[0] == 127;
+ return ip4->uint8[0] == 127;
}
-/* Is IP a local ip or not. */
-bool ip_is_local(IP ip)
+/**
+ * Is IP a local ip or not.
+ */
+bool ip_is_local(const IP *ip)
{
- if (net_family_is_ipv4(ip.family)) {
- return ip4_is_local(ip.ip.v4);
+ if (net_family_is_ipv4(ip->family)) {
+ return ip4_is_local(&ip->ip.v4);
}
/* embedded IPv4-in-IPv6 */
- if (ipv6_ipv4_in_v6(ip.ip.v6)) {
+ if (ipv6_ipv4_in_v6(&ip->ip.v6)) {
IP4 ip4;
- ip4.uint32 = ip.ip.v6.uint32[3];
- return ip4_is_local(ip4);
+ ip4.uint32 = ip->ip.v6.uint32[3];
+ return ip4_is_local(&ip4);
}
/* localhost in IPv6 (::1) */
- if (ip.ip.v6.uint64[0] == 0 && ip.ip.v6.uint32[2] == 0 && ip.ip.v6.uint32[3] == net_htonl(1)) {
+ if (ip->ip.v6.uint64[0] == 0 && ip->ip.v6.uint32[2] == 0 && ip->ip.v6.uint32[3] == net_htonl(1)) {
return true;
}
return false;
}
-static bool ip4_is_lan(IP4 ip4)
+static bool ip4_is_lan(const IP4 *ip4)
{
/* 10.0.0.0 to 10.255.255.255 range. */
- if (ip4.uint8[0] == 10) {
+ if (ip4->uint8[0] == 10) {
return true;
}
/* 172.16.0.0 to 172.31.255.255 range. */
- if (ip4.uint8[0] == 172 && ip4.uint8[1] >= 16 && ip4.uint8[1] <= 31) {
+ if (ip4->uint8[0] == 172 && ip4->uint8[1] >= 16 && ip4->uint8[1] <= 31) {
return true;
}
/* 192.168.0.0 to 192.168.255.255 range. */
- if (ip4.uint8[0] == 192 && ip4.uint8[1] == 168) {
+ if (ip4->uint8[0] == 192 && ip4->uint8[1] == 168) {
return true;
}
/* 169.254.1.0 to 169.254.254.255 range. */
- if (ip4.uint8[0] == 169 && ip4.uint8[1] == 254 && ip4.uint8[2] != 0
- && ip4.uint8[2] != 255) {
+ if (ip4->uint8[0] == 169 && ip4->uint8[1] == 254 && ip4->uint8[2] != 0
+ && ip4->uint8[2] != 255) {
return true;
}
/* RFC 6598: 100.64.0.0 to 100.127.255.255 (100.64.0.0/10)
* (shared address space to stack another layer of NAT) */
- if ((ip4.uint8[0] == 100) && ((ip4.uint8[1] & 0xC0) == 0x40)) {
+ if ((ip4->uint8[0] == 100) && ((ip4->uint8[1] & 0xC0) == 0x40)) {
return true;
}
return false;
}
-bool ip_is_lan(IP ip)
+bool ip_is_lan(const IP *ip)
{
if (ip_is_local(ip)) {
return true;
}
- if (net_family_is_ipv4(ip.family)) {
- return ip4_is_lan(ip.ip.v4);
+ if (net_family_is_ipv4(ip->family)) {
+ return ip4_is_lan(&ip->ip.v4);
}
- if (net_family_is_ipv6(ip.family)) {
+ if (net_family_is_ipv6(ip->family)) {
/* autogenerated for each interface: `FE80::*` (up to `FEBF::*`)
* `FF02::1` is - according to RFC 4291 - multicast all-nodes link-local */
- if (((ip.ip.v6.uint8[0] == 0xFF) && (ip.ip.v6.uint8[1] < 3) && (ip.ip.v6.uint8[15] == 1)) ||
- ((ip.ip.v6.uint8[0] == 0xFE) && ((ip.ip.v6.uint8[1] & 0xC0) == 0x80))) {
+ if (((ip->ip.v6.uint8[0] == 0xFF) && (ip->ip.v6.uint8[1] < 3) && (ip->ip.v6.uint8[15] == 1)) ||
+ ((ip->ip.v6.uint8[0] == 0xFE) && ((ip->ip.v6.uint8[1] & 0xC0) == 0x80))) {
return true;
}
/* embedded IPv4-in-IPv6 */
- if (ipv6_ipv4_in_v6(ip.ip.v6)) {
+ if (ipv6_ipv4_in_v6(&ip->ip.v6)) {
IP4 ip4;
- ip4.uint32 = ip.ip.v6.uint32[3];
- return ip4_is_lan(ip4);
+ ip4.uint32 = ip->ip.v6.uint32[3];
+ return ip4_is_lan(&ip4);
}
}
return false;
}
-static int handle_LANdiscovery(void *object, IP_Port source, const uint8_t *packet, uint16_t length, void *userdata)
+static int handle_LANdiscovery(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length,
+ void *userdata)
{
DHT *dht = (DHT *)object;
- char ip_str[IP_NTOA_LEN] = { 0 };
- ip_ntoa(&source.ip, ip_str, sizeof(ip_str));
-
- if (!ip_is_lan(source.ip)) {
+ if (!ip_is_lan(&source->ip)) {
return 1;
}
@@ -368,35 +369,35 @@ static int handle_LANdiscovery(void *object, IP_Port source, const uint8_t *pack
}
-int lan_discovery_send(uint16_t port, DHT *dht)
+bool lan_discovery_send(Networking_Core *net, const uint8_t *dht_pk, uint16_t port)
{
uint8_t data[CRYPTO_PUBLIC_KEY_SIZE + 1];
data[0] = NET_PACKET_LAN_DISCOVERY;
- id_copy(data + 1, dht_get_self_public_key(dht));
+ id_copy(data + 1, dht_pk);
- send_broadcasts(dht_get_net(dht), port, data, 1 + CRYPTO_PUBLIC_KEY_SIZE);
+ send_broadcasts(net, port, data, 1 + CRYPTO_PUBLIC_KEY_SIZE);
- int res = -1;
+ bool res = false;
IP_Port ip_port;
ip_port.port = port;
/* IPv6 multicast */
- if (net_family_is_ipv6(net_family(dht_get_net(dht)))) {
+ if (net_family_is_ipv6(net_family(net))) {
ip_port.ip = broadcast_ip(net_family_ipv6, net_family_ipv6);
if (ip_isset(&ip_port.ip)) {
- if (sendpacket(dht_get_net(dht), ip_port, data, 1 + CRYPTO_PUBLIC_KEY_SIZE) > 0) {
- res = 1;
+ if (sendpacket(net, &ip_port, data, 1 + CRYPTO_PUBLIC_KEY_SIZE) > 0) {
+ res = true;
}
}
}
/* IPv4 broadcast (has to be IPv4-in-IPv6 mapping if socket is IPv6 */
- ip_port.ip = broadcast_ip(net_family(dht_get_net(dht)), net_family_ipv4);
+ ip_port.ip = broadcast_ip(net_family(net), net_family_ipv4);
if (ip_isset(&ip_port.ip)) {
- if (sendpacket(dht_get_net(dht), ip_port, data, 1 + CRYPTO_PUBLIC_KEY_SIZE)) {
- res = 1;
+ if (sendpacket(net, &ip_port, data, 1 + CRYPTO_PUBLIC_KEY_SIZE)) {
+ res = true;
}
}
diff --git a/protocols/Tox/libtox/src/toxcore/LAN_discovery.h b/protocols/Tox/libtox/src/toxcore/LAN_discovery.h
index 6b55e3193b..cce7b5c190 100644
--- a/protocols/Tox/libtox/src/toxcore/LAN_discovery.h
+++ b/protocols/Tox/libtox/src/toxcore/LAN_discovery.h
@@ -3,7 +3,7 @@
* Copyright © 2013 Tox project.
*/
-/*
+/**
* LAN discovery implementation.
*/
#ifndef C_TOXCORE_TOXCORE_LAN_DISCOVERY_H
@@ -11,16 +11,6 @@
#include "DHT.h"
-#ifndef DHT_DEFINED
-#define DHT_DEFINED
-typedef struct DHT DHT;
-#endif /* DHT_DEFINED */
-
-#ifndef IP_DEFINED
-#define IP_DEFINED
-typedef struct IP IP;
-#endif /* IP_DEFINED */
-
/**
* Interval in seconds between LAN discovery packet sending.
*/
@@ -28,8 +18,10 @@ typedef struct IP IP;
/**
* Send a LAN discovery pcaket to the broadcast address with port port.
+ *
+ * @return true on success, false on failure.
*/
-int32_t lan_discovery_send(uint16_t port, DHT *dht);
+bool lan_discovery_send(Networking_Core *net, const uint8_t *dht_pk, uint16_t port);
/**
* Sets up packet handlers.
@@ -44,13 +36,13 @@ void lan_discovery_kill(DHT *dht);
/**
* Is IP a local ip or not.
*/
-bool ip_is_local(IP ip);
+bool ip_is_local(const IP *ip);
/**
* Checks if a given IP isn't routable.
*
* @return true if ip is a LAN ip, false if it is not.
*/
-bool ip_is_lan(IP ip);
+bool ip_is_lan(const IP *ip);
#endif // C_TOXCORE_TOXCORE_LAN_DISCOVERY_H
diff --git a/protocols/Tox/libtox/src/toxcore/Messenger.c b/protocols/Tox/libtox/src/toxcore/Messenger.c
index 22c3e9e856..6413dc928e 100644
--- a/protocols/Tox/libtox/src/toxcore/Messenger.c
+++ b/protocols/Tox/libtox/src/toxcore/Messenger.c
@@ -3,13 +3,9 @@
* Copyright © 2013 Tox project.
*/
-/*
+/**
* An implementation of a simple text chat only messenger on the tox network core.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include "Messenger.h"
#include <assert.h>
@@ -24,6 +20,9 @@
#include "state.h"
#include "util.h"
+static_assert(MAX_CONCURRENT_FILE_PIPES <= UINT8_MAX + 1,
+ "uint8_t cannot represent all file transfer numbers");
+
static int write_cryptpacket_id(const Messenger *m, int32_t friendnumber, uint8_t packet_id, const uint8_t *data,
uint32_t length, uint8_t congestion_control);
static void m_register_default_plugins(Messenger *m);
@@ -38,7 +37,7 @@ static bool friend_is_valid(const Messenger *m, int32_t friendnumber)
return (unsigned int)friendnumber < m->numfriends && m->friendlist[friendnumber].status != 0;
}
-/* Set the size of the friend list to numfriends.
+/** Set the size of the friend list to numfriends.
*
* return -1 if realloc fails.
*/
@@ -60,14 +59,12 @@ static int realloc_friendlist(Messenger *m, uint32_t num)
return 0;
}
-/* return the friend id associated to that public key.
+/** return the friend number associated to that public key.
* return -1 if no such friend.
*/
int32_t getfriend_id(const Messenger *m, const uint8_t *real_pk)
{
- uint32_t i;
-
- for (i = 0; i < m->numfriends; ++i) {
+ for (uint32_t i = 0; i < m->numfriends; ++i) {
if (m->friendlist[i].status > 0) {
if (id_equal(real_pk, m->friendlist[i].real_pk)) {
return i;
@@ -78,7 +75,7 @@ int32_t getfriend_id(const Messenger *m, const uint8_t *real_pk)
return -1;
}
-/* Copies the public key associated to that friend id into real_pk buffer.
+/** Copies the public key associated to that friend id into real_pk buffer.
* Make sure that real_pk is of size CRYPTO_PUBLIC_KEY_SIZE.
*
* return 0 if success.
@@ -94,7 +91,7 @@ int get_real_pk(const Messenger *m, int32_t friendnumber, uint8_t *real_pk)
return 0;
}
-/* return friend connection id on success.
+/** return friend connection id on success.
* return -1 if failure.
*/
int getfriendcon_id(const Messenger *m, int32_t friendnumber)
@@ -106,16 +103,15 @@ int getfriendcon_id(const Messenger *m, int32_t friendnumber)
return m->friendlist[friendnumber].friendcon_id;
}
-/*
+/**
* return a uint16_t that represents the checksum of address of length len.
*/
static uint16_t address_checksum(const uint8_t *address, uint32_t len)
{
uint8_t checksum[2] = {0};
uint16_t check;
- uint32_t i;
- for (i = 0; i < len; ++i) {
+ for (uint32_t i = 0; i < len; ++i) {
checksum[i % 2] ^= address[i];
}
@@ -123,7 +119,7 @@ static uint16_t address_checksum(const uint8_t *address, uint32_t len)
return check;
}
-/* Format: `[real_pk (32 bytes)][nospam number (4 bytes)][checksum (2 bytes)]`
+/** Format: `[real_pk (32 bytes)][nospam number (4 bytes)][checksum (2 bytes)]`
*
* return FRIEND_ADDRESS_SIZE byte address to give to others.
*/
@@ -180,9 +176,7 @@ static int32_t init_new_friend(Messenger *m, const uint8_t *real_pk, uint8_t sta
return FAERR_NOMEM;
}
- uint32_t i;
-
- for (i = 0; i <= m->numfriends; ++i) {
+ for (uint32_t i = 0; i <= m->numfriends; ++i) {
if (m->friendlist[i].status == NOFRIEND) {
m->friendlist[i].status = status;
m->friendlist[i].friendcon_id = friendcon_id;
@@ -210,11 +204,16 @@ static int32_t init_new_friend(Messenger *m, const uint8_t *real_pk, uint8_t sta
return FAERR_NOMEM;
}
-/*
+/**
* Add a friend.
+ *
* Set the data that will be sent along with friend request.
- * Address is the address of the friend (returned by getaddress of the friend you wish to add) it must be FRIEND_ADDRESS_SIZE bytes.
- * data is the data and length is the length.
+ *
+ * @param address is the address of the friend (returned by getaddress of the friend
+ * you wish to add) it must be FRIEND_ADDRESS_SIZE bytes.
+ * TODO(irungentoo): add checksum.
+ * @param data is the data.
+ * @param length is the length.
*
* return the friend number if success.
* return FA_TOOLONG if message length is too long.
@@ -348,7 +347,7 @@ static int add_receipt(Messenger *m, int32_t friendnumber, uint32_t packet_num,
new_receipts->next = nullptr;
return 0;
}
-/*
+/**
* return -1 on failure.
* return 0 if packet was received.
*/
@@ -395,7 +394,7 @@ static int do_receipts(Messenger *m, int32_t friendnumber, void *userdata)
return 0;
}
-/* Remove a friend.
+/** Remove a friend.
*
* return 0 if success.
* return -1 if failure.
@@ -421,6 +420,7 @@ int m_delfriend(Messenger *m, int32_t friendnumber)
kill_friend_connection(m->fr_c, m->friendlist[friendnumber].friendcon_id);
memset(&m->friendlist[friendnumber], 0, sizeof(Friend));
+
uint32_t i;
for (i = m->numfriends; i != 0; --i) {
@@ -480,7 +480,7 @@ int m_friend_exists(const Messenger *m, int32_t friendnumber)
return 1;
}
-/* Send a message of type.
+/** Send a message of type to an online friend.
*
* return -1 if friend not valid.
* return -2 if too large.
@@ -488,27 +488,29 @@ int m_friend_exists(const Messenger *m, int32_t friendnumber)
* return -4 if send failed (because queue is full).
* return -5 if bad type.
* return 0 if success.
+ *
+ * the value in message_id will be passed to your read_receipt callback when the other receives the message.
*/
int m_send_message_generic(Messenger *m, int32_t friendnumber, uint8_t type, const uint8_t *message, uint32_t length,
uint32_t *message_id)
{
if (type > MESSAGE_ACTION) {
- LOGGER_ERROR(m->log, "Message type %d is invalid", type);
+ LOGGER_WARNING(m->log, "Message type %d is invalid", type);
return -5;
}
if (!friend_is_valid(m, friendnumber)) {
- LOGGER_ERROR(m->log, "Friend number %d is invalid", friendnumber);
+ LOGGER_WARNING(m->log, "Friend number %d is invalid", friendnumber);
return -1;
}
if (length >= MAX_CRYPTO_DATA_SIZE) {
- LOGGER_ERROR(m->log, "Message length %u is too large", length);
+ LOGGER_WARNING(m->log, "Message length %u is too large", length);
return -2;
}
if (m->friendlist[friendnumber].status != FRIEND_ONLINE) {
- LOGGER_ERROR(m->log, "Friend %d is not online", friendnumber);
+ LOGGER_WARNING(m->log, "Friend %d is not online", friendnumber);
return -3;
}
@@ -523,8 +525,8 @@ int m_send_message_generic(Messenger *m, int32_t friendnumber, uint8_t type, con
m->friendlist[friendnumber].friendcon_id), packet, length + 1, 0);
if (packet_num == -1) {
- LOGGER_ERROR(m->log, "Failed to write crypto packet for message of length %d to friend %d",
- length, friendnumber);
+ LOGGER_WARNING(m->log, "Failed to write crypto packet for message of length %d to friend %d",
+ length, friendnumber);
return -4;
}
@@ -539,7 +541,7 @@ int m_send_message_generic(Messenger *m, int32_t friendnumber, uint8_t type, con
return 0;
}
-/* Send a name packet to friendnumber.
+/** Send a name packet to friendnumber.
* length is the length with the NULL terminator.
*/
static int m_sendname(const Messenger *m, int32_t friendnumber, const uint8_t *name, uint16_t length)
@@ -551,7 +553,10 @@ static int m_sendname(const Messenger *m, int32_t friendnumber, const uint8_t *n
return write_cryptpacket_id(m, friendnumber, PACKET_ID_NICKNAME, name, length, 0);
}
-/* Set the name and name_length of a friend.
+/** Set the name and name_length of a friend.
+ * name must be a string of maximum MAX_NAME_LENGTH length.
+ * length must be at least 1 byte.
+ * length is the length of name with the NULL terminator.
*
* return 0 if success.
* return -1 if failure.
@@ -571,7 +576,7 @@ int setfriendname(Messenger *m, int32_t friendnumber, const uint8_t *name, uint1
return 0;
}
-/* Set our nickname
+/** Set our nickname.
* name must be a string of maximum MAX_NAME_LENGTH length.
* length must be at least 1 byte.
* length is the length of name with the NULL terminator.
@@ -594,19 +599,21 @@ int setname(Messenger *m, const uint8_t *name, uint16_t length)
}
m->name_length = length;
- uint32_t i;
- for (i = 0; i < m->numfriends; ++i) {
+ for (uint32_t i = 0; i < m->numfriends; ++i) {
m->friendlist[i].name_sent = 0;
}
return 0;
}
-/* Get our nickname and put it in name.
+/**
+ * Get your nickname.
+ * m - The messenger context to use.
* name needs to be a valid memory location with a size of at least MAX_NAME_LENGTH bytes.
*
- * return the length of the name.
+ * return length of the name.
+ * return 0 on error.
*/
uint16_t getself_name(const Messenger *m, uint8_t *name)
{
@@ -619,8 +626,8 @@ uint16_t getself_name(const Messenger *m, uint8_t *name)
return m->name_length;
}
-/* Get name of friendnumber and put it in name.
- * name needs to be a valid memory location with a size of at least MAX_NAME_LENGTH bytes.
+/** Get name of friendnumber and put it in name.
+ * name needs to be a valid memory location with a size of at least MAX_NAME_LENGTH (128) bytes.
*
* return length of name if success.
* return -1 if failure.
@@ -665,9 +672,7 @@ int m_set_statusmessage(Messenger *m, const uint8_t *status, uint16_t length)
m->statusmessage_length = length;
- uint32_t i;
-
- for (i = 0; i < m->numfriends; ++i) {
+ for (uint32_t i = 0; i < m->numfriends; ++i) {
m->friendlist[i].statusmessage_sent = 0;
}
@@ -685,17 +690,19 @@ int m_set_userstatus(Messenger *m, uint8_t status)
}
m->userstatus = (Userstatus)status;
- uint32_t i;
- for (i = 0; i < m->numfriends; ++i) {
+ for (uint32_t i = 0; i < m->numfriends; ++i) {
m->friendlist[i].userstatus_sent = 0;
}
return 0;
}
-/* return the size of friendnumber's user status.
+/**
* Guaranteed to be at most MAX_STATUSMESSAGE_LENGTH.
+ *
+ * returns the length of friendnumber's status message, including null on success.
+ * returns -1 on failure.
*/
int m_get_statusmessage_size(const Messenger *m, int32_t friendnumber)
{
@@ -706,8 +713,12 @@ int m_get_statusmessage_size(const Messenger *m, int32_t friendnumber)
return m->friendlist[friendnumber].statusmessage_length;
}
-/* Copy the user status of friendnumber into buf, truncating if needed to maxlen
- * bytes, use m_get_statusmessage_size to find out how much you need to allocate.
+/** Copy friendnumber's status message into buf, truncating if size is over maxlen.
+ * Get the size you need to allocate from m_get_statusmessage_size.
+ * The self variant will copy our own status message.
+ *
+ * returns the length of the copied data on success
+ * returns -1 on failure.
*/
int m_copy_statusmessage(const Messenger *m, int32_t friendnumber, uint8_t *buf, uint32_t maxlen)
{
@@ -724,7 +735,7 @@ int m_copy_statusmessage(const Messenger *m, int32_t friendnumber, uint8_t *buf,
return msglen;
}
-/* return the size of friendnumber's user status.
+/** return the size of friendnumber's user status.
* Guaranteed to be at most MAX_STATUSMESSAGE_LENGTH.
*/
int m_get_self_statusmessage_size(const Messenger *m)
@@ -840,13 +851,13 @@ static void set_friend_typing(const Messenger *m, int32_t friendnumber, uint8_t
m->friendlist[friendnumber].is_typing = is_typing;
}
-/* Set the function that will be executed when a friend request is received. */
+/** Set the function that will be executed when a friend request is received. */
void m_callback_friendrequest(Messenger *m, m_friend_request_cb *function)
{
callback_friendrequest(m->fr, (fr_friend_request_cb *)function, m);
}
-/* Set the function that will be executed when a message from a friend is received. */
+/** Set the function that will be executed when a message from a friend is received. */
void m_callback_friendmessage(Messenger *m, m_friend_message_cb *function)
{
m->friend_message = function;
@@ -973,10 +984,10 @@ static int write_cryptpacket_id(const Messenger *m, int32_t friendnumber, uint8_
m->friendlist[friendnumber].friendcon_id), packet, length + 1, congestion_control) != -1;
}
-/** CONFERENCES */
+/*** CONFERENCES */
-/* Set the callback for conference invites.
+/** Set the callback for conference invites.
*/
void m_callback_conference_invite(Messenger *m, m_conference_invite_cb *function)
{
@@ -984,7 +995,7 @@ void m_callback_conference_invite(Messenger *m, m_conference_invite_cb *function
}
-/* Send a conference invite packet.
+/** Send a conference invite packet.
*
* return 1 on success
* return 0 on failure
@@ -994,31 +1005,31 @@ int send_conference_invite_packet(const Messenger *m, int32_t friendnumber, cons
return write_cryptpacket_id(m, friendnumber, PACKET_ID_INVITE_CONFERENCE, data, length, 0);
}
-/** FILE SENDING */
+/*** FILE SENDING */
-/* Set the callback for file send requests.
+/** Set the callback for file send requests.
*/
void callback_file_sendrequest(Messenger *m, m_file_recv_cb *function)
{
m->file_sendrequest = function;
}
-/* Set the callback for file control requests.
+/** Set the callback for file control requests.
*/
void callback_file_control(Messenger *m, m_file_recv_control_cb *function)
{
m->file_filecontrol = function;
}
-/* Set the callback for file data.
+/** Set the callback for file data.
*/
void callback_file_data(Messenger *m, m_file_recv_chunk_cb *function)
{
m->file_filedata = function;
}
-/* Set the callback for file request chunk.
+/** Set the callback for file request chunk.
*/
void callback_file_reqchunk(Messenger *m, m_file_chunk_request_cb *function)
{
@@ -1027,7 +1038,7 @@ void callback_file_reqchunk(Messenger *m, m_file_chunk_request_cb *function)
#define MAX_FILENAME_LENGTH 255
-/* Copy the file transfer file id to file_id
+/** Copy the file transfer file id to file_id
*
* return 0 on success.
* return -1 if friend not valid.
@@ -1077,7 +1088,7 @@ int file_get_id(const Messenger *m, int32_t friendnumber, uint32_t filenumber, u
return 0;
}
-/* Send a file send request.
+/** Send a file send request.
* Maximum filename length is 255 bytes.
* return 1 on success
* return 0 on failure
@@ -1107,7 +1118,7 @@ static int file_sendrequest(const Messenger *m, int32_t friendnumber, uint8_t fi
return write_cryptpacket_id(m, friendnumber, PACKET_ID_FILE_SENDREQUEST, packet, SIZEOF_VLA(packet), 0);
}
-/* Send a file send request.
+/** Send a file send request.
* Maximum filename length is 255 bytes.
* return file number on success
* return -1 if friend not found.
@@ -1157,13 +1168,11 @@ long int new_filesender(const Messenger *m, int32_t friendnumber, uint32_t file_
memcpy(ft->id, file_id, FILE_ID_LENGTH);
- ++m->friendlist[friendnumber].num_sending_files;
-
return i;
}
static int send_file_control_packet(const Messenger *m, int32_t friendnumber, uint8_t send_receive, uint8_t filenumber,
- uint8_t control_type, uint8_t *data, uint16_t data_length)
+ uint8_t control_type, const uint8_t *data, uint16_t data_length)
{
if ((unsigned int)(1 + 3 + data_length) > MAX_CRYPTO_DATA_SIZE) {
return -1;
@@ -1182,7 +1191,7 @@ static int send_file_control_packet(const Messenger *m, int32_t friendnumber, ui
return write_cryptpacket_id(m, friendnumber, PACKET_ID_FILE_CONTROL, packet, SIZEOF_VLA(packet), 0);
}
-/* Send a file control request.
+/** Send a file control request.
*
* return 0 on success
* return -1 if friend not valid.
@@ -1264,11 +1273,12 @@ int file_control(const Messenger *m, int32_t friendnumber, uint32_t filenumber,
if (send_file_control_packet(m, friendnumber, send_receive, file_number, control, nullptr, 0)) {
if (control == FILECONTROL_KILL) {
- ft->status = FILESTATUS_NONE;
-
- if (send_receive == 0) {
+ if (send_receive == 0 && (ft->status == FILESTATUS_TRANSFERRING || ft->status == FILESTATUS_FINISHED)) {
+ // We are actively sending that file, remove from list
--m->friendlist[friendnumber].num_sending_files;
}
+
+ ft->status = FILESTATUS_NONE;
} else if (control == FILECONTROL_PAUSE) {
ft->paused |= FILE_PAUSE_US;
} else if (control == FILECONTROL_ACCEPT) {
@@ -1285,7 +1295,7 @@ int file_control(const Messenger *m, int32_t friendnumber, uint32_t filenumber,
return 0;
}
-/* Send a seek file control request.
+/** Send a seek file control request.
*
* return 0 on success
* return -1 if friend not valid.
@@ -1348,7 +1358,7 @@ int file_seek(const Messenger *m, int32_t friendnumber, uint32_t filenumber, uin
return 0;
}
-/* return packet number on success.
+/** return packet number on success.
* return -1 on failure.
*/
static int64_t send_file_data_packet(const Messenger *m, int32_t friendnumber, uint8_t filenumber, const uint8_t *data,
@@ -1372,7 +1382,7 @@ static int64_t send_file_data_packet(const Messenger *m, int32_t friendnumber, u
#define MAX_FILE_DATA_SIZE (MAX_CRYPTO_DATA_SIZE - 2)
#define MIN_SLOTS_FREE (CRYPTO_MIN_QUEUE_LENGTH / 4)
-/* Send file data.
+/** Send file data.
*
* return 0 on success
* return -1 if friend not valid.
@@ -1474,15 +1484,13 @@ static bool do_all_filetransfers(Messenger *m, int32_t friendnumber, void *userd
return false;
}
- if (max_speed_reached(m->net_crypto, friend_connection_crypt_connection_id(
- m->fr_c, friendcon->friendcon_id))) {
- LOGGER_TRACE(m->log, "Maximum connection speed reached");
- // connection doesn't support any more data
- return false;
- }
-
struct File_Transfers *const ft = &friendcon->file_sending[i];
+ if (ft->status == FILESTATUS_NONE || ft->status == FILESTATUS_NOT_ACCEPTED) {
+ // Filetransfers not actively sending, nothing to do
+ continue;
+ }
+
// If the file transfer is complete, we request a chunk of size 0.
if (ft->status == FILESTATUS_FINISHED && friend_received_packet(m, friendnumber, ft->last_packet_number) == 0) {
if (m->file_reqchunk) {
@@ -1492,9 +1500,7 @@ static bool do_all_filetransfers(Messenger *m, int32_t friendnumber, void *userd
// Now it's inactive, we're no longer sending this.
ft->status = FILESTATUS_NONE;
--friendcon->num_sending_files;
- }
-
- if (ft->status == FILESTATUS_TRANSFERRING && ft->paused == FILE_PAUSE_NOT) {
+ } else if (ft->status == FILESTATUS_TRANSFERRING && ft->paused == FILE_PAUSE_NOT) {
if (ft->size == 0) {
/* Send 0 data to friend if file is 0 length. */
file_data(m, friendnumber, i, 0, nullptr, 0);
@@ -1517,6 +1523,14 @@ static bool do_all_filetransfers(Messenger *m, int32_t friendnumber, void *userd
// The allocated slot is no longer free.
--*free_slots;
}
+
+ // Must be last to allow finishing file transfers
+ if (max_speed_reached(m->net_crypto, friend_connection_crypt_connection_id(
+ m->fr_c, friendcon->friendcon_id))) {
+ LOGGER_TRACE(m->log, "Maximum connection speed reached");
+ // connection doesn't support any more data
+ return false;
+ }
}
return true;
@@ -1561,7 +1575,7 @@ static void do_reqchunk_filecb(Messenger *m, int32_t friendnumber, void *userdat
}
-/* Run this when the friend disconnects.
+/** Run this when the friend disconnects.
* Kill all current file transfers.
*/
static void break_files(const Messenger *m, int32_t friendnumber)
@@ -1598,7 +1612,7 @@ static struct File_Transfers *get_file_transfer(uint8_t receive_send, uint8_t fi
return ft;
}
-/* return -1 on failure, 0 on success.
+/** return -1 on failure, 0 on success.
*/
static int handle_filecontrol(Messenger *m, int32_t friendnumber, uint8_t receive_send, uint8_t filenumber,
uint8_t control_type, const uint8_t *data, uint16_t length, void *userdata)
@@ -1623,6 +1637,7 @@ static int handle_filecontrol(Messenger *m, int32_t friendnumber, uint8_t receiv
case FILECONTROL_ACCEPT: {
if (receive_send && ft->status == FILESTATUS_NOT_ACCEPTED) {
ft->status = FILESTATUS_TRANSFERRING;
+ ++m->friendlist[friendnumber].num_sending_files;
} else {
if (ft->paused & FILE_PAUSE_OTHER) {
ft->paused ^= FILE_PAUSE_OTHER;
@@ -1661,12 +1676,12 @@ static int handle_filecontrol(Messenger *m, int32_t friendnumber, uint8_t receiv
m->file_filecontrol(m, friendnumber, real_filenumber, control_type, userdata);
}
- ft->status = FILESTATUS_NONE;
-
- if (receive_send) {
+ if (receive_send && (ft->status == FILESTATUS_TRANSFERRING || ft->status == FILESTATUS_FINISHED)) {
--m->friendlist[friendnumber].num_sending_files;
}
+ ft->status = FILESTATUS_NONE;
+
return 0;
}
@@ -1709,7 +1724,7 @@ static int handle_filecontrol(Messenger *m, int32_t friendnumber, uint8_t receiv
}
}
-/* Set the callback for msi packets.
+/** Set the callback for msi packets.
*/
void m_callback_msi_packet(Messenger *m, m_msi_packet_cb *function, void *userdata)
{
@@ -1717,7 +1732,7 @@ void m_callback_msi_packet(Messenger *m, m_msi_packet_cb *function, void *userda
m->msi_packet_userdata = userdata;
}
-/* Send an msi packet.
+/** Send an msi packet.
*
* return 1 on success
* return 0 on failure
@@ -1776,12 +1791,21 @@ int m_callback_rtp_packet(Messenger *m, int32_t friendnumber, uint8_t byte, m_lo
}
-/* TODO(oxij): this name is confusing, because this function sends both av and custom lossy packets.
+/** High level function to send custom lossy packets.
+ *
+ * TODO(oxij): this name is confusing, because this function sends both av and custom lossy packets.
* Meanwhile, m_handle_lossy_packet routes custom packets to custom_lossy_packet_registerhandler
* as you would expect from its name.
*
* I.e. custom_lossy_packet_registerhandler's "custom lossy packet" and this "custom lossy packet"
* are not the same set of packets.
+ *
+ * return -1 if friend invalid.
+ * return -2 if length wrong.
+ * return -3 if first byte invalid.
+ * return -4 if friend offline.
+ * return -5 if packet failed to send because of other error.
+ * return 0 on success.
*/
int m_send_custom_lossy_packet(const Messenger *m, int32_t friendnumber, const uint8_t *data, uint32_t length)
{
@@ -1862,7 +1886,7 @@ int send_custom_lossless_packet(const Messenger *m, int32_t friendnumber, const
return 0;
}
-/* Function to filter out some friend requests*/
+/** Function to filter out some friend requests*/
static int friend_already_added(const uint8_t *real_pk, void *data)
{
const Messenger *m = (const Messenger *)data;
@@ -1874,7 +1898,12 @@ static int friend_already_added(const uint8_t *real_pk, void *data)
return -1;
}
-/* Run this at startup. */
+/** Run this at startup.
+ * return allocated instance of Messenger on success.
+ * return 0 if there are problems.
+ *
+ * if error is not NULL it will be set to one of the values in the enum above.
+ */
Messenger *new_messenger(Mono_Time *mono_time, Messenger_Options *options, unsigned int *error)
{
if (!options) {
@@ -1923,7 +1952,7 @@ Messenger *new_messenger(Mono_Time *mono_time, Messenger_Options *options, unsig
} else {
IP ip;
ip_init(&ip, options->ipv6enabled);
- m->net = new_networking_ex(m->log, ip, options->port_range[0], options->port_range[1], &net_err);
+ m->net = new_networking_ex(m->log, &ip, options->port_range[0], options->port_range[1], &net_err);
}
if (m->net == nullptr) {
@@ -1959,8 +1988,8 @@ Messenger *new_messenger(Mono_Time *mono_time, Messenger_Options *options, unsig
return nullptr;
}
- m->onion = new_onion(m->mono_time, m->dht);
- m->onion_a = new_onion_announce(m->mono_time, m->dht);
+ m->onion = new_onion(m->log, m->mono_time, m->dht);
+ m->onion_a = new_onion_announce(m->log, m->mono_time, m->dht);
m->onion_c = new_onion_client(m->log, m->mono_time, m->net_crypto);
m->fr_c = new_friend_connections(m->log, m->mono_time, m->onion_c, options->local_discovery_enabled);
@@ -2018,15 +2047,15 @@ Messenger *new_messenger(Mono_Time *mono_time, Messenger_Options *options, unsig
return m;
}
-/* Run this before closing shop. */
+/** Run this before closing shop
+ * Free all datastructures.
+ */
void kill_messenger(Messenger *m)
{
if (!m) {
return;
}
- uint32_t i;
-
if (m->tcp_server) {
kill_TCP_server(m->tcp_server);
}
@@ -2039,7 +2068,7 @@ void kill_messenger(Messenger *m)
kill_dht(m->dht);
kill_networking(m->net);
- for (i = 0; i < m->numfriends; ++i) {
+ for (uint32_t i = 0; i < m->numfriends; ++i) {
clear_receipts(m, i);
}
@@ -2051,7 +2080,7 @@ void kill_messenger(Messenger *m)
free(m);
}
-/* Check for and handle a timed-out friend request. If the request has
+/** Check for and handle a timed-out friend request. If the request has
* timed-out then the friend status is set back to FRIEND_ADDED.
* i: friendlist index of the timed-out friend
* t: time
@@ -2093,7 +2122,7 @@ static int m_handle_packet(void *object, int i, const uint8_t *temp, uint16_t le
Messenger *m = (Messenger *)object;
uint8_t packet_id = temp[0];
const uint8_t *data = temp + 1;
- uint32_t data_length = len - 1;
+ uint16_t data_length = len - 1;
if (m->friendlist[i].status != FRIEND_ONLINE) {
if (packet_id == PACKET_ID_ONLINE && len == 1) {
@@ -2204,7 +2233,7 @@ static int m_handle_packet(void *object, int i, const uint8_t *temp, uint16_t le
uint8_t type = packet_id - PACKET_ID_MESSAGE;
if (m->friend_message) {
- (*m->friend_message)(m, i, type, message_terminated, message_length, userdata);
+ m->friend_message(m, i, type, message_terminated, message_length, userdata);
}
break;
@@ -2216,7 +2245,7 @@ static int m_handle_packet(void *object, int i, const uint8_t *temp, uint16_t le
}
if (m->conference_invite) {
- (*m->conference_invite)(m, i, data, data_length, userdata);
+ m->conference_invite(m, i, data, data_length, userdata);
}
break;
@@ -2264,7 +2293,7 @@ static int m_handle_packet(void *object, int i, const uint8_t *temp, uint16_t le
memcpy(ft->id, data + 1 + sizeof(uint32_t) + sizeof(uint64_t), FILE_ID_LENGTH);
VLA(uint8_t, filename_terminated, filename_length + 1);
- uint8_t *filename = nullptr;
+ const uint8_t *filename = nullptr;
if (filename_length) {
/* Force NULL terminate file name. */
@@ -2278,8 +2307,8 @@ static int m_handle_packet(void *object, int i, const uint8_t *temp, uint16_t le
real_filenumber <<= 16;
if (m->file_sendrequest) {
- (*m->file_sendrequest)(m, i, real_filenumber, file_type, filesize, filename, filename_length,
- userdata);
+ m->file_sendrequest(m, i, real_filenumber, file_type, filesize, filename, filename_length,
+ userdata);
}
break;
@@ -2336,7 +2365,7 @@ static int m_handle_packet(void *object, int i, const uint8_t *temp, uint16_t le
uint32_t real_filenumber = filenumber;
real_filenumber += 1;
real_filenumber <<= 16;
- uint16_t file_data_length = (data_length - 1);
+ uint16_t file_data_length = data_length - 1;
const uint8_t *file_data;
if (file_data_length == 0) {
@@ -2351,7 +2380,7 @@ static int m_handle_packet(void *object, int i, const uint8_t *temp, uint16_t le
}
if (m->file_filedata) {
- (*m->file_filedata)(m, i, real_filenumber, position, file_data, file_data_length, userdata);
+ m->file_filedata(m, i, real_filenumber, position, file_data, file_data_length, userdata);
}
ft->transferred += file_data_length;
@@ -2363,7 +2392,7 @@ static int m_handle_packet(void *object, int i, const uint8_t *temp, uint16_t le
/* Full file received. */
if (m->file_filedata) {
- (*m->file_filedata)(m, i, real_filenumber, position, file_data, file_data_length, userdata);
+ m->file_filedata(m, i, real_filenumber, position, file_data, file_data_length, userdata);
}
}
@@ -2381,7 +2410,7 @@ static int m_handle_packet(void *object, int i, const uint8_t *temp, uint16_t le
}
if (m->msi_packet) {
- (*m->msi_packet)(m, i, data, data_length, m->msi_packet_userdata);
+ m->msi_packet(m, i, data, data_length, m->msi_packet_userdata);
}
break;
@@ -2398,10 +2427,9 @@ static int m_handle_packet(void *object, int i, const uint8_t *temp, uint16_t le
static void do_friends(Messenger *m, void *userdata)
{
- uint32_t i;
uint64_t temp_time = mono_time_get(m->mono_time);
- for (i = 0; i < m->numfriends; ++i) {
+ for (uint32_t i = 0; i < m->numfriends; ++i) {
if (m->friendlist[i].status == FRIEND_ADDED) {
int fr = send_friend_request_packet(m->fr_c, m->friendlist[i].friendcon_id, m->friendlist[i].friendrequest_nospam,
m->friendlist[i].info,
@@ -2463,7 +2491,7 @@ static void connection_status_callback(Messenger *m, void *userdata)
if (conn_status != m->last_connection_status) {
if (m->core_connection_change) {
- (*m->core_connection_change)(m, conn_status, userdata);
+ m->core_connection_change(m, conn_status, userdata);
}
m->last_connection_status = conn_status;
@@ -2474,7 +2502,7 @@ static void connection_status_callback(Messenger *m, void *userdata)
#define DUMPING_CLIENTS_FRIENDS_EVERY_N_SECONDS 60UL
#define IDSTRING_LEN (CRYPTO_PUBLIC_KEY_SIZE * 2 + 1)
-/* id_str should be of length at least IDSTRING_LEN */
+/** id_str should be of length at least IDSTRING_LEN */
static char *id_to_string(const uint8_t *pk, char *id_str, size_t length)
{
if (length < IDSTRING_LEN) {
@@ -2483,18 +2511,18 @@ static char *id_to_string(const uint8_t *pk, char *id_str, size_t length)
}
for (uint32_t i = 0; i < CRYPTO_PUBLIC_KEY_SIZE; ++i) {
- sprintf(&id_str[i * 2], "%02X", pk[i]);
+ snprintf(&id_str[i * 2], length - i * 2, "%02X", pk[i]);
}
id_str[CRYPTO_PUBLIC_KEY_SIZE * 2] = 0;
return id_str;
}
-/* Minimum messenger run interval in ms
+/** Minimum messenger run interval in ms
* TODO(mannol): A/V */
#define MIN_RUN_INTERVAL 50
-/* Return the time in milliseconds before do_messenger() should be called again
+/** Return the time in milliseconds before do_messenger() should be called again
* for optimal performance.
*
* returns time (in ms) before the next do_messenger() needs to be run on success.
@@ -2510,7 +2538,7 @@ uint32_t messenger_run_interval(const Messenger *m)
return crypto_interval;
}
-/* The main loop that needs to be run at least 20 times per second. */
+/** The main loop that needs to be run at least 20 times per second. */
void do_messenger(Messenger *m, void *userdata)
{
// Add the TCP relays, but only if this is the first time calling do_messenger
@@ -2518,7 +2546,7 @@ void do_messenger(Messenger *m, void *userdata)
m->has_added_relays = true;
for (uint16_t i = 0; i < m->num_loaded_relays; ++i) {
- add_tcp_relay(m->net_crypto, m->loaded_relays[i].ip_port, m->loaded_relays[i].public_key);
+ add_tcp_relay(m->net_crypto, &m->loaded_relays[i].ip_port, m->loaded_relays[i].public_key);
}
m->num_loaded_relays = 0;
@@ -2529,8 +2557,7 @@ void do_messenger(Messenger *m, void *userdata)
local_ip_port.port = m->options.tcp_server_port;
local_ip_port.ip.family = net_family_ipv4;
local_ip_port.ip.ip.v4 = get_ip4_loopback();
- add_tcp_relay(m->net_crypto, local_ip_port,
- tcp_server_public_key(m->tcp_server));
+ add_tcp_relay(m->net_crypto, &local_ip_port, tcp_server_public_key(m->tcp_server));
}
}
@@ -2609,17 +2636,9 @@ void do_messenger(Messenger *m, void *userdata)
LOGGER_TRACE(m->log, "Friend num in DHT %u != friend num in msger %u", dht_get_num_friends(m->dht), m->numfriends);
}
- Friend *msgfptr;
- DHT_Friend *dhtfptr;
-
for (uint32_t friend_idx = 0; friend_idx < num_dhtfriends; ++friend_idx) {
- if (dht2m[friend_idx] >= 0) {
- msgfptr = &m->friendlist[dht2m[friend_idx]];
- } else {
- msgfptr = nullptr;
- }
-
- dhtfptr = dht_get_friend(m->dht, friend_idx);
+ const Friend *const msgfptr = dht2m[friend_idx] >= 0 ? &m->friendlist[dht2m[friend_idx]] : nullptr;
+ const DHT_Friend *const dhtfptr = dht_get_friend(m->dht, friend_idx);
if (msgfptr) {
char id_str[IDSTRING_LEN];
@@ -2659,7 +2678,7 @@ void do_messenger(Messenger *m, void *userdata)
}
}
-/* new messenger format for load/save, more robust and forward compatible */
+/** new messenger format for load/save, more robust and forward compatible */
#define SAVED_FRIEND_REQUEST_SIZE 1024
#define NUM_SAVED_PATH_NODES 8
@@ -2794,10 +2813,10 @@ static uint32_t m_state_plugins_size(const Messenger *m)
return size;
}
-/*
- * Registers a state plugin with the messenger
+/** Registers a state plugin for saving, loadding, and getting the size of a section of the save
+ *
* returns true on success
- * returns false on failure
+ * returns false on error
*/
bool m_register_state_plugin(Messenger *m, State_Type type, m_state_size_cb size_callback,
m_state_load_cb load_callback,
@@ -2837,13 +2856,13 @@ static uint32_t m_plugin_size(const Messenger *m, State_Type type)
return UINT32_MAX;
}
-/* return size of the messenger data (for saving) */
+/** return size of the messenger data (for saving). */
uint32_t messenger_size(const Messenger *m)
{
return m_state_plugins_size(m);
}
-/* Save the messenger in data of size messenger_size(). */
+/** Save the messenger in data (must be allocated memory of size at least Messenger_size()) */
uint8_t *messenger_save(const Messenger *m, uint8_t *data)
{
for (uint8_t i = 0; i < m->options.state_plugins_length; ++i) {
@@ -2969,21 +2988,20 @@ static uint8_t *friends_list_save(const Messenger *m, uint8_t *data)
static State_Load_Status friends_list_load(Messenger *m, const uint8_t *data, uint32_t length)
{
- if (length % friend_size() != 0) {
+ const uint32_t l_friend_size = friend_size();
+
+ if (length % l_friend_size != 0) {
return STATE_LOAD_STATUS_ERROR; // TODO(endoffile78): error or continue?
}
- uint32_t num = length / friend_size();
- uint32_t i;
+ uint32_t num = length / l_friend_size;
const uint8_t *cur_data = data;
- for (i = 0; i < num; ++i) {
+ for (uint32_t i = 0; i < num; ++i) {
struct Saved_Friend temp = { 0 };
const uint8_t *next_data = friend_load(&temp, cur_data);
- assert(next_data - cur_data == friend_size());
-#ifdef __LP64__
- assert(memcmp(&temp, cur_data, friend_size()) == 0);
-#endif
+ assert(next_data - cur_data == l_friend_size);
+
cur_data = next_data;
if (temp.status >= 3) {
@@ -3091,7 +3109,7 @@ static uint32_t tcp_relay_size(const Messenger *m)
static uint8_t *save_tcp_relays(const Messenger *m, uint8_t *data)
{
- Node_format relays[NUM_SAVED_TCP_RELAYS];
+ Node_format relays[NUM_SAVED_TCP_RELAYS] = {0};
uint8_t *temp_data = data;
data = state_write_section_header(temp_data, STATE_COOKIE_TYPE, 0, STATE_TYPE_TCP_RELAY);
@@ -3166,7 +3184,7 @@ static State_Load_Status load_path_nodes(Messenger *m, const uint8_t *data, uint
}
for (int i = 0; i < num; ++i) {
- onion_add_bs_path_node(m->onion_c, nodes[i].ip_port, nodes[i].public_key);
+ onion_add_bs_path_node(m->onion_c, &nodes[i].ip_port, nodes[i].public_key);
}
}
@@ -3201,15 +3219,14 @@ bool messenger_load_state_section(Messenger *m, const uint8_t *data, uint32_t le
return false;
}
-/* Return the number of friends in the instance m.
+/** Return the number of friends in the instance m.
* You should use this to determine how much memory to allocate
* for copy_friendlist. */
uint32_t count_friendlist(const Messenger *m)
{
uint32_t ret = 0;
- uint32_t i;
- for (i = 0; i < m->numfriends; ++i) {
+ for (uint32_t i = 0; i < m->numfriends; ++i) {
if (m->friendlist[i].status > 0) {
++ret;
}
@@ -3218,7 +3235,7 @@ uint32_t count_friendlist(const Messenger *m)
return ret;
}
-/* Copy a list of valid friend IDs into the array out_list.
+/** Copy a list of valid friend IDs into the array out_list.
* If out_list is NULL, returns 0.
* Otherwise, returns the number of elements copied.
* If the array was too small, the contents
@@ -3233,10 +3250,9 @@ uint32_t copy_friendlist(Messenger const *m, uint32_t *out_list, uint32_t list_s
return 0;
}
- uint32_t i;
uint32_t ret = 0;
- for (i = 0; i < m->numfriends; ++i) {
+ for (uint32_t i = 0; i < m->numfriends; ++i) {
if (ret >= list_size) {
break; /* Abandon ship */
}
diff --git a/protocols/Tox/libtox/src/toxcore/Messenger.h b/protocols/Tox/libtox/src/toxcore/Messenger.h
index 673fd425a2..477b997391 100644
--- a/protocols/Tox/libtox/src/toxcore/Messenger.h
+++ b/protocols/Tox/libtox/src/toxcore/Messenger.h
@@ -3,13 +3,14 @@
* Copyright © 2013 Tox project.
*/
-/*
+/**
* An implementation of a simple text chat only messenger on the tox network
* core.
*/
#ifndef C_TOXCORE_TOXCORE_MESSENGER_H
#define C_TOXCORE_TOXCORE_MESSENGER_H
+#include "TCP_server.h"
#include "friend_connection.h"
#include "friend_requests.h"
#include "logger.h"
@@ -24,10 +25,6 @@
/* This cannot be bigger than 256 */
#define MAX_CONCURRENT_FILE_PIPES 256
-#if !defined(__SPLINT__) && MAX_CONCURRENT_FILE_PIPES > UINT8_MAX + 1
-#error "uint8_t cannot represent all file transfer numbers"
-#endif
-
#define FRIEND_ADDRESS_SIZE (CRYPTO_PUBLIC_KEY_SIZE + sizeof(uint32_t) + sizeof(uint16_t))
@@ -79,7 +76,7 @@ struct Receipts {
struct Receipts *next;
};
-/* Status definitions. */
+/** Status definitions. */
typedef enum Friend_Status {
NOFRIEND,
FRIEND_ADDED,
@@ -88,7 +85,7 @@ typedef enum Friend_Status {
FRIEND_ONLINE,
} Friend_Status;
-/* Errors for m_addfriend
+/** Errors for m_addfriend
* FAERR - Friend Add Error
*/
typedef enum Friend_Add_Error {
@@ -102,7 +99,7 @@ typedef enum Friend_Add_Error {
} Friend_Add_Error;
-/* Default start timeout in seconds between friend requests. */
+/** Default start timeout in seconds between friend requests. */
#define FRIENDREQUEST_TIMEOUT 5
typedef enum Connection_Status {
@@ -111,7 +108,7 @@ typedef enum Connection_Status {
CONNECTION_UDP,
} Connection_Status;
-/* USERSTATUS -
+/** USERSTATUS -
* Represents userstatuses someone can have.
*/
@@ -298,33 +295,37 @@ struct Messenger {
Messenger_Options options;
};
-/* Format: `[real_pk (32 bytes)][nospam number (4 bytes)][checksum (2 bytes)]`
+/** Format: `[real_pk (32 bytes)][nospam number (4 bytes)][checksum (2 bytes)]`
*
* return FRIEND_ADDRESS_SIZE byte address to give to others.
*/
void getaddress(const Messenger *m, uint8_t *address);
-/* Add a friend.
+/**
+ * Add a friend.
+ *
* Set the data that will be sent along with friend request.
- * address is the address of the friend (returned by getaddress of the friend
+ *
+ * @param address is the address of the friend (returned by getaddress of the friend
* you wish to add) it must be FRIEND_ADDRESS_SIZE bytes.
* TODO(irungentoo): add checksum.
- * data is the data and length is the length.
+ * @param data is the data.
+ * @param length is the length.
*
* return the friend number if success.
- * return -1 if message length is too long.
- * return -2 if no message (message length must be >= 1 byte).
- * return -3 if user's own key.
- * return -4 if friend request already sent or already a friend.
- * return -6 if bad checksum in address.
- * return -7 if the friend was already there but the nospam was different.
+ * return FA_TOOLONG if message length is too long.
+ * return FAERR_NOMESSAGE if no message (message length must be >= 1 byte).
+ * return FAERR_OWNKEY if user's own key.
+ * return FAERR_ALREADYSENT if friend request already sent or already a friend.
+ * return FAERR_BADCHECKSUM if bad checksum in address.
+ * return FAERR_SETNEWNOSPAM if the friend was already there but the nospam was different.
* (the nospam for that friend was set to the new one).
- * return -8 if increasing the friend list size fails.
+ * return FAERR_NOMEM if increasing the friend list size fails.
*/
int32_t m_addfriend(Messenger *m, const uint8_t *address, const uint8_t *data, uint16_t length);
-/* Add a friend without sending a friendrequest.
+/** Add a friend without sending a friendrequest.
* return the friend number if success.
* return -3 if user's own key.
* return -4 if friend request already sent or already a friend.
@@ -333,32 +334,32 @@ int32_t m_addfriend(Messenger *m, const uint8_t *address, const uint8_t *data, u
*/
int32_t m_addfriend_norequest(Messenger *m, const uint8_t *real_pk);
-/* return the friend number associated to that client id.
+/** return the friend number associated to that public key.
* return -1 if no such friend.
*/
int32_t getfriend_id(const Messenger *m, const uint8_t *real_pk);
-/* Copies the public key associated to that friend id into real_pk buffer.
+/** Copies the public key associated to that friend id into real_pk buffer.
* Make sure that real_pk is of size CRYPTO_PUBLIC_KEY_SIZE.
*
- * return 0 if success
- * return -1 if failure
+ * return 0 if success.
+ * return -1 if failure.
*/
int get_real_pk(const Messenger *m, int32_t friendnumber, uint8_t *real_pk);
-/* return friend connection id on success.
+/** return friend connection id on success.
* return -1 if failure.
*/
int getfriendcon_id(const Messenger *m, int32_t friendnumber);
-/* Remove a friend.
+/** Remove a friend.
*
- * return 0 if success
- * return -1 if failure
+ * return 0 if success.
+ * return -1 if failure.
*/
int m_delfriend(Messenger *m, int32_t friendnumber);
-/* Checks friend's connection status.
+/** Checks friend's connection status.
*
* return CONNECTION_UDP (2) if friend is directly connected to us (Online UDP).
* return CONNECTION_TCP (1) if friend is connected to us (Online TCP).
@@ -367,14 +368,14 @@ int m_delfriend(Messenger *m, int32_t friendnumber);
*/
int m_get_friend_connectionstatus(const Messenger *m, int32_t friendnumber);
-/* Checks if there exists a friend with given friendnumber.
+/** Checks if there exists a friend with given friendnumber.
*
* return 1 if friend exists.
* return 0 if friend doesn't exist.
*/
int m_friend_exists(const Messenger *m, int32_t friendnumber);
-/* Send a message of type to an online friend.
+/** Send a message of type to an online friend.
*
* return -1 if friend not valid.
* return -2 if too large.
@@ -389,7 +390,7 @@ int m_send_message_generic(Messenger *m, int32_t friendnumber, uint8_t type, con
uint32_t *message_id);
-/* Set the name and name_length of a friend.
+/** Set the name and name_length of a friend.
* name must be a string of maximum MAX_NAME_LENGTH length.
* length must be at least 1 byte.
* length is the length of name with the NULL terminator.
@@ -399,7 +400,7 @@ int m_send_message_generic(Messenger *m, int32_t friendnumber, uint8_t type, con
*/
int setfriendname(Messenger *m, int32_t friendnumber, const uint8_t *name, uint16_t length);
-/* Set our nickname.
+/** Set our nickname.
* name must be a string of maximum MAX_NAME_LENGTH length.
* length must be at least 1 byte.
* length is the length of name with the NULL terminator.
@@ -409,7 +410,7 @@ int setfriendname(Messenger *m, int32_t friendnumber, const uint8_t *name, uint1
*/
int setname(Messenger *m, const uint8_t *name, uint16_t length);
-/*
+/**
* Get your nickname.
* m - The messenger context to use.
* name needs to be a valid memory location with a size of at least MAX_NAME_LENGTH bytes.
@@ -419,7 +420,7 @@ int setname(Messenger *m, const uint8_t *name, uint16_t length);
*/
uint16_t getself_name(const Messenger *m, uint8_t *name);
-/* Get name of friendnumber and put it in name.
+/** Get name of friendnumber and put it in name.
* name needs to be a valid memory location with a size of at least MAX_NAME_LENGTH (128) bytes.
*
* return length of name if success.
@@ -427,13 +428,13 @@ uint16_t getself_name(const Messenger *m, uint8_t *name);
*/
int getname(const Messenger *m, int32_t friendnumber, uint8_t *name);
-/* return the length of name, including null on success.
+/** return the length of name, including null on success.
* return -1 on failure.
*/
int m_get_name_size(const Messenger *m, int32_t friendnumber);
int m_get_self_name_size(const Messenger *m);
-/* Set our user status.
+/** Set our user status.
* You are responsible for freeing status after.
*
* returns 0 on success.
@@ -442,23 +443,26 @@ int m_get_self_name_size(const Messenger *m);
int m_set_statusmessage(Messenger *m, const uint8_t *status, uint16_t length);
int m_set_userstatus(Messenger *m, uint8_t status);
-/* return the length of friendnumber's status message, including null on success.
- * return -1 on failure.
+/**
+ * Guaranteed to be at most MAX_STATUSMESSAGE_LENGTH.
+ *
+ * returns the length of friendnumber's status message, including null on success.
+ * returns -1 on failure.
*/
int m_get_statusmessage_size(const Messenger *m, int32_t friendnumber);
int m_get_self_statusmessage_size(const Messenger *m);
-/* Copy friendnumber's status message into buf, truncating if size is over maxlen.
+/** Copy friendnumber's status message into buf, truncating if size is over maxlen.
* Get the size you need to allocate from m_get_statusmessage_size.
* The self variant will copy our own status message.
*
* returns the length of the copied data on success
- * retruns -1 on failure.
+ * returns -1 on failure.
*/
int m_copy_statusmessage(const Messenger *m, int32_t friendnumber, uint8_t *buf, uint32_t maxlen);
int m_copy_self_statusmessage(const Messenger *m, uint8_t *buf);
-/* return one of Userstatus values.
+/** return one of Userstatus values.
* Values unknown to your application should be represented as USERSTATUS_NONE.
* As above, the self variant will return our own Userstatus.
* If friendnumber is invalid, this shall return USERSTATUS_INVALID.
@@ -467,12 +471,12 @@ uint8_t m_get_userstatus(const Messenger *m, int32_t friendnumber);
uint8_t m_get_self_userstatus(const Messenger *m);
-/* returns timestamp of last time friendnumber was seen online or 0 if never seen.
+/** returns timestamp of last time friendnumber was seen online or 0 if never seen.
* if friendnumber is invalid this function will return UINT64_MAX.
*/
uint64_t m_get_last_online(const Messenger *m, int32_t friendnumber);
-/* Set our typing status for a friend.
+/** Set our typing status for a friend.
* You are responsible for turning it on or off.
*
* returns 0 on success.
@@ -480,48 +484,39 @@ uint64_t m_get_last_online(const Messenger *m, int32_t friendnumber);
*/
int m_set_usertyping(Messenger *m, int32_t friendnumber, uint8_t is_typing);
-/* Get the typing status of a friend.
+/** Get the typing status of a friend.
*
* returns 0 if friend is not typing.
* returns 1 if friend is typing.
*/
int m_get_istyping(const Messenger *m, int32_t friendnumber);
-/* Set the function that will be executed when a friend request is received.
- * Function format is `function(uint8_t * public_key, uint8_t * data, size_t length)`
- */
+/** Set the function that will be executed when a friend request is received. */
void m_callback_friendrequest(Messenger *m, m_friend_request_cb *function);
-/* Set the function that will be executed when a message from a friend is received.
- * Function format is: `function(uint32_t friendnumber, unsigned int type, uint8_t * message, uint32_t length)`
- */
+/** Set the function that will be executed when a message from a friend is received. */
void m_callback_friendmessage(Messenger *m, m_friend_message_cb *function);
-/* Set the callback for name changes.
- * `Function(uint32_t friendnumber, uint8_t *newname, size_t length)`
+/** Set the callback for name changes.
* You are not responsible for freeing newname.
*/
void m_callback_namechange(Messenger *m, m_friend_name_cb *function);
-/* Set the callback for status message changes.
- * `Function(uint32_t friendnumber, uint8_t *newstatus, size_t length)`
+/** Set the callback for status message changes.
*
* You are not responsible for freeing newstatus
*/
void m_callback_statusmessage(Messenger *m, m_friend_status_message_cb *function);
-/* Set the callback for status type changes.
- * `Function(uint32_t friendnumber, Userstatus kind)`
+/** Set the callback for status type changes.
*/
void m_callback_userstatus(Messenger *m, m_friend_status_cb *function);
-/* Set the callback for typing changes.
- * `Function(uint32_t friendnumber, uint8_t is_typing)`
+/** Set the callback for typing changes.
*/
void m_callback_typingchange(Messenger *m, m_friend_typing_cb *function);
-/* Set the callback for read receipts.
- * `Function(uint32_t friendnumber, uint32_t receipt)`
+/** Set the callback for read receipts.
*
* If you are keeping a record of returns from m_sendmessage,
* receipt might be one of those values, meaning the message
@@ -531,8 +526,7 @@ void m_callback_typingchange(Messenger *m, m_friend_typing_cb *function);
*/
void m_callback_read_receipt(Messenger *m, m_friend_read_receipt_cb *function);
-/* Set the callback for connection status changes.
- * `function(uint32_t friendnumber, uint8_t status)`
+/** Set the callback for connection status changes.
*
* Status:
* 0 -- friend went offline after being previously online.
@@ -544,51 +538,50 @@ void m_callback_read_receipt(Messenger *m, m_friend_read_receipt_cb *function);
*/
void m_callback_connectionstatus(Messenger *m, m_friend_connection_status_cb *function);
-/* Same as previous but for internal A/V core usage only */
+/** Same as previous but for internal A/V core usage only */
void m_callback_connectionstatus_internal_av(Messenger *m, m_friend_connectionstatuschange_internal_cb *function,
void *userdata);
-/* Set the callback for typing changes.
- * Function(unsigned int connection_status (0 = not connected, 1 = TCP only, 2 = UDP + TCP))
+/** Set the callback for typing changes.
*/
void m_callback_core_connection(Messenger *m, m_self_connection_status_cb *function);
-/** CONFERENCES */
+/*** CONFERENCES */
-/* Set the callback for conference invites.
+/** Set the callback for conference invites.
*/
void m_callback_conference_invite(Messenger *m, m_conference_invite_cb *function);
-/* Send a conference invite packet.
+/** Send a conference invite packet.
*
* return 1 on success
* return 0 on failure
*/
int send_conference_invite_packet(const Messenger *m, int32_t friendnumber, const uint8_t *data, uint16_t length);
-/** FILE SENDING */
+/*** FILE SENDING */
-/* Set the callback for file send requests.
+/** Set the callback for file send requests.
*/
void callback_file_sendrequest(Messenger *m, m_file_recv_cb *function);
-/* Set the callback for file control requests.
+/** Set the callback for file control requests.
*/
void callback_file_control(Messenger *m, m_file_recv_control_cb *function);
-/* Set the callback for file data.
+/** Set the callback for file data.
*/
void callback_file_data(Messenger *m, m_file_recv_chunk_cb *function);
-/* Set the callback for file request chunk.
+/** Set the callback for file request chunk.
*/
void callback_file_reqchunk(Messenger *m, m_file_chunk_request_cb *function);
-/* Copy the file transfer file id to file_id
+/** Copy the file transfer file id to file_id
*
* return 0 on success.
* return -1 if friend not valid.
@@ -596,7 +589,7 @@ void callback_file_reqchunk(Messenger *m, m_file_chunk_request_cb *function);
*/
int file_get_id(const Messenger *m, int32_t friendnumber, uint32_t filenumber, uint8_t *file_id);
-/* Send a file send request.
+/** Send a file send request.
* Maximum filename length is 255 bytes.
* return file number on success
* return -1 if friend not found.
@@ -608,7 +601,7 @@ int file_get_id(const Messenger *m, int32_t friendnumber, uint32_t filenumber, u
long int new_filesender(const Messenger *m, int32_t friendnumber, uint32_t file_type, uint64_t filesize,
const uint8_t *file_id, const uint8_t *filename, uint16_t filename_length);
-/* Send a file control request.
+/** Send a file control request.
*
* return 0 on success
* return -1 if friend not valid.
@@ -622,7 +615,7 @@ long int new_filesender(const Messenger *m, int32_t friendnumber, uint32_t file_
*/
int file_control(const Messenger *m, int32_t friendnumber, uint32_t filenumber, unsigned int control);
-/* Send a seek file control request.
+/** Send a seek file control request.
*
* return 0 on success
* return -1 if friend not valid.
@@ -635,7 +628,7 @@ int file_control(const Messenger *m, int32_t friendnumber, uint32_t filenumber,
*/
int file_seek(const Messenger *m, int32_t friendnumber, uint32_t filenumber, uint64_t position);
-/* Send file data.
+/** Send file data.
*
* return 0 on success
* return -1 if friend not valid.
@@ -649,20 +642,20 @@ int file_seek(const Messenger *m, int32_t friendnumber, uint32_t filenumber, uin
int file_data(const Messenger *m, int32_t friendnumber, uint32_t filenumber, uint64_t position, const uint8_t *data,
uint16_t length);
-/** A/V related */
+/*** A/V related */
-/* Set the callback for msi packets.
+/** Set the callback for msi packets.
*/
void m_callback_msi_packet(Messenger *m, m_msi_packet_cb *function, void *userdata);
-/* Send an msi packet.
+/** Send an msi packet.
*
* return 1 on success
* return 0 on failure
*/
int m_msi_packet(const Messenger *m, int32_t friendnumber, const uint8_t *data, uint16_t length);
-/* Set handlers for lossy rtp packets.
+/** Set handlers for lossy rtp packets.
*
* return -1 on failure.
* return 0 on success.
@@ -670,14 +663,21 @@ int m_msi_packet(const Messenger *m, int32_t friendnumber, const uint8_t *data,
int m_callback_rtp_packet(Messenger *m, int32_t friendnumber, uint8_t byte,
m_lossy_rtp_packet_cb *function, void *object);
-/** CUSTOM PACKETS */
+/*** CUSTOM PACKETS */
-/* Set handlers for custom lossy packets.
+/** Set handlers for custom lossy packets.
*
*/
void custom_lossy_packet_registerhandler(Messenger *m, m_friend_lossy_packet_cb *lossy_packethandler);
-/* High level function to send custom lossy packets.
+/** High level function to send custom lossy packets.
+ *
+ * TODO(oxij): this name is confusing, because this function sends both av and custom lossy packets.
+ * Meanwhile, m_handle_lossy_packet routes custom packets to custom_lossy_packet_registerhandler
+ * as you would expect from its name.
+ *
+ * I.e. custom_lossy_packet_registerhandler's "custom lossy packet" and this "custom lossy packet"
+ * are not the same set of packets.
*
* return -1 if friend invalid.
* return -2 if length wrong.
@@ -689,12 +689,12 @@ void custom_lossy_packet_registerhandler(Messenger *m, m_friend_lossy_packet_cb
int m_send_custom_lossy_packet(const Messenger *m, int32_t friendnumber, const uint8_t *data, uint32_t length);
-/* Set handlers for custom lossless packets.
+/** Set handlers for custom lossless packets.
*
*/
void custom_lossless_packet_registerhandler(Messenger *m, m_friend_lossless_packet_cb *lossless_packethandler);
-/* High level function to send custom lossless packets.
+/** High level function to send custom lossless packets.
*
* return -1 if friend invalid.
* return -2 if length wrong.
@@ -705,7 +705,7 @@ void custom_lossless_packet_registerhandler(Messenger *m, m_friend_lossless_pack
*/
int send_custom_lossless_packet(const Messenger *m, int32_t friendnumber, const uint8_t *data, uint32_t length);
-/** Messenger constructor/destructor/operations. */
+/*** Messenger constructor/destructor/operations. */
typedef enum Messenger_Error {
MESSENGER_ERROR_NONE,
@@ -714,7 +714,7 @@ typedef enum Messenger_Error {
MESSENGER_ERROR_OTHER,
} Messenger_Error;
-/* Run this at startup.
+/** Run this at startup.
* return allocated instance of Messenger on success.
* return 0 if there are problems.
*
@@ -722,15 +722,15 @@ typedef enum Messenger_Error {
*/
Messenger *new_messenger(Mono_Time *mono_time, Messenger_Options *options, unsigned int *error);
-/* Run this before closing shop
+/** Run this before closing shop
* Free all datastructures.
*/
void kill_messenger(Messenger *m);
-/* The main loop that needs to be run at least 20 times per second. */
+/** The main loop that needs to be run at least 20 times per second. */
void do_messenger(Messenger *m, void *userdata);
-/* Return the time in milliseconds before do_messenger() should be called again
+/** Return the time in milliseconds before do_messenger() should be called again
* for optimal performance.
*
* returns time (in ms) before the next do_messenger() needs to be run on success.
@@ -739,7 +739,7 @@ uint32_t messenger_run_interval(const Messenger *m);
/* SAVING AND LOADING FUNCTIONS: */
-/* Registers a state plugin for saving, loadding, and getting the size of a section of the save
+/** Registers a state plugin for saving, loadding, and getting the size of a section of the save
*
* returns true on success
* returns false on error
@@ -747,13 +747,13 @@ uint32_t messenger_run_interval(const Messenger *m);
bool m_register_state_plugin(Messenger *m, State_Type type, m_state_size_cb size_callback,
m_state_load_cb load_callback, m_state_save_cb save_callback);
-/* return size of the messenger data (for saving). */
+/** return size of the messenger data (for saving). */
uint32_t messenger_size(const Messenger *m);
-/* Save the messenger in data (must be allocated memory of size at least Messenger_size()) */
+/** Save the messenger in data (must be allocated memory of size at least Messenger_size()) */
uint8_t *messenger_save(const Messenger *m, uint8_t *data);
-/* Load a state section.
+/** Load a state section.
*
* @param data Data to load.
* @param length Length of data.
@@ -764,12 +764,12 @@ uint8_t *messenger_save(const Messenger *m, uint8_t *data);
bool messenger_load_state_section(Messenger *m, const uint8_t *data, uint32_t length, uint16_t type,
State_Load_Status *status);
-/* Return the number of friends in the instance m.
+/** Return the number of friends in the instance m.
* You should use this to determine how much memory to allocate
* for copy_friendlist. */
uint32_t count_friendlist(const Messenger *m);
-/* Copy a list of valid friend IDs into the array out_list.
+/** Copy a list of valid friend IDs into the array out_list.
* If out_list is NULL, returns 0.
* Otherwise, returns the number of elements copied.
* If the array was too small, the contents
diff --git a/protocols/Tox/libtox/src/toxcore/TCP_client.c b/protocols/Tox/libtox/src/toxcore/TCP_client.c
index 1405d9b2c3..30aa268f1c 100644
--- a/protocols/Tox/libtox/src/toxcore/TCP_client.c
+++ b/protocols/Tox/libtox/src/toxcore/TCP_client.c
@@ -3,19 +3,16 @@
* Copyright © 2014 Tox project.
*/
-/*
+/**
* Implementation of the TCP relay client part of Tox.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include "TCP_client.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include "TCP_common.h"
#include "mono_time.h"
#include "util.h"
@@ -27,26 +24,17 @@ typedef struct TCP_Client_Conn {
} TCP_Client_Conn;
struct TCP_Client_Connection {
+ TCP_Connection con;
TCP_Client_Status status;
- Socket sock;
uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* our public key */
uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* public key of the server */
IP_Port ip_port; /* The ip and port of the server */
TCP_Proxy_Info proxy_info;
uint8_t recv_nonce[CRYPTO_NONCE_SIZE]; /* Nonce of received packets. */
- uint8_t sent_nonce[CRYPTO_NONCE_SIZE]; /* Nonce of sent packets. */
- uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE];
uint16_t next_packet_length;
uint8_t temp_secret_key[CRYPTO_SECRET_KEY_SIZE];
- uint8_t last_packet[2 + MAX_PACKET_SIZE];
- uint16_t last_packet_length;
- uint16_t last_packet_sent;
-
- TCP_Priority_List *priority_queue_start;
- TCP_Priority_List *priority_queue_end;
-
uint64_t kill_at;
uint64_t last_pinged;
@@ -104,21 +92,24 @@ void tcp_con_set_custom_uint(TCP_Client_Connection *con, uint32_t value)
con->custom_uint = value;
}
-/* return 1 on success
+/** return 1 on success
* return 0 on failure
*/
-static int connect_sock_to(Socket sock, IP_Port ip_port, TCP_Proxy_Info *proxy_info)
+static int connect_sock_to(const Logger *logger, Socket sock, const IP_Port *ip_port, const TCP_Proxy_Info *proxy_info)
{
+ IP_Port ipp_copy = *ip_port;
+
if (proxy_info->proxy_type != TCP_PROXY_NONE) {
- ip_port = proxy_info->ip_port;
+ ipp_copy = proxy_info->ip_port;
}
/* nonblocking socket, connect will never return success */
- net_connect(sock, ip_port);
+ net_connect(logger, sock, &ipp_copy);
+
return 1;
}
-/* return 1 on success.
+/** return 1 on success.
* return 0 on failure.
*/
static int proxy_http_generate_connection_request(TCP_Client_Connection *tcp_conn)
@@ -134,29 +125,29 @@ static int proxy_http_generate_connection_request(TCP_Client_Connection *tcp_con
}
const uint16_t port = net_ntohs(tcp_conn->ip_port.port);
- const int written = snprintf((char *)tcp_conn->last_packet, MAX_PACKET_SIZE, "%s%s:%hu%s%s:%hu%s", one, ip, port, two,
- ip, port, three);
+ const int written = snprintf((char *)tcp_conn->con.last_packet, MAX_PACKET_SIZE, "%s%s:%hu%s%s:%hu%s", one, ip, port,
+ two, ip, port, three);
if (written < 0 || MAX_PACKET_SIZE < written) {
return 0;
}
- tcp_conn->last_packet_length = written;
- tcp_conn->last_packet_sent = 0;
+ tcp_conn->con.last_packet_length = written;
+ tcp_conn->con.last_packet_sent = 0;
return 1;
}
-/* return 1 on success.
+/** return 1 on success.
* return 0 if no data received.
* return -1 on failure (connection refused).
*/
-static int proxy_http_read_connection_response(const Logger *logger, TCP_Client_Connection *tcp_conn)
+static int proxy_http_read_connection_response(const Logger *logger, const TCP_Client_Connection *tcp_conn)
{
char success[] = "200";
uint8_t data[16]; // draining works the best if the length is a power of 2
- int ret = read_TCP_packet(logger, tcp_conn->sock, data, sizeof(data) - 1);
+ int ret = read_TCP_packet(logger, tcp_conn->con.sock, data, sizeof(data) - 1, &tcp_conn->con.ip_port);
if (ret == -1) {
return 0;
@@ -164,13 +155,13 @@ static int proxy_http_read_connection_response(const Logger *logger, TCP_Client_
data[sizeof(data) - 1] = 0;
- if (strstr((char *)data, success)) {
+ if (strstr((const char *)data, success)) {
// drain all data
- unsigned int data_left = net_socket_data_recv_buffer(tcp_conn->sock);
+ const uint16_t data_left = net_socket_data_recv_buffer(tcp_conn->con.sock);
if (data_left) {
VLA(uint8_t, temp_data, data_left);
- read_TCP_packet(logger, tcp_conn->sock, temp_data, data_left);
+ read_TCP_packet(logger, tcp_conn->con.sock, temp_data, data_left, &tcp_conn->con.ip_port);
}
return 1;
@@ -179,30 +170,39 @@ static int proxy_http_read_connection_response(const Logger *logger, TCP_Client_
return -1;
}
-static void proxy_socks5_generate_handshake(TCP_Client_Connection *tcp_conn)
+#define TCP_SOCKS5_PROXY_HS_VERSION_SOCKS5 0x05
+#define TCP_SOCKS5_PROXY_HS_COMM_ESTABLISH_REQUEST 0x01
+#define TCP_SOCKS5_PROXY_HS_COMM_REQUEST_GRANTED 0x00
+#define TCP_SOCKS5_PROXY_HS_AUTH_METHODS_SUPPORTED 0x01
+#define TCP_SOCKS5_PROXY_HS_NO_AUTH 0x00
+#define TCP_SOCKS5_PROXY_HS_RESERVED 0x00
+#define TCP_SOCKS5_PROXY_HS_ADDR_TYPE_IPV4 0x01
+#define TCP_SOCKS5_PROXY_HS_ADDR_TYPE_IPV6 0x04
+
+static void proxy_socks5_generate_greetings(TCP_Client_Connection *tcp_conn)
{
- tcp_conn->last_packet[0] = 5; /* SOCKSv5 */
- tcp_conn->last_packet[1] = 1; /* number of authentication methods supported */
- tcp_conn->last_packet[2] = 0; /* No authentication */
+ tcp_conn->con.last_packet[0] = TCP_SOCKS5_PROXY_HS_VERSION_SOCKS5;
+ tcp_conn->con.last_packet[1] = TCP_SOCKS5_PROXY_HS_AUTH_METHODS_SUPPORTED;
+ tcp_conn->con.last_packet[2] = TCP_SOCKS5_PROXY_HS_NO_AUTH;
- tcp_conn->last_packet_length = 3;
- tcp_conn->last_packet_sent = 0;
+ tcp_conn->con.last_packet_length = 3;
+ tcp_conn->con.last_packet_sent = 0;
}
-/* return 1 on success.
+/** return 1 on success.
* return 0 if no data received.
* return -1 on failure (connection refused).
*/
-static int socks5_read_handshake_response(const Logger *logger, TCP_Client_Connection *tcp_conn)
+static int socks5_read_handshake_response(const Logger *logger, const TCP_Client_Connection *tcp_conn)
{
uint8_t data[2];
- int ret = read_TCP_packet(logger, tcp_conn->sock, data, sizeof(data));
+ int ret = read_TCP_packet(logger, tcp_conn->con.sock, data, sizeof(data), &tcp_conn->con.ip_port);
if (ret == -1) {
return 0;
}
- if (data[0] == 5 && data[1] == 0) { // TODO(irungentoo): magic numbers
+ if (data[0] == TCP_SOCKS5_PROXY_HS_VERSION_SOCKS5 && data[1] == TCP_SOCKS5_PROXY_HS_COMM_REQUEST_GRANTED) {
return 1;
}
@@ -211,56 +211,56 @@ static int socks5_read_handshake_response(const Logger *logger, TCP_Client_Conne
static void proxy_socks5_generate_connection_request(TCP_Client_Connection *tcp_conn)
{
- tcp_conn->last_packet[0] = 5; /* SOCKSv5 */
- tcp_conn->last_packet[1] = 1; /* command code: establish a TCP/IP stream connection */
- tcp_conn->last_packet[2] = 0; /* reserved, must be 0 */
+ tcp_conn->con.last_packet[0] = TCP_SOCKS5_PROXY_HS_VERSION_SOCKS5;
+ tcp_conn->con.last_packet[1] = TCP_SOCKS5_PROXY_HS_COMM_ESTABLISH_REQUEST;
+ tcp_conn->con.last_packet[2] = TCP_SOCKS5_PROXY_HS_RESERVED;
uint16_t length = 3;
if (net_family_is_ipv4(tcp_conn->ip_port.ip.family)) {
- tcp_conn->last_packet[3] = 1; /* IPv4 address */
+ tcp_conn->con.last_packet[3] = TCP_SOCKS5_PROXY_HS_ADDR_TYPE_IPV4;
++length;
- memcpy(tcp_conn->last_packet + length, tcp_conn->ip_port.ip.ip.v4.uint8, sizeof(IP4));
+ memcpy(tcp_conn->con.last_packet + length, tcp_conn->ip_port.ip.ip.v4.uint8, sizeof(IP4));
length += sizeof(IP4);
} else {
- tcp_conn->last_packet[3] = 4; /* IPv6 address */
+ tcp_conn->con.last_packet[3] = TCP_SOCKS5_PROXY_HS_ADDR_TYPE_IPV6;
++length;
- memcpy(tcp_conn->last_packet + length, tcp_conn->ip_port.ip.ip.v6.uint8, sizeof(IP6));
+ memcpy(tcp_conn->con.last_packet + length, tcp_conn->ip_port.ip.ip.v6.uint8, sizeof(IP6));
length += sizeof(IP6);
}
- memcpy(tcp_conn->last_packet + length, &tcp_conn->ip_port.port, sizeof(uint16_t));
+ memcpy(tcp_conn->con.last_packet + length, &tcp_conn->ip_port.port, sizeof(uint16_t));
length += sizeof(uint16_t);
- tcp_conn->last_packet_length = length;
- tcp_conn->last_packet_sent = 0;
+ tcp_conn->con.last_packet_length = length;
+ tcp_conn->con.last_packet_sent = 0;
}
-/* return 1 on success.
+/** return 1 on success.
* return 0 if no data received.
* return -1 on failure (connection refused).
*/
-static int proxy_socks5_read_connection_response(const Logger *logger, TCP_Client_Connection *tcp_conn)
+static int proxy_socks5_read_connection_response(const Logger *logger, const TCP_Client_Connection *tcp_conn)
{
if (net_family_is_ipv4(tcp_conn->ip_port.ip.family)) {
uint8_t data[4 + sizeof(IP4) + sizeof(uint16_t)];
- int ret = read_TCP_packet(logger, tcp_conn->sock, data, sizeof(data));
+ int ret = read_TCP_packet(logger, tcp_conn->con.sock, data, sizeof(data), &tcp_conn->con.ip_port);
if (ret == -1) {
return 0;
}
- if (data[0] == 5 && data[1] == 0) {
+ if (data[0] == TCP_SOCKS5_PROXY_HS_VERSION_SOCKS5 && data[1] == TCP_SOCKS5_PROXY_HS_COMM_REQUEST_GRANTED) {
return 1;
}
} else {
uint8_t data[4 + sizeof(IP6) + sizeof(uint16_t)];
- int ret = read_TCP_packet(logger, tcp_conn->sock, data, sizeof(data));
+ int ret = read_TCP_packet(logger, tcp_conn->con.sock, data, sizeof(data), &tcp_conn->con.ip_port);
if (ret == -1) {
return 0;
}
- if (data[0] == 5 && data[1] == 0) {
+ if (data[0] == TCP_SOCKS5_PROXY_HS_VERSION_SOCKS5 && data[1] == TCP_SOCKS5_PROXY_HS_COMM_REQUEST_GRANTED) {
return 1;
}
}
@@ -268,30 +268,30 @@ static int proxy_socks5_read_connection_response(const Logger *logger, TCP_Clien
return -1;
}
-/* return 0 on success.
+/** return 0 on success.
* return -1 on failure.
*/
static int generate_handshake(TCP_Client_Connection *tcp_conn)
{
uint8_t plain[CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE];
crypto_new_keypair(plain, tcp_conn->temp_secret_key);
- random_nonce(tcp_conn->sent_nonce);
- memcpy(plain + CRYPTO_PUBLIC_KEY_SIZE, tcp_conn->sent_nonce, CRYPTO_NONCE_SIZE);
- memcpy(tcp_conn->last_packet, tcp_conn->self_public_key, CRYPTO_PUBLIC_KEY_SIZE);
- random_nonce(tcp_conn->last_packet + CRYPTO_PUBLIC_KEY_SIZE);
- int len = encrypt_data_symmetric(tcp_conn->shared_key, tcp_conn->last_packet + CRYPTO_PUBLIC_KEY_SIZE, plain,
- sizeof(plain), tcp_conn->last_packet + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE);
+ random_nonce(tcp_conn->con.sent_nonce);
+ memcpy(plain + CRYPTO_PUBLIC_KEY_SIZE, tcp_conn->con.sent_nonce, CRYPTO_NONCE_SIZE);
+ memcpy(tcp_conn->con.last_packet, tcp_conn->self_public_key, CRYPTO_PUBLIC_KEY_SIZE);
+ random_nonce(tcp_conn->con.last_packet + CRYPTO_PUBLIC_KEY_SIZE);
+ int len = encrypt_data_symmetric(tcp_conn->con.shared_key, tcp_conn->con.last_packet + CRYPTO_PUBLIC_KEY_SIZE, plain,
+ sizeof(plain), tcp_conn->con.last_packet + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE);
if (len != sizeof(plain) + CRYPTO_MAC_SIZE) {
return -1;
}
- tcp_conn->last_packet_length = CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + sizeof(plain) + CRYPTO_MAC_SIZE;
- tcp_conn->last_packet_sent = 0;
+ tcp_conn->con.last_packet_length = CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + sizeof(plain) + CRYPTO_MAC_SIZE;
+ tcp_conn->con.last_packet_sent = 0;
return 0;
}
-/* data must be of length TCP_SERVER_HANDSHAKE_SIZE
+/** data must be of length TCP_SERVER_HANDSHAKE_SIZE
*
* return 0 on success.
* return -1 on failure.
@@ -299,7 +299,7 @@ static int generate_handshake(TCP_Client_Connection *tcp_conn)
static int handle_handshake(TCP_Client_Connection *tcp_conn, const uint8_t *data)
{
uint8_t plain[CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE];
- int len = decrypt_data_symmetric(tcp_conn->shared_key, data, data + CRYPTO_NONCE_SIZE,
+ int len = decrypt_data_symmetric(tcp_conn->con.shared_key, data, data + CRYPTO_NONCE_SIZE,
TCP_SERVER_HANDSHAKE_SIZE - CRYPTO_NONCE_SIZE, plain);
if (len != sizeof(plain)) {
@@ -307,178 +307,21 @@ static int handle_handshake(TCP_Client_Connection *tcp_conn, const uint8_t *data
}
memcpy(tcp_conn->recv_nonce, plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_NONCE_SIZE);
- encrypt_precompute(plain, tcp_conn->temp_secret_key, tcp_conn->shared_key);
+ encrypt_precompute(plain, tcp_conn->temp_secret_key, tcp_conn->con.shared_key);
crypto_memzero(tcp_conn->temp_secret_key, CRYPTO_SECRET_KEY_SIZE);
return 0;
}
-/* return 0 if pending data was sent completely
- * return -1 if it wasn't
- */
-static int client_send_pending_data_nonpriority(TCP_Client_Connection *con)
-{
- if (con->last_packet_length == 0) {
- return 0;
- }
-
- const uint16_t left = con->last_packet_length - con->last_packet_sent;
- const int len = net_send(con->sock, con->last_packet + con->last_packet_sent, left);
-
- if (len <= 0) {
- return -1;
- }
-
- if (len == left) {
- con->last_packet_length = 0;
- con->last_packet_sent = 0;
- return 0;
- }
-
- con->last_packet_sent += len;
- return -1;
-}
-
-/* return 0 if pending data was sent completely
- * return -1 if it wasn't
- */
-static int client_send_pending_data(TCP_Client_Connection *con)
-{
- /* finish sending current non-priority packet */
- if (client_send_pending_data_nonpriority(con) == -1) {
- return -1;
- }
-
- TCP_Priority_List *p = con->priority_queue_start;
-
- while (p) {
- const uint16_t left = p->size - p->sent;
- const int len = net_send(con->sock, p->data + p->sent, left);
-
- if (len != left) {
- if (len > 0) {
- p->sent += len;
- }
-
- break;
- }
-
- TCP_Priority_List *pp = p;
- p = p->next;
- free(pp);
- }
-
- con->priority_queue_start = p;
-
- if (!p) {
- con->priority_queue_end = nullptr;
- return 0;
- }
-
- return -1;
-}
-
-/* return 0 on failure (only if malloc fails)
- * return 1 on success
- */
-static bool client_add_priority(TCP_Client_Connection *con, const uint8_t *packet, uint16_t size, uint16_t sent)
-{
- TCP_Priority_List *p = con->priority_queue_end;
- TCP_Priority_List *new_list = (TCP_Priority_List *)malloc(sizeof(TCP_Priority_List) + size);
-
- if (!new_list) {
- return 0;
- }
-
- new_list->next = nullptr;
- new_list->size = size;
- new_list->sent = sent;
- memcpy(new_list->data, packet, size);
-
- if (p) {
- p->next = new_list;
- } else {
- con->priority_queue_start = new_list;
- }
-
- con->priority_queue_end = new_list;
- return 1;
-}
-
-/* return 1 on success.
+/** return 1 on success.
* return 0 if could not send packet.
* return -1 on failure (connection must be killed).
*/
-static int write_packet_TCP_client_secure_connection(TCP_Client_Connection *con, const uint8_t *data, uint16_t length,
- bool priority)
-{
- if (length + CRYPTO_MAC_SIZE > MAX_PACKET_SIZE) {
- return -1;
- }
-
- bool sendpriority = 1;
-
- if (client_send_pending_data(con) == -1) {
- if (priority) {
- sendpriority = 0;
- } else {
- return 0;
- }
- }
-
- VLA(uint8_t, packet, sizeof(uint16_t) + length + CRYPTO_MAC_SIZE);
-
- uint16_t c_length = net_htons(length + CRYPTO_MAC_SIZE);
- memcpy(packet, &c_length, sizeof(uint16_t));
- int len = encrypt_data_symmetric(con->shared_key, con->sent_nonce, data, length, packet + sizeof(uint16_t));
-
- if ((unsigned int)len != (SIZEOF_VLA(packet) - sizeof(uint16_t))) {
- return -1;
- }
-
- if (priority) {
- len = sendpriority ? net_send(con->sock, packet, SIZEOF_VLA(packet)) : 0;
-
- if (len <= 0) {
- len = 0;
- }
-
- increment_nonce(con->sent_nonce);
-
- if ((unsigned int)len == SIZEOF_VLA(packet)) {
- return 1;
- }
-
- return client_add_priority(con, packet, SIZEOF_VLA(packet), len);
- }
-
- len = net_send(con->sock, packet, SIZEOF_VLA(packet));
-
- if (len <= 0) {
- return 0;
- }
-
- increment_nonce(con->sent_nonce);
-
- if ((unsigned int)len == SIZEOF_VLA(packet)) {
- return 1;
- }
-
- memcpy(con->last_packet, packet, SIZEOF_VLA(packet));
- con->last_packet_length = SIZEOF_VLA(packet);
- con->last_packet_sent = len;
- return 1;
-}
-
-/* return 1 on success.
- * return 0 if could not send packet.
- * return -1 on failure (connection must be killed).
- */
-int send_routing_request(TCP_Client_Connection *con, uint8_t *public_key)
+int send_routing_request(const Logger *logger, TCP_Client_Connection *con, const uint8_t *public_key)
{
uint8_t packet[1 + CRYPTO_PUBLIC_KEY_SIZE];
packet[0] = TCP_PACKET_ROUTING_REQUEST;
memcpy(packet + 1, public_key, CRYPTO_PUBLIC_KEY_SIZE);
- return write_packet_TCP_client_secure_connection(con, packet, sizeof(packet), 1);
+ return write_packet_TCP_secure_connection(logger, &con->con, packet, sizeof(packet), 1);
}
void routing_response_handler(TCP_Client_Connection *con, tcp_routing_response_cb *response_callback, void *object)
@@ -493,14 +336,14 @@ void routing_status_handler(TCP_Client_Connection *con, tcp_routing_status_cb *s
con->status_callback_object = object;
}
-static int tcp_send_ping_response(TCP_Client_Connection *con);
-static int tcp_send_ping_request(TCP_Client_Connection *con);
+static int tcp_send_ping_response(const Logger *logger, TCP_Client_Connection *con);
+static int tcp_send_ping_request(const Logger *logger, TCP_Client_Connection *con);
-/* return 1 on success.
+/** return 1 on success.
* return 0 if could not send packet.
* return -1 on failure.
*/
-int send_data(TCP_Client_Connection *con, uint8_t con_id, const uint8_t *data, uint16_t length)
+int send_data(const Logger *logger, TCP_Client_Connection *con, uint8_t con_id, const uint8_t *data, uint16_t length)
{
if (con_id >= NUM_CLIENT_CONNECTIONS) {
return -1;
@@ -510,21 +353,22 @@ int send_data(TCP_Client_Connection *con, uint8_t con_id, const uint8_t *data, u
return -1;
}
- if (tcp_send_ping_response(con) == 0 || tcp_send_ping_request(con) == 0) {
+ if (tcp_send_ping_response(logger, con) == 0 || tcp_send_ping_request(logger, con) == 0) {
return 0;
}
VLA(uint8_t, packet, 1 + length);
packet[0] = con_id + NUM_RESERVED_PORTS;
memcpy(packet + 1, data, length);
- return write_packet_TCP_client_secure_connection(con, packet, SIZEOF_VLA(packet), 0);
+ return write_packet_TCP_secure_connection(logger, &con->con, packet, SIZEOF_VLA(packet), 0);
}
-/* return 1 on success.
+/** return 1 on success.
* return 0 if could not send packet.
* return -1 on failure.
*/
-int send_oob_packet(TCP_Client_Connection *con, const uint8_t *public_key, const uint8_t *data, uint16_t length)
+int send_oob_packet(const Logger *logger, TCP_Client_Connection *con, const uint8_t *public_key, const uint8_t *data,
+ uint16_t length)
{
if (length == 0 || length > TCP_MAX_OOB_DATA_LENGTH) {
return -1;
@@ -534,11 +378,11 @@ int send_oob_packet(TCP_Client_Connection *con, const uint8_t *public_key, const
packet[0] = TCP_PACKET_OOB_SEND;
memcpy(packet + 1, public_key, CRYPTO_PUBLIC_KEY_SIZE);
memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, data, length);
- return write_packet_TCP_client_secure_connection(con, packet, SIZEOF_VLA(packet), 0);
+ return write_packet_TCP_secure_connection(logger, &con->con, packet, SIZEOF_VLA(packet), 0);
}
-/* Set the number that will be used as an argument in the callbacks related to con_id.
+/** Set the number that will be used as an argument in the callbacks related to con_id.
*
* When not set by this function, the number is -1.
*
@@ -571,23 +415,23 @@ void oob_data_handler(TCP_Client_Connection *con, tcp_oob_data_cb *oob_data_call
con->oob_data_callback_object = object;
}
-/* return 1 on success.
+/** return 1 on success.
* return 0 if could not send packet.
* return -1 on failure (connection must be killed).
*/
-static int client_send_disconnect_notification(TCP_Client_Connection *con, uint8_t id)
+static int client_send_disconnect_notification(const Logger *logger, TCP_Client_Connection *con, uint8_t id)
{
uint8_t packet[1 + 1];
packet[0] = TCP_PACKET_DISCONNECT_NOTIFICATION;
packet[1] = id;
- return write_packet_TCP_client_secure_connection(con, packet, sizeof(packet), 1);
+ return write_packet_TCP_secure_connection(logger, &con->con, packet, sizeof(packet), 1);
}
-/* return 1 on success.
+/** return 1 on success.
* return 0 if could not send packet.
* return -1 on failure (connection must be killed).
*/
-static int tcp_send_ping_request(TCP_Client_Connection *con)
+static int tcp_send_ping_request(const Logger *logger, TCP_Client_Connection *con)
{
if (!con->ping_request_id) {
return 1;
@@ -596,7 +440,7 @@ static int tcp_send_ping_request(TCP_Client_Connection *con)
uint8_t packet[1 + sizeof(uint64_t)];
packet[0] = TCP_PACKET_PING;
memcpy(packet + 1, &con->ping_request_id, sizeof(uint64_t));
- const int ret = write_packet_TCP_client_secure_connection(con, packet, sizeof(packet), 1);
+ const int ret = write_packet_TCP_secure_connection(logger, &con->con, packet, sizeof(packet), 1);
if (ret == 1) {
con->ping_request_id = 0;
@@ -605,11 +449,11 @@ static int tcp_send_ping_request(TCP_Client_Connection *con)
return ret;
}
-/* return 1 on success.
+/** return 1 on success.
* return 0 if could not send packet.
* return -1 on failure (connection must be killed).
*/
-static int tcp_send_ping_response(TCP_Client_Connection *con)
+static int tcp_send_ping_response(const Logger *logger, TCP_Client_Connection *con)
{
if (!con->ping_response_id) {
return 1;
@@ -618,7 +462,7 @@ static int tcp_send_ping_response(TCP_Client_Connection *con)
uint8_t packet[1 + sizeof(uint64_t)];
packet[0] = TCP_PACKET_PONG;
memcpy(packet + 1, &con->ping_response_id, sizeof(uint64_t));
- const int ret = write_packet_TCP_client_secure_connection(con, packet, sizeof(packet), 1);
+ const int ret = write_packet_TCP_secure_connection(logger, &con->con, packet, sizeof(packet), 1);
if (ret == 1) {
con->ping_response_id = 0;
@@ -627,11 +471,11 @@ static int tcp_send_ping_response(TCP_Client_Connection *con)
return ret;
}
-/* return 1 on success.
+/** return 1 on success.
* return 0 if could not send packet.
* return -1 on failure (connection must be killed).
*/
-int send_disconnect_request(TCP_Client_Connection *con, uint8_t con_id)
+int send_disconnect_request(const Logger *logger, TCP_Client_Connection *con, uint8_t con_id)
{
if (con_id >= NUM_CLIENT_CONNECTIONS) {
return -1;
@@ -639,19 +483,19 @@ int send_disconnect_request(TCP_Client_Connection *con, uint8_t con_id)
con->connections[con_id].status = 0;
con->connections[con_id].number = 0;
- return client_send_disconnect_notification(con, con_id + NUM_RESERVED_PORTS);
+ return client_send_disconnect_notification(logger, con, con_id + NUM_RESERVED_PORTS);
}
-/* return 1 on success.
+/** return 1 on success.
* return 0 if could not send packet.
* return -1 on failure (connection must be killed).
*/
-int send_onion_request(TCP_Client_Connection *con, const uint8_t *data, uint16_t length)
+int send_onion_request(const Logger *logger, TCP_Client_Connection *con, const uint8_t *data, uint16_t length)
{
VLA(uint8_t, packet, 1 + length);
packet[0] = TCP_PACKET_ONION_REQUEST;
memcpy(packet + 1, data, length);
- return write_packet_TCP_client_secure_connection(con, packet, SIZEOF_VLA(packet), 0);
+ return write_packet_TCP_secure_connection(logger, &con->con, packet, SIZEOF_VLA(packet), 0);
}
void onion_response_handler(TCP_Client_Connection *con, tcp_onion_response_cb *onion_callback, void *object)
@@ -660,27 +504,27 @@ void onion_response_handler(TCP_Client_Connection *con, tcp_onion_response_cb *o
con->onion_callback_object = object;
}
-/* Create new TCP connection to ip_port/public_key
+/** Create new TCP connection to ip_port/public_key
*/
-TCP_Client_Connection *new_TCP_connection(const Mono_Time *mono_time, IP_Port ip_port, const uint8_t *public_key,
- const uint8_t *self_public_key, const uint8_t *self_secret_key, TCP_Proxy_Info *proxy_info)
+TCP_Client_Connection *new_TCP_connection(const Logger *logger, const Mono_Time *mono_time, const IP_Port *ip_port,
+ const uint8_t *public_key, const uint8_t *self_public_key, const uint8_t *self_secret_key,
+ const TCP_Proxy_Info *proxy_info)
{
if (networking_at_startup() != 0) {
return nullptr;
}
- if (!net_family_is_ipv4(ip_port.ip.family) && !net_family_is_ipv6(ip_port.ip.family)) {
+ if (!net_family_is_ipv4(ip_port->ip.family) && !net_family_is_ipv6(ip_port->ip.family)) {
return nullptr;
}
- TCP_Proxy_Info default_proxyinfo;
+ const TCP_Proxy_Info default_proxyinfo = {0};
if (proxy_info == nullptr) {
- default_proxyinfo.proxy_type = TCP_PROXY_NONE;
proxy_info = &default_proxyinfo;
}
- Family family = ip_port.ip.family;
+ Family family = ip_port->ip.family;
if (proxy_info->proxy_type != TCP_PROXY_NONE) {
family = proxy_info->ip_port.ip.family;
@@ -697,37 +541,40 @@ TCP_Client_Connection *new_TCP_connection(const Mono_Time *mono_time, IP_Port ip
return nullptr;
}
- if (!(set_socket_nonblock(sock) && connect_sock_to(sock, ip_port, proxy_info))) {
+ if (!(set_socket_nonblock(sock) && connect_sock_to(logger, sock, ip_port, proxy_info))) {
kill_sock(sock);
return nullptr;
}
- TCP_Client_Connection *temp = (TCP_Client_Connection *)calloc(sizeof(TCP_Client_Connection), 1);
+ TCP_Client_Connection *temp = (TCP_Client_Connection *)calloc(1, sizeof(TCP_Client_Connection));
if (temp == nullptr) {
kill_sock(sock);
return nullptr;
}
- temp->sock = sock;
+ temp->con.sock = sock;
+ temp->con.ip_port = *ip_port;
memcpy(temp->public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE);
memcpy(temp->self_public_key, self_public_key, CRYPTO_PUBLIC_KEY_SIZE);
- encrypt_precompute(temp->public_key, self_secret_key, temp->shared_key);
- temp->ip_port = ip_port;
+ encrypt_precompute(temp->public_key, self_secret_key, temp->con.shared_key);
+ temp->ip_port = *ip_port;
temp->proxy_info = *proxy_info;
switch (proxy_info->proxy_type) {
- case TCP_PROXY_HTTP:
+ case TCP_PROXY_HTTP: {
temp->status = TCP_CLIENT_PROXY_HTTP_CONNECTING;
proxy_http_generate_connection_request(temp);
break;
+ }
- case TCP_PROXY_SOCKS5:
+ case TCP_PROXY_SOCKS5: {
temp->status = TCP_CLIENT_PROXY_SOCKS5_CONNECTING;
- proxy_socks5_generate_handshake(temp);
+ proxy_socks5_generate_greetings(temp);
break;
+ }
- case TCP_PROXY_NONE:
+ case TCP_PROXY_NONE: {
temp->status = TCP_CLIENT_CONNECTING;
if (generate_handshake(temp) == -1) {
@@ -737,6 +584,7 @@ TCP_Client_Connection *new_TCP_connection(const Mono_Time *mono_time, IP_Port ip
}
break;
+ }
}
temp->kill_at = mono_time_get(mono_time) + TCP_CONNECTION_TIMEOUT;
@@ -744,10 +592,11 @@ TCP_Client_Connection *new_TCP_connection(const Mono_Time *mono_time, IP_Port ip
return temp;
}
-/* return 0 on success
+/** return 0 on success
* return -1 on failure
*/
-static int handle_TCP_client_packet(TCP_Client_Connection *conn, const uint8_t *data, uint16_t length, void *userdata)
+static int handle_TCP_client_packet(const Logger *logger, TCP_Client_Connection *conn, const uint8_t *data,
+ uint16_t length, void *userdata)
{
if (length <= 1) {
return -1;
@@ -842,7 +691,7 @@ static int handle_TCP_client_packet(TCP_Client_Connection *conn, const uint8_t *
uint64_t ping_id;
memcpy(&ping_id, data + 1, sizeof(uint64_t));
conn->ping_response_id = ping_id;
- tcp_send_ping_response(conn);
+ tcp_send_ping_response(logger, conn);
return 0;
}
@@ -903,8 +752,8 @@ static int handle_TCP_client_packet(TCP_Client_Connection *conn, const uint8_t *
static bool tcp_process_packet(const Logger *logger, TCP_Client_Connection *conn, void *userdata)
{
uint8_t packet[MAX_PACKET_SIZE];
- const int len = read_packet_TCP_secure_connection(logger, conn->sock, &conn->next_packet_length, conn->shared_key,
- conn->recv_nonce, packet, sizeof(packet));
+ const int len = read_packet_TCP_secure_connection(logger, conn->con.sock, &conn->next_packet_length,
+ conn->con.shared_key, conn->recv_nonce, packet, sizeof(packet), &conn->ip_port);
if (len == 0) {
return false;
@@ -915,7 +764,7 @@ static bool tcp_process_packet(const Logger *logger, TCP_Client_Connection *conn
return false;
}
- if (handle_TCP_client_packet(conn, packet, len, userdata) == -1) {
+ if (handle_TCP_client_packet(logger, conn, packet, len, userdata) == -1) {
conn->status = TCP_CLIENT_DISCONNECTED;
return false;
}
@@ -926,9 +775,9 @@ static bool tcp_process_packet(const Logger *logger, TCP_Client_Connection *conn
static int do_confirmed_TCP(const Logger *logger, TCP_Client_Connection *conn, const Mono_Time *mono_time,
void *userdata)
{
- client_send_pending_data(conn);
- tcp_send_ping_response(conn);
- tcp_send_ping_request(conn);
+ send_pending_data(logger, &conn->con);
+ tcp_send_ping_response(logger, conn);
+ tcp_send_ping_request(logger, conn);
if (mono_time_is_timeout(mono_time, conn->last_pinged, TCP_PING_FREQUENCY)) {
uint64_t ping_id = random_u64();
@@ -939,7 +788,7 @@ static int do_confirmed_TCP(const Logger *logger, TCP_Client_Connection *conn, c
conn->ping_request_id = ping_id;
conn->ping_id = ping_id;
- tcp_send_ping_request(conn);
+ tcp_send_ping_request(logger, conn);
conn->last_pinged = mono_time_get(mono_time);
}
@@ -956,17 +805,17 @@ static int do_confirmed_TCP(const Logger *logger, TCP_Client_Connection *conn, c
return 0;
}
-/* Run the TCP connection
+/** Run the TCP connection
*/
-void do_TCP_connection(const Logger *logger, Mono_Time *mono_time, TCP_Client_Connection *tcp_connection,
- void *userdata)
+void do_TCP_connection(const Logger *logger, const Mono_Time *mono_time,
+ TCP_Client_Connection *tcp_connection, void *userdata)
{
if (tcp_connection->status == TCP_CLIENT_DISCONNECTED) {
return;
}
if (tcp_connection->status == TCP_CLIENT_PROXY_HTTP_CONNECTING) {
- if (client_send_pending_data(tcp_connection) == 0) {
+ if (send_pending_data(logger, &tcp_connection->con) == 0) {
int ret = proxy_http_read_connection_response(logger, tcp_connection);
if (ret == -1) {
@@ -982,7 +831,7 @@ void do_TCP_connection(const Logger *logger, Mono_Time *mono_time, TCP_Client_Co
}
if (tcp_connection->status == TCP_CLIENT_PROXY_SOCKS5_CONNECTING) {
- if (client_send_pending_data(tcp_connection) == 0) {
+ if (send_pending_data(logger, &tcp_connection->con) == 0) {
int ret = socks5_read_handshake_response(logger, tcp_connection);
if (ret == -1) {
@@ -998,7 +847,7 @@ void do_TCP_connection(const Logger *logger, Mono_Time *mono_time, TCP_Client_Co
}
if (tcp_connection->status == TCP_CLIENT_PROXY_SOCKS5_UNCONFIRMED) {
- if (client_send_pending_data(tcp_connection) == 0) {
+ if (send_pending_data(logger, &tcp_connection->con) == 0) {
int ret = proxy_socks5_read_connection_response(logger, tcp_connection);
if (ret == -1) {
@@ -1014,14 +863,14 @@ void do_TCP_connection(const Logger *logger, Mono_Time *mono_time, TCP_Client_Co
}
if (tcp_connection->status == TCP_CLIENT_CONNECTING) {
- if (client_send_pending_data(tcp_connection) == 0) {
+ if (send_pending_data(logger, &tcp_connection->con) == 0) {
tcp_connection->status = TCP_CLIENT_UNCONFIRMED;
}
}
if (tcp_connection->status == TCP_CLIENT_UNCONFIRMED) {
uint8_t data[TCP_SERVER_HANDSHAKE_SIZE];
- int len = read_TCP_packet(logger, tcp_connection->sock, data, sizeof(data));
+ int len = read_TCP_packet(logger, tcp_connection->con.sock, data, sizeof(data), &tcp_connection->con.ip_port);
if (sizeof(data) == len) {
if (handle_handshake(tcp_connection, data) == 0) {
@@ -1043,7 +892,7 @@ void do_TCP_connection(const Logger *logger, Mono_Time *mono_time, TCP_Client_Co
}
}
-/* Kill the TCP connection
+/** Kill the TCP connection
*/
void kill_TCP_connection(TCP_Client_Connection *tcp_connection)
{
@@ -1051,8 +900,8 @@ void kill_TCP_connection(TCP_Client_Connection *tcp_connection)
return;
}
- wipe_priority_list(tcp_connection->priority_queue_start);
- kill_sock(tcp_connection->sock);
+ wipe_priority_list(tcp_connection->con.priority_queue_start);
+ kill_sock(tcp_connection->con.sock);
crypto_memzero(tcp_connection, sizeof(TCP_Client_Connection));
free(tcp_connection);
}
diff --git a/protocols/Tox/libtox/src/toxcore/TCP_client.h b/protocols/Tox/libtox/src/toxcore/TCP_client.h
index ed4304cb00..dd170d7849 100644
--- a/protocols/Tox/libtox/src/toxcore/TCP_client.h
+++ b/protocols/Tox/libtox/src/toxcore/TCP_client.h
@@ -3,14 +3,14 @@
* Copyright © 2014 Tox project.
*/
-/*
+/**
* Implementation of the TCP relay client part of Tox.
*/
#ifndef C_TOXCORE_TOXCORE_TCP_CLIENT_H
#define C_TOXCORE_TOXCORE_TCP_CLIENT_H
-#include "TCP_server.h"
-#include "crypto_core.h"
+#include "mono_time.h"
+#include "network.h"
#define TCP_CONNECTION_TIMEOUT 10
@@ -47,47 +47,48 @@ uint32_t tcp_con_custom_uint(const TCP_Client_Connection *con);
void tcp_con_set_custom_object(TCP_Client_Connection *con, void *object);
void tcp_con_set_custom_uint(TCP_Client_Connection *con, uint32_t value);
-/* Create new TCP connection to ip_port/public_key
+/** Create new TCP connection to ip_port/public_key
*/
-TCP_Client_Connection *new_TCP_connection(const Mono_Time *mono_time, IP_Port ip_port, const uint8_t *public_key,
- const uint8_t *self_public_key, const uint8_t *self_secret_key, TCP_Proxy_Info *proxy_info);
+TCP_Client_Connection *new_TCP_connection(const Logger *logger, const Mono_Time *mono_time, const IP_Port *ip_port,
+ const uint8_t *public_key, const uint8_t *self_public_key, const uint8_t *self_secret_key,
+ const TCP_Proxy_Info *proxy_info);
-/* Run the TCP connection
+/** Run the TCP connection
*/
-void do_TCP_connection(const Logger *logger, Mono_Time *mono_time, TCP_Client_Connection *tcp_connection,
- void *userdata);
+void do_TCP_connection(const Logger *logger, const Mono_Time *mono_time,
+ TCP_Client_Connection *tcp_connection, void *userdata);
-/* Kill the TCP connection
+/** Kill the TCP connection
*/
void kill_TCP_connection(TCP_Client_Connection *tcp_connection);
typedef int tcp_onion_response_cb(void *object, const uint8_t *data, uint16_t length, void *userdata);
-/* return 1 on success.
+/** return 1 on success.
* return 0 if could not send packet.
* return -1 on failure (connection must be killed).
*/
-int send_onion_request(TCP_Client_Connection *con, const uint8_t *data, uint16_t length);
+int send_onion_request(const Logger *logger, TCP_Client_Connection *con, const uint8_t *data, uint16_t length);
void onion_response_handler(TCP_Client_Connection *con, tcp_onion_response_cb *onion_callback, void *object);
typedef int tcp_routing_response_cb(void *object, uint8_t connection_id, const uint8_t *public_key);
typedef int tcp_routing_status_cb(void *object, uint32_t number, uint8_t connection_id, uint8_t status);
-/* return 1 on success.
+/** return 1 on success.
* return 0 if could not send packet.
* return -1 on failure (connection must be killed).
*/
-int send_routing_request(TCP_Client_Connection *con, uint8_t *public_key);
+int send_routing_request(const Logger *logger, TCP_Client_Connection *con, const uint8_t *public_key);
void routing_response_handler(TCP_Client_Connection *con, tcp_routing_response_cb *response_callback, void *object);
void routing_status_handler(TCP_Client_Connection *con, tcp_routing_status_cb *status_callback, void *object);
-/* return 1 on success.
+/** return 1 on success.
* return 0 if could not send packet.
* return -1 on failure (connection must be killed).
*/
-int send_disconnect_request(TCP_Client_Connection *con, uint8_t con_id);
+int send_disconnect_request(const Logger *logger, TCP_Client_Connection *con, uint8_t con_id);
-/* Set the number that will be used as an argument in the callbacks related to con_id.
+/** Set the number that will be used as an argument in the callbacks related to con_id.
*
* When not set by this function, the number is -1.
*
@@ -99,21 +100,22 @@ int set_tcp_connection_number(TCP_Client_Connection *con, uint8_t con_id, uint32
typedef int tcp_routing_data_cb(void *object, uint32_t number, uint8_t connection_id, const uint8_t *data,
uint16_t length, void *userdata);
-/* return 1 on success.
+/** return 1 on success.
* return 0 if could not send packet.
* return -1 on failure.
*/
-int send_data(TCP_Client_Connection *con, uint8_t con_id, const uint8_t *data, uint16_t length);
+int send_data(const Logger *logger, TCP_Client_Connection *con, uint8_t con_id, const uint8_t *data, uint16_t length);
void routing_data_handler(TCP_Client_Connection *con, tcp_routing_data_cb *data_callback, void *object);
typedef int tcp_oob_data_cb(void *object, const uint8_t *public_key, const uint8_t *data, uint16_t length,
void *userdata);
-/* return 1 on success.
+/** return 1 on success.
* return 0 if could not send packet.
* return -1 on failure.
*/
-int send_oob_packet(TCP_Client_Connection *con, const uint8_t *public_key, const uint8_t *data, uint16_t length);
+int send_oob_packet(const Logger *logger, TCP_Client_Connection *con, const uint8_t *public_key, const uint8_t *data,
+ uint16_t length);
void oob_data_handler(TCP_Client_Connection *con, tcp_oob_data_cb *oob_data_callback, void *object);
diff --git a/protocols/Tox/libtox/src/toxcore/TCP_common.c b/protocols/Tox/libtox/src/toxcore/TCP_common.c
new file mode 100644
index 0000000000..237df20f89
--- /dev/null
+++ b/protocols/Tox/libtox/src/toxcore/TCP_common.c
@@ -0,0 +1,291 @@
+/* SPDX-License-Identifier: GPL-3.0-or-later
+ * Copyright © 2016-2018 The TokTok team.
+ * Copyright © 2014 Tox project.
+ */
+
+#include "TCP_common.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+void wipe_priority_list(TCP_Priority_List *p)
+{
+ while (p) {
+ TCP_Priority_List *pp = p;
+ p = p->next;
+ free(pp->data);
+ free(pp);
+ }
+}
+
+/** return 0 if pending data was sent completely
+ * return -1 if it wasn't
+ */
+int send_pending_data_nonpriority(const Logger *logger, TCP_Connection *con)
+{
+ if (con->last_packet_length == 0) {
+ return 0;
+ }
+
+ const uint16_t left = con->last_packet_length - con->last_packet_sent;
+ const int len = net_send(logger, con->sock, con->last_packet + con->last_packet_sent, left, &con->ip_port);
+
+ if (len <= 0) {
+ return -1;
+ }
+
+ if (len == left) {
+ con->last_packet_length = 0;
+ con->last_packet_sent = 0;
+ return 0;
+ }
+
+ con->last_packet_sent += len;
+ return -1;
+}
+
+/** return 0 if pending data was sent completely
+ * return -1 if it wasn't
+ */
+int send_pending_data(const Logger *logger, TCP_Connection *con)
+{
+ /* finish sending current non-priority packet */
+ if (send_pending_data_nonpriority(logger, con) == -1) {
+ return -1;
+ }
+
+ TCP_Priority_List *p = con->priority_queue_start;
+
+ while (p) {
+ const uint16_t left = p->size - p->sent;
+ const int len = net_send(logger, con->sock, p->data + p->sent, left, &con->ip_port);
+
+ if (len != left) {
+ if (len > 0) {
+ p->sent += len;
+ }
+
+ break;
+ }
+
+ TCP_Priority_List *pp = p;
+ p = p->next;
+ free(pp->data);
+ free(pp);
+ }
+
+ con->priority_queue_start = p;
+
+ if (!p) {
+ con->priority_queue_end = nullptr;
+ return 0;
+ }
+
+ return -1;
+}
+
+/** return 0 on failure (only if calloc fails)
+ * return 1 on success
+ */
+bool add_priority(TCP_Connection *con, const uint8_t *packet, uint16_t size, uint16_t sent)
+{
+ TCP_Priority_List *p = con->priority_queue_end;
+ TCP_Priority_List *new_list = (TCP_Priority_List *)calloc(1, sizeof(TCP_Priority_List));
+
+ if (new_list == nullptr) {
+ return false;
+ }
+
+ new_list->next = nullptr;
+ new_list->size = size;
+ new_list->sent = sent;
+ new_list->data = (uint8_t *)malloc(size);
+
+ if (new_list->data == nullptr) {
+ free(new_list);
+ return false;
+ }
+
+ memcpy(new_list->data, packet, size);
+
+ if (p) {
+ p->next = new_list;
+ } else {
+ con->priority_queue_start = new_list;
+ }
+
+ con->priority_queue_end = new_list;
+ return true;
+}
+
+/** return 1 on success.
+ * return 0 if could not send packet.
+ * return -1 on failure (connection must be killed).
+ */
+int write_packet_TCP_secure_connection(const Logger *logger, TCP_Connection *con, const uint8_t *data, uint16_t length,
+ bool priority)
+{
+ if (length + CRYPTO_MAC_SIZE > MAX_PACKET_SIZE) {
+ return -1;
+ }
+
+ bool sendpriority = 1;
+
+ if (send_pending_data(logger, con) == -1) {
+ if (priority) {
+ sendpriority = 0;
+ } else {
+ return 0;
+ }
+ }
+
+ VLA(uint8_t, packet, sizeof(uint16_t) + length + CRYPTO_MAC_SIZE);
+
+ uint16_t c_length = net_htons(length + CRYPTO_MAC_SIZE);
+ memcpy(packet, &c_length, sizeof(uint16_t));
+ int len = encrypt_data_symmetric(con->shared_key, con->sent_nonce, data, length, packet + sizeof(uint16_t));
+
+ if ((unsigned int)len != (SIZEOF_VLA(packet) - sizeof(uint16_t))) {
+ return -1;
+ }
+
+ if (priority) {
+ len = sendpriority ? net_send(logger, con->sock, packet, SIZEOF_VLA(packet), &con->ip_port) : 0;
+
+ if (len <= 0) {
+ len = 0;
+ }
+
+ increment_nonce(con->sent_nonce);
+
+ if ((unsigned int)len == SIZEOF_VLA(packet)) {
+ return 1;
+ }
+
+ return add_priority(con, packet, SIZEOF_VLA(packet), len);
+ }
+
+ len = net_send(logger, con->sock, packet, SIZEOF_VLA(packet), &con->ip_port);
+
+ if (len <= 0) {
+ return 0;
+ }
+
+ increment_nonce(con->sent_nonce);
+
+ if ((unsigned int)len == SIZEOF_VLA(packet)) {
+ return 1;
+ }
+
+ memcpy(con->last_packet, packet, SIZEOF_VLA(packet));
+ con->last_packet_length = SIZEOF_VLA(packet);
+ con->last_packet_sent = len;
+ return 1;
+}
+
+/** Read length bytes from socket.
+ *
+ * return length on success
+ * return -1 on failure/no data in buffer.
+ */
+int read_TCP_packet(const Logger *logger, Socket sock, uint8_t *data, uint16_t length, const IP_Port *ip_port)
+{
+ const uint16_t count = net_socket_data_recv_buffer(sock);
+
+ if (count < length) {
+ LOGGER_TRACE(logger, "recv buffer has %d bytes, but requested %d bytes", count, length);
+ return -1;
+ }
+
+ const int len = net_recv(logger, sock, data, length, ip_port);
+
+ if (len != length) {
+ LOGGER_ERROR(logger, "FAIL recv packet");
+ return -1;
+ }
+
+ return len;
+}
+
+/** Read the next two bytes in TCP stream then convert them to
+ * length (host byte order).
+ *
+ * return length on success
+ * return 0 if nothing has been read from socket.
+ * return -1 on failure.
+ */
+static uint16_t read_TCP_length(const Logger *logger, Socket sock, const IP_Port *ip_port)
+{
+ const uint16_t count = net_socket_data_recv_buffer(sock);
+
+ if (count >= sizeof(uint16_t)) {
+ uint8_t length_buf[sizeof(uint16_t)];
+ const int len = net_recv(logger, sock, length_buf, sizeof(length_buf), ip_port);
+
+ if (len != sizeof(uint16_t)) {
+ LOGGER_ERROR(logger, "FAIL recv packet");
+ return 0;
+ }
+
+ uint16_t length;
+ net_unpack_u16(length_buf, &length);
+
+ if (length > MAX_PACKET_SIZE) {
+ LOGGER_WARNING(logger, "TCP packet too large: %d > %d", length, MAX_PACKET_SIZE);
+ return -1;
+ }
+
+ return length;
+ }
+
+ return 0;
+}
+
+/** return length of received packet on success.
+ * return 0 if could not read any packet.
+ * return -1 on failure (connection must be killed).
+ */
+int read_packet_TCP_secure_connection(const Logger *logger, Socket sock, uint16_t *next_packet_length,
+ const uint8_t *shared_key, uint8_t *recv_nonce, uint8_t *data,
+ uint16_t max_len, const IP_Port *ip_port)
+{
+ if (*next_packet_length == 0) {
+ const uint16_t len = read_TCP_length(logger, sock, ip_port);
+
+ if (len == (uint16_t) -1) {
+ return -1;
+ }
+
+ if (len == 0) {
+ return 0;
+ }
+
+ *next_packet_length = len;
+ }
+
+ if (max_len + CRYPTO_MAC_SIZE < *next_packet_length) {
+ LOGGER_DEBUG(logger, "packet too large");
+ return -1;
+ }
+
+ VLA(uint8_t, data_encrypted, *next_packet_length);
+ const int len_packet = read_TCP_packet(logger, sock, data_encrypted, *next_packet_length, ip_port);
+
+ if (len_packet != *next_packet_length) {
+ LOGGER_WARNING(logger, "invalid packet length: %d, expected %d", len_packet, *next_packet_length);
+ return 0;
+ }
+
+ *next_packet_length = 0;
+
+ const int len = decrypt_data_symmetric(shared_key, recv_nonce, data_encrypted, len_packet, data);
+
+ if (len + CRYPTO_MAC_SIZE != len_packet) {
+ LOGGER_WARNING(logger, "decrypted length %d does not match expected length %d", len + CRYPTO_MAC_SIZE, len_packet);
+ return -1;
+ }
+
+ increment_nonce(recv_nonce);
+
+ return len;
+}
diff --git a/protocols/Tox/libtox/src/toxcore/TCP_common.h b/protocols/Tox/libtox/src/toxcore/TCP_common.h
new file mode 100644
index 0000000000..92c0a9a3d9
--- /dev/null
+++ b/protocols/Tox/libtox/src/toxcore/TCP_common.h
@@ -0,0 +1,97 @@
+/* SPDX-License-Identifier: GPL-3.0-or-later
+ * Copyright © 2016-2018 The TokTok team.
+ * Copyright © 2014 Tox project.
+ */
+
+#ifndef C_TOXCORE_TOXCORE_TCP_COMMON_H
+#define C_TOXCORE_TOXCORE_TCP_COMMON_H
+
+#include "crypto_core.h"
+#include "network.h"
+
+typedef struct TCP_Priority_List TCP_Priority_List;
+struct TCP_Priority_List {
+ TCP_Priority_List *next;
+ uint16_t size;
+ uint16_t sent;
+ uint8_t *data;
+};
+
+void wipe_priority_list(TCP_Priority_List *p);
+
+#define NUM_RESERVED_PORTS 16
+#define NUM_CLIENT_CONNECTIONS (256 - NUM_RESERVED_PORTS)
+
+#define TCP_PACKET_ROUTING_REQUEST 0
+#define TCP_PACKET_ROUTING_RESPONSE 1
+#define TCP_PACKET_CONNECTION_NOTIFICATION 2
+#define TCP_PACKET_DISCONNECT_NOTIFICATION 3
+#define TCP_PACKET_PING 4
+#define TCP_PACKET_PONG 5
+#define TCP_PACKET_OOB_SEND 6
+#define TCP_PACKET_OOB_RECV 7
+#define TCP_PACKET_ONION_REQUEST 8
+#define TCP_PACKET_ONION_RESPONSE 9
+
+#define TCP_HANDSHAKE_PLAIN_SIZE (CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE)
+#define TCP_SERVER_HANDSHAKE_SIZE (CRYPTO_NONCE_SIZE + TCP_HANDSHAKE_PLAIN_SIZE + CRYPTO_MAC_SIZE)
+#define TCP_CLIENT_HANDSHAKE_SIZE (CRYPTO_PUBLIC_KEY_SIZE + TCP_SERVER_HANDSHAKE_SIZE)
+#define TCP_MAX_OOB_DATA_LENGTH 1024
+
+/** frequency to ping connected nodes and timeout in seconds */
+#define TCP_PING_FREQUENCY 30
+#define TCP_PING_TIMEOUT 10
+
+#define MAX_PACKET_SIZE 2048
+
+typedef struct TCP_Connection {
+ Socket sock;
+ IP_Port ip_port; // for debugging.
+ uint8_t sent_nonce[CRYPTO_NONCE_SIZE]; /* Nonce of sent packets. */
+ uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE];
+ uint8_t last_packet[2 + MAX_PACKET_SIZE];
+ uint16_t last_packet_length;
+ uint16_t last_packet_sent;
+
+ TCP_Priority_List *priority_queue_start;
+ TCP_Priority_List *priority_queue_end;
+} TCP_Connection;
+
+/** return 0 if pending data was sent completely
+ * return -1 if it wasn't
+ */
+int send_pending_data_nonpriority(const Logger *logger, TCP_Connection *con);
+
+/** return 0 if pending data was sent completely
+ * return -1 if it wasn't
+ */
+int send_pending_data(const Logger *logger, TCP_Connection *con);
+
+/** return 0 on failure (only if calloc fails)
+ * return 1 on success
+ */
+bool add_priority(TCP_Connection *con, const uint8_t *packet, uint16_t size, uint16_t sent);
+
+/** return 1 on success.
+ * return 0 if could not send packet.
+ * return -1 on failure (connection must be killed).
+ */
+int write_packet_TCP_secure_connection(const Logger *logger, TCP_Connection *con, const uint8_t *data, uint16_t length,
+ bool priority);
+
+/** Read length bytes from socket.
+ *
+ * return length on success
+ * return -1 on failure/no data in buffer.
+ */
+int read_TCP_packet(const Logger *logger, Socket sock, uint8_t *data, uint16_t length, const IP_Port *ip_port);
+
+/** return length of received packet on success.
+ * return 0 if could not read any packet.
+ * return -1 on failure (connection must be killed).
+ */
+int read_packet_TCP_secure_connection(const Logger *logger, Socket sock, uint16_t *next_packet_length,
+ const uint8_t *shared_key, uint8_t *recv_nonce, uint8_t *data,
+ uint16_t max_len, const IP_Port *ip_port);
+
+#endif
diff --git a/protocols/Tox/libtox/src/toxcore/TCP_connection.c b/protocols/Tox/libtox/src/toxcore/TCP_connection.c
index ac933cc3cc..4b406097c2 100644
--- a/protocols/Tox/libtox/src/toxcore/TCP_connection.c
+++ b/protocols/Tox/libtox/src/toxcore/TCP_connection.c
@@ -3,24 +3,21 @@
* Copyright © 2015 Tox project.
*/
-/*
+/**
* Handles TCP relay connections between two Tox clients.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include "TCP_connection.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
+#include "TCP_client.h"
#include "mono_time.h"
#include "util.h"
-
struct TCP_Connections {
+ const Logger *logger;
Mono_Time *mono_time;
DHT *dht;
@@ -55,7 +52,12 @@ const uint8_t *tcp_connections_public_key(const TCP_Connections *tcp_c)
}
-/* Set the size of the array to num.
+uint32_t tcp_connections_count(const TCP_Connections *tcp_c)
+{
+ return tcp_c->tcp_connections_length;
+}
+
+/** Set the size of the array to num.
*
* return -1 if realloc fails.
* return 0 if it succeeds.
@@ -140,16 +142,14 @@ static bool tcp_connections_number_is_valid(const TCP_Connections *tcp_c, int tc
return true;
}
-/* Create a new empty connection.
+/** Create a new empty connection.
*
* return -1 on failure.
* return connections_number on success.
*/
static int create_connection(TCP_Connections *tcp_c)
{
- uint32_t i;
-
- for (i = 0; i < tcp_c->connections_length; ++i) {
+ for (uint32_t i = 0; i < tcp_c->connections_length; ++i) {
if (tcp_c->connections[i].status == TCP_CONN_NONE) {
return i;
}
@@ -166,7 +166,7 @@ static int create_connection(TCP_Connections *tcp_c)
return id;
}
-/* Create a new empty tcp connection.
+/** Create a new empty tcp connection.
*
* return -1 on failure.
* return tcp_connections_number on success.
@@ -190,7 +190,7 @@ static int create_tcp_connection(TCP_Connections *tcp_c)
return id;
}
-/* Wipe a connection.
+/** Wipe a connection.
*
* return -1 on failure.
* return 0 on success.
@@ -218,7 +218,7 @@ static int wipe_connection(TCP_Connections *tcp_c, int connections_number)
return 0;
}
-/* Wipe a connection.
+/** Wipe a connection.
*
* return -1 on failure.
* return 0 on success.
@@ -265,14 +265,35 @@ static TCP_con *get_tcp_connection(const TCP_Connections *tcp_c, int tcp_connect
return &tcp_c->tcp_connections[tcp_connections_number];
}
-/* Send a packet to the TCP connection.
+/** Returns the number of connected TCP relays */
+uint32_t tcp_connected_relays_count(const TCP_Connections *tcp_c)
+{
+ uint32_t count = 0;
+
+ for (uint32_t i = 0; i < tcp_connections_count(tcp_c); ++i) {
+ const TCP_con *tcp_con = get_tcp_connection(tcp_c, i);
+
+ if (tcp_con == nullptr) {
+ continue;
+ }
+
+ if (tcp_con->status == TCP_CONN_CONNECTED) {
+ ++count;
+ }
+ }
+
+ return count;
+}
+
+/** Send a packet to the TCP connection.
*
* return -1 on failure.
* return 0 on success.
*/
-int send_packet_tcp_connection(TCP_Connections *tcp_c, int connections_number, const uint8_t *packet, uint16_t length)
+int send_packet_tcp_connection(const TCP_Connections *tcp_c, int connections_number, const uint8_t *packet,
+ uint16_t length)
{
- TCP_Connection_to *con_to = get_connection(tcp_c, connections_number);
+ const TCP_Connection_to *con_to = get_connection(tcp_c, connections_number);
if (!con_to) {
return -1;
@@ -280,12 +301,11 @@ int send_packet_tcp_connection(TCP_Connections *tcp_c, int connections_number, c
// TODO(irungentoo): detect and kill bad relays.
// TODO(irungentoo): thread safety?
- unsigned int i;
int ret = -1;
bool limit_reached = 0;
- for (i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) {
+ for (unsigned int i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) {
uint32_t tcp_con_num = con_to->connections[i].tcp_connection;
uint8_t status = con_to->connections[i].status;
uint8_t connection_id = con_to->connections[i].connection_id;
@@ -298,7 +318,7 @@ int send_packet_tcp_connection(TCP_Connections *tcp_c, int connections_number, c
continue;
}
- ret = send_data(tcp_con->connection, connection_id, packet, length);
+ ret = send_data(tcp_c->logger, tcp_con->connection, connection_id, packet, length);
if (ret == 0) {
limit_reached = 1;
@@ -318,7 +338,7 @@ int send_packet_tcp_connection(TCP_Connections *tcp_c, int connections_number, c
ret = 0;
/* Send oob packets to all relays tied to the connection. */
- for (i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) {
+ for (unsigned int i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) {
uint32_t tcp_con_num = con_to->connections[i].tcp_connection;
uint8_t status = con_to->connections[i].status;
@@ -330,7 +350,7 @@ int send_packet_tcp_connection(TCP_Connections *tcp_c, int connections_number, c
continue;
}
- if (send_oob_packet(tcp_con->connection, con_to->public_key, packet, length) == 1) {
+ if (send_oob_packet(tcp_c->logger, tcp_con->connection, con_to->public_key, packet, length) == 1) {
ret += 1;
}
}
@@ -346,7 +366,7 @@ int send_packet_tcp_connection(TCP_Connections *tcp_c, int connections_number, c
return -1;
}
-/* Return a random TCP connection number for use in send_tcp_onion_request.
+/** Return a random TCP connection number for use in send_tcp_onion_request.
*
* TODO(irungentoo): This number is just the index of an array that the elements
* can change without warning.
@@ -354,12 +374,12 @@ int send_packet_tcp_connection(TCP_Connections *tcp_c, int connections_number, c
* return TCP connection number on success.
* return -1 on failure.
*/
-int get_random_tcp_onion_conn_number(TCP_Connections *tcp_c)
+int get_random_tcp_onion_conn_number(const TCP_Connections *tcp_c)
{
const uint32_t r = random_u32();
for (uint32_t i = 0; i < tcp_c->tcp_connections_length; ++i) {
- uint32_t index = ((i + r) % tcp_c->tcp_connections_length);
+ uint32_t index = (i + r) % tcp_c->tcp_connections_length;
if (tcp_c->tcp_connections[index].onion && tcp_c->tcp_connections[index].status == TCP_CONN_CONNECTED) {
return index;
@@ -369,7 +389,7 @@ int get_random_tcp_onion_conn_number(TCP_Connections *tcp_c)
return -1;
}
-/* Send an onion packet via the TCP relay corresponding to tcp_connections_number.
+/** Send an onion packet via the TCP relay corresponding to tcp_connections_number.
*
* return 0 on success.
* return -1 on failure.
@@ -382,7 +402,8 @@ int tcp_send_onion_request(TCP_Connections *tcp_c, uint32_t tcp_connections_numb
}
if (tcp_c->tcp_connections[tcp_connections_number].status == TCP_CONN_CONNECTED) {
- int ret = send_onion_request(tcp_c->tcp_connections[tcp_connections_number].connection, data, length);
+ const int ret = send_onion_request(tcp_c->logger, tcp_c->tcp_connections[tcp_connections_number].connection, data,
+ length);
if (ret == 1) {
return 0;
@@ -392,13 +413,13 @@ int tcp_send_onion_request(TCP_Connections *tcp_c, uint32_t tcp_connections_numb
return -1;
}
-/* Send an oob packet via the TCP relay corresponding to tcp_connections_number.
+/** Send an oob packet via the TCP relay corresponding to tcp_connections_number.
*
* return 0 on success.
* return -1 on failure.
*/
-int tcp_send_oob_packet(TCP_Connections *tcp_c, unsigned int tcp_connections_number, const uint8_t *public_key,
- const uint8_t *packet, uint16_t length)
+int tcp_send_oob_packet(const TCP_Connections *tcp_c, unsigned int tcp_connections_number,
+ const uint8_t *public_key, const uint8_t *packet, uint16_t length)
{
TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number);
@@ -410,7 +431,7 @@ int tcp_send_oob_packet(TCP_Connections *tcp_c, unsigned int tcp_connections_num
return -1;
}
- int ret = send_oob_packet(tcp_con->connection, public_key, packet, length);
+ const int ret = send_oob_packet(tcp_c->logger, tcp_con->connection, public_key, packet, length);
if (ret == 1) {
return 0;
@@ -419,7 +440,26 @@ int tcp_send_oob_packet(TCP_Connections *tcp_c, unsigned int tcp_connections_num
return -1;
}
-/* Set the callback for TCP data packets.
+static int find_tcp_connection_relay(const TCP_Connections *tcp_c, const uint8_t *relay_pk);
+
+/** Send an oob packet via the TCP relay corresponding to relay_pk.
+ *
+ * return 0 on success.
+ * return -1 on failure.
+ */
+int tcp_send_oob_packet_using_relay(const TCP_Connections *tcp_c, const uint8_t *relay_pk, const uint8_t *public_key,
+ const uint8_t *packet, uint16_t length)
+{
+ int tcp_con_number = find_tcp_connection_relay(tcp_c, relay_pk);
+
+ if (tcp_con_number < 0) {
+ return -1;
+ }
+
+ return tcp_send_oob_packet(tcp_c, tcp_con_number, public_key, packet, length);
+}
+
+/** Set the callback for TCP data packets.
*/
void set_packet_tcp_connection_callback(TCP_Connections *tcp_c, tcp_data_cb *tcp_data_callback, void *object)
{
@@ -427,7 +467,7 @@ void set_packet_tcp_connection_callback(TCP_Connections *tcp_c, tcp_data_cb *tcp
tcp_c->tcp_data_callback_object = object;
}
-/* Set the callback for TCP onion packets.
+/** Set the callback for TCP oob data packets.
*/
void set_oob_packet_tcp_connection_callback(TCP_Connections *tcp_c, tcp_oob_cb *tcp_oob_callback, void *object)
{
@@ -435,7 +475,7 @@ void set_oob_packet_tcp_connection_callback(TCP_Connections *tcp_c, tcp_oob_cb *
tcp_c->tcp_oob_callback_object = object;
}
-/* Set the callback for TCP oob data packets.
+/** Set the callback for TCP onion packets.
*/
void set_onion_packet_tcp_connection_callback(TCP_Connections *tcp_c, tcp_onion_cb *tcp_onion_callback, void *object)
{
@@ -443,18 +483,15 @@ void set_onion_packet_tcp_connection_callback(TCP_Connections *tcp_c, tcp_onion_
tcp_c->tcp_onion_callback_object = object;
}
-
-/* Find the TCP connection with public_key.
+/** Find the TCP connection with public_key.
*
* return connections_number on success.
* return -1 on failure.
*/
-static int find_tcp_connection_to(TCP_Connections *tcp_c, const uint8_t *public_key)
+static int find_tcp_connection_to(const TCP_Connections *tcp_c, const uint8_t *public_key)
{
- unsigned int i;
-
- for (i = 0; i < tcp_c->connections_length; ++i) {
- TCP_Connection_to *con_to = get_connection(tcp_c, i);
+ for (unsigned int i = 0; i < tcp_c->connections_length; ++i) {
+ const TCP_Connection_to *con_to = get_connection(tcp_c, i);
if (con_to) {
if (public_key_cmp(con_to->public_key, public_key) == 0) {
@@ -466,15 +503,15 @@ static int find_tcp_connection_to(TCP_Connections *tcp_c, const uint8_t *public_
return -1;
}
-/* Find the TCP connection to a relay with relay_pk.
+/** Find the TCP connection to a relay with relay_pk.
*
* return connections_number on success.
* return -1 on failure.
*/
-static int find_tcp_connection_relay(TCP_Connections *tcp_c, const uint8_t *relay_pk)
+static int find_tcp_connection_relay(const TCP_Connections *tcp_c, const uint8_t *relay_pk)
{
for (uint32_t i = 0; i < tcp_c->tcp_connections_length; ++i) {
- TCP_con *tcp_con = get_tcp_connection(tcp_c, i);
+ const TCP_con *tcp_con = get_tcp_connection(tcp_c, i);
if (tcp_con) {
if (tcp_con->status == TCP_CONN_SLEEPING) {
@@ -492,7 +529,7 @@ static int find_tcp_connection_relay(TCP_Connections *tcp_c, const uint8_t *rela
return -1;
}
-/* Create a new TCP connection to public_key.
+/** Create a new TCP connection to public_key.
*
* public_key must be the counterpart to the secret key that the other peer used with new_tcp_connections().
*
@@ -522,20 +559,18 @@ int new_tcp_connection_to(TCP_Connections *tcp_c, const uint8_t *public_key, int
return connections_number;
}
-/* return 0 on success.
+/** return 0 on success.
* return -1 on failure.
*/
int kill_tcp_connection_to(TCP_Connections *tcp_c, int connections_number)
{
- TCP_Connection_to *con_to = get_connection(tcp_c, connections_number);
+ const TCP_Connection_to *con_to = get_connection(tcp_c, connections_number);
if (!con_to) {
return -1;
}
- unsigned int i;
-
- for (i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) {
+ for (unsigned int i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) {
if (con_to->connections[i].tcp_connection) {
unsigned int tcp_connections_number = con_to->connections[i].tcp_connection - 1;
TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number);
@@ -545,7 +580,7 @@ int kill_tcp_connection_to(TCP_Connections *tcp_c, int connections_number)
}
if (tcp_con->status == TCP_CONN_CONNECTED) {
- send_disconnect_request(tcp_con->connection, con_to->connections[i].connection_id);
+ send_disconnect_request(tcp_c->logger, tcp_con->connection, con_to->connections[i].connection_id);
}
if (con_to->connections[i].status == TCP_CONNECTIONS_STATUS_ONLINE) {
@@ -561,7 +596,7 @@ int kill_tcp_connection_to(TCP_Connections *tcp_c, int connections_number)
return wipe_connection(tcp_c, connections_number);
}
-/* Set connection status.
+/** Set connection status.
*
* status of 1 means we are using the connection.
* status of 0 means we are not using it.
@@ -571,7 +606,7 @@ int kill_tcp_connection_to(TCP_Connections *tcp_c, int connections_number)
* return 0 on success.
* return -1 on failure.
*/
-int set_tcp_connection_to_status(TCP_Connections *tcp_c, int connections_number, bool status)
+int set_tcp_connection_to_status(const TCP_Connections *tcp_c, int connections_number, bool status)
{
TCP_Connection_to *con_to = get_connection(tcp_c, connections_number);
@@ -585,9 +620,7 @@ int set_tcp_connection_to_status(TCP_Connections *tcp_c, int connections_number,
return -1;
}
- unsigned int i;
-
- for (i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) {
+ for (unsigned int i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) {
if (con_to->connections[i].tcp_connection) {
unsigned int tcp_connections_number = con_to->connections[i].tcp_connection - 1;
TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number);
@@ -611,9 +644,7 @@ int set_tcp_connection_to_status(TCP_Connections *tcp_c, int connections_number,
return -1;
}
- unsigned int i;
-
- for (i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) {
+ for (unsigned int i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) {
if (con_to->connections[i].tcp_connection) {
unsigned int tcp_connections_number = con_to->connections[i].tcp_connection - 1;
TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number);
@@ -632,11 +663,9 @@ int set_tcp_connection_to_status(TCP_Connections *tcp_c, int connections_number,
return 0;
}
-static bool tcp_connection_in_conn(TCP_Connection_to *con_to, unsigned int tcp_connections_number)
+static bool tcp_connection_in_conn(const TCP_Connection_to *con_to, unsigned int tcp_connections_number)
{
- unsigned int i;
-
- for (i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) {
+ for (unsigned int i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) {
if (con_to->connections[i].tcp_connection == (tcp_connections_number + 1)) {
return 1;
}
@@ -645,18 +674,16 @@ static bool tcp_connection_in_conn(TCP_Connection_to *con_to, unsigned int tcp_c
return 0;
}
-/* return index on success.
+/** return index on success.
* return -1 on failure.
*/
static int add_tcp_connection_to_conn(TCP_Connection_to *con_to, unsigned int tcp_connections_number)
{
- unsigned int i;
-
if (tcp_connection_in_conn(con_to, tcp_connections_number)) {
return -1;
}
- for (i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) {
+ for (unsigned int i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) {
if (con_to->connections[i].tcp_connection == 0) {
con_to->connections[i].tcp_connection = tcp_connections_number + 1;
con_to->connections[i].status = TCP_CONNECTIONS_STATUS_NONE;
@@ -668,14 +695,12 @@ static int add_tcp_connection_to_conn(TCP_Connection_to *con_to, unsigned int tc
return -1;
}
-/* return index on success.
+/** return index on success.
* return -1 on failure.
*/
static int rm_tcp_connection_from_conn(TCP_Connection_to *con_to, unsigned int tcp_connections_number)
{
- unsigned int i;
-
- for (i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) {
+ for (unsigned int i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) {
if (con_to->connections[i].tcp_connection == (tcp_connections_number + 1)) {
con_to->connections[i].tcp_connection = 0;
con_to->connections[i].status = TCP_CONNECTIONS_STATUS_NONE;
@@ -687,10 +712,10 @@ static int rm_tcp_connection_from_conn(TCP_Connection_to *con_to, unsigned int t
return -1;
}
-/* return number of online connections on success.
+/** return number of online connections on success.
* return -1 on failure.
*/
-static unsigned int online_tcp_connection_from_conn(TCP_Connection_to *con_to)
+static unsigned int online_tcp_connection_from_conn(const TCP_Connection_to *con_to)
{
unsigned int count = 0;
@@ -705,15 +730,14 @@ static unsigned int online_tcp_connection_from_conn(TCP_Connection_to *con_to)
return count;
}
-/* return index on success.
+/** return index on success.
* return -1 on failure.
*/
static int set_tcp_connection_status(TCP_Connection_to *con_to, unsigned int tcp_connections_number,
- unsigned int status, uint8_t connection_id)
+ uint8_t status,
+ uint8_t connection_id)
{
- unsigned int i;
-
- for (i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) {
+ for (unsigned int i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) {
if (con_to->connections[i].tcp_connection == (tcp_connections_number + 1)) {
if (con_to->connections[i].status == status) {
@@ -729,12 +753,12 @@ static int set_tcp_connection_status(TCP_Connection_to *con_to, unsigned int tcp
return -1;
}
-/* Kill a TCP relay connection.
+/** Kill a TCP relay connection.
*
* return 0 on success.
* return -1 on failure.
*/
-static int kill_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connections_number)
+int kill_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connections_number)
{
TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number);
@@ -742,9 +766,7 @@ static int kill_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connections
return -1;
}
- unsigned int i;
-
- for (i = 0; i < tcp_c->connections_length; ++i) {
+ for (unsigned int i = 0; i < tcp_c->connections_length; ++i) {
TCP_Connection_to *con_to = get_connection(tcp_c, i);
if (con_to) {
@@ -777,7 +799,7 @@ static int reconnect_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connec
uint8_t relay_pk[CRYPTO_PUBLIC_KEY_SIZE];
memcpy(relay_pk, tcp_con_public_key(tcp_con->connection), CRYPTO_PUBLIC_KEY_SIZE);
kill_TCP_connection(tcp_con->connection);
- tcp_con->connection = new_TCP_connection(tcp_c->mono_time, ip_port, relay_pk, tcp_c->self_public_key,
+ tcp_con->connection = new_TCP_connection(tcp_c->logger, tcp_c->mono_time, &ip_port, relay_pk, tcp_c->self_public_key,
tcp_c->self_secret_key, &tcp_c->proxy_info);
if (!tcp_con->connection) {
@@ -785,9 +807,7 @@ static int reconnect_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connec
return -1;
}
- unsigned int i;
-
- for (i = 0; i < tcp_c->connections_length; ++i) {
+ for (unsigned int i = 0; i < tcp_c->connections_length; ++i) {
TCP_Connection_to *con_to = get_connection(tcp_c, i);
if (con_to) {
@@ -831,9 +851,7 @@ static int sleep_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connection
kill_TCP_connection(tcp_con->connection);
tcp_con->connection = nullptr;
- unsigned int i;
-
- for (i = 0; i < tcp_c->connections_length; ++i) {
+ for (unsigned int i = 0; i < tcp_c->connections_length; ++i) {
TCP_Connection_to *con_to = get_connection(tcp_c, i);
if (con_to) {
@@ -867,8 +885,8 @@ static int unsleep_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connecti
return -1;
}
- tcp_con->connection = new_TCP_connection(tcp_c->mono_time, tcp_con->ip_port, tcp_con->relay_pk, tcp_c->self_public_key,
- tcp_c->self_secret_key, &tcp_c->proxy_info);
+ tcp_con->connection = new_TCP_connection(tcp_c->logger, tcp_c->mono_time, &tcp_con->ip_port, tcp_con->relay_pk,
+ tcp_c->self_public_key, tcp_c->self_secret_key, &tcp_c->proxy_info);
if (!tcp_con->connection) {
kill_tcp_relay_connection(tcp_c, tcp_connections_number);
@@ -883,12 +901,13 @@ static int unsleep_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connecti
return 0;
}
-/* Send a TCP routing request.
+/** Send a TCP routing request.
*
* return 0 on success.
* return -1 on failure.
*/
-static int send_tcp_relay_routing_request(TCP_Connections *tcp_c, int tcp_connections_number, uint8_t *public_key)
+static int send_tcp_relay_routing_request(const TCP_Connections *tcp_c, int tcp_connections_number,
+ const uint8_t *public_key)
{
TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number);
@@ -900,7 +919,7 @@ static int send_tcp_relay_routing_request(TCP_Connections *tcp_c, int tcp_connec
return -1;
}
- if (send_routing_request(tcp_con->connection, public_key) != 1) {
+ if (send_routing_request(tcp_c->logger, tcp_con->connection, public_key) != 1) {
return -1;
}
@@ -910,7 +929,7 @@ static int send_tcp_relay_routing_request(TCP_Connections *tcp_c, int tcp_connec
static int tcp_response_callback(void *object, uint8_t connection_id, const uint8_t *public_key)
{
TCP_Client_Connection *tcp_client_con = (TCP_Client_Connection *)object;
- TCP_Connections *tcp_c = (TCP_Connections *)tcp_con_custom_object(tcp_client_con);
+ const TCP_Connections *tcp_c = (const TCP_Connections *)tcp_con_custom_object(tcp_client_con);
unsigned int tcp_connections_number = tcp_con_custom_uint(tcp_client_con);
TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number);
@@ -942,8 +961,8 @@ static int tcp_response_callback(void *object, uint8_t connection_id, const uint
static int tcp_status_callback(void *object, uint32_t number, uint8_t connection_id, uint8_t status)
{
- TCP_Client_Connection *tcp_client_con = (TCP_Client_Connection *)object;
- TCP_Connections *tcp_c = (TCP_Connections *)tcp_con_custom_object(tcp_client_con);
+ const TCP_Client_Connection *tcp_client_con = (const TCP_Client_Connection *)object;
+ const TCP_Connections *tcp_c = (const TCP_Connections *)tcp_con_custom_object(tcp_client_con);
unsigned int tcp_connections_number = tcp_con_custom_uint(tcp_client_con);
TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number);
@@ -985,17 +1004,17 @@ static int tcp_conn_data_callback(void *object, uint32_t number, uint8_t connect
return -1;
}
- TCP_Client_Connection *tcp_client_con = (TCP_Client_Connection *)object;
+ const TCP_Client_Connection *tcp_client_con = (TCP_Client_Connection *)object;
TCP_Connections *tcp_c = (TCP_Connections *)tcp_con_custom_object(tcp_client_con);
unsigned int tcp_connections_number = tcp_con_custom_uint(tcp_client_con);
- TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number);
+ const TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number);
if (!tcp_con) {
return -1;
}
- TCP_Connection_to *con_to = get_connection(tcp_c, number);
+ const TCP_Connection_to *con_to = get_connection(tcp_c, number);
if (!con_to) {
return -1;
@@ -1015,11 +1034,11 @@ static int tcp_conn_oob_callback(void *object, const uint8_t *public_key, const
return -1;
}
- TCP_Client_Connection *tcp_client_con = (TCP_Client_Connection *)object;
+ const TCP_Client_Connection *tcp_client_con = (const TCP_Client_Connection *)object;
TCP_Connections *tcp_c = (TCP_Connections *)tcp_con_custom_object(tcp_client_con);
unsigned int tcp_connections_number = tcp_con_custom_uint(tcp_client_con);
- TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number);
+ const TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number);
if (!tcp_con) {
return -1;
@@ -1028,7 +1047,7 @@ static int tcp_conn_oob_callback(void *object, const uint8_t *public_key, const
/* TODO(irungentoo): optimize */
int connections_number = find_tcp_connection_to(tcp_c, public_key);
- TCP_Connection_to *con_to = get_connection(tcp_c, connections_number);
+ const TCP_Connection_to *con_to = get_connection(tcp_c, connections_number);
if (con_to && tcp_connection_in_conn(con_to, tcp_connections_number)) {
return tcp_conn_data_callback(object, connections_number, 0, data, length, userdata);
@@ -1052,7 +1071,7 @@ static int tcp_onion_callback(void *object, const uint8_t *data, uint16_t length
return 0;
}
-/* Set callbacks for the TCP relay connection.
+/** Set callbacks for the TCP relay connection.
*
* return 0 on success.
* return -1 on failure.
@@ -1118,15 +1137,17 @@ static int tcp_relay_on_online(TCP_Connections *tcp_c, int tcp_connections_numbe
return 0;
}
-static int add_tcp_relay_instance(TCP_Connections *tcp_c, IP_Port ip_port, const uint8_t *relay_pk)
+static int add_tcp_relay_instance(TCP_Connections *tcp_c, const IP_Port *ip_port, const uint8_t *relay_pk)
{
- if (net_family_is_tcp_ipv4(ip_port.ip.family)) {
- ip_port.ip.family = net_family_ipv4;
- } else if (net_family_is_tcp_ipv6(ip_port.ip.family)) {
- ip_port.ip.family = net_family_ipv6;
+ IP_Port ipp_copy = *ip_port;
+
+ if (net_family_is_tcp_ipv4(ipp_copy.ip.family)) {
+ ipp_copy.ip.family = net_family_ipv4;
+ } else if (net_family_is_tcp_ipv6(ipp_copy.ip.family)) {
+ ipp_copy.ip.family = net_family_ipv6;
}
- if (!net_family_is_ipv4(ip_port.ip.family) && !net_family_is_ipv6(ip_port.ip.family)) {
+ if (!net_family_is_ipv4(ipp_copy.ip.family) && !net_family_is_ipv6(ipp_copy.ip.family)) {
return -1;
}
@@ -1138,7 +1159,7 @@ static int add_tcp_relay_instance(TCP_Connections *tcp_c, IP_Port ip_port, const
TCP_con *tcp_con = &tcp_c->tcp_connections[tcp_connections_number];
- tcp_con->connection = new_TCP_connection(tcp_c->mono_time, ip_port, relay_pk, tcp_c->self_public_key,
+ tcp_con->connection = new_TCP_connection(tcp_c->logger, tcp_c->mono_time, &ipp_copy, relay_pk, tcp_c->self_public_key,
tcp_c->self_secret_key, &tcp_c->proxy_info);
if (!tcp_con->connection) {
@@ -1150,12 +1171,12 @@ static int add_tcp_relay_instance(TCP_Connections *tcp_c, IP_Port ip_port, const
return tcp_connections_number;
}
-/* Add a TCP relay to the TCP_Connections instance.
+/** Add a TCP relay to the TCP_Connections instance.
*
* return 0 on success.
* return -1 on failure.
*/
-int add_tcp_relay_global(TCP_Connections *tcp_c, IP_Port ip_port, const uint8_t *relay_pk)
+int add_tcp_relay_global(TCP_Connections *tcp_c, const IP_Port *ip_port, const uint8_t *relay_pk)
{
int tcp_connections_number = find_tcp_connection_relay(tcp_c, relay_pk);
@@ -1170,12 +1191,15 @@ int add_tcp_relay_global(TCP_Connections *tcp_c, IP_Port ip_port, const uint8_t
return 0;
}
-/* Add a TCP relay tied to a connection.
+/** Add a TCP relay tied to a connection.
+ *
+ * NOTE: This can only be used during the tcp_oob_callback.
*
* return 0 on success.
* return -1 on failure.
*/
-int add_tcp_number_relay_connection(TCP_Connections *tcp_c, int connections_number, unsigned int tcp_connections_number)
+int add_tcp_number_relay_connection(const TCP_Connections *tcp_c, int connections_number,
+ unsigned int tcp_connections_number)
{
TCP_Connection_to *con_to = get_connection(tcp_c, connections_number);
@@ -1206,14 +1230,15 @@ int add_tcp_number_relay_connection(TCP_Connections *tcp_c, int connections_numb
return 0;
}
-/* Add a TCP relay tied to a connection.
+/** Add a TCP relay tied to a connection.
*
* This should be called with the same relay by two peers who want to create a TCP connection with each other.
*
* return 0 on success.
* return -1 on failure.
*/
-int add_tcp_relay_connection(TCP_Connections *tcp_c, int connections_number, IP_Port ip_port, const uint8_t *relay_pk)
+int add_tcp_relay_connection(TCP_Connections *tcp_c, int connections_number, const IP_Port *ip_port,
+ const uint8_t *relay_pk)
{
TCP_Connection_to *con_to = get_connection(tcp_c, connections_number);
@@ -1233,7 +1258,7 @@ int add_tcp_relay_connection(TCP_Connections *tcp_c, int connections_number, IP_
tcp_connections_number = add_tcp_relay_instance(tcp_c, ip_port, relay_pk);
- TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number);
+ const TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number);
if (!tcp_con) {
return -1;
@@ -1246,12 +1271,12 @@ int add_tcp_relay_connection(TCP_Connections *tcp_c, int connections_number, IP_
return 0;
}
-/* return number of online tcp relays tied to the connection on success.
+/** return number of online tcp relays tied to the connection on success.
* return 0 on failure.
*/
-unsigned int tcp_connection_to_online_tcp_relays(TCP_Connections *tcp_c, int connections_number)
+unsigned int tcp_connection_to_online_tcp_relays(const TCP_Connections *tcp_c, int connections_number)
{
- TCP_Connection_to *con_to = get_connection(tcp_c, connections_number);
+ const TCP_Connection_to *con_to = get_connection(tcp_c, connections_number);
if (!con_to) {
return 0;
@@ -1260,19 +1285,19 @@ unsigned int tcp_connection_to_online_tcp_relays(TCP_Connections *tcp_c, int con
return online_tcp_connection_from_conn(con_to);
}
-/* Copy a maximum of max_num TCP relays we are connected to to tcp_relays.
+/** Copy a maximum of max_num TCP relays we are connected to to tcp_relays.
* NOTE that the family of the copied ip ports will be set to TCP_INET or TCP_INET6.
*
* return number of relays copied to tcp_relays on success.
* return 0 on failure.
*/
-uint32_t tcp_copy_connected_relays(TCP_Connections *tcp_c, Node_format *tcp_relays, uint16_t max_num)
+uint32_t tcp_copy_connected_relays(const TCP_Connections *tcp_c, Node_format *tcp_relays, uint16_t max_num)
{
const uint32_t r = random_u32();
uint32_t copied = 0;
for (uint32_t i = 0; (i < tcp_c->tcp_connections_length) && (copied < max_num); ++i) {
- TCP_con *tcp_con = get_tcp_connection(tcp_c, (i + r) % tcp_c->tcp_connections_length);
+ const TCP_con *tcp_con = get_tcp_connection(tcp_c, (i + r) % tcp_c->tcp_connections_length);
if (!tcp_con) {
continue;
@@ -1297,7 +1322,7 @@ uint32_t tcp_copy_connected_relays(TCP_Connections *tcp_c, Node_format *tcp_rela
return copied;
}
-/* Set if we want TCP_connection to allocate some connection for onion use.
+/** Set if we want TCP_connection to allocate some connection for onion use.
*
* If status is 1, allocate some connections. if status is 0, don't.
*
@@ -1363,14 +1388,15 @@ int set_tcp_onion_status(TCP_Connections *tcp_c, bool status)
return 0;
}
-/* Returns a new TCP_Connections object associated with the secret_key.
+/** Returns a new TCP_Connections object associated with the secret_key.
*
* In order for others to connect to this instance new_tcp_connection_to() must be called with the
* public_key associated with secret_key.
*
* Returns NULL on failure.
*/
-TCP_Connections *new_tcp_connections(Mono_Time *mono_time, const uint8_t *secret_key, TCP_Proxy_Info *proxy_info)
+TCP_Connections *new_tcp_connections(const Logger *logger, Mono_Time *mono_time, const uint8_t *secret_key,
+ const TCP_Proxy_Info *proxy_info)
{
if (secret_key == nullptr) {
return nullptr;
@@ -1382,6 +1408,7 @@ TCP_Connections *new_tcp_connections(Mono_Time *mono_time, const uint8_t *secret
return nullptr;
}
+ temp->logger = logger;
temp->mono_time = mono_time;
memcpy(temp->self_secret_key, secret_key, CRYPTO_SECRET_KEY_SIZE);
@@ -1423,7 +1450,8 @@ static void do_tcp_conns(const Logger *logger, TCP_Connections *tcp_c, void *use
tcp_relay_on_online(tcp_c, i);
}
- if (tcp_con->status == TCP_CONN_CONNECTED && !tcp_con->onion && tcp_con->lock_count
+ if (tcp_con->status == TCP_CONN_CONNECTED
+ && !tcp_con->onion && tcp_con->lock_count
&& tcp_con->lock_count == tcp_con->sleep_count
&& mono_time_is_timeout(tcp_c->mono_time, tcp_con->connected_time, TCP_CONNECTION_ANNOUNCE_TIMEOUT)) {
sleep_tcp_relay_connection(tcp_c, i);
@@ -1438,42 +1466,36 @@ static void do_tcp_conns(const Logger *logger, TCP_Connections *tcp_c, void *use
static void kill_nonused_tcp(TCP_Connections *tcp_c)
{
- if (tcp_c->tcp_connections_length == 0) {
+ if (tcp_c->tcp_connections_length <= RECOMMENDED_FRIEND_TCP_CONNECTIONS) {
return;
}
- uint32_t num_online = 0;
- uint32_t num_kill = 0;
- VLA(unsigned int, to_kill, tcp_c->tcp_connections_length);
-
- for (uint32_t i = 0; i < tcp_c->tcp_connections_length; ++i) {
- TCP_con *tcp_con = get_tcp_connection(tcp_c, i);
-
- if (tcp_con) {
- if (tcp_con->status == TCP_CONN_CONNECTED) {
- if (!tcp_con->onion && !tcp_con->lock_count
- && mono_time_is_timeout(tcp_c->mono_time, tcp_con->connected_time, TCP_CONNECTION_ANNOUNCE_TIMEOUT)) {
- to_kill[num_kill] = i;
- ++num_kill;
- }
-
- ++num_online;
- }
- }
- }
+ const uint32_t num_online = tcp_connected_relays_count(tcp_c);
if (num_online <= RECOMMENDED_FRIEND_TCP_CONNECTIONS) {
return;
}
- uint32_t n = num_online - RECOMMENDED_FRIEND_TCP_CONNECTIONS;
+ const uint32_t max_kill_count = num_online - RECOMMENDED_FRIEND_TCP_CONNECTIONS;
+ uint32_t kill_count = 0;
- if (n < num_kill) {
- num_kill = n;
- }
+ for (uint32_t i = 0; i < tcp_c->tcp_connections_length && kill_count < max_kill_count; ++i) {
+ const TCP_con *tcp_con = get_tcp_connection(tcp_c, i);
+
+ if (tcp_con == nullptr) {
+ continue;
+ }
+
+ if (tcp_con->status == TCP_CONN_CONNECTED) {
+ if (tcp_con->onion || tcp_con->lock_count) { // connection is in use so we skip it
+ continue;
+ }
- for (uint32_t i = 0; i < num_kill; ++i) {
- kill_tcp_relay_connection(tcp_c, to_kill[i]);
+ if (mono_time_is_timeout(tcp_c->mono_time, tcp_con->connected_time, TCP_CONNECTION_ANNOUNCE_TIMEOUT)) {
+ kill_tcp_relay_connection(tcp_c, i);
+ ++kill_count;
+ }
+ }
}
}
@@ -1489,6 +1511,8 @@ void kill_tcp_connections(TCP_Connections *tcp_c)
kill_TCP_connection(tcp_c->tcp_connections[i].connection);
}
+ crypto_memzero(tcp_c->self_secret_key, sizeof(tcp_c->self_secret_key));
+
free(tcp_c->tcp_connections);
free(tcp_c->connections);
free(tcp_c);
diff --git a/protocols/Tox/libtox/src/toxcore/TCP_connection.h b/protocols/Tox/libtox/src/toxcore/TCP_connection.h
index 0ae3304541..84890b98d7 100644
--- a/protocols/Tox/libtox/src/toxcore/TCP_connection.h
+++ b/protocols/Tox/libtox/src/toxcore/TCP_connection.h
@@ -3,21 +3,25 @@
* Copyright © 2015 Tox project.
*/
-/*
+/**
* Handles TCP relay connections between two Tox clients.
*/
#ifndef C_TOXCORE_TOXCORE_TCP_CONNECTION_H
#define C_TOXCORE_TOXCORE_TCP_CONNECTION_H
+#include "DHT.h" // for Node_format
#include "TCP_client.h"
+#include "TCP_common.h"
+
+#include <stdbool.h>
#define TCP_CONN_NONE 0
#define TCP_CONN_VALID 1
-/* NOTE: only used by TCP_con */
+/** NOTE: only used by TCP_con */
#define TCP_CONN_CONNECTED 2
-/* Connection is not connected but can be quickly reconnected in case it is needed. */
+/** Connection is not connected but can be quickly reconnected in case it is needed. */
#define TCP_CONN_SLEEPING 3
#define TCP_CONNECTIONS_STATUS_NONE 0
@@ -26,20 +30,20 @@
#define MAX_FRIEND_TCP_CONNECTIONS 6
-/* Time until connection to friend gets killed (if it doesn't get locked within that time) */
+/** Time until connection to friend gets killed (if it doesn't get locked within that time) */
#define TCP_CONNECTION_ANNOUNCE_TIMEOUT TCP_CONNECTION_TIMEOUT
-/* The amount of recommended connections for each friend
+/** The amount of recommended connections for each friend
* NOTE: Must be at most (MAX_FRIEND_TCP_CONNECTIONS / 2) */
#define RECOMMENDED_FRIEND_TCP_CONNECTIONS (MAX_FRIEND_TCP_CONNECTIONS / 2)
-/* Number of TCP connections used for onion purposes. */
+/** Number of TCP connections used for onion purposes. */
#define NUM_ONION_TCP_CONNECTIONS RECOMMENDED_FRIEND_TCP_CONNECTIONS
typedef struct TCP_Conn_to {
uint32_t tcp_connection;
- unsigned int status;
- unsigned int connection_id;
+ uint8_t status;
+ uint8_t connection_id;
} TCP_Conn_to;
typedef struct TCP_Connection_to {
@@ -69,14 +73,20 @@ typedef struct TCP_Connections TCP_Connections;
const uint8_t *tcp_connections_public_key(const TCP_Connections *tcp_c);
-/* Send a packet to the TCP connection.
+uint32_t tcp_connections_count(const TCP_Connections *tcp_c);
+
+/** Returns the number of connected TCP relays */
+uint32_t tcp_connected_relays_count(const TCP_Connections *tcp_c);
+
+/** Send a packet to the TCP connection.
*
* return -1 on failure.
* return 0 on success.
*/
-int send_packet_tcp_connection(TCP_Connections *tcp_c, int connections_number, const uint8_t *packet, uint16_t length);
+int send_packet_tcp_connection(const TCP_Connections *tcp_c, int connections_number, const uint8_t *packet,
+ uint16_t length);
-/* Return a random TCP connection number for use in send_tcp_onion_request.
+/** Return a random TCP connection number for use in send_tcp_onion_request.
*
* TODO(irungentoo): This number is just the index of an array that the elements
* can change without warning.
@@ -84,9 +94,9 @@ int send_packet_tcp_connection(TCP_Connections *tcp_c, int connections_number, c
* return TCP connection number on success.
* return -1 on failure.
*/
-int get_random_tcp_onion_conn_number(TCP_Connections *tcp_c);
+int get_random_tcp_onion_conn_number(const TCP_Connections *tcp_c);
-/* Send an onion packet via the TCP relay corresponding to tcp_connections_number.
+/** Send an onion packet via the TCP relay corresponding to tcp_connections_number.
*
* return 0 on success.
* return -1 on failure.
@@ -94,7 +104,7 @@ int get_random_tcp_onion_conn_number(TCP_Connections *tcp_c);
int tcp_send_onion_request(TCP_Connections *tcp_c, unsigned int tcp_connections_number, const uint8_t *data,
uint16_t length);
-/* Set if we want TCP_connection to allocate some connection for onion use.
+/** Set if we want TCP_connection to allocate some connection for onion use.
*
* If status is 1, allocate some connections. if status is 0, don't.
*
@@ -103,34 +113,37 @@ int tcp_send_onion_request(TCP_Connections *tcp_c, unsigned int tcp_connections_
*/
int set_tcp_onion_status(TCP_Connections *tcp_c, bool status);
-/* Send an oob packet via the TCP relay corresponding to tcp_connections_number.
+/** Send an oob packet via the TCP relay corresponding to tcp_connections_number.
*
* return 0 on success.
* return -1 on failure.
*/
-int tcp_send_oob_packet(TCP_Connections *tcp_c, unsigned int tcp_connections_number, const uint8_t *public_key,
+int tcp_send_oob_packet(const TCP_Connections *tcp_c, unsigned int tcp_connections_number, const uint8_t *public_key,
const uint8_t *packet, uint16_t length);
typedef int tcp_data_cb(void *object, int id, const uint8_t *data, uint16_t length, void *userdata);
-/* Set the callback for TCP data packets.
+int tcp_send_oob_packet_using_relay(const TCP_Connections *tcp_c, const uint8_t *relay_pk, const uint8_t *public_key,
+ const uint8_t *packet, uint16_t length);
+
+/** Set the callback for TCP data packets.
*/
void set_packet_tcp_connection_callback(TCP_Connections *tcp_c, tcp_data_cb *tcp_data_callback, void *object);
typedef int tcp_onion_cb(void *object, const uint8_t *data, uint16_t length, void *userdata);
-/* Set the callback for TCP onion packets.
+/** Set the callback for TCP onion packets.
*/
void set_onion_packet_tcp_connection_callback(TCP_Connections *tcp_c, tcp_onion_cb *tcp_onion_callback, void *object);
typedef int tcp_oob_cb(void *object, const uint8_t *public_key, unsigned int tcp_connections_number,
const uint8_t *data, uint16_t length, void *userdata);
-/* Set the callback for TCP oob data packets.
+/** Set the callback for TCP oob data packets.
*/
void set_oob_packet_tcp_connection_callback(TCP_Connections *tcp_c, tcp_oob_cb *tcp_oob_callback, void *object);
-/* Create a new TCP connection to public_key.
+/** Create a new TCP connection to public_key.
*
* public_key must be the counterpart to the secret key that the other peer used with new_tcp_connections().
*
@@ -141,12 +154,12 @@ void set_oob_packet_tcp_connection_callback(TCP_Connections *tcp_c, tcp_oob_cb *
*/
int new_tcp_connection_to(TCP_Connections *tcp_c, const uint8_t *public_key, int id);
-/* return 0 on success.
+/** return 0 on success.
* return -1 on failure.
*/
int kill_tcp_connection_to(TCP_Connections *tcp_c, int connections_number);
-/* Set connection status.
+/** Set connection status.
*
* status of 1 means we are using the connection.
* status of 0 means we are not using it.
@@ -156,59 +169,61 @@ int kill_tcp_connection_to(TCP_Connections *tcp_c, int connections_number);
* return 0 on success.
* return -1 on failure.
*/
-int set_tcp_connection_to_status(TCP_Connections *tcp_c, int connections_number, bool status);
+int set_tcp_connection_to_status(const TCP_Connections *tcp_c, int connections_number, bool status);
-/* return number of online tcp relays tied to the connection on success.
+/** return number of online tcp relays tied to the connection on success.
* return 0 on failure.
*/
-unsigned int tcp_connection_to_online_tcp_relays(TCP_Connections *tcp_c, int connections_number);
+unsigned int tcp_connection_to_online_tcp_relays(const TCP_Connections *tcp_c, int connections_number);
-/* Add a TCP relay tied to a connection.
+/** Add a TCP relay tied to a connection.
*
* NOTE: This can only be used during the tcp_oob_callback.
*
* return 0 on success.
* return -1 on failure.
*/
-int add_tcp_number_relay_connection(TCP_Connections *tcp_c, int connections_number,
+int add_tcp_number_relay_connection(const TCP_Connections *tcp_c, int connections_number,
unsigned int tcp_connections_number);
-/* Add a TCP relay tied to a connection.
+/** Add a TCP relay tied to a connection.
*
* This should be called with the same relay by two peers who want to create a TCP connection with each other.
*
* return 0 on success.
* return -1 on failure.
*/
-int add_tcp_relay_connection(TCP_Connections *tcp_c, int connections_number, IP_Port ip_port, const uint8_t *relay_pk);
+int add_tcp_relay_connection(TCP_Connections *tcp_c, int connections_number, const IP_Port *ip_port,
+ const uint8_t *relay_pk);
-/* Add a TCP relay to the instance.
+/** Add a TCP relay to the TCP_Connections instance.
*
* return 0 on success.
* return -1 on failure.
*/
-int add_tcp_relay_global(TCP_Connections *tcp_c, IP_Port ip_port, const uint8_t *relay_pk);
+int add_tcp_relay_global(TCP_Connections *tcp_c, const IP_Port *ip_port, const uint8_t *relay_pk);
-/* Copy a maximum of max_num TCP relays we are connected to to tcp_relays.
+/** Copy a maximum of max_num TCP relays we are connected to to tcp_relays.
* NOTE that the family of the copied ip ports will be set to TCP_INET or TCP_INET6.
*
* return number of relays copied to tcp_relays on success.
* return 0 on failure.
*/
-uint32_t tcp_copy_connected_relays(TCP_Connections *tcp_c, Node_format *tcp_relays, uint16_t max_num);
+uint32_t tcp_copy_connected_relays(const TCP_Connections *tcp_c, Node_format *tcp_relays, uint16_t max_num);
-/* Returns a new TCP_Connections object associated with the secret_key.
+/** Returns a new TCP_Connections object associated with the secret_key.
*
* In order for others to connect to this instance new_tcp_connection_to() must be called with the
* public_key associated with secret_key.
*
* Returns NULL on failure.
*/
-TCP_Connections *new_tcp_connections(Mono_Time *mono_time, const uint8_t *secret_key, TCP_Proxy_Info *proxy_info);
+TCP_Connections *new_tcp_connections(const Logger *logger, Mono_Time *mono_time, const uint8_t *secret_key,
+ const TCP_Proxy_Info *proxy_info);
-void do_tcp_connections(const Logger *logger, TCP_Connections *tcp_c, void *userdata);
+int kill_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connections_number);
+void do_tcp_connections(const Logger *logger, TCP_Connections *tcp_c, void *userdata);
void kill_tcp_connections(TCP_Connections *tcp_c);
#endif
-
diff --git a/protocols/Tox/libtox/src/toxcore/TCP_server.c b/protocols/Tox/libtox/src/toxcore/TCP_server.c
index 79a9e560c3..4f7fe12121 100644
--- a/protocols/Tox/libtox/src/toxcore/TCP_server.c
+++ b/protocols/Tox/libtox/src/toxcore/TCP_server.c
@@ -3,13 +3,9 @@
* Copyright © 2014 Tox project.
*/
-/*
+/**
* Implementation of the TCP relay server part of Tox.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include "TCP_server.h"
#include <stdlib.h>
@@ -23,6 +19,8 @@
#include <unistd.h>
#endif
+#include "TCP_common.h"
+#include "list.h"
#include "mono_time.h"
#include "util.h"
@@ -42,20 +40,13 @@ typedef struct TCP_Secure_Conn {
} TCP_Secure_Conn;
typedef struct TCP_Secure_Connection {
- Socket sock;
+ TCP_Connection con;
+
uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE];
uint8_t recv_nonce[CRYPTO_NONCE_SIZE]; /* Nonce of received packets. */
- uint8_t sent_nonce[CRYPTO_NONCE_SIZE]; /* Nonce of sent packets. */
- uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE];
uint16_t next_packet_length;
TCP_Secure_Conn connections[NUM_CLIENT_CONNECTIONS];
- uint8_t last_packet[2 + MAX_PACKET_SIZE];
uint8_t status;
- uint16_t last_packet_length;
- uint16_t last_packet_sent;
-
- TCP_Priority_List *priority_queue_start;
- TCP_Priority_List *priority_queue_end;
uint64_t identifier;
@@ -101,7 +92,7 @@ size_t tcp_server_listen_count(const TCP_Server *tcp_server)
return tcp_server->num_listening_socks;
}
-/* This is needed to compile on Android below API 21
+/** This is needed to compile on Android below API 21
*/
#ifdef TCP_SERVER_USE_EPOLL
#ifndef EPOLLRDHUP
@@ -109,7 +100,7 @@ size_t tcp_server_listen_count(const TCP_Server *tcp_server)
#endif
#endif
-/* Increase the size of the connection list
+/** Increase the size of the connection list
*
* return -1 on failure
* return 0 on success.
@@ -139,26 +130,17 @@ static int alloc_new_connections(TCP_Server *tcp_server, uint32_t num)
return 0;
}
-void wipe_priority_list(TCP_Priority_List *p)
-{
- while (p) {
- TCP_Priority_List *pp = p;
- p = p->next;
- free(pp);
- }
-}
-
static void wipe_secure_connection(TCP_Secure_Connection *con)
{
if (con->status) {
- wipe_priority_list(con->priority_queue_start);
+ wipe_priority_list(con->con.priority_queue_start);
crypto_memzero(con, sizeof(TCP_Secure_Connection));
}
}
static void move_secure_connection(TCP_Secure_Connection *con_new, TCP_Secure_Connection *con_old)
{
- memcpy(con_new, con_old, sizeof(TCP_Secure_Connection));
+ *con_new = *con_old;
crypto_memzero(con_old, sizeof(TCP_Secure_Connection));
}
@@ -177,7 +159,7 @@ static void free_accepted_connection_array(TCP_Server *tcp_server)
tcp_server->size_accepted_connections = 0;
}
-/* return index corresponding to connection with peer on success
+/** return index corresponding to connection with peer on success
* return -1 on failure.
*/
static int get_TCP_connection_index(const TCP_Server *tcp_server, const uint8_t *public_key)
@@ -188,7 +170,7 @@ static int get_TCP_connection_index(const TCP_Server *tcp_server, const uint8_t
static int kill_accepted(TCP_Server *tcp_server, int index);
-/* Add accepted TCP connection to the list.
+/** Add accepted TCP connection to the list.
*
* return index on success
* return -1 on failure
@@ -209,9 +191,7 @@ static int add_accepted(TCP_Server *tcp_server, const Mono_Time *mono_time, TCP_
index = tcp_server->num_accepted_connections;
} else {
- uint32_t i;
-
- for (i = tcp_server->size_accepted_connections; i != 0; --i) {
+ for (uint32_t i = tcp_server->size_accepted_connections; i != 0; --i) {
if (tcp_server->accepted_connection_array[i - 1].status == TCP_STATUS_NO_STATUS) {
index = i - 1;
break;
@@ -239,7 +219,7 @@ static int add_accepted(TCP_Server *tcp_server, const Mono_Time *mono_time, TCP_
return index;
}
-/* Delete accepted connection from list.
+/** Delete accepted connection from list.
*
* return 0 on success
* return -1 on failure
@@ -268,274 +248,17 @@ static int del_accepted(TCP_Server *tcp_server, int index)
return 0;
}
-/* Read the next two bytes in TCP stream then convert them to
- * length (host byte order).
- *
- * return length on success
- * return 0 if nothing has been read from socket.
- * return -1 on failure.
- */
-uint16_t read_TCP_length(const Logger *logger, Socket sock)
-{
- const unsigned int count = net_socket_data_recv_buffer(sock);
-
- if (count >= sizeof(uint16_t)) {
- uint16_t length;
- const int len = net_recv(sock, &length, sizeof(uint16_t));
-
- if (len != sizeof(uint16_t)) {
- LOGGER_ERROR(logger, "FAIL recv packet");
- return 0;
- }
-
- length = net_ntohs(length);
-
- if (length > MAX_PACKET_SIZE) {
- return -1;
- }
-
- return length;
- }
-
- return 0;
-}
-
-/* Read length bytes from socket.
- *
- * return length on success
- * return -1 on failure/no data in buffer.
- */
-int read_TCP_packet(const Logger *logger, Socket sock, uint8_t *data, uint16_t length)
-{
- unsigned int count = net_socket_data_recv_buffer(sock);
-
- if (count >= length) {
- const int len = net_recv(sock, data, length);
-
- if (len != length) {
- LOGGER_ERROR(logger, "FAIL recv packet");
- return -1;
- }
-
- return len;
- }
-
- return -1;
-}
-
-/* return length of received packet on success.
- * return 0 if could not read any packet.
- * return -1 on failure (connection must be killed).
- */
-int read_packet_TCP_secure_connection(const Logger *logger, Socket sock, uint16_t *next_packet_length,
- const uint8_t *shared_key, uint8_t *recv_nonce, uint8_t *data, uint16_t max_len)
-{
- if (*next_packet_length == 0) {
- uint16_t len = read_TCP_length(logger, sock);
-
- if (len == (uint16_t) -1) {
- return -1;
- }
-
- if (len == 0) {
- return 0;
- }
-
- *next_packet_length = len;
- }
-
- if (max_len + CRYPTO_MAC_SIZE < *next_packet_length) {
- return -1;
- }
-
- VLA(uint8_t, data_encrypted, *next_packet_length);
- int len_packet = read_TCP_packet(logger, sock, data_encrypted, *next_packet_length);
-
- if (len_packet != *next_packet_length) {
- return 0;
- }
-
- *next_packet_length = 0;
-
- int len = decrypt_data_symmetric(shared_key, recv_nonce, data_encrypted, len_packet, data);
-
- if (len + CRYPTO_MAC_SIZE != len_packet) {
- return -1;
- }
-
- increment_nonce(recv_nonce);
-
- return len;
-}
-
-/* return 0 if pending data was sent completely
- * return -1 if it wasn't
- */
-static int send_pending_data_nonpriority(TCP_Secure_Connection *con)
-{
- if (con->last_packet_length == 0) {
- return 0;
- }
-
- const uint16_t left = con->last_packet_length - con->last_packet_sent;
- const int len = net_send(con->sock, con->last_packet + con->last_packet_sent, left);
-
- if (len <= 0) {
- return -1;
- }
-
- if (len == left) {
- con->last_packet_length = 0;
- con->last_packet_sent = 0;
- return 0;
- }
-
- con->last_packet_sent += len;
- return -1;
-}
-
-/* return 0 if pending data was sent completely
- * return -1 if it wasn't
- */
-static int send_pending_data(TCP_Secure_Connection *con)
-{
- /* finish sending current non-priority packet */
- if (send_pending_data_nonpriority(con) == -1) {
- return -1;
- }
-
- TCP_Priority_List *p = con->priority_queue_start;
-
- while (p) {
- const uint16_t left = p->size - p->sent;
- const int len = net_send(con->sock, p->data + p->sent, left);
-
- if (len != left) {
- if (len > 0) {
- p->sent += len;
- }
-
- break;
- }
-
- TCP_Priority_List *pp = p;
- p = p->next;
- free(pp);
- }
-
- con->priority_queue_start = p;
-
- if (!p) {
- con->priority_queue_end = nullptr;
- return 0;
- }
-
- return -1;
-}
-
-/* return 0 on failure (only if malloc fails)
- * return 1 on success
- */
-static bool add_priority(TCP_Secure_Connection *con, const uint8_t *packet, uint16_t size, uint16_t sent)
-{
- TCP_Priority_List *p = con->priority_queue_end;
- TCP_Priority_List *new_list = (TCP_Priority_List *)malloc(sizeof(TCP_Priority_List) + size);
-
- if (!new_list) {
- return 0;
- }
-
- new_list->next = nullptr;
- new_list->size = size;
- new_list->sent = sent;
- memcpy(new_list->data, packet, size);
-
- if (p) {
- p->next = new_list;
- } else {
- con->priority_queue_start = new_list;
- }
-
- con->priority_queue_end = new_list;
- return 1;
-}
-
-/* return 1 on success.
- * return 0 if could not send packet.
- * return -1 on failure (connection must be killed).
- */
-static int write_packet_TCP_secure_connection(TCP_Secure_Connection *con, const uint8_t *data, uint16_t length,
- bool priority)
-{
- if (length + CRYPTO_MAC_SIZE > MAX_PACKET_SIZE) {
- return -1;
- }
-
- bool sendpriority = 1;
-
- if (send_pending_data(con) == -1) {
- if (priority) {
- sendpriority = 0;
- } else {
- return 0;
- }
- }
-
- VLA(uint8_t, packet, sizeof(uint16_t) + length + CRYPTO_MAC_SIZE);
-
- const uint16_t c_length = net_htons(length + CRYPTO_MAC_SIZE);
- memcpy(packet, &c_length, sizeof(uint16_t));
- int len = encrypt_data_symmetric(con->shared_key, con->sent_nonce, data, length, packet + sizeof(uint16_t));
-
- if ((unsigned int)len != (SIZEOF_VLA(packet) - sizeof(uint16_t))) {
- return -1;
- }
-
- if (priority) {
- len = sendpriority ? net_send(con->sock, packet, SIZEOF_VLA(packet)) : 0;
-
- if (len <= 0) {
- len = 0;
- }
-
- increment_nonce(con->sent_nonce);
-
- if ((unsigned int)len == SIZEOF_VLA(packet)) {
- return 1;
- }
-
- return add_priority(con, packet, SIZEOF_VLA(packet), len);
- }
-
- len = net_send(con->sock, packet, SIZEOF_VLA(packet));
-
- if (len <= 0) {
- return 0;
- }
-
- increment_nonce(con->sent_nonce);
-
- if ((unsigned int)len == SIZEOF_VLA(packet)) {
- return 1;
- }
-
- memcpy(con->last_packet, packet, SIZEOF_VLA(packet));
- con->last_packet_length = SIZEOF_VLA(packet);
- con->last_packet_sent = len;
- return 1;
-}
-
-/* Kill a TCP_Secure_Connection
+/** Kill a TCP_Secure_Connection
*/
static void kill_TCP_secure_connection(TCP_Secure_Connection *con)
{
- kill_sock(con->sock);
+ kill_sock(con->con.sock);
wipe_secure_connection(con);
}
static int rm_connection_index(TCP_Server *tcp_server, TCP_Secure_Connection *con, uint8_t con_number);
-/* Kill an accepted TCP_Secure_Connection
+/** Kill an accepted TCP_Secure_Connection
*
* return -1 on failure.
* return 0 on success.
@@ -546,13 +269,11 @@ static int kill_accepted(TCP_Server *tcp_server, int index)
return -1;
}
- uint32_t i;
-
- for (i = 0; i < NUM_CLIENT_CONNECTIONS; ++i) {
+ for (uint32_t i = 0; i < NUM_CLIENT_CONNECTIONS; ++i) {
rm_connection_index(tcp_server, &tcp_server->accepted_connection_array[index], i);
}
- Socket sock = tcp_server->accepted_connection_array[index].sock;
+ Socket sock = tcp_server->accepted_connection_array[index].con.sock;
if (del_accepted(tcp_server, index) != 0) {
return -1;
@@ -562,17 +283,19 @@ static int kill_accepted(TCP_Server *tcp_server, int index)
return 0;
}
-/* return 1 if everything went well.
+/** return 1 if everything went well.
* return -1 if the connection must be killed.
*/
-static int handle_TCP_handshake(TCP_Secure_Connection *con, const uint8_t *data, uint16_t length,
+static int handle_TCP_handshake(const Logger *logger, TCP_Secure_Connection *con, const uint8_t *data, uint16_t length,
const uint8_t *self_secret_key)
{
if (length != TCP_CLIENT_HANDSHAKE_SIZE) {
+ LOGGER_WARNING(logger, "invalid handshake length: %d != %d", length, TCP_CLIENT_HANDSHAKE_SIZE);
return -1;
}
if (con->status != TCP_STATUS_CONNECTED) {
+ LOGGER_WARNING(logger, "TCP connection %u not connected", (unsigned int)con->identifier);
return -1;
}
@@ -583,6 +306,8 @@ static int handle_TCP_handshake(TCP_Secure_Connection *con, const uint8_t *data,
data + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, TCP_HANDSHAKE_PLAIN_SIZE + CRYPTO_MAC_SIZE, plain);
if (len != TCP_HANDSHAKE_PLAIN_SIZE) {
+ LOGGER_WARNING(logger, "invalid TCP handshake decrypted length: %d != %d", len, TCP_HANDSHAKE_PLAIN_SIZE);
+ crypto_memzero(shared_key, sizeof(shared_key));
return -1;
}
@@ -590,8 +315,8 @@ static int handle_TCP_handshake(TCP_Secure_Connection *con, const uint8_t *data,
uint8_t temp_secret_key[CRYPTO_SECRET_KEY_SIZE];
uint8_t resp_plain[TCP_HANDSHAKE_PLAIN_SIZE];
crypto_new_keypair(resp_plain, temp_secret_key);
- random_nonce(con->sent_nonce);
- memcpy(resp_plain + CRYPTO_PUBLIC_KEY_SIZE, con->sent_nonce, CRYPTO_NONCE_SIZE);
+ random_nonce(con->con.sent_nonce);
+ memcpy(resp_plain + CRYPTO_PUBLIC_KEY_SIZE, con->con.sent_nonce, CRYPTO_NONCE_SIZE);
memcpy(con->recv_nonce, plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_NONCE_SIZE);
uint8_t response[TCP_SERVER_HANDSHAKE_SIZE];
@@ -601,90 +326,98 @@ static int handle_TCP_handshake(TCP_Secure_Connection *con, const uint8_t *data,
response + CRYPTO_NONCE_SIZE);
if (len != TCP_HANDSHAKE_PLAIN_SIZE + CRYPTO_MAC_SIZE) {
+ crypto_memzero(shared_key, sizeof(shared_key));
return -1;
}
- if (TCP_SERVER_HANDSHAKE_SIZE != net_send(con->sock, response, TCP_SERVER_HANDSHAKE_SIZE)) {
+ IP_Port ipp = {0};
+
+ if (TCP_SERVER_HANDSHAKE_SIZE != net_send(logger, con->con.sock, response, TCP_SERVER_HANDSHAKE_SIZE, &ipp)) {
+ crypto_memzero(shared_key, sizeof(shared_key));
return -1;
}
- encrypt_precompute(plain, temp_secret_key, con->shared_key);
+ encrypt_precompute(plain, temp_secret_key, con->con.shared_key);
con->status = TCP_STATUS_UNCONFIRMED;
+
+ crypto_memzero(shared_key, sizeof(shared_key));
+
return 1;
}
-/* return 1 if connection handshake was handled correctly.
+/** return 1 if connection handshake was handled correctly.
* return 0 if we didn't get it yet.
* return -1 if the connection must be killed.
*/
static int read_connection_handshake(const Logger *logger, TCP_Secure_Connection *con, const uint8_t *self_secret_key)
{
uint8_t data[TCP_CLIENT_HANDSHAKE_SIZE];
- const int len = read_TCP_packet(logger, con->sock, data, TCP_CLIENT_HANDSHAKE_SIZE);
+ const int len = read_TCP_packet(logger, con->con.sock, data, TCP_CLIENT_HANDSHAKE_SIZE, &con->con.ip_port);
- if (len != -1) {
- return handle_TCP_handshake(con, data, len, self_secret_key);
+ if (len == -1) {
+ LOGGER_TRACE(logger, "connection handshake is not ready yet");
+ return 0;
}
- return 0;
+ return handle_TCP_handshake(logger, con, data, len, self_secret_key);
}
-/* return 1 on success.
+/** return 1 on success.
* return 0 if could not send packet.
* return -1 on failure (connection must be killed).
*/
-static int send_routing_response(TCP_Secure_Connection *con, uint8_t rpid, const uint8_t *public_key)
+static int send_routing_response(const Logger *logger, TCP_Secure_Connection *con, uint8_t rpid,
+ const uint8_t *public_key)
{
uint8_t data[1 + 1 + CRYPTO_PUBLIC_KEY_SIZE];
data[0] = TCP_PACKET_ROUTING_RESPONSE;
data[1] = rpid;
memcpy(data + 2, public_key, CRYPTO_PUBLIC_KEY_SIZE);
- return write_packet_TCP_secure_connection(con, data, sizeof(data), 1);
+ return write_packet_TCP_secure_connection(logger, &con->con, data, sizeof(data), 1);
}
-/* return 1 on success.
+/** return 1 on success.
* return 0 if could not send packet.
* return -1 on failure (connection must be killed).
*/
-static int send_connect_notification(TCP_Secure_Connection *con, uint8_t id)
+static int send_connect_notification(const Logger *logger, TCP_Secure_Connection *con, uint8_t id)
{
uint8_t data[2] = {TCP_PACKET_CONNECTION_NOTIFICATION, (uint8_t)(id + NUM_RESERVED_PORTS)};
- return write_packet_TCP_secure_connection(con, data, sizeof(data), 1);
+ return write_packet_TCP_secure_connection(logger, &con->con, data, sizeof(data), 1);
}
-/* return 1 on success.
+/** return 1 on success.
* return 0 if could not send packet.
* return -1 on failure (connection must be killed).
*/
-static int send_disconnect_notification(TCP_Secure_Connection *con, uint8_t id)
+static int send_disconnect_notification(const Logger *logger, TCP_Secure_Connection *con, uint8_t id)
{
uint8_t data[2] = {TCP_PACKET_DISCONNECT_NOTIFICATION, (uint8_t)(id + NUM_RESERVED_PORTS)};
- return write_packet_TCP_secure_connection(con, data, sizeof(data), 1);
+ return write_packet_TCP_secure_connection(logger, &con->con, data, sizeof(data), 1);
}
-/* return 0 on success.
+/** return 0 on success.
* return -1 on failure (connection must be killed).
*/
static int handle_TCP_routing_req(TCP_Server *tcp_server, uint32_t con_id, const uint8_t *public_key)
{
- uint32_t i;
uint32_t index = -1;
TCP_Secure_Connection *con = &tcp_server->accepted_connection_array[con_id];
/* If person tries to cennect to himself we deny the request*/
if (public_key_cmp(con->public_key, public_key) == 0) {
- if (send_routing_response(con, 0, public_key) == -1) {
+ if (send_routing_response(tcp_server->logger, con, 0, public_key) == -1) {
return -1;
}
return 0;
}
- for (i = 0; i < NUM_CLIENT_CONNECTIONS; ++i) {
+ for (uint32_t i = 0; i < NUM_CLIENT_CONNECTIONS; ++i) {
if (con->connections[i].status != 0) {
if (public_key_cmp(public_key, con->connections[i].public_key) == 0) {
- if (send_routing_response(con, i + NUM_RESERVED_PORTS, public_key) == -1) {
+ if (send_routing_response(tcp_server->logger, con, i + NUM_RESERVED_PORTS, public_key) == -1) {
return -1;
}
@@ -696,14 +429,14 @@ static int handle_TCP_routing_req(TCP_Server *tcp_server, uint32_t con_id, const
}
if (index == (uint32_t) -1) {
- if (send_routing_response(con, 0, public_key) == -1) {
+ if (send_routing_response(tcp_server->logger, con, 0, public_key) == -1) {
return -1;
}
return 0;
}
- int ret = send_routing_response(con, index + NUM_RESERVED_PORTS, public_key);
+ int ret = send_routing_response(tcp_server->logger, con, index + NUM_RESERVED_PORTS, public_key);
if (ret == 0) {
return 0;
@@ -721,7 +454,7 @@ static int handle_TCP_routing_req(TCP_Server *tcp_server, uint32_t con_id, const
uint32_t other_id = -1;
TCP_Secure_Connection *other_conn = &tcp_server->accepted_connection_array[other_index];
- for (i = 0; i < NUM_CLIENT_CONNECTIONS; ++i) {
+ for (uint32_t i = 0; i < NUM_CLIENT_CONNECTIONS; ++i) {
if (other_conn->connections[i].status == 1
&& public_key_cmp(other_conn->connections[i].public_key, con->public_key) == 0) {
other_id = i;
@@ -737,15 +470,15 @@ static int handle_TCP_routing_req(TCP_Server *tcp_server, uint32_t con_id, const
other_conn->connections[other_id].index = con_id;
other_conn->connections[other_id].other_id = index;
// TODO(irungentoo): return values?
- send_connect_notification(con, index);
- send_connect_notification(other_conn, other_id);
+ send_connect_notification(tcp_server->logger, con, index);
+ send_connect_notification(tcp_server->logger, other_conn, other_id);
}
}
return 0;
}
-/* return 0 on success.
+/** return 0 on success.
* return -1 on failure (connection must be killed).
*/
static int handle_TCP_oob_send(TCP_Server *tcp_server, uint32_t con_id, const uint8_t *public_key, const uint8_t *data,
@@ -755,7 +488,7 @@ static int handle_TCP_oob_send(TCP_Server *tcp_server, uint32_t con_id, const ui
return -1;
}
- TCP_Secure_Connection *con = &tcp_server->accepted_connection_array[con_id];
+ const TCP_Secure_Connection *con = &tcp_server->accepted_connection_array[con_id];
int other_index = get_TCP_connection_index(tcp_server, public_key);
@@ -764,14 +497,14 @@ static int handle_TCP_oob_send(TCP_Server *tcp_server, uint32_t con_id, const ui
resp_packet[0] = TCP_PACKET_OOB_RECV;
memcpy(resp_packet + 1, con->public_key, CRYPTO_PUBLIC_KEY_SIZE);
memcpy(resp_packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, data, length);
- write_packet_TCP_secure_connection(&tcp_server->accepted_connection_array[other_index], resp_packet,
- SIZEOF_VLA(resp_packet), 0);
+ write_packet_TCP_secure_connection(tcp_server->logger, &tcp_server->accepted_connection_array[other_index].con,
+ resp_packet, SIZEOF_VLA(resp_packet), 0);
}
return 0;
}
-/* Remove connection with con_number from the connections array of con.
+/** Remove connection with con_number from the connections array of con.
*
* return -1 on failure.
* return 0 on success.
@@ -783,10 +516,9 @@ static int rm_connection_index(TCP_Server *tcp_server, TCP_Secure_Connection *co
}
if (con->connections[con_number].status) {
- uint32_t index = con->connections[con_number].index;
- uint8_t other_id = con->connections[con_number].other_id;
-
if (con->connections[con_number].status == 2) {
+ const uint32_t index = con->connections[con_number].index;
+ const uint8_t other_id = con->connections[con_number].other_id;
if (index >= tcp_server->size_accepted_connections) {
return -1;
@@ -796,7 +528,7 @@ static int rm_connection_index(TCP_Server *tcp_server, TCP_Secure_Connection *co
tcp_server->accepted_connection_array[index].connections[other_id].index = 0;
tcp_server->accepted_connection_array[index].connections[other_id].status = 1;
// TODO(irungentoo): return values?
- send_disconnect_notification(&tcp_server->accepted_connection_array[index], other_id);
+ send_disconnect_notification(tcp_server->logger, &tcp_server->accepted_connection_array[index], other_id);
}
con->connections[con_number].index = 0;
@@ -808,10 +540,10 @@ static int rm_connection_index(TCP_Server *tcp_server, TCP_Secure_Connection *co
return -1;
}
-static int handle_onion_recv_1(void *object, IP_Port dest, const uint8_t *data, uint16_t length)
+static int handle_onion_recv_1(void *object, const IP_Port *dest, const uint8_t *data, uint16_t length)
{
TCP_Server *tcp_server = (TCP_Server *)object;
- uint32_t index = dest.ip.ip.v6.uint32[0];
+ uint32_t index = dest->ip.ip.v6.uint32[0];
if (index >= tcp_server->size_accepted_connections) {
return 1;
@@ -819,7 +551,7 @@ static int handle_onion_recv_1(void *object, IP_Port dest, const uint8_t *data,
TCP_Secure_Connection *con = &tcp_server->accepted_connection_array[index];
- if (con->identifier != dest.ip.ip.v6.uint64[1]) {
+ if (con->identifier != dest->ip.ip.v6.uint64[1]) {
return 1;
}
@@ -827,14 +559,14 @@ static int handle_onion_recv_1(void *object, IP_Port dest, const uint8_t *data,
memcpy(packet + 1, data, length);
packet[0] = TCP_PACKET_ONION_RESPONSE;
- if (write_packet_TCP_secure_connection(con, packet, SIZEOF_VLA(packet), 0) != 1) {
+ if (write_packet_TCP_secure_connection(tcp_server->logger, &con->con, packet, SIZEOF_VLA(packet), 0) != 1) {
return 1;
}
return 0;
}
-/* return 0 on success
+/** return 0 on success
* return -1 on failure
*/
static int handle_TCP_packet(TCP_Server *tcp_server, uint32_t con_id, const uint8_t *data, uint16_t length)
@@ -843,7 +575,7 @@ static int handle_TCP_packet(TCP_Server *tcp_server, uint32_t con_id, const uint
return -1;
}
- TCP_Secure_Connection *con = &tcp_server->accepted_connection_array[con_id];
+ TCP_Secure_Connection *const con = &tcp_server->accepted_connection_array[con_id];
switch (data[0]) {
case TCP_PACKET_ROUTING_REQUEST: {
@@ -851,6 +583,7 @@ static int handle_TCP_packet(TCP_Server *tcp_server, uint32_t con_id, const uint
return -1;
}
+ LOGGER_TRACE(tcp_server->logger, "handling routing request for %d", con_id);
return handle_TCP_routing_req(tcp_server, con_id, data + 1);
}
@@ -859,6 +592,7 @@ static int handle_TCP_packet(TCP_Server *tcp_server, uint32_t con_id, const uint
return -1;
}
+ LOGGER_TRACE(tcp_server->logger, "handling connection notification for %d", con_id);
break;
}
@@ -867,6 +601,7 @@ static int handle_TCP_packet(TCP_Server *tcp_server, uint32_t con_id, const uint
return -1;
}
+ LOGGER_TRACE(tcp_server->logger, "handling disconnect notification for %d", con_id);
return rm_connection_index(tcp_server, con, data[1] - NUM_RESERVED_PORTS);
}
@@ -875,10 +610,12 @@ static int handle_TCP_packet(TCP_Server *tcp_server, uint32_t con_id, const uint
return -1;
}
+ LOGGER_TRACE(tcp_server->logger, "handling ping for %d", con_id);
+
uint8_t response[1 + sizeof(uint64_t)];
response[0] = TCP_PACKET_PONG;
memcpy(response + 1, data + 1, sizeof(uint64_t));
- write_packet_TCP_secure_connection(con, response, sizeof(response), 1);
+ write_packet_TCP_secure_connection(tcp_server->logger, &con->con, response, sizeof(response), 1);
return 0;
}
@@ -887,6 +624,8 @@ static int handle_TCP_packet(TCP_Server *tcp_server, uint32_t con_id, const uint
return -1;
}
+ LOGGER_TRACE(tcp_server->logger, "handling pong for %d", con_id);
+
uint64_t ping_id;
memcpy(&ping_id, data + 1, sizeof(uint64_t));
@@ -906,11 +645,15 @@ static int handle_TCP_packet(TCP_Server *tcp_server, uint32_t con_id, const uint
return -1;
}
+ LOGGER_TRACE(tcp_server->logger, "handling oob send for %d", con_id);
+
return handle_TCP_oob_send(tcp_server, con_id, data + 1, data + 1 + CRYPTO_PUBLIC_KEY_SIZE,
length - (1 + CRYPTO_PUBLIC_KEY_SIZE));
}
case TCP_PACKET_ONION_REQUEST: {
+ LOGGER_TRACE(tcp_server->logger, "handling onion request for %d", con_id);
+
if (tcp_server->onion) {
if (length <= 1 + CRYPTO_NONCE_SIZE + ONION_SEND_BASE * 2) {
return -1;
@@ -922,7 +665,7 @@ static int handle_TCP_packet(TCP_Server *tcp_server, uint32_t con_id, const uint
source.ip.ip.v6.uint32[0] = con_id;
source.ip.ip.v6.uint32[1] = 0;
source.ip.ip.v6.uint64[1] = con->identifier;
- onion_send_1(tcp_server->onion, data + 1 + CRYPTO_NONCE_SIZE, length - (1 + CRYPTO_NONCE_SIZE), source,
+ onion_send_1(tcp_server->onion, data + 1 + CRYPTO_NONCE_SIZE, length - (1 + CRYPTO_NONCE_SIZE), &source,
data + 1);
}
@@ -930,6 +673,7 @@ static int handle_TCP_packet(TCP_Server *tcp_server, uint32_t con_id, const uint
}
case TCP_PACKET_ONION_RESPONSE: {
+ LOGGER_TRACE(tcp_server->logger, "handling onion response for %d", con_id);
return -1;
}
@@ -938,7 +682,8 @@ static int handle_TCP_packet(TCP_Server *tcp_server, uint32_t con_id, const uint
return -1;
}
- uint8_t c_id = data[0] - NUM_RESERVED_PORTS;
+ const uint8_t c_id = data[0] - NUM_RESERVED_PORTS;
+ LOGGER_TRACE(tcp_server->logger, "handling packet id %d for %d", c_id, con_id);
if (c_id >= NUM_CLIENT_CONNECTIONS) {
return -1;
@@ -952,12 +697,13 @@ static int handle_TCP_packet(TCP_Server *tcp_server, uint32_t con_id, const uint
return 0;
}
- uint32_t index = con->connections[c_id].index;
- uint8_t other_c_id = con->connections[c_id].other_id + NUM_RESERVED_PORTS;
+ const uint32_t index = con->connections[c_id].index;
+ const uint8_t other_c_id = con->connections[c_id].other_id + NUM_RESERVED_PORTS;
VLA(uint8_t, new_data, length);
memcpy(new_data, data, length);
new_data[0] = other_c_id;
- int ret = write_packet_TCP_secure_connection(&tcp_server->accepted_connection_array[index], new_data, length, 0);
+ const int ret = write_packet_TCP_secure_connection(tcp_server->logger,
+ &tcp_server->accepted_connection_array[index].con, new_data, length, 0);
if (ret == -1) {
return -1;
@@ -972,12 +718,12 @@ static int handle_TCP_packet(TCP_Server *tcp_server, uint32_t con_id, const uint
static int confirm_TCP_connection(TCP_Server *tcp_server, const Mono_Time *mono_time, TCP_Secure_Connection *con,
- const uint8_t *data,
- uint16_t length)
+ const uint8_t *data, uint16_t length)
{
- int index = add_accepted(tcp_server, mono_time, con);
+ const int index = add_accepted(tcp_server, mono_time, con);
if (index == -1) {
+ LOGGER_DEBUG(tcp_server->logger, "dropping connection %u: not accepted", (unsigned int)con->identifier);
kill_TCP_secure_connection(con);
return -1;
}
@@ -985,6 +731,8 @@ static int confirm_TCP_connection(TCP_Server *tcp_server, const Mono_Time *mono_
wipe_secure_connection(con);
if (handle_TCP_packet(tcp_server, index, data, length) == -1) {
+ LOGGER_DEBUG(tcp_server->logger, "dropping connection %u: data packet (len=%d) not handled",
+ (unsigned int)con->identifier, length);
kill_accepted(tcp_server, index);
return -1;
}
@@ -992,7 +740,7 @@ static int confirm_TCP_connection(TCP_Server *tcp_server, const Mono_Time *mono_
return index;
}
-/* return index on success
+/** return index on success
* return -1 on failure
*/
static int accept_connection(TCP_Server *tcp_server, Socket sock)
@@ -1011,16 +759,17 @@ static int accept_connection(TCP_Server *tcp_server, Socket sock)
return -1;
}
- uint16_t index = tcp_server->incoming_connection_queue_index % MAX_INCOMING_CONNECTIONS;
+ const uint16_t index = tcp_server->incoming_connection_queue_index % MAX_INCOMING_CONNECTIONS;
TCP_Secure_Connection *conn = &tcp_server->incoming_connection_queue[index];
if (conn->status != TCP_STATUS_NO_STATUS) {
+ LOGGER_DEBUG(tcp_server->logger, "connection %d dropped before accepting", index);
kill_TCP_secure_connection(conn);
}
conn->status = TCP_STATUS_CONNECTED;
- conn->sock = sock;
+ conn->con.sock = sock;
conn->next_packet_length = 0;
++tcp_server->incoming_connection_queue_index;
@@ -1094,16 +843,13 @@ TCP_Server *new_TCP_server(const Logger *logger, uint8_t ipv6_enabled, uint16_t
const Family family = ipv6_enabled ? net_family_ipv6 : net_family_ipv4;
- uint32_t i;
-#ifdef TCP_SERVER_USE_EPOLL
- struct epoll_event ev;
-#endif
-
- for (i = 0; i < num_sockets; ++i) {
+ for (uint32_t i = 0; i < num_sockets; ++i) {
Socket sock = new_listening_TCP_socket(family, ports[i]);
if (sock_valid(sock)) {
#ifdef TCP_SERVER_USE_EPOLL
+ struct epoll_event ev;
+
ev.events = EPOLLIN | EPOLLET;
ev.data.u64 = sock.socket | ((uint64_t)TCP_SOCKET_LISTENING << 32);
@@ -1140,9 +886,7 @@ TCP_Server *new_TCP_server(const Logger *logger, uint8_t ipv6_enabled, uint16_t
#ifndef TCP_SERVER_USE_EPOLL
static void do_TCP_accept_new(TCP_Server *tcp_server)
{
- uint32_t i;
-
- for (i = 0; i < tcp_server->num_listening_socks; ++i) {
+ for (uint32_t i = 0; i < tcp_server->num_listening_socks; ++i) {
Socket sock;
do {
@@ -1154,44 +898,54 @@ static void do_TCP_accept_new(TCP_Server *tcp_server)
static int do_incoming(TCP_Server *tcp_server, uint32_t i)
{
- if (tcp_server->incoming_connection_queue[i].status != TCP_STATUS_CONNECTED) {
+ TCP_Secure_Connection *const conn = &tcp_server->incoming_connection_queue[i];
+
+ if (conn->status != TCP_STATUS_CONNECTED) {
return -1;
}
- int ret = read_connection_handshake(tcp_server->logger, &tcp_server->incoming_connection_queue[i],
- tcp_server->secret_key);
+ LOGGER_TRACE(tcp_server->logger, "handling incoming TCP connection %d", i);
+
+ const int ret = read_connection_handshake(tcp_server->logger, conn, tcp_server->secret_key);
if (ret == -1) {
- kill_TCP_secure_connection(&tcp_server->incoming_connection_queue[i]);
- } else if (ret == 1) {
- int index_new = tcp_server->unconfirmed_connection_queue_index % MAX_INCOMING_CONNECTIONS;
- TCP_Secure_Connection *conn_old = &tcp_server->incoming_connection_queue[i];
- TCP_Secure_Connection *conn_new = &tcp_server->unconfirmed_connection_queue[index_new];
-
- if (conn_new->status != TCP_STATUS_NO_STATUS) {
- kill_TCP_secure_connection(conn_new);
- }
+ LOGGER_TRACE(tcp_server->logger, "incoming connection %d dropped due to failed handshake", i);
+ kill_TCP_secure_connection(conn);
+ return -1;
+ }
+
+ if (ret != 1) {
+ return -1;
+ }
- move_secure_connection(conn_new, conn_old);
- ++tcp_server->unconfirmed_connection_queue_index;
+ const int index_new = tcp_server->unconfirmed_connection_queue_index % MAX_INCOMING_CONNECTIONS;
+ TCP_Secure_Connection *conn_old = conn;
+ TCP_Secure_Connection *conn_new = &tcp_server->unconfirmed_connection_queue[index_new];
- return index_new;
+ if (conn_new->status != TCP_STATUS_NO_STATUS) {
+ LOGGER_WARNING(tcp_server->logger, "incoming connection %d would overwrite existing", i);
+ kill_TCP_secure_connection(conn_new);
}
- return -1;
+ move_secure_connection(conn_new, conn_old);
+ ++tcp_server->unconfirmed_connection_queue_index;
+
+ return index_new;
}
static int do_unconfirmed(TCP_Server *tcp_server, const Mono_Time *mono_time, uint32_t i)
{
- TCP_Secure_Connection *conn = &tcp_server->unconfirmed_connection_queue[i];
+ TCP_Secure_Connection *const conn = &tcp_server->unconfirmed_connection_queue[i];
if (conn->status != TCP_STATUS_UNCONFIRMED) {
return -1;
}
+ LOGGER_TRACE(tcp_server->logger, "handling unconfirmed TCP connection %d", i);
+
uint8_t packet[MAX_PACKET_SIZE];
- int len = read_packet_TCP_secure_connection(tcp_server->logger, conn->sock, &conn->next_packet_length, conn->shared_key,
- conn->recv_nonce, packet, sizeof(packet));
+ const int len = read_packet_TCP_secure_connection(tcp_server->logger, conn->con.sock, &conn->next_packet_length,
+ conn->con.shared_key, conn->recv_nonce, packet, sizeof(packet), &conn->con.ip_port);
if (len == 0) {
return -1;
@@ -1210,8 +964,9 @@ static bool tcp_process_secure_packet(TCP_Server *tcp_server, uint32_t i)
TCP_Secure_Connection *const conn = &tcp_server->accepted_connection_array[i];
uint8_t packet[MAX_PACKET_SIZE];
- int len = read_packet_TCP_secure_connection(tcp_server->logger, conn->sock, &conn->next_packet_length, conn->shared_key,
- conn->recv_nonce, packet, sizeof(packet));
+ const int len = read_packet_TCP_secure_connection(tcp_server->logger, conn->con.sock, &conn->next_packet_length,
+ conn->con.shared_key, conn->recv_nonce, packet, sizeof(packet), &conn->con.ip_port);
+ LOGGER_TRACE(tcp_server->logger, "processing packet for %d: %d", i, len);
if (len == 0) {
return false;
@@ -1223,6 +978,7 @@ static bool tcp_process_secure_packet(TCP_Server *tcp_server, uint32_t i)
}
if (handle_TCP_packet(tcp_server, i, packet, len) == -1) {
+ LOGGER_TRACE(tcp_server->logger, "dropping connection %d: data packet (len=%d) not handled", i, len);
kill_accepted(tcp_server, i);
return false;
}
@@ -1264,9 +1020,8 @@ static void do_TCP_confirmed(TCP_Server *tcp_server, const Mono_Time *mono_time)
tcp_server->last_run_pinged = mono_time_get(mono_time);
#endif
- uint32_t i;
- for (i = 0; i < tcp_server->size_accepted_connections; ++i) {
+ for (uint32_t i = 0; i < tcp_server->size_accepted_connections; ++i) {
TCP_Secure_Connection *conn = &tcp_server->accepted_connection_array[i];
if (conn->status != TCP_STATUS_CONFIRMED) {
@@ -1283,7 +1038,7 @@ static void do_TCP_confirmed(TCP_Server *tcp_server, const Mono_Time *mono_time)
}
memcpy(ping + 1, &ping_id, sizeof(uint64_t));
- int ret = write_packet_TCP_secure_connection(conn, ping, sizeof(ping), 1);
+ int ret = write_packet_TCP_secure_connection(tcp_server->logger, &conn->con, ping, sizeof(ping), 1);
if (ret == 1) {
conn->last_pinged = mono_time_get(mono_time);
@@ -1301,7 +1056,7 @@ static void do_TCP_confirmed(TCP_Server *tcp_server, const Mono_Time *mono_time)
continue;
}
- send_pending_data(conn);
+ send_pending_data(tcp_server->logger, &conn->con);
#ifndef TCP_SERVER_USE_EPOLL
@@ -1328,20 +1083,24 @@ static bool tcp_epoll_process(TCP_Server *tcp_server, const Mono_Time *mono_time
switch (status) {
case TCP_SOCKET_LISTENING: {
// should never happen
+ LOGGER_ERROR(tcp_server->logger, "connection %d was in listening state", index);
break;
}
case TCP_SOCKET_INCOMING: {
+ LOGGER_TRACE(tcp_server->logger, "incoming connection %d dropped", index);
kill_TCP_secure_connection(&tcp_server->incoming_connection_queue[index]);
break;
}
case TCP_SOCKET_UNCONFIRMED: {
+ LOGGER_TRACE(tcp_server->logger, "unconfirmed connection %d dropped", index);
kill_TCP_secure_connection(&tcp_server->unconfirmed_connection_queue[index]);
break;
}
case TCP_SOCKET_CONFIRMED: {
+ LOGGER_TRACE(tcp_server->logger, "confirmed connection %d dropped", index);
kill_accepted(tcp_server, index);
break;
}
@@ -1365,7 +1124,7 @@ static bool tcp_epoll_process(TCP_Server *tcp_server, const Mono_Time *mono_time
break;
}
- int index_new = accept_connection(tcp_server, sock_new);
+ const int index_new = accept_connection(tcp_server, sock_new);
if (index_new == -1) {
continue;
@@ -1378,6 +1137,7 @@ static bool tcp_epoll_process(TCP_Server *tcp_server, const Mono_Time *mono_time
ev.data.u64 = sock_new.socket | ((uint64_t)TCP_SOCKET_INCOMING << 32) | ((uint64_t)index_new << 40);
if (epoll_ctl(tcp_server->efd, EPOLL_CTL_ADD, sock_new.socket, &ev) == -1) {
+ LOGGER_DEBUG(tcp_server->logger, "new connection %d was dropped due to epoll error %d", index, net_error());
kill_TCP_secure_connection(&tcp_server->incoming_connection_queue[index_new]);
continue;
}
@@ -1390,10 +1150,12 @@ static bool tcp_epoll_process(TCP_Server *tcp_server, const Mono_Time *mono_time
const int index_new = do_incoming(tcp_server, index);
if (index_new != -1) {
+ LOGGER_TRACE(tcp_server->logger, "incoming connection %d was accepted as %d", index, index_new);
events[n].events = EPOLLIN | EPOLLET | EPOLLRDHUP;
events[n].data.u64 = sock.socket | ((uint64_t)TCP_SOCKET_UNCONFIRMED << 32) | ((uint64_t)index_new << 40);
if (epoll_ctl(tcp_server->efd, EPOLL_CTL_MOD, sock.socket, &events[n]) == -1) {
+ LOGGER_DEBUG(tcp_server->logger, "incoming connection %d was dropped due to epoll error %d", index, net_error());
kill_TCP_secure_connection(&tcp_server->unconfirmed_connection_queue[index_new]);
break;
}
@@ -1406,11 +1168,13 @@ static bool tcp_epoll_process(TCP_Server *tcp_server, const Mono_Time *mono_time
const int index_new = do_unconfirmed(tcp_server, mono_time, index);
if (index_new != -1) {
+ LOGGER_TRACE(tcp_server->logger, "unconfirmed connection %d was confirmed as %d", index, index_new);
events[n].events = EPOLLIN | EPOLLET | EPOLLRDHUP;
events[n].data.u64 = sock.socket | ((uint64_t)TCP_SOCKET_CONFIRMED << 32) | ((uint64_t)index_new << 40);
if (epoll_ctl(tcp_server->efd, EPOLL_CTL_MOD, sock.socket, &events[n]) == -1) {
// remove from confirmed connections
+ LOGGER_DEBUG(tcp_server->logger, "unconfirmed connection %d was dropped due to epoll error %d", index, net_error());
kill_accepted(tcp_server, index_new);
break;
}
@@ -1438,7 +1202,7 @@ static void do_TCP_epoll(TCP_Server *tcp_server, const Mono_Time *mono_time)
}
#endif
-void do_TCP_server(TCP_Server *tcp_server, Mono_Time *mono_time)
+void do_TCP_server(TCP_Server *tcp_server, const Mono_Time *mono_time)
{
#ifdef TCP_SERVER_USE_EPOLL
do_TCP_epoll(tcp_server, mono_time);
@@ -1475,6 +1239,8 @@ void kill_TCP_server(TCP_Server *tcp_server)
free_accepted_connection_array(tcp_server);
+ crypto_memzero(tcp_server->secret_key, sizeof(tcp_server->secret_key));
+
free(tcp_server->socks_listening);
free(tcp_server);
}
diff --git a/protocols/Tox/libtox/src/toxcore/TCP_server.h b/protocols/Tox/libtox/src/toxcore/TCP_server.h
index 46dd03304f..3269ed3b0a 100644
--- a/protocols/Tox/libtox/src/toxcore/TCP_server.h
+++ b/protocols/Tox/libtox/src/toxcore/TCP_server.h
@@ -3,47 +3,21 @@
* Copyright © 2014 Tox project.
*/
-/*
+/**
* Implementation of the TCP relay server part of Tox.
*/
#ifndef C_TOXCORE_TOXCORE_TCP_SERVER_H
#define C_TOXCORE_TOXCORE_TCP_SERVER_H
#include "crypto_core.h"
-#include "list.h"
#include "onion.h"
#define MAX_INCOMING_CONNECTIONS 256
#define TCP_MAX_BACKLOG MAX_INCOMING_CONNECTIONS
-#define MAX_PACKET_SIZE 2048
-
-#define TCP_HANDSHAKE_PLAIN_SIZE (CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE)
-#define TCP_SERVER_HANDSHAKE_SIZE (CRYPTO_NONCE_SIZE + TCP_HANDSHAKE_PLAIN_SIZE + CRYPTO_MAC_SIZE)
-#define TCP_CLIENT_HANDSHAKE_SIZE (CRYPTO_PUBLIC_KEY_SIZE + TCP_SERVER_HANDSHAKE_SIZE)
-#define TCP_MAX_OOB_DATA_LENGTH 1024
-
-#define NUM_RESERVED_PORTS 16
-#define NUM_CLIENT_CONNECTIONS (256 - NUM_RESERVED_PORTS)
-
-#define TCP_PACKET_ROUTING_REQUEST 0
-#define TCP_PACKET_ROUTING_RESPONSE 1
-#define TCP_PACKET_CONNECTION_NOTIFICATION 2
-#define TCP_PACKET_DISCONNECT_NOTIFICATION 3
-#define TCP_PACKET_PING 4
-#define TCP_PACKET_PONG 5
-#define TCP_PACKET_OOB_SEND 6
-#define TCP_PACKET_OOB_RECV 7
-#define TCP_PACKET_ONION_REQUEST 8
-#define TCP_PACKET_ONION_RESPONSE 9
-
#define ARRAY_ENTRY_SIZE 6
-/* frequency to ping connected nodes and timeout in seconds */
-#define TCP_PING_FREQUENCY 30
-#define TCP_PING_TIMEOUT 10
-
typedef enum TCP_Status {
TCP_STATUS_NO_STATUS,
TCP_STATUS_CONNECTED,
@@ -51,57 +25,23 @@ typedef enum TCP_Status {
TCP_STATUS_CONFIRMED,
} TCP_Status;
-typedef struct TCP_Priority_List TCP_Priority_List;
-
-struct TCP_Priority_List {
- TCP_Priority_List *next;
- uint16_t size;
- uint16_t sent;
- uint8_t data[];
-};
-
-void wipe_priority_list(TCP_Priority_List *p);
-
typedef struct TCP_Server TCP_Server;
const uint8_t *tcp_server_public_key(const TCP_Server *tcp_server);
size_t tcp_server_listen_count(const TCP_Server *tcp_server);
-/* Create new TCP server instance.
+/** Create new TCP server instance.
*/
TCP_Server *new_TCP_server(const Logger *logger, uint8_t ipv6_enabled, uint16_t num_sockets, const uint16_t *ports,
const uint8_t *secret_key, Onion *onion);
-/* Run the TCP_server
+/** Run the TCP_server
*/
-void do_TCP_server(TCP_Server *tcp_server, Mono_Time *mono_time);
+void do_TCP_server(TCP_Server *tcp_server, const Mono_Time *mono_time);
-/* Kill the TCP server
+/** Kill the TCP server
*/
void kill_TCP_server(TCP_Server *tcp_server);
-/* Read the next two bytes in TCP stream then convert them to
- * length (host byte order).
- *
- * return length on success
- * return 0 if nothing has been read from socket.
- * return -1 on failure.
- */
-uint16_t read_TCP_length(const Logger *logger, Socket sock);
-
-/* Read length bytes from socket.
- *
- * return length on success
- * return -1 on failure/no data in buffer.
- */
-int read_TCP_packet(const Logger *logger, Socket sock, uint8_t *data, uint16_t length);
-
-/* return length of received packet on success.
- * return 0 if could not read any packet.
- * return -1 on failure (connection must be killed).
- */
-int read_packet_TCP_secure_connection(const Logger *logger, Socket sock, uint16_t *next_packet_length,
- const uint8_t *shared_key, uint8_t *recv_nonce, uint8_t *data, uint16_t max_len);
-
#endif
diff --git a/protocols/Tox/libtox/src/toxcore/ccompat.h b/protocols/Tox/libtox/src/toxcore/ccompat.h
index 34def21bf9..295cd10d9b 100644
--- a/protocols/Tox/libtox/src/toxcore/ccompat.h
+++ b/protocols/Tox/libtox/src/toxcore/ccompat.h
@@ -1,9 +1,17 @@
-/*
+/* SPDX-License-Identifier: GPL-3.0-or-later
+ * Copyright © 2016-2021 The TokTok team.
+ */
+
+/**
* C language compatibility macros for varying compiler support.
*/
#ifndef C_TOXCORE_TOXCORE_CCOMPAT_H
#define C_TOXCORE_TOXCORE_CCOMPAT_H
+#include <stdbool.h>
+
+bool unused_for_tokstyle(void);
+
//!TOKSTYLE-
// Variable length arrays.
@@ -15,7 +23,7 @@
// "function") is used. Note the semantic difference: alloca'd memory does not
// get freed at the end of the declaration's scope. Do not use VLA() in loops or
// you may run out of stack space.
-#if !defined(_MSC_VER) && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+#if !defined(DISABLE_VLA) && !defined(_MSC_VER) && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
// C99 VLAs.
#define VLA(type, name, size) type name[size]
#define SIZEOF_VLA sizeof
@@ -24,6 +32,11 @@
// Emulation using alloca.
#ifdef _WIN32
#include <malloc.h>
+#elif defined(__COMPCERT__)
+// TODO(iphydf): This leaks memory like crazy, so compcert is useless for now.
+// Once we're rid of VLAs, we can remove this and compcert becomes useful.
+#define alloca malloc
+#include <stdlib.h>
#elif defined(__linux__)
#include <alloca.h>
#else
@@ -43,7 +56,7 @@
#if !defined(__cplusplus) || __cplusplus < 201103L
#define nullptr NULL
#ifndef static_assert
-#define static_assert(cond, msg) extern int unused_for_static_assert
+#define static_assert(cond, msg) extern const int unused_for_static_assert
#endif
#endif
diff --git a/protocols/Tox/libtox/src/toxcore/crypto_core.api.h b/protocols/Tox/libtox/src/toxcore/crypto_core.api.h
deleted file mode 100644
index 0db3a42001..0000000000
--- a/protocols/Tox/libtox/src/toxcore/crypto_core.api.h
+++ /dev/null
@@ -1,253 +0,0 @@
-%{
-/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2018 The TokTok team.
- * Copyright © 2013 Tox project.
- */
-
-/*
- * Functions for the core crypto.
- */
-#ifndef C_TOXCORE_TOXCORE_CRYPTO_CORE_H
-#define C_TOXCORE_TOXCORE_CRYPTO_CORE_H
-
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdint.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-%}
-
-/**
- * The number of bytes in a Tox public key.
- */
-const CRYPTO_PUBLIC_KEY_SIZE = 32;
-
-/**
- * The number of bytes in a Tox secret key.
- */
-const CRYPTO_SECRET_KEY_SIZE = 32;
-
-/**
- * The number of bytes in a shared key computed from public and secret keys.
- */
-const CRYPTO_SHARED_KEY_SIZE = 32;
-
-/**
- * The number of bytes in a symmetric key.
- */
-const CRYPTO_SYMMETRIC_KEY_SIZE = CRYPTO_SHARED_KEY_SIZE;
-
-/**
- * The number of bytes needed for the MAC (message authentication code) in an
- * encrypted message.
- */
-const CRYPTO_MAC_SIZE = 16;
-
-/**
- * The number of bytes in a nonce used for encryption/decryption.
- */
-const CRYPTO_NONCE_SIZE = 24;
-
-/**
- * The number of bytes in a SHA256 hash.
- */
-const CRYPTO_SHA256_SIZE = 32;
-
-/**
- * The number of bytes in a SHA512 hash.
- */
-const CRYPTO_SHA512_SIZE = 64;
-
-/**
- * A `memcmp`-like function whose running time does not depend on the input
- * bytes, only on the input length. Useful to compare sensitive data where
- * timing attacks could reveal that data.
- *
- * This means for instance that comparing "aaaa" and "aaaa" takes 4 time, and
- * "aaaa" and "baaa" also takes 4 time. With a regular `memcmp`, the latter may
- * take 1 time, because it immediately knows that the two strings are not equal.
- */
-static int32_t crypto_memcmp(const uint8_t *p1, const uint8_t *p2, size_t length);
-
-/**
- * A `bzero`-like function which won't be optimised away by the compiler. Some
- * compilers will inline `bzero` or `memset` if they can prove that there will
- * be no reads to the written data. Use this function if you want to be sure the
- * memory is indeed zeroed.
- */
-static void crypto_memzero(void *data, size_t length);
-
-/**
- * Compute a SHA256 hash (32 bytes).
- */
-static void crypto_sha256(uint8_t[CRYPTO_SHA256_SIZE] hash, const uint8_t[length] data);
-
-/**
- * Compute a SHA512 hash (64 bytes).
- */
-static void crypto_sha512(uint8_t[CRYPTO_SHA512_SIZE] hash, const uint8_t[length] data);
-
-/**
- * Compare 2 public keys of length CRYPTO_PUBLIC_KEY_SIZE, not vulnerable to
- * timing attacks.
- *
- * @return 0 if both mem locations of length are equal, -1 if they are not.
- */
-static int32_t public_key_cmp(
- const uint8_t[CRYPTO_PUBLIC_KEY_SIZE] pk1,
- const uint8_t[CRYPTO_PUBLIC_KEY_SIZE] pk2);
-
-namespace random {
-
-/**
- * Return a random 8 bit integer.
- */
-static uint8_t u08();
-
-/**
- * Return a random 16 bit integer.
- */
-static uint16_t u16();
-
-/**
- * Return a random 32 bit integer.
- */
-static uint32_t u32();
-
-/**
- * Return a random 64 bit integer.
- */
-static uint64_t u64();
-
-/**
- * Fill the given nonce with random bytes.
- */
-static void nonce(uint8_t[CRYPTO_NONCE_SIZE] nonce);
-
-/**
- * Fill an array of bytes with random values.
- */
-static void bytes(uint8_t[length] bytes);
-
-}
-
-/**
- * Check if a Tox public key CRYPTO_PUBLIC_KEY_SIZE is valid or not. This
- * should only be used for input validation.
- *
- * @return false if it isn't, true if it is.
- */
-static bool public_key_valid(const uint8_t[CRYPTO_PUBLIC_KEY_SIZE] public_key);
-
-/**
- * Generate a new random keypair. Every call to this function is likely to
- * generate a different keypair.
- */
-static int32_t crypto_new_keypair(
- uint8_t[CRYPTO_PUBLIC_KEY_SIZE] public_key,
- uint8_t[CRYPTO_SECRET_KEY_SIZE] secret_key);
-
-/**
- * Derive the public key from a given secret key.
- */
-static void crypto_derive_public_key(
- uint8_t[CRYPTO_PUBLIC_KEY_SIZE] public_key,
- const uint8_t[CRYPTO_SECRET_KEY_SIZE] secret_key);
-
-/**
- * Encrypt plain text of the given length to encrypted of length +
- * $CRYPTO_MAC_SIZE using the public key ($CRYPTO_PUBLIC_KEY_SIZE bytes) of the
- * receiver and the secret key of the sender and a $CRYPTO_NONCE_SIZE byte
- * nonce.
- *
- * @return -1 if there was a problem, length of encrypted data if everything
- * was fine.
- */
-static int32_t encrypt_data(
- const uint8_t[CRYPTO_PUBLIC_KEY_SIZE] public_key,
- const uint8_t[CRYPTO_SECRET_KEY_SIZE] secret_key,
- const uint8_t[CRYPTO_NONCE_SIZE] nonce,
- const uint8_t[length] plain,
- uint8_t *encrypted);
-
-
-/**
- * Decrypt encrypted text of the given length to plain text of the given length
- * - $CRYPTO_MAC_SIZE using the public key ($CRYPTO_PUBLIC_KEY_SIZE bytes) of
- * the sender, the secret key of the receiver and a $CRYPTO_NONCE_SIZE byte
- * nonce.
- *
- * @return -1 if there was a problem (decryption failed), length of plain text
- * data if everything was fine.
- */
-static int32_t decrypt_data(
- const uint8_t[CRYPTO_PUBLIC_KEY_SIZE] public_key,
- const uint8_t[CRYPTO_SECRET_KEY_SIZE] secret_key,
- const uint8_t[CRYPTO_NONCE_SIZE] nonce,
- const uint8_t[length] encrypted,
- uint8_t *plain);
-
-/**
- * Fast encrypt/decrypt operations. Use if this is not a one-time communication.
- * $encrypt_precompute does the shared-key generation once so it does not have
- * to be performed on every encrypt/decrypt.
- */
-static int32_t encrypt_precompute(
- const uint8_t[CRYPTO_PUBLIC_KEY_SIZE] public_key,
- const uint8_t[CRYPTO_SECRET_KEY_SIZE] secret_key,
- uint8_t[CRYPTO_SHARED_KEY_SIZE] shared_key);
-
-/**
- * Encrypts plain of length length to encrypted of length + $CRYPTO_MAC_SIZE
- * using a shared key $CRYPTO_SYMMETRIC_KEY_SIZE big and a $CRYPTO_NONCE_SIZE
- * byte nonce.
- *
- * @return -1 if there was a problem, length of encrypted data if everything
- * was fine.
- */
-static int32_t encrypt_data_symmetric(
- const uint8_t[CRYPTO_SHARED_KEY_SIZE] shared_key,
- const uint8_t[CRYPTO_NONCE_SIZE] nonce,
- const uint8_t[length] plain,
- uint8_t *encrypted);
-
-/**
- * Decrypts encrypted of length length to plain of length length -
- * $CRYPTO_MAC_SIZE using a shared key CRYPTO_SHARED_KEY_SIZE big and a
- * $CRYPTO_NONCE_SIZE byte nonce.
- *
- * @return -1 if there was a problem (decryption failed), length of plain data
- * if everything was fine.
- */
-static int32_t decrypt_data_symmetric(
- const uint8_t[CRYPTO_SHARED_KEY_SIZE] shared_key,
- const uint8_t[CRYPTO_NONCE_SIZE] nonce,
- const uint8_t[length] encrypted,
- uint8_t *plain);
-
-/**
- * Increment the given nonce by 1 in big endian (rightmost byte incremented
- * first).
- */
-static void increment_nonce(uint8_t[CRYPTO_NONCE_SIZE] nonce);
-
-/**
- * Increment the given nonce by a given number. The number should be in host
- * byte order.
- */
-static void increment_nonce_number(uint8_t[CRYPTO_NONCE_SIZE] nonce, uint32_t host_order_num);
-
-/**
- * Fill a key CRYPTO_SYMMETRIC_KEY_SIZE big with random bytes.
- */
-static void new_symmetric_key(uint8_t[CRYPTO_SYMMETRIC_KEY_SIZE] key);
-
-%{
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#endif // C_TOXCORE_TOXCORE_CRYPTO_CORE_H
-%}
diff --git a/protocols/Tox/libtox/src/toxcore/crypto_core.c b/protocols/Tox/libtox/src/toxcore/crypto_core.c
index 35e3a60307..3402395b63 100644
--- a/protocols/Tox/libtox/src/toxcore/crypto_core.c
+++ b/protocols/Tox/libtox/src/toxcore/crypto_core.c
@@ -3,15 +3,11 @@
* Copyright © 2013 Tox project.
*/
-/*
+/**
* Functions for the core crypto.
*
* NOTE: This code has to be perfect. We don't mess around with encryption.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include "crypto_core.h"
#include <stdlib.h>
@@ -20,7 +16,7 @@
#include "ccompat.h"
#ifndef VANILLA_NACL
-/* We use libsodium by default. */
+// We use libsodium by default.
#include <sodium.h>
#else
#include <crypto_box.h>
@@ -30,10 +26,18 @@
#include <crypto_verify_16.h>
#include <crypto_verify_32.h>
#include <randombytes.h>
+#endif
+
+#ifndef crypto_box_MACBYTES
#define crypto_box_MACBYTES (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES)
#endif
//!TOKSTYLE-
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+#include "../testing/fuzzing/fuzz_adapter.h"
+#endif
+//!TOKSTYLE+
+
static_assert(CRYPTO_PUBLIC_KEY_SIZE == crypto_box_PUBLICKEYBYTES,
"CRYPTO_PUBLIC_KEY_SIZE should be equal to crypto_box_PUBLICKEYBYTES");
static_assert(CRYPTO_SECRET_KEY_SIZE == crypto_box_SECRETKEYBYTES,
@@ -52,25 +56,84 @@ static_assert(CRYPTO_SHA512_SIZE == crypto_hash_sha512_BYTES,
"CRYPTO_SHA512_SIZE should be equal to crypto_hash_sha512_BYTES");
static_assert(CRYPTO_PUBLIC_KEY_SIZE == 32,
"CRYPTO_PUBLIC_KEY_SIZE is required to be 32 bytes for public_key_cmp to work");
-//!TOKSTYLE+
+#if !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
static uint8_t *crypto_malloc(size_t bytes)
{
- return (uint8_t *)malloc(bytes);
+ uint8_t *ptr = (uint8_t *)malloc(bytes);
+
+ if (ptr != nullptr) {
+ crypto_memlock(ptr, bytes);
+ }
+
+ return ptr;
}
static void crypto_free(uint8_t *ptr, size_t bytes)
{
if (ptr != nullptr) {
crypto_memzero(ptr, bytes);
+ crypto_memunlock(ptr, bytes);
}
free(ptr);
}
+#endif // !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
+
+void crypto_memzero(void *data, size_t length)
+{
+#ifndef VANILLA_NACL
+ sodium_memzero(data, length);
+#else
+ memset(data, 0, length);
+#endif
+}
+
+bool crypto_memlock(void *data, size_t length)
+{
+#ifndef VANILLA_NACL
+
+ if (sodium_mlock(data, length) != 0) {
+ return false;
+ }
+
+ return true;
+#else
+ return false;
+#endif
+}
+
+bool crypto_memunlock(void *data, size_t length)
+{
+#ifndef VANILLA_NACL
+
+ if (sodium_munlock(data, length) != 0) {
+ return false;
+ }
+
+ return true;
+#else
+ return false;
+#endif
+}
int32_t public_key_cmp(const uint8_t *pk1, const uint8_t *pk2)
{
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+ // Hope that this is better for the fuzzer
+ return memcmp(pk1, pk2, CRYPTO_PUBLIC_KEY_SIZE) == 0 ? 0 : -1;
+#else
return crypto_verify_32(pk1, pk2);
+#endif
+}
+
+int32_t crypto_sha512_cmp(const uint8_t *cksum1, const uint8_t *cksum2)
+{
+#ifndef VANILLA_NACL
+ return crypto_verify_64(cksum1, cksum2);
+#else
+ return crypto_verify_32(cksum1, cksum2) && crypto_verify_32(cksum1 + 8, cksum2 + 8);
+#endif
}
uint8_t random_u08(void)
@@ -101,6 +164,15 @@ uint64_t random_u64(void)
return randnum;
}
+uint32_t random_range_u32(uint32_t upper_bound)
+{
+#ifdef VANILLA_NACL
+ return random_u32() % upper_bound;
+#else
+ return randombytes_uniform(upper_bound);
+#endif // VANILLA_NACL
+}
+
bool public_key_valid(const uint8_t *public_key)
{
if (public_key[31] >= 128) { /* Last bit of key is always zero. */
@@ -110,11 +182,6 @@ bool public_key_valid(const uint8_t *public_key)
return 1;
}
-/* Precomputes the shared key from their public_key and our secret_key.
- * This way we can avoid an expensive elliptic curve scalar multiply for each
- * encrypt/decrypt operation.
- * shared_key has to be crypto_box_BEFORENMBYTES bytes long.
- */
int32_t encrypt_precompute(const uint8_t *public_key, const uint8_t *secret_key,
uint8_t *shared_key)
{
@@ -128,6 +195,13 @@ int32_t encrypt_data_symmetric(const uint8_t *secret_key, const uint8_t *nonce,
return -1;
}
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+ // Don't encrypt anything.
+ memcpy(encrypted, plain, length);
+ // Zero MAC to avoid uninitialized memory reads.
+ memset(encrypted + length, 0, crypto_box_MACBYTES);
+#else
+
const size_t size_temp_plain = length + crypto_box_ZEROBYTES;
const size_t size_temp_encrypted = length + crypto_box_MACBYTES + crypto_box_BOXZEROBYTES;
@@ -140,6 +214,11 @@ int32_t encrypt_data_symmetric(const uint8_t *secret_key, const uint8_t *nonce,
return -1;
}
+ // crypto_box_afternm requires the entire range of the output array be
+ // initialised with something. It doesn't matter what it's initialised with,
+ // so we'll pick 0x00.
+ memset(temp_encrypted, 0, size_temp_encrypted);
+
memset(temp_plain, 0, crypto_box_ZEROBYTES);
// Pad the message with 32 0 bytes.
memcpy(temp_plain + crypto_box_ZEROBYTES, plain, length);
@@ -156,7 +235,7 @@ int32_t encrypt_data_symmetric(const uint8_t *secret_key, const uint8_t *nonce,
crypto_free(temp_plain, size_temp_plain);
crypto_free(temp_encrypted, size_temp_encrypted);
-
+#endif
return length + crypto_box_MACBYTES;
}
@@ -167,6 +246,11 @@ int32_t decrypt_data_symmetric(const uint8_t *secret_key, const uint8_t *nonce,
return -1;
}
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+ assert(length >= crypto_box_MACBYTES);
+ memcpy(plain, encrypted, length - crypto_box_MACBYTES); // Don't encrypt anything
+#else
+
const size_t size_temp_plain = length + crypto_box_ZEROBYTES;
const size_t size_temp_encrypted = length + crypto_box_BOXZEROBYTES;
@@ -179,6 +263,11 @@ int32_t decrypt_data_symmetric(const uint8_t *secret_key, const uint8_t *nonce,
return -1;
}
+ // crypto_box_open_afternm requires the entire range of the output array be
+ // initialised with something. It doesn't matter what it's initialised with,
+ // so we'll pick 0x00.
+ memset(temp_plain, 0, size_temp_plain);
+
memset(temp_encrypted, 0, crypto_box_BOXZEROBYTES);
// Pad the message with 16 0 bytes.
memcpy(temp_encrypted + crypto_box_BOXZEROBYTES, encrypted, length);
@@ -194,6 +283,7 @@ int32_t decrypt_data_symmetric(const uint8_t *secret_key, const uint8_t *nonce,
crypto_free(temp_plain, size_temp_plain);
crypto_free(temp_encrypted, size_temp_encrypted);
+#endif
return length - crypto_box_MACBYTES;
}
@@ -225,7 +315,6 @@ int32_t decrypt_data(const uint8_t *public_key, const uint8_t *secret_key, const
return ret;
}
-/* Increment the given nonce by 1. */
void increment_nonce(uint8_t *nonce)
{
/* TODO(irungentoo): use `increment_nonce_number(nonce, 1)` or
@@ -236,61 +325,42 @@ void increment_nonce(uint8_t *nonce)
* that loop bounds and their potential underflow or overflow
* are independent of user-controlled input (you may have heard of the Heartbleed bug).
*/
- uint32_t i = crypto_box_NONCEBYTES;
uint_fast16_t carry = 1U;
- for (; i != 0; --i) {
+ for (uint32_t i = crypto_box_NONCEBYTES; i != 0; --i) {
carry += (uint_fast16_t)nonce[i - 1];
nonce[i - 1] = (uint8_t)carry;
carry >>= 8;
}
}
-static uint32_t host_to_network(uint32_t x)
-{
-#if !defined(BYTE_ORDER) || BYTE_ORDER == LITTLE_ENDIAN
- return ((x >> 24) & 0x000000FF) | // move byte 3 to byte 0
- ((x >> 8) & 0x0000FF00) | // move byte 2 to byte 1
- ((x << 8) & 0x00FF0000) | // move byte 1 to byte 2
- ((x << 24) & 0xFF000000); // move byte 0 to byte 3
-#else
- return x;
-#endif
-}
-
-/* increment the given nonce by num */
-void increment_nonce_number(uint8_t *nonce, uint32_t host_order_num)
+void increment_nonce_number(uint8_t *nonce, uint32_t increment)
{
/* NOTE don't use breaks inside this loop
* In particular, make sure, as far as possible,
* that loop bounds and their potential underflow or overflow
* are independent of user-controlled input (you may have heard of the Heartbleed bug).
*/
- const uint32_t big_endian_num = host_to_network(host_order_num);
- const uint8_t *const num_vec = (const uint8_t *)&big_endian_num;
uint8_t num_as_nonce[crypto_box_NONCEBYTES] = {0};
- num_as_nonce[crypto_box_NONCEBYTES - 4] = num_vec[0];
- num_as_nonce[crypto_box_NONCEBYTES - 3] = num_vec[1];
- num_as_nonce[crypto_box_NONCEBYTES - 2] = num_vec[2];
- num_as_nonce[crypto_box_NONCEBYTES - 1] = num_vec[3];
+ num_as_nonce[crypto_box_NONCEBYTES - 4] = increment >> 24;
+ num_as_nonce[crypto_box_NONCEBYTES - 3] = increment >> 16;
+ num_as_nonce[crypto_box_NONCEBYTES - 2] = increment >> 8;
+ num_as_nonce[crypto_box_NONCEBYTES - 1] = increment;
- uint32_t i = crypto_box_NONCEBYTES;
uint_fast16_t carry = 0U;
- for (; i != 0; --i) {
+ for (uint32_t i = crypto_box_NONCEBYTES; i != 0; --i) {
carry += (uint_fast16_t)nonce[i - 1] + (uint_fast16_t)num_as_nonce[i - 1];
nonce[i - 1] = (uint8_t)carry;
carry >>= 8;
}
}
-/* Fill the given nonce with random bytes. */
void random_nonce(uint8_t *nonce)
{
random_bytes(nonce, crypto_box_NONCEBYTES);
}
-/* Fill a key CRYPTO_SYMMETRIC_KEY_SIZE big with random bytes */
void new_symmetric_key(uint8_t *key)
{
random_bytes(key, CRYPTO_SYMMETRIC_KEY_SIZE);
@@ -298,7 +368,14 @@ void new_symmetric_key(uint8_t *key)
int32_t crypto_new_keypair(uint8_t *public_key, uint8_t *secret_key)
{
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+ random_bytes(secret_key, CRYPTO_SECRET_KEY_SIZE);
+ memset(public_key, 0, CRYPTO_PUBLIC_KEY_SIZE); // Make MSAN happy
+ crypto_scalarmult_curve25519_base(public_key, secret_key);
+ return 0;
+#else
return crypto_box_keypair(public_key, secret_key);
+#endif
}
void crypto_derive_public_key(uint8_t *public_key, const uint8_t *secret_key)
@@ -318,5 +395,9 @@ void crypto_sha512(uint8_t *hash, const uint8_t *data, size_t length)
void random_bytes(uint8_t *data, size_t length)
{
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+ fuzz_random_bytes(data, length);
+#else
randombytes(data, length);
+#endif
}
diff --git a/protocols/Tox/libtox/src/toxcore/crypto_core.h b/protocols/Tox/libtox/src/toxcore/crypto_core.h
index 425c3244f0..f3709abaac 100644
--- a/protocols/Tox/libtox/src/toxcore/crypto_core.h
+++ b/protocols/Tox/libtox/src/toxcore/crypto_core.h
@@ -3,8 +3,8 @@
* Copyright © 2013 Tox project.
*/
-/*
- * Functions for the core crypto.
+/** @file
+ * @brief Functions for the core crypto.
*/
#ifndef C_TOXCORE_TOXCORE_CRYPTO_CORE_H
#define C_TOXCORE_TOXCORE_CRYPTO_CORE_H
@@ -18,182 +18,183 @@ extern "C" {
#endif
/**
- * The number of bytes in a Tox public key.
+ * @brief The number of bytes in a Tox public key used for encryption.
*/
#define CRYPTO_PUBLIC_KEY_SIZE 32
-uint32_t crypto_public_key_size(void);
-
/**
- * The number of bytes in a Tox secret key.
+ * @brief The number of bytes in a Tox secret key used for encryption.
*/
#define CRYPTO_SECRET_KEY_SIZE 32
-uint32_t crypto_secret_key_size(void);
-
/**
- * The number of bytes in a shared key computed from public and secret keys.
+ * @brief The number of bytes in a shared key computed from public and secret keys.
*/
#define CRYPTO_SHARED_KEY_SIZE 32
-uint32_t crypto_shared_key_size(void);
-
/**
- * The number of bytes in a symmetric key.
+ * @brief The number of bytes in a symmetric key.
*/
#define CRYPTO_SYMMETRIC_KEY_SIZE CRYPTO_SHARED_KEY_SIZE
-uint32_t crypto_symmetric_key_size(void);
-
/**
- * The number of bytes needed for the MAC (message authentication code) in an
+ * @brief The number of bytes needed for the MAC (message authentication code) in an
* encrypted message.
*/
#define CRYPTO_MAC_SIZE 16
-uint32_t crypto_mac_size(void);
-
/**
- * The number of bytes in a nonce used for encryption/decryption.
+ * @brief The number of bytes in a nonce used for encryption/decryption.
*/
#define CRYPTO_NONCE_SIZE 24
-uint32_t crypto_nonce_size(void);
-
/**
- * The number of bytes in a SHA256 hash.
+ * @brief The number of bytes in a SHA256 hash.
*/
#define CRYPTO_SHA256_SIZE 32
-uint32_t crypto_sha256_size(void);
-
/**
- * The number of bytes in a SHA512 hash.
+ * @brief The number of bytes in a SHA512 hash.
*/
#define CRYPTO_SHA512_SIZE 64
-uint32_t crypto_sha512_size(void);
-
/**
- * A `memcmp`-like function whose running time does not depend on the input
- * bytes, only on the input length. Useful to compare sensitive data where
- * timing attacks could reveal that data.
+ * @brief A `bzero`-like function which won't be optimised away by the compiler.
*
- * This means for instance that comparing "aaaa" and "aaaa" takes 4 time, and
- * "aaaa" and "baaa" also takes 4 time. With a regular `memcmp`, the latter may
- * take 1 time, because it immediately knows that the two strings are not equal.
- */
-int32_t crypto_memcmp(const uint8_t *p1, const uint8_t *p2, size_t length);
-
-/**
- * A `bzero`-like function which won't be optimised away by the compiler. Some
- * compilers will inline `bzero` or `memset` if they can prove that there will
- * be no reads to the written data. Use this function if you want to be sure the
- * memory is indeed zeroed.
+ * Some compilers will inline `bzero` or `memset` if they can prove that there
+ * will be no reads to the written data. Use this function if you want to be
+ * sure the memory is indeed zeroed.
*/
void crypto_memzero(void *data, size_t length);
/**
- * Compute a SHA256 hash (32 bytes).
+ * @brief Compute a SHA256 hash (32 bytes).
*/
void crypto_sha256(uint8_t *hash, const uint8_t *data, size_t length);
/**
- * Compute a SHA512 hash (64 bytes).
+ * @brief Compute a SHA512 hash (64 bytes).
*/
void crypto_sha512(uint8_t *hash, const uint8_t *data, size_t length);
/**
- * Compare 2 public keys of length CRYPTO_PUBLIC_KEY_SIZE, not vulnerable to
+ * @brief Compare 2 public keys of length @ref CRYPTO_PUBLIC_KEY_SIZE, not vulnerable to
* timing attacks.
*
- * @return 0 if both mem locations of length are equal, -1 if they are not.
+ * @retval 0 if both mem locations of length are equal
+ * @retval -1 if they are not
*/
int32_t public_key_cmp(const uint8_t *pk1, const uint8_t *pk2);
/**
- * Return a random 8 bit integer.
+ * @brief Compare 2 SHA512 checksums of length CRYPTO_SHA512_SIZE, not vulnerable to
+ * timing attacks.
+ *
+ * @return 0 if both mem locations of length are equal, -1 if they are not.
+ */
+int32_t crypto_sha512_cmp(const uint8_t *cksum1, const uint8_t *cksum2);
+
+/**
+ * @brief Return a random 8 bit integer.
*/
uint8_t random_u08(void);
/**
- * Return a random 16 bit integer.
+ * @brief Return a random 16 bit integer.
*/
uint16_t random_u16(void);
/**
- * Return a random 32 bit integer.
+ * @brief Return a random 32 bit integer.
*/
uint32_t random_u32(void);
/**
- * Return a random 64 bit integer.
+ * @brief Return a random 64 bit integer.
*/
uint64_t random_u64(void);
/**
- * Fill the given nonce with random bytes.
+ * @brief Return a random 32 bit integer between 0 and upper_bound (excluded).
+ *
+ * On libsodium builds this function guarantees a uniform distribution of possible outputs.
+ * On vanilla NACL builds this function is equivalent to `random() % upper_bound`.
+ */
+uint32_t random_range_u32(uint32_t upper_bound);
+
+/**
+ * @brief Fill the given nonce with random bytes.
*/
void random_nonce(uint8_t *nonce);
/**
- * Fill an array of bytes with random values.
+ * @brief Fill an array of bytes with random values.
*/
void random_bytes(uint8_t *bytes, size_t length);
/**
- * Check if a Tox public key CRYPTO_PUBLIC_KEY_SIZE is valid or not. This
- * should only be used for input validation.
+ * @brief Check if a Tox public key CRYPTO_PUBLIC_KEY_SIZE is valid or not.
+ *
+ * This should only be used for input validation.
*
* @return false if it isn't, true if it is.
*/
bool public_key_valid(const uint8_t *public_key);
/**
- * Generate a new random keypair. Every call to this function is likely to
- * generate a different keypair.
+ * @brief Generate a new random keypair.
+ *
+ * Every call to this function is likely to generate a different keypair.
*/
int32_t crypto_new_keypair(uint8_t *public_key, uint8_t *secret_key);
/**
- * Derive the public key from a given secret key.
+ * @brief Derive the public key from a given secret key.
*/
void crypto_derive_public_key(uint8_t *public_key, const uint8_t *secret_key);
/**
- * Encrypt plain text of the given length to encrypted of length +
- * CRYPTO_MAC_SIZE using the public key (CRYPTO_PUBLIC_KEY_SIZE bytes) of the
- * receiver and the secret key of the sender and a CRYPTO_NONCE_SIZE byte
- * nonce.
+ * @brief Encrypt message to send from secret key to public key.
*
- * @return -1 if there was a problem, length of encrypted data if everything
- * was fine.
+ * Encrypt plain text of the given length to encrypted of
+ * `length + CRYPTO_MAC_SIZE` using the public key (@ref CRYPTO_PUBLIC_KEY_SIZE
+ * bytes) of the receiver and the secret key of the sender and a
+ * @ref CRYPTO_NONCE_SIZE byte nonce.
+ *
+ * @retval -1 if there was a problem.
+ * @retval >=0 length of encrypted data if everything was fine.
*/
int32_t encrypt_data(const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *nonce, const uint8_t *plain,
size_t length, uint8_t *encrypted);
/**
- * Decrypt encrypted text of the given length to plain text of the given length
- * - CRYPTO_MAC_SIZE using the public key (CRYPTO_PUBLIC_KEY_SIZE bytes) of
- * the sender, the secret key of the receiver and a CRYPTO_NONCE_SIZE byte
- * nonce.
+ * @brief Decrypt message from public key to secret key.
+ *
+ * Decrypt encrypted text of the given @p length to plain text of the given
+ * `length - CRYPTO_MAC_SIZE` using the public key (@ref CRYPTO_PUBLIC_KEY_SIZE
+ * bytes) of the sender, the secret key of the receiver and a
+ * @ref CRYPTO_NONCE_SIZE byte nonce.
*
- * @return -1 if there was a problem (decryption failed), length of plain text
- * data if everything was fine.
+ * @retval -1 if there was a problem (decryption failed).
+ * @retval >=0 length of plain text data if everything was fine.
*/
int32_t decrypt_data(const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *nonce,
const uint8_t *encrypted, size_t length, uint8_t *plain);
/**
- * Fast encrypt/decrypt operations. Use if this is not a one-time communication.
- * encrypt_precompute does the shared-key generation once so it does not have
- * to be performed on every encrypt/decrypt.
+ * @brief Fast encrypt/decrypt operations.
+ *
+ * Use if this is not a one-time communication. @ref encrypt_precompute does the
+ * shared-key generation once so it does not have to be performed on every
+ * encrypt/decrypt.
*/
int32_t encrypt_precompute(const uint8_t *public_key, const uint8_t *secret_key, uint8_t *shared_key);
/**
- * Encrypts plain of length length to encrypted of length + CRYPTO_MAC_SIZE
- * using a shared key CRYPTO_SYMMETRIC_KEY_SIZE big and a CRYPTO_NONCE_SIZE
+ * @brief Encrypt message with precomputed shared key.
+ *
+ * Encrypts plain of length length to encrypted of length + @ref CRYPTO_MAC_SIZE
+ * using a shared key @ref CRYPTO_SYMMETRIC_KEY_SIZE big and a @ref CRYPTO_NONCE_SIZE
* byte nonce.
*
* @return -1 if there was a problem, length of encrypted data if everything
@@ -203,9 +204,11 @@ int32_t encrypt_data_symmetric(const uint8_t *shared_key, const uint8_t *nonce,
uint8_t *encrypted);
/**
+ * @brief Decrypt message with precomputed shared key.
+ *
* Decrypts encrypted of length length to plain of length length -
- * CRYPTO_MAC_SIZE using a shared key CRYPTO_SHARED_KEY_SIZE big and a
- * CRYPTO_NONCE_SIZE byte nonce.
+ * @ref CRYPTO_MAC_SIZE using a shared key @ref CRYPTO_SHARED_KEY_SIZE big and a
+ * @ref CRYPTO_NONCE_SIZE byte nonce.
*
* @return -1 if there was a problem (decryption failed), length of plain data
* if everything was fine.
@@ -214,22 +217,46 @@ int32_t decrypt_data_symmetric(const uint8_t *shared_key, const uint8_t *nonce,
uint8_t *plain);
/**
- * Increment the given nonce by 1 in big endian (rightmost byte incremented
+ * @brief Increment the given nonce by 1 in big endian (rightmost byte incremented
* first).
*/
void increment_nonce(uint8_t *nonce);
/**
- * Increment the given nonce by a given number. The number should be in host
- * byte order.
+ * @brief Increment the given nonce by a given number.
+ *
+ * The number should be in host byte order.
*/
-void increment_nonce_number(uint8_t *nonce, uint32_t host_order_num);
+void increment_nonce_number(uint8_t *nonce, uint32_t increment);
/**
- * Fill a key CRYPTO_SYMMETRIC_KEY_SIZE big with random bytes.
+ * @brief Fill a key @ref CRYPTO_SYMMETRIC_KEY_SIZE big with random bytes.
*/
void new_symmetric_key(uint8_t *key);
+/**
+ * @brief Locks `length` bytes of memory pointed to by `data`.
+ *
+ * This will attempt to prevent the specified memory region from being swapped
+ * to disk.
+ *
+ * @return true on success.
+ */
+bool crypto_memlock(void *data, size_t length);
+
+/**
+ * @brief Unlocks `length` bytes of memory pointed to by `data`.
+ *
+ * This allows the specified memory region to be swapped to disk.
+ *
+ * This function call has the side effect of zeroing the specified memory region
+ * whether or not it succeeds. Therefore it should only be used once the memory
+ * is no longer in use.
+ *
+ * @return true on success.
+ */
+bool crypto_memunlock(void *data, size_t length);
+
#ifdef __cplusplus
} // extern "C"
#endif
diff --git a/protocols/Tox/libtox/src/toxcore/crypto_core_mem.c b/protocols/Tox/libtox/src/toxcore/crypto_core_mem.c
deleted file mode 100644
index b8c0bd9b98..0000000000
--- a/protocols/Tox/libtox/src/toxcore/crypto_core_mem.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * ISC License
- *
- * Copyright (c) 2013-2016
- * Frank Denis <j at pureftpd dot org>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "crypto_core.h"
-
-#ifndef VANILLA_NACL
-/* We use libsodium by default. */
-#include <sodium.h>
-#else
-#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
-#include <windows.h>
-#include <wincrypt.h>
-#endif
-#endif
-
-
-void crypto_memzero(void *data, size_t length)
-{
-#ifndef VANILLA_NACL
- sodium_memzero(data, length);
-#elif defined(_WIN32)
- SecureZeroMemory(data, length);
-#elif defined(HAVE_MEMSET_S)
-
- if (length > 0U) {
- errno_t code = memset_s(data, (rsize_t) length, 0, (rsize_t) length);
-
- if (code != 0) {
- abort(); /* LCOV_EXCL_LINE */
- }
- }
-
-#elif defined(HAVE_EXPLICIT_BZERO)
- explicit_bzero(data, length);
-#else
- //!TOKSTYLE-
- volatile uint8_t *volatile pnt = data;
- //!TOKSTYLE+
- size_t i = (size_t) 0U;
-
- while (i < length) {
- pnt[i] = 0U;
- ++i;
- }
-
-#endif
-}
-
-int32_t crypto_memcmp(const uint8_t *p1, const uint8_t *p2, size_t length)
-{
-#ifndef VANILLA_NACL
- return sodium_memcmp(p1, p2, length);
-#else
- //!TOKSTYLE-
- const volatile uint8_t *volatile b1 = p1;
- const volatile uint8_t *volatile b2 = p2;
- //!TOKSTYLE+
-
- size_t i;
- uint8_t d = (uint8_t) 0U;
-
- for (i = 0U; i < length; ++i) {
- d |= b1[i] ^ b2[i];
- }
-
- return (1 & ((d - 1) >> 8)) - 1;
-#endif
-}
diff --git a/protocols/Tox/libtox/src/toxcore/friend_connection.c b/protocols/Tox/libtox/src/toxcore/friend_connection.c
index 496b83b505..8a46194848 100644
--- a/protocols/Tox/libtox/src/toxcore/friend_connection.c
+++ b/protocols/Tox/libtox/src/toxcore/friend_connection.c
@@ -3,13 +3,9 @@
* Copyright © 2014 Tox project.
*/
-/*
+/**
* Connection to friends.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include "friend_connection.h"
#include <stdlib.h>
@@ -29,7 +25,7 @@ typedef struct Friend_Conn_Callbacks {
int callback_id;
} Friend_Conn_Callbacks;
-typedef struct Friend_Conn {
+struct Friend_Conn {
uint8_t status;
uint8_t real_public_key[CRYPTO_PUBLIC_KEY_SIZE];
@@ -54,7 +50,7 @@ typedef struct Friend_Conn {
uint16_t tcp_relay_counter;
bool hosting_tcp_relay;
-} Friend_Conn;
+};
struct Friend_Connections {
@@ -79,13 +75,23 @@ struct Friend_Connections {
bool local_discovery_enabled;
};
+int friend_conn_get_onion_friendnum(const Friend_Conn *fc)
+{
+ return fc->onion_friendnum;
+}
+
Net_Crypto *friendconn_net_crypto(const Friend_Connections *fr_c)
{
return fr_c->net_crypto;
}
+const IP_Port *friend_conn_get_dht_ip_port(const Friend_Conn *fc)
+{
+ return &fc->dht_ip_port;
+}
+
-/* return true if the friendcon_id is valid.
+/** return true if the friendcon_id is valid.
* return false if the friendcon_id is not valid.
*/
static bool friendconn_id_valid(const Friend_Connections *fr_c, int friendcon_id)
@@ -96,7 +102,7 @@ static bool friendconn_id_valid(const Friend_Connections *fr_c, int friendcon_id
}
-/* Set the size of the friend connections list to num.
+/** Set the size of the friend connections list to num.
*
* return false if realloc fails.
* return true if it succeeds.
@@ -119,7 +125,7 @@ static bool realloc_friendconns(Friend_Connections *fr_c, uint32_t num)
return true;
}
-/* Create a new empty friend connection.
+/** Create a new empty friend connection.
*
* return -1 on failure.
* return friendcon_id on success.
@@ -143,7 +149,7 @@ static int create_friend_conn(Friend_Connections *fr_c)
return id;
}
-/* Wipe a friend connection.
+/** Wipe a friend connection.
*
* return -1 on failure.
* return 0 on success.
@@ -172,7 +178,7 @@ static int wipe_friend_conn(Friend_Connections *fr_c, int friendcon_id)
return 0;
}
-static Friend_Conn *get_conn(const Friend_Connections *fr_c, int friendcon_id)
+Friend_Conn *get_conn(const Friend_Connections *fr_c, int friendcon_id)
{
if (!friendconn_id_valid(fr_c, friendcon_id)) {
return nullptr;
@@ -181,13 +187,13 @@ static Friend_Conn *get_conn(const Friend_Connections *fr_c, int friendcon_id)
return &fr_c->conns[friendcon_id];
}
-/* return friendcon_id corresponding to the real public key on success.
+/** return friendcon_id corresponding to the real public key on success.
* return -1 on failure.
*/
-int getfriend_conn_id_pk(Friend_Connections *fr_c, const uint8_t *real_pk)
+int getfriend_conn_id_pk(const Friend_Connections *fr_c, const uint8_t *real_pk)
{
for (uint32_t i = 0; i < fr_c->num_cons; ++i) {
- Friend_Conn *friend_con = get_conn(fr_c, i);
+ const Friend_Conn *friend_con = get_conn(fr_c, i);
if (friend_con) {
if (public_key_cmp(friend_con->real_public_key, real_pk) == 0) {
@@ -199,13 +205,16 @@ int getfriend_conn_id_pk(Friend_Connections *fr_c, const uint8_t *real_pk)
return -1;
}
-/* Add a TCP relay associated to the friend.
+/** Add a TCP relay associated to the friend.
*
* return -1 on failure.
* return 0 on success.
*/
-int friend_add_tcp_relay(Friend_Connections *fr_c, int friendcon_id, IP_Port ip_port, const uint8_t *public_key)
+static int friend_add_tcp_relay(Friend_Connections *fr_c, int friendcon_id, const IP_Port *ip_port,
+ const uint8_t *public_key)
{
+ IP_Port ipp_copy = *ip_port;
+
Friend_Conn *const friend_con = get_conn(fr_c, friendcon_id);
if (!friend_con) {
@@ -213,9 +222,9 @@ int friend_add_tcp_relay(Friend_Connections *fr_c, int friendcon_id, IP_Port ip_
}
/* Local ip and same pk means that they are hosting a TCP relay. */
- if (ip_is_local(ip_port.ip) && public_key_cmp(friend_con->dht_temp_pk, public_key) == 0) {
+ if (ip_is_local(&ipp_copy.ip) && public_key_cmp(friend_con->dht_temp_pk, public_key) == 0) {
if (!net_family_is_unspec(friend_con->dht_ip_port.ip.family)) {
- ip_port.ip = friend_con->dht_ip_port.ip;
+ ipp_copy.ip = friend_con->dht_ip_port.ip;
} else {
friend_con->hosting_tcp_relay = 0;
}
@@ -230,14 +239,14 @@ int friend_add_tcp_relay(Friend_Connections *fr_c, int friendcon_id, IP_Port ip_
}
}
- friend_con->tcp_relays[index].ip_port = ip_port;
+ friend_con->tcp_relays[index].ip_port = ipp_copy;
memcpy(friend_con->tcp_relays[index].public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE);
++friend_con->tcp_relay_counter;
- return add_tcp_relay_peer(fr_c->net_crypto, friend_con->crypt_connection_id, ip_port, public_key);
+ return add_tcp_relay_peer(fr_c->net_crypto, friend_con->crypt_connection_id, &ipp_copy, public_key);
}
-/* Connect to number saved relays for friend. */
+/** Connect to number saved relays for friend. */
static void connect_to_saved_tcp_relays(Friend_Connections *fr_c, int friendcon_id, unsigned int number)
{
const Friend_Conn *const friend_con = get_conn(fr_c, friendcon_id);
@@ -250,7 +259,7 @@ static void connect_to_saved_tcp_relays(Friend_Connections *fr_c, int friendcon_
const uint16_t index = (friend_con->tcp_relay_counter - (i + 1)) % FRIEND_MAX_STORED_TCP_RELAYS;
if (!net_family_is_unspec(friend_con->tcp_relays[index].ip_port.ip.family)) {
- if (add_tcp_relay_peer(fr_c->net_crypto, friend_con->crypt_connection_id, friend_con->tcp_relays[index].ip_port,
+ if (add_tcp_relay_peer(fr_c->net_crypto, friend_con->crypt_connection_id, &friend_con->tcp_relays[index].ip_port,
friend_con->tcp_relays[index].public_key) == 0) {
--number;
}
@@ -266,7 +275,7 @@ static unsigned int send_relays(Friend_Connections *fr_c, int friendcon_id)
return 0;
}
- Node_format nodes[MAX_SHARED_RELAYS];
+ Node_format nodes[MAX_SHARED_RELAYS] = {{{0}}};
uint8_t data[1024];
const int n = copy_connected_tcp_relays(fr_c->net_crypto, nodes, MAX_SHARED_RELAYS);
@@ -274,7 +283,7 @@ static unsigned int send_relays(Friend_Connections *fr_c, int friendcon_id)
for (int i = 0; i < n; ++i) {
/* Associated the relays being sent with this connection.
* On receiving the peer will do the same which will establish the connection. */
- friend_add_tcp_relay(fr_c, friendcon_id, nodes[i].ip_port, nodes[i].public_key);
+ friend_add_tcp_relay(fr_c, friendcon_id, &nodes[i].ip_port, nodes[i].public_key);
}
int length = pack_nodes(data + 1, sizeof(data) - 1, nodes, n);
@@ -294,8 +303,8 @@ static unsigned int send_relays(Friend_Connections *fr_c, int friendcon_id)
return 0;
}
-/* callback for recv TCP relay nodes. */
-static int tcp_relay_node_callback(void *object, uint32_t number, IP_Port ip_port, const uint8_t *public_key)
+/** callback for recv TCP relay nodes. */
+static int tcp_relay_node_callback(void *object, uint32_t number, const IP_Port *ip_port, const uint8_t *public_key)
{
Friend_Connections *fr_c = (Friend_Connections *)object;
const Friend_Conn *friend_con = get_conn(fr_c, number);
@@ -312,8 +321,8 @@ static int tcp_relay_node_callback(void *object, uint32_t number, IP_Port ip_por
}
static int friend_new_connection(Friend_Connections *fr_c, int friendcon_id);
-/* Callback for DHT ip_port changes. */
-static void dht_ip_callback(void *object, int32_t number, IP_Port ip_port)
+/** Callback for DHT ip_port changes. */
+static void dht_ip_callback(void *object, int32_t number, const IP_Port *ip_port)
{
Friend_Connections *const fr_c = (Friend_Connections *)object;
Friend_Conn *const friend_con = get_conn(fr_c, number);
@@ -327,7 +336,7 @@ static void dht_ip_callback(void *object, int32_t number, IP_Port ip_port)
}
set_direct_ip_port(fr_c->net_crypto, friend_con->crypt_connection_id, ip_port, 1);
- friend_con->dht_ip_port = ip_port;
+ friend_con->dht_ip_port = *ip_port;
friend_con->dht_ip_port_lastrecv = mono_time_get(fr_c->mono_time);
if (friend_con->hosting_tcp_relay) {
@@ -405,7 +414,7 @@ static int handle_status(void *object, int number, uint8_t status, void *userdat
return 0;
}
-/* Callback for dht public key changes. */
+/** Callback for dht public key changes. */
static void dht_pk_callback(void *object, int32_t number, const uint8_t *dht_public_key, void *userdata)
{
Friend_Connections *const fr_c = (Friend_Connections *)object;
@@ -467,7 +476,7 @@ static int handle_packet(void *object, int number, const uint8_t *data, uint16_t
}
for (int j = 0; j < n; ++j) {
- friend_add_tcp_relay(fr_c, number, nodes[j].ip_port, nodes[j].public_key);
+ friend_add_tcp_relay(fr_c, number, &nodes[j].ip_port, nodes[j].public_key);
}
return 0;
@@ -496,7 +505,7 @@ static int handle_lossy_packet(void *object, int number, const uint8_t *data, ui
return -1;
}
- Friend_Connections *const fr_c = (Friend_Connections *)object;
+ const Friend_Connections *const fr_c = (const Friend_Connections *)object;
const Friend_Conn *friend_con = get_conn(fr_c, number);
if (!friend_con) {
@@ -520,7 +529,7 @@ static int handle_lossy_packet(void *object, int number, const uint8_t *data, ui
return 0;
}
-static int handle_new_connections(void *object, New_Connection *n_c)
+static int handle_new_connections(void *object, const New_Connection *n_c)
{
Friend_Connections *const fr_c = (Friend_Connections *)object;
const int friendcon_id = getfriend_conn_id_pk(fr_c, n_c->public_key);
@@ -546,7 +555,7 @@ static int handle_new_connections(void *object, New_Connection *n_c)
friend_con->crypt_connection_id = id;
if (!net_family_is_ipv4(n_c->source.ip.family) && !net_family_is_ipv6(n_c->source.ip.family)) {
- set_direct_ip_port(fr_c->net_crypto, friend_con->crypt_connection_id, friend_con->dht_ip_port, 0);
+ set_direct_ip_port(fr_c->net_crypto, friend_con->crypt_connection_id, &friend_con->dht_ip_port, 0);
} else {
friend_con->dht_ip_port = n_c->source;
friend_con->dht_ip_port_lastrecv = mono_time_get(fr_c->mono_time);
@@ -611,12 +620,12 @@ static int send_ping(const Friend_Connections *fr_c, int friendcon_id)
return -1;
}
-/* Increases lock_count for the connection with friendcon_id by 1.
+/** Increases lock_count for the connection with friendcon_id by 1.
*
* return 0 on success.
* return -1 on failure.
*/
-int friend_connection_lock(Friend_Connections *fr_c, int friendcon_id)
+int friend_connection_lock(const Friend_Connections *fr_c, int friendcon_id)
{
Friend_Conn *const friend_con = get_conn(fr_c, friendcon_id);
@@ -628,11 +637,11 @@ int friend_connection_lock(Friend_Connections *fr_c, int friendcon_id)
return 0;
}
-/* return FRIENDCONN_STATUS_CONNECTED if the friend is connected.
+/** return FRIENDCONN_STATUS_CONNECTED if the friend is connected.
* return FRIENDCONN_STATUS_CONNECTING if the friend isn't connected.
* return FRIENDCONN_STATUS_NONE on failure.
*/
-unsigned int friend_con_connected(Friend_Connections *fr_c, int friendcon_id)
+unsigned int friend_con_connected(const Friend_Connections *fr_c, int friendcon_id)
{
const Friend_Conn *const friend_con = get_conn(fr_c, friendcon_id);
@@ -643,12 +652,12 @@ unsigned int friend_con_connected(Friend_Connections *fr_c, int friendcon_id)
return friend_con->status;
}
-/* Copy public keys associated to friendcon_id.
+/** Copy public keys associated to friendcon_id.
*
* return 0 on success.
* return -1 on failure.
*/
-int get_friendcon_public_keys(uint8_t *real_pk, uint8_t *dht_temp_pk, Friend_Connections *fr_c, int friendcon_id)
+int get_friendcon_public_keys(uint8_t *real_pk, uint8_t *dht_temp_pk, const Friend_Connections *fr_c, int friendcon_id)
{
const Friend_Conn *const friend_con = get_conn(fr_c, friendcon_id);
@@ -667,20 +676,20 @@ int get_friendcon_public_keys(uint8_t *real_pk, uint8_t *dht_temp_pk, Friend_Con
return 0;
}
-/* Set temp dht key for connection.
+/** Set temp dht key for connection.
*/
void set_dht_temp_pk(Friend_Connections *fr_c, int friendcon_id, const uint8_t *dht_temp_pk, void *userdata)
{
dht_pk_callback(fr_c, friendcon_id, dht_temp_pk, userdata);
}
-/* Set the callbacks for the friend connection.
+/** Set the callbacks for the friend connection.
* index is the index (0 to (MAX_FRIEND_CONNECTION_CALLBACKS - 1)) we want the callback to set in the array.
*
* return 0 on success.
* return -1 on failure
*/
-int friend_connection_callbacks(Friend_Connections *fr_c, int friendcon_id, unsigned int index,
+int friend_connection_callbacks(const Friend_Connections *fr_c, int friendcon_id, unsigned int index,
fc_status_cb *status_callback,
fc_data_cb *data_callback,
fc_lossy_data_cb *lossy_data_callback,
@@ -706,19 +715,19 @@ int friend_connection_callbacks(Friend_Connections *fr_c, int friendcon_id, unsi
return 0;
}
-/* Set global status callback for friend connections. */
+/** Set global status callback for friend connections. */
void set_global_status_callback(Friend_Connections *fr_c, global_status_cb *global_status_callback, void *object)
{
fr_c->global_status_callback = global_status_callback;
fr_c->global_status_callback_object = object;
}
-/* return the crypt_connection_id for the connection.
+/** return the crypt_connection_id for the connection.
*
* return crypt_connection_id on success.
* return -1 on failure.
*/
-int friend_connection_crypt_connection_id(Friend_Connections *fr_c, int friendcon_id)
+int friend_connection_crypt_connection_id(const Friend_Connections *fr_c, int friendcon_id)
{
const Friend_Conn *const friend_con = get_conn(fr_c, friendcon_id);
@@ -729,7 +738,7 @@ int friend_connection_crypt_connection_id(Friend_Connections *fr_c, int friendco
return friend_con->crypt_connection_id;
}
-/* Create a new friend connection.
+/** Create a new friend connection.
* If one to that real public key already exists, increase lock count and return it.
*
* return -1 on failure.
@@ -769,7 +778,7 @@ int new_friend_connection(Friend_Connections *fr_c, const uint8_t *real_public_k
return friendcon_id;
}
-/* Kill a friend connection.
+/** Kill a friend connection.
*
* return -1 on failure.
* return 0 on success.
@@ -798,7 +807,7 @@ int kill_friend_connection(Friend_Connections *fr_c, int friendcon_id)
}
-/* Set friend request callback.
+/** Set friend request callback.
*
* This function will be called every time a friend request packet is received.
*/
@@ -809,7 +818,7 @@ void set_friend_request_callback(Friend_Connections *fr_c, fr_request_cb *fr_req
oniondata_registerhandler(fr_c->onion_c, CRYPTO_PACKET_FRIEND_REQ, fr_request_callback, object);
}
-/* Send a Friend request packet.
+/** Send a Friend request packet.
*
* return -1 if failure.
* return 0 if it sent the friend request directly to the friend.
@@ -847,7 +856,7 @@ int send_friend_request_packet(Friend_Connections *fr_c, int friendcon_id, uint3
return num;
}
-/* Create new friend_connections instance. */
+/** Create new friend_connections instance. */
Friend_Connections *new_friend_connections(const Logger *logger, const Mono_Time *mono_time, Onion_Client *onion_c,
bool local_discovery_enabled)
{
@@ -879,7 +888,7 @@ Friend_Connections *new_friend_connections(const Logger *logger, const Mono_Time
return temp;
}
-/* Send a LAN discovery packet every LAN_DISCOVERY_INTERVAL seconds. */
+/** Send a LAN discovery packet every LAN_DISCOVERY_INTERVAL seconds. */
static void lan_discovery(Friend_Connections *fr_c)
{
if (fr_c->last_lan_discovery + LAN_DISCOVERY_INTERVAL < mono_time_get(fr_c->mono_time)) {
@@ -888,11 +897,11 @@ static void lan_discovery(Friend_Connections *fr_c)
last = last > TOX_PORTRANGE_TO ? TOX_PORTRANGE_TO : last;
// Always send to default port
- lan_discovery_send(net_htons(TOX_PORT_DEFAULT), fr_c->dht);
+ lan_discovery_send(dht_get_net(fr_c->dht), dht_get_self_public_key(fr_c->dht), net_htons(TOX_PORT_DEFAULT));
// And check some extra ports
for (uint16_t port = first; port < last; ++port) {
- lan_discovery_send(net_htons(port), fr_c->dht);
+ lan_discovery_send(dht_get_net(fr_c->dht), dht_get_self_public_key(fr_c->dht), net_htons(port));
}
// Don't include default port in port range
@@ -901,7 +910,7 @@ static void lan_discovery(Friend_Connections *fr_c)
}
}
-/* main friend_connections loop. */
+/** main friend_connections loop. */
void do_friend_connections(Friend_Connections *fr_c, void *userdata)
{
const uint64_t temp_time = mono_time_get(fr_c->mono_time);
@@ -925,8 +934,8 @@ void do_friend_connections(Friend_Connections *fr_c, void *userdata)
if (friend_con->dht_lock) {
if (friend_new_connection(fr_c, i) == 0) {
- set_direct_ip_port(fr_c->net_crypto, friend_con->crypt_connection_id, friend_con->dht_ip_port, 0);
- connect_to_saved_tcp_relays(fr_c, i, (MAX_FRIEND_TCP_CONNECTIONS / 2)); /* Only fill it half up. */
+ set_direct_ip_port(fr_c->net_crypto, friend_con->crypt_connection_id, &friend_con->dht_ip_port, 0);
+ connect_to_saved_tcp_relays(fr_c, i, MAX_FRIEND_TCP_CONNECTIONS / 2); /* Only fill it half up. */
}
}
} else if (friend_con->status == FRIENDCONN_STATUS_CONNECTED) {
@@ -953,7 +962,7 @@ void do_friend_connections(Friend_Connections *fr_c, void *userdata)
}
}
-/* Free everything related with friend_connections. */
+/** Free everything related with friend_connections. */
void kill_friend_connections(Friend_Connections *fr_c)
{
if (!fr_c) {
diff --git a/protocols/Tox/libtox/src/toxcore/friend_connection.h b/protocols/Tox/libtox/src/toxcore/friend_connection.h
index fecd745565..4986b3bfb9 100644
--- a/protocols/Tox/libtox/src/toxcore/friend_connection.h
+++ b/protocols/Tox/libtox/src/toxcore/friend_connection.h
@@ -3,7 +3,7 @@
* Copyright © 2014 Tox project.
*/
-/*
+/**
* Connection to friends.
*/
#ifndef C_TOXCORE_TOXCORE_FRIEND_CONNECTION_H
@@ -22,21 +22,21 @@
#define PACKET_ID_SHARE_RELAYS 17
#define PACKET_ID_FRIEND_REQUESTS 18
-/* Interval between the sending of ping packets. */
+/** Interval between the sending of ping packets. */
#define FRIEND_PING_INTERVAL 8
-/* If no packets are received from friend in this time interval, kill the connection. */
+/** If no packets are received from friend in this time interval, kill the connection. */
#define FRIEND_CONNECTION_TIMEOUT (FRIEND_PING_INTERVAL * 4)
-/* Time before friend is removed from the DHT after last hearing about him. */
+/** Time before friend is removed from the DHT after last hearing about him. */
#define FRIEND_DHT_TIMEOUT BAD_NODE_TIMEOUT
#define FRIEND_MAX_STORED_TCP_RELAYS (MAX_FRIEND_TCP_CONNECTIONS * 4)
-/* Max number of tcp relays sent to friends */
+/** Max number of tcp relays sent to friends */
#define MAX_SHARED_RELAYS RECOMMENDED_FRIEND_TCP_CONNECTIONS
-/* Interval between the sending of tcp relay information */
+/** Interval between the sending of tcp relay information */
#define SHARE_RELAYS_INTERVAL (5 * 60)
@@ -50,71 +50,64 @@ typedef struct Friend_Connections Friend_Connections;
Net_Crypto *friendconn_net_crypto(const Friend_Connections *fr_c);
-/* return friendcon_id corresponding to the real public key on success.
+/** return friendcon_id corresponding to the real public key on success.
* return -1 on failure.
*/
-int getfriend_conn_id_pk(Friend_Connections *fr_c, const uint8_t *real_pk);
+int getfriend_conn_id_pk(const Friend_Connections *fr_c, const uint8_t *real_pk);
-/* Increases lock_count for the connection with friendcon_id by 1.
+/** Increases lock_count for the connection with friendcon_id by 1.
*
* return 0 on success.
* return -1 on failure.
*/
-int friend_connection_lock(Friend_Connections *fr_c, int friendcon_id);
+int friend_connection_lock(const Friend_Connections *fr_c, int friendcon_id);
-/* return FRIENDCONN_STATUS_CONNECTED if the friend is connected.
+/** return FRIENDCONN_STATUS_CONNECTED if the friend is connected.
* return FRIENDCONN_STATUS_CONNECTING if the friend isn't connected.
* return FRIENDCONN_STATUS_NONE on failure.
*/
-unsigned int friend_con_connected(Friend_Connections *fr_c, int friendcon_id);
+unsigned int friend_con_connected(const Friend_Connections *fr_c, int friendcon_id);
-/* Copy public keys associated to friendcon_id.
+/** Copy public keys associated to friendcon_id.
*
* return 0 on success.
* return -1 on failure.
*/
-int get_friendcon_public_keys(uint8_t *real_pk, uint8_t *dht_temp_pk, Friend_Connections *fr_c, int friendcon_id);
+int get_friendcon_public_keys(uint8_t *real_pk, uint8_t *dht_temp_pk, const Friend_Connections *fr_c, int friendcon_id);
-/* Set temp dht key for connection.
+/** Set temp dht key for connection.
*/
void set_dht_temp_pk(Friend_Connections *fr_c, int friendcon_id, const uint8_t *dht_temp_pk, void *userdata);
-/* Add a TCP relay associated to the friend.
- *
- * return -1 on failure.
- * return 0 on success.
- */
-int friend_add_tcp_relay(Friend_Connections *fr_c, int friendcon_id, IP_Port ip_port, const uint8_t *public_key);
-
typedef int global_status_cb(void *object, int id, uint8_t status, void *userdata);
typedef int fc_status_cb(void *object, int id, uint8_t status, void *userdata);
typedef int fc_data_cb(void *object, int id, const uint8_t *data, uint16_t length, void *userdata);
typedef int fc_lossy_data_cb(void *object, int id, const uint8_t *data, uint16_t length, void *userdata);
-/* Set global status callback for friend connections. */
+/** Set global status callback for friend connections. */
void set_global_status_callback(Friend_Connections *fr_c, global_status_cb *global_status_callback, void *object);
-/* Set the callbacks for the friend connection.
+/** Set the callbacks for the friend connection.
* index is the index (0 to (MAX_FRIEND_CONNECTION_CALLBACKS - 1)) we want the callback to set in the array.
*
* return 0 on success.
* return -1 on failure
*/
-int friend_connection_callbacks(Friend_Connections *fr_c, int friendcon_id, unsigned int index,
+int friend_connection_callbacks(const Friend_Connections *fr_c, int friendcon_id, unsigned int index,
fc_status_cb *status_callback,
fc_data_cb *data_callback,
fc_lossy_data_cb *lossy_data_callback,
void *object, int number);
-/* return the crypt_connection_id for the connection.
+/** return the crypt_connection_id for the connection.
*
* return crypt_connection_id on success.
* return -1 on failure.
*/
-int friend_connection_crypt_connection_id(Friend_Connections *fr_c, int friendcon_id);
+int friend_connection_crypt_connection_id(const Friend_Connections *fr_c, int friendcon_id);
-/* Create a new friend connection.
+/** Create a new friend connection.
* If one to that real public key already exists, increase lock count and return it.
*
* return -1 on failure.
@@ -122,14 +115,14 @@ int friend_connection_crypt_connection_id(Friend_Connections *fr_c, int friendco
*/
int new_friend_connection(Friend_Connections *fr_c, const uint8_t *real_public_key);
-/* Kill a friend connection.
+/** Kill a friend connection.
*
* return -1 on failure.
* return 0 on success.
*/
int kill_friend_connection(Friend_Connections *fr_c, int friendcon_id);
-/* Send a Friend request packet.
+/** Send a Friend request packet.
*
* return -1 if failure.
* return 0 if it sent the friend request directly to the friend.
@@ -141,20 +134,26 @@ int send_friend_request_packet(Friend_Connections *fr_c, int friendcon_id, uint3
typedef int fr_request_cb(void *object, const uint8_t *source_pubkey, const uint8_t *data, uint16_t len,
void *userdata);
-/* Set friend request callback.
+/** Set friend request callback.
*
- * This function will be called every time a friend request is received.
+ * This function will be called every time a friend request packet is received.
*/
void set_friend_request_callback(Friend_Connections *fr_c, fr_request_cb *fr_request_callback, void *object);
-/* Create new friend_connections instance. */
+/** Create new friend_connections instance. */
Friend_Connections *new_friend_connections(const Logger *logger, const Mono_Time *mono_time, Onion_Client *onion_c,
bool local_discovery_enabled);
-/* main friend_connections loop. */
+/** main friend_connections loop. */
void do_friend_connections(Friend_Connections *fr_c, void *userdata);
-/* Free everything related with friend_connections. */
+/** Free everything related with friend_connections. */
void kill_friend_connections(Friend_Connections *fr_c);
+typedef struct Friend_Conn Friend_Conn;
+
+Friend_Conn *get_conn(const Friend_Connections *fr_c, int friendcon_id);
+int friend_conn_get_onion_friendnum(const Friend_Conn *fc);
+const IP_Port *friend_conn_get_dht_ip_port(const Friend_Conn *fc);
+
#endif
diff --git a/protocols/Tox/libtox/src/toxcore/friend_requests.c b/protocols/Tox/libtox/src/toxcore/friend_requests.c
index c6c9a0e048..f4d572996d 100644
--- a/protocols/Tox/libtox/src/toxcore/friend_requests.c
+++ b/protocols/Tox/libtox/src/toxcore/friend_requests.c
@@ -3,13 +3,9 @@
* Copyright © 2013 Tox project.
*/
-/*
+/**
* Handle friend requests.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include "friend_requests.h"
#include <stdlib.h>
@@ -17,7 +13,7 @@
#include "util.h"
-/* NOTE: The following is just a temporary fix for the multiple friend requests received at the same time problem.
+/** NOTE: The following is just a temporary fix for the multiple friend requests received at the same time problem.
* TODO(irungentoo): Make this better (This will most likely tie in with the way we will handle spam.)
*/
#define MAX_RECEIVED_STORED 32
@@ -39,7 +35,7 @@ struct Friend_Requests {
struct Received_Requests received;
};
-/* Set and get the nospam variable used to prevent one type of friend request spam. */
+/** Set and get the nospam variable used to prevent one type of friend request spam. */
void set_nospam(Friend_Requests *fr, uint32_t num)
{
fr->nospam = num;
@@ -51,7 +47,8 @@ uint32_t get_nospam(const Friend_Requests *fr)
}
-/* Set the function that will be executed when a friend request is received. */
+/** Set the function that will be executed when a friend request for us is received.
+ */
void callback_friendrequest(Friend_Requests *fr, fr_friend_request_cb *function, void *object)
{
fr->handle_friendrequest = function;
@@ -59,14 +56,16 @@ void callback_friendrequest(Friend_Requests *fr, fr_friend_request_cb *function,
fr->handle_friendrequest_object = object;
}
-/* Set the function used to check if a friend request should be displayed to the user or not. */
+/** Set the function used to check if a friend request should be displayed to the user or not.
+ * It must return 0 if the request is ok (anything else if it is bad.)
+ */
void set_filter_function(Friend_Requests *fr, filter_function_cb *function, void *userdata)
{
fr->filter_function = function;
fr->filter_function_userdata = userdata;
}
-/* Add to list of received friend requests. */
+/** Add to list of received friend requests. */
static void addto_receivedlist(Friend_Requests *fr, const uint8_t *real_pk)
{
if (fr->received.requests_index >= MAX_RECEIVED_STORED) {
@@ -77,7 +76,7 @@ static void addto_receivedlist(Friend_Requests *fr, const uint8_t *real_pk)
++fr->received.requests_index;
}
-/* Check if a friend request was already received.
+/** Check if a friend request was already received.
*
* return false if it did not.
* return true if it did.
@@ -93,7 +92,7 @@ static bool request_received(const Friend_Requests *fr, const uint8_t *real_pk)
return false;
}
-/* Remove real pk from received.requests list.
+/** Remove real_pk from received_requests list.
*
* return 0 if it removed it successfully.
* return -1 if it didn't find it.
diff --git a/protocols/Tox/libtox/src/toxcore/friend_requests.h b/protocols/Tox/libtox/src/toxcore/friend_requests.h
index e3a03a51e8..bb2b10b81c 100644
--- a/protocols/Tox/libtox/src/toxcore/friend_requests.h
+++ b/protocols/Tox/libtox/src/toxcore/friend_requests.h
@@ -3,7 +3,7 @@
* Copyright © 2014 Tox project.
*/
-/*
+/**
* Handle friend requests.
*/
#ifndef C_TOXCORE_TOXCORE_FRIEND_REQUESTS_H
@@ -15,11 +15,11 @@
typedef struct Friend_Requests Friend_Requests;
-/* Set and get the nospam variable used to prevent one type of friend request spam. */
+/** Set and get the nospam variable used to prevent one type of friend request spam. */
void set_nospam(Friend_Requests *fr, uint32_t num);
uint32_t get_nospam(const Friend_Requests *fr);
-/* Remove real_pk from received_requests list.
+/** Remove real_pk from received_requests list.
*
* return 0 if it removed it successfully.
* return -1 if it didn't find it.
@@ -29,18 +29,18 @@ int remove_request_received(Friend_Requests *fr, const uint8_t *real_pk);
typedef void fr_friend_request_cb(void *object, const uint8_t *public_key, const uint8_t *message, size_t length,
void *user_data);
-/* Set the function that will be executed when a friend request for us is received.
+/** Set the function that will be executed when a friend request for us is received.
*/
void callback_friendrequest(Friend_Requests *fr, fr_friend_request_cb *function, void *object);
typedef int filter_function_cb(const uint8_t *public_key, void *user_data);
-/* Set the function used to check if a friend request should be displayed to the user or not.
+/** Set the function used to check if a friend request should be displayed to the user or not.
* It must return 0 if the request is ok (anything else if it is bad.)
*/
void set_filter_function(Friend_Requests *fr, filter_function_cb *function, void *userdata);
-/* Sets up friendreq packet handlers. */
+/** Sets up friendreq packet handlers. */
void friendreq_init(Friend_Requests *fr, Friend_Connections *fr_c);
Friend_Requests *friendreq_new(void);
diff --git a/protocols/Tox/libtox/src/toxcore/group.c b/protocols/Tox/libtox/src/toxcore/group.c
index 4b331f986e..fd7c491a1d 100644
--- a/protocols/Tox/libtox/src/toxcore/group.c
+++ b/protocols/Tox/libtox/src/toxcore/group.c
@@ -3,13 +3,9 @@
* Copyright © 2014 Tox project.
*/
-/*
+/**
* Slightly better groupchats implementation.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include "group.h"
#include <assert.h>
@@ -58,7 +54,15 @@ typedef enum Peer_Id {
#define MIN_MESSAGE_PACKET_LEN (sizeof(uint16_t) * 2 + sizeof(uint32_t) + 1)
-/* return false if the groupnumber is not valid.
+static_assert(GROUP_ID_LENGTH == CRYPTO_PUBLIC_KEY_SIZE,
+ "GROUP_ID_LENGTH should be equal to CRYPTO_PUBLIC_KEY_SIZE");
+
+static bool group_id_eq(const uint8_t *a, const uint8_t *b)
+{
+ return public_key_cmp(a, b) == 0;
+}
+
+/** return false if the groupnumber is not valid.
* return true if the groupnumber is valid.
*/
static bool is_groupnumber_valid(const Group_Chats *g_c, uint32_t groupnumber)
@@ -69,7 +73,7 @@ static bool is_groupnumber_valid(const Group_Chats *g_c, uint32_t groupnumber)
}
-/* Set the size of the groupchat list to num.
+/** Set the size of the groupchat list to num.
*
* return false if realloc fails.
* return true if it succeeds.
@@ -99,7 +103,7 @@ static void setup_conference(Group_c *g)
g->maxfrozen = MAX_FROZEN_DEFAULT;
}
-/* Create a new empty groupchat connection.
+/** Create a new empty groupchat connection.
*
* return -1 on failure.
* return groupnumber on success.
@@ -123,7 +127,7 @@ static int32_t create_group_chat(Group_Chats *g_c)
}
-/* Wipe a groupchat.
+/** Wipe a groupchat.
*
* return true on success.
*/
@@ -159,7 +163,7 @@ static Group_c *get_group_c(const Group_Chats *g_c, uint32_t groupnumber)
return &g_c->chats[groupnumber];
}
-/*
+/**
* check if peer with real_pk is in peer array.
*
* return peer index if peer is in group.
@@ -167,7 +171,6 @@ static Group_c *get_group_c(const Group_Chats *g_c, uint32_t groupnumber)
*
* TODO(irungentoo): make this more efficient.
*/
-
static int peer_in_group(const Group_c *g, const uint8_t *real_pk)
{
for (uint32_t i = 0; i < g->numpeers; ++i) {
@@ -190,7 +193,7 @@ static int frozen_in_group(const Group_c *g, const uint8_t *real_pk)
return -1;
}
-/*
+/**
* check if group with the given type and id is in group array.
*
* return group number if peer is in list.
@@ -201,7 +204,7 @@ static int frozen_in_group(const Group_c *g, const uint8_t *real_pk)
static int32_t get_group_num(const Group_Chats *g_c, const uint8_t type, const uint8_t *id)
{
for (uint16_t i = 0; i < g_c->num_chats; ++i) {
- if (g_c->chats[i].type == type && crypto_memcmp(g_c->chats[i].id, id, GROUP_ID_LENGTH) == 0) {
+ if (g_c->chats[i].type == type && group_id_eq(g_c->chats[i].id, id)) {
return i;
}
}
@@ -212,7 +215,7 @@ static int32_t get_group_num(const Group_Chats *g_c, const uint8_t type, const u
int32_t conference_by_id(const Group_Chats *g_c, const uint8_t *id)
{
for (uint16_t i = 0; i < g_c->num_chats; ++i) {
- if (crypto_memcmp(g_c->chats[i].id, id, GROUP_ID_LENGTH) == 0) {
+ if (group_id_eq(g_c->chats[i].id, id)) {
return i;
}
}
@@ -220,7 +223,7 @@ int32_t conference_by_id(const Group_Chats *g_c, const uint8_t *id)
return -1;
}
-/*
+/**
* check if peer with peer_number is in peer array.
*
* return peer index if peer is in chat.
@@ -295,7 +298,7 @@ static bool add_to_closest(Group_c *g, const uint8_t *real_pk, const uint8_t *te
comp_val = calculate_comp_value(real_pk, g->real_pk);
- for (unsigned int i = (DESIRED_CLOSEST / 2); i < DESIRED_CLOSEST; ++i) {
+ for (unsigned int i = DESIRED_CLOSEST / 2; i < DESIRED_CLOSEST; ++i) {
uint64_t comp = calculate_comp_value(g->closest_peers[i].real_pk, g->real_pk);
if (comp > comp_val && comp > comp_d) {
@@ -334,7 +337,7 @@ static bool add_to_closest(Group_c *g, const uint8_t *real_pk, const uint8_t *te
return true;
}
-static bool pk_in_closest_peers(const Group_c *g, uint8_t *real_pk)
+static bool pk_in_closest_peers(const Group_c *g, const uint8_t *real_pk)
{
for (unsigned int i = 0; i < DESIRED_CLOSEST; ++i) {
if (!g->closest_peers[i].entry) {
@@ -377,8 +380,8 @@ static void purge_closest(Group_Chats *g_c, uint32_t groupnumber)
}
}
-static int send_packet_online(Friend_Connections *fr_c, int friendcon_id, uint16_t group_num, uint8_t type,
- const uint8_t *id);
+static int send_packet_online(const Friend_Connections *fr_c, int friendcon_id, uint16_t group_num,
+ uint8_t type, const uint8_t *id);
static int add_conn_to_groupchat(Group_Chats *g_c, int friendcon_id, Group_c *g, uint8_t reason,
uint8_t lock);
@@ -483,7 +486,7 @@ static bool delete_frozen(Group_c *g, uint32_t frozen_index)
g->frozen[frozen_index] = g->frozen[g->numfrozen];
}
- Group_Peer *const frozen_temp = (Group_Peer *)realloc(g->frozen, sizeof(Group_Peer) * (g->numfrozen));
+ Group_Peer *const frozen_temp = (Group_Peer *)realloc(g->frozen, sizeof(Group_Peer) * g->numfrozen);
if (frozen_temp == nullptr) {
return false;
@@ -495,7 +498,7 @@ static bool delete_frozen(Group_c *g, uint32_t frozen_index)
return true;
}
-/* Update last_active timestamp on peer, and thaw the peer if it is frozen.
+/** Update last_active timestamp on peer, and thaw the peer if it is frozen.
*
* return peer index if peer is in the conference.
* return -1 otherwise, and on error.
@@ -578,7 +581,7 @@ static void delete_any_peer_with_pk(Group_Chats *g_c, uint32_t groupnumber, cons
}
}
-/* Add a peer to the group chat, or update an existing peer.
+/** Add a peer to the group chat, or update an existing peer.
*
* fresh indicates whether we should consider this information on the peer to
* be current, and so should update temp_pk and consider the peer active.
@@ -686,7 +689,7 @@ static void remove_from_closest(Group_c *g, int peer_index)
}
}
-/*
+/**
* Delete a peer from the group chat.
*
* return true on success
@@ -728,7 +731,7 @@ static bool delpeer(Group_Chats *g_c, uint32_t groupnumber, int peer_index, void
g->group[peer_index] = g->group[g->numpeers];
}
- Group_Peer *temp = (Group_Peer *)realloc(g->group, sizeof(Group_Peer) * (g->numpeers));
+ Group_Peer *temp = (Group_Peer *)realloc(g->group, sizeof(Group_Peer) * g->numpeers);
if (temp == nullptr) {
return false;
@@ -753,11 +756,11 @@ static int cmp_u64(uint64_t a, uint64_t b)
return (a > b) - (a < b);
}
-/* Order peers with friends first and with more recently active earlier */
+/** Order peers with friends first and with more recently active earlier */
static int cmp_frozen(const void *a, const void *b)
{
- const Group_Peer *pa = (const Group_Peer *) a;
- const Group_Peer *pb = (const Group_Peer *) b;
+ const Group_Peer *pa = (const Group_Peer *)a;
+ const Group_Peer *pb = (const Group_Peer *)b;
if (pa->is_friend ^ pb->is_friend) {
return pa->is_friend ? -1 : 1;
@@ -766,7 +769,7 @@ static int cmp_frozen(const void *a, const void *b)
return cmp_u64(pb->last_active, pa->last_active);
}
-/* Delete frozen peers as necessary to ensure at most g->maxfrozen remain.
+/** Delete frozen peers as necessary to ensure at most g->maxfrozen remain.
*
* return true if any frozen peers are removed.
*/
@@ -832,7 +835,7 @@ static bool freeze_peer(Group_Chats *g_c, uint32_t groupnumber, int peer_index,
}
-/* Set the nick for a peer.
+/** Set the nick for a peer.
*
* do_gc_callback indicates whether we want to trigger callbacks set by the client
* via the public API. This should be set to false if this function is called
@@ -874,7 +877,7 @@ static bool setnick(Group_Chats *g_c, uint32_t groupnumber, int peer_index, cons
return true;
}
-/* Set the title for a group.
+/** Set the title for a group.
*
* return true on success.
*/
@@ -908,10 +911,10 @@ static bool settitle(Group_Chats *g_c, uint32_t groupnumber, int peer_index, con
return true;
}
-/* Check if the group has no online connection, and freeze all peers if so */
+/** Check if the group has no online connection, and freeze all peers if so */
static void check_disconnected(Group_Chats *g_c, uint32_t groupnumber, void *userdata)
{
- Group_c *g = get_group_c(g_c, groupnumber);
+ const Group_c *g = get_group_c(g_c, groupnumber);
if (!g) {
return;
@@ -957,7 +960,7 @@ static void set_conns_type_connections(Group_Chats *g_c, uint32_t groupnumber, i
}
}
-/* Set the type for all connections with friendcon_id */
+/** Set the type for all connections with friendcon_id */
static void set_conns_status_groups(Group_Chats *g_c, int friendcon_id, uint8_t type, void *userdata)
{
for (uint16_t i = 0; i < g_c->num_chats; ++i) {
@@ -1014,7 +1017,7 @@ static int g_handle_status(void *object, int friendcon_id, uint8_t status, void
static int g_handle_packet(void *object, int friendcon_id, const uint8_t *data, uint16_t length, void *userdata);
static int handle_lossy(void *object, int friendcon_id, const uint8_t *data, uint16_t length, void *userdata);
-/* Add friend to group chat.
+/** Add friend to group chat.
*
* return connections index on success
* return -1 on failure.
@@ -1066,9 +1069,9 @@ static int add_conn_to_groupchat(Group_Chats *g_c, int friendcon_id, Group_c *g,
return ind;
}
-static unsigned int send_peer_introduced(Group_Chats *g_c, int friendcon_id, uint16_t group_num);
+static unsigned int send_peer_introduced(const Group_Chats *g_c, int friendcon_id, uint16_t group_num);
-/* Removes reason for keeping connection.
+/** Removes reason for keeping connection.
*
* Kills connection if this was the last reason.
*/
@@ -1094,7 +1097,7 @@ static void remove_connection_reason(Group_Chats *g_c, Group_c *g, uint16_t i, u
}
}
-/* Creates a new groupchat and puts it in the chats array.
+/** Creates a new groupchat and puts it in the chats array.
*
* type is one of `GROUPCHAT_TYPE_*`
*
@@ -1130,7 +1133,7 @@ int add_groupchat(Group_Chats *g_c, uint8_t type)
static bool group_leave(const Group_Chats *g_c, uint32_t groupnumber, bool permanent);
-/* Delete a groupchat from the chats array, informing the group first as
+/** Delete a groupchat from the chats array, informing the group first as
* appropriate.
*
* return 0 on success.
@@ -1184,7 +1187,7 @@ static const Group_Peer *peer_in_list(const Group_c *g, uint32_t peernumber, boo
}
-/* Copy the public key of (frozen, if frozen is true) peernumber who is in
+/** Copy the public key of (frozen, if frozen is true) peernumber who is in
* groupnumber to pk. pk must be CRYPTO_PUBLIC_KEY_SIZE long.
*
* return 0 on success
@@ -1209,7 +1212,7 @@ int group_peer_pubkey(const Group_Chats *g_c, uint32_t groupnumber, uint32_t pee
return 0;
}
-/*
+/**
* Return the size of (frozen, if frozen is true) peernumber's name.
*
* return -1 if groupnumber is invalid.
@@ -1232,7 +1235,7 @@ int group_peername_size(const Group_Chats *g_c, uint32_t groupnumber, uint32_t p
return peer->nick_len;
}
-/* Copy the name of (frozen, if frozen is true) peernumber who is in
+/** Copy the name of (frozen, if frozen is true) peernumber who is in
* groupnumber to name. name must be at least MAX_NAME_LENGTH long.
*
* return length of name if success
@@ -1260,12 +1263,12 @@ int group_peername(const Group_Chats *g_c, uint32_t groupnumber, uint32_t peernu
return peer->nick_len;
}
-/* Copy last active timestamp of frozennumber who is in groupnumber to
+/** Copy last active timestamp of frozen peernumber who is in groupnumber to
* last_active.
*
* return 0 on success.
* return -1 if groupnumber is invalid.
- * return -2 if frozennumber is invalid.
+ * return -2 if peernumber is invalid.
*/
int group_frozen_last_active(const Group_Chats *g_c, uint32_t groupnumber, uint32_t peernumber,
uint64_t *last_active)
@@ -1284,7 +1287,7 @@ int group_frozen_last_active(const Group_Chats *g_c, uint32_t groupnumber, uint3
return 0;
}
-/* Set maximum number of frozen peers.
+/** Set maximum number of frozen peers.
*
* return 0 on success.
* return -1 if groupnumber is invalid.
@@ -1302,7 +1305,7 @@ int group_set_max_frozen(const Group_Chats *g_c, uint32_t groupnumber, uint32_t
return 0;
}
-/* Return the number of (frozen, if frozen is true) peers in the group chat on
+/** Return the number of (frozen, if frozen is true) peers in the group chat on
* success.
* return -1 if groupnumber is invalid.
*/
@@ -1317,7 +1320,7 @@ int group_number_peers(const Group_Chats *g_c, uint32_t groupnumber, bool frozen
return frozen ? g->numfrozen : g->numpeers;
}
-/* return 1 if the peernumber corresponds to ours.
+/** return 1 if the peernumber corresponds to ours.
* return 0 if the peernumber is not ours.
* return -1 if groupnumber is invalid.
* return -2 if peernumber is invalid.
@@ -1342,7 +1345,7 @@ int group_peernumber_is_ours(const Group_Chats *g_c, uint32_t groupnumber, uint3
return g->peer_number == g->group[peernumber].peer_number;
}
-/* return the type of groupchat (GROUPCHAT_TYPE_) that groupnumber is.
+/** return the type of groupchat (GROUPCHAT_TYPE_) that groupnumber is.
*
* return -1 on failure.
* return type on success.
@@ -1358,7 +1361,7 @@ int group_get_type(const Group_Chats *g_c, uint32_t groupnumber)
return g->type;
}
-/* Copies the unique id of `group_chat[groupnumber]` into `id`.
+/** Copies the unique id of `group_chat[groupnumber]` into `id`.
*
* return false on failure.
* return true on success.
@@ -1378,12 +1381,12 @@ bool conference_get_id(const Group_Chats *g_c, uint32_t groupnumber, uint8_t *id
return true;
}
-/* Send a group packet to friendcon_id.
+/** Send a group packet to friendcon_id.
*
* return 1 on success
* return 0 on failure
*/
-static unsigned int send_packet_group_peer(Friend_Connections *fr_c, int friendcon_id, uint8_t packet_id,
+static unsigned int send_packet_group_peer(const Friend_Connections *fr_c, int friendcon_id, uint8_t packet_id,
uint16_t group_num, const uint8_t *data, uint16_t length)
{
if (1 + sizeof(uint16_t) + length > MAX_CRYPTO_DATA_SIZE) {
@@ -1399,12 +1402,12 @@ static unsigned int send_packet_group_peer(Friend_Connections *fr_c, int friendc
SIZEOF_VLA(packet), 0) != -1;
}
-/* Send a group lossy packet to friendcon_id.
+/** Send a group lossy packet to friendcon_id.
*
* return 1 on success
* return 0 on failure
*/
-static unsigned int send_lossy_group_peer(Friend_Connections *fr_c, int friendcon_id, uint8_t packet_id,
+static unsigned int send_lossy_group_peer(const Friend_Connections *fr_c, int friendcon_id, uint8_t packet_id,
uint16_t group_num, const uint8_t *data, uint16_t length)
{
if (1 + sizeof(uint16_t) + length > MAX_CRYPTO_DATA_SIZE) {
@@ -1420,16 +1423,16 @@ static unsigned int send_lossy_group_peer(Friend_Connections *fr_c, int friendco
packet, SIZEOF_VLA(packet)) != -1;
}
-/* invite friendnumber to groupnumber.
+/** invite friendnumber to groupnumber.
*
* return 0 on success.
* return -1 if groupnumber is invalid.
* return -2 if invite packet failed to send.
* return -3 if we are not connected to the group chat.
*/
-int invite_friend(Group_Chats *g_c, uint32_t friendnumber, uint32_t groupnumber)
+int invite_friend(const Group_Chats *g_c, uint32_t friendnumber, uint32_t groupnumber)
{
- Group_c *g = get_group_c(g_c, groupnumber);
+ const Group_c *g = get_group_c(g_c, groupnumber);
if (!g) {
return -1;
@@ -1453,7 +1456,7 @@ int invite_friend(Group_Chats *g_c, uint32_t friendnumber, uint32_t groupnumber)
return -2;
}
-/* Send a rejoin packet to a peer if we have a friend connection to the peer.
+/** Send a rejoin packet to a peer if we have a friend connection to the peer.
* return true if a packet was sent.
* return false otherwise.
*/
@@ -1480,12 +1483,12 @@ static bool try_send_rejoin(Group_Chats *g_c, Group_c *g, const uint8_t *real_pk
return true;
}
-static unsigned int send_peer_query(Group_Chats *g_c, int friendcon_id, uint16_t group_num);
+static unsigned int send_peer_query(const Group_Chats *g_c, int friendcon_id, uint16_t group_num);
static bool send_invite_response(Group_Chats *g_c, int groupnumber, uint32_t friendnumber, const uint8_t *data,
uint16_t length);
-/* Join a group (we need to have been invited first.)
+/** Join a group (we need to have been invited first.)
*
* expected_type is the groupchat type we expect the chat we are joining to
* have.
@@ -1546,7 +1549,7 @@ static bool send_invite_response(Group_Chats *g_c, int groupnumber, uint32_t fri
return false;
}
- const bool member = (g->status == GROUPCHAT_STATUS_CONNECTED);
+ const bool member = g->status == GROUPCHAT_STATUS_CONNECTED;
VLA(uint8_t, response, member ? INVITE_MEMBER_PACKET_SIZE : INVITE_ACCEPT_PACKET_SIZE);
response[0] = member ? INVITE_MEMBER_ID : INVITE_ACCEPT_ID;
@@ -1591,31 +1594,31 @@ static bool send_invite_response(Group_Chats *g_c, int groupnumber, uint32_t fri
return true;
}
-/* Set handlers for custom lossy packets. */
+/** Set handlers for custom lossy packets. */
void group_lossy_packet_registerhandler(Group_Chats *g_c, uint8_t byte, lossy_packet_cb *function)
{
g_c->lossy_packethandlers[byte].function = function;
}
-/* Set the callback for group invites. */
+/** Set the callback for group invites. */
void g_callback_group_invite(Group_Chats *g_c, g_conference_invite_cb *function)
{
g_c->invite_callback = function;
}
-/* Set the callback for group connection. */
+/** Set the callback for group connection. */
void g_callback_group_connected(Group_Chats *g_c, g_conference_connected_cb *function)
{
g_c->connected_callback = function;
}
-/* Set the callback for group messages. */
+/** Set the callback for group messages. */
void g_callback_group_message(Group_Chats *g_c, g_conference_message_cb *function)
{
g_c->message_callback = function;
}
-/* Set callback function for peer nickname changes.
+/** Set callback function for peer nickname changes.
*
* It gets called every time a peer changes their nickname.
*/
@@ -1624,7 +1627,7 @@ void g_callback_peer_name(Group_Chats *g_c, peer_name_cb *function)
g_c->peer_name_callback = function;
}
-/* Set callback function for peer list changes.
+/** Set callback function for peer list changes.
*
* It gets called every time the name list changes(new peer, deleted peer)
*/
@@ -1633,13 +1636,13 @@ void g_callback_peer_list_changed(Group_Chats *g_c, peer_list_changed_cb *functi
g_c->peer_list_changed_callback = function;
}
-/* Set callback function for title changes. */
+/** Set callback function for title changes. */
void g_callback_group_title(Group_Chats *g_c, title_cb *function)
{
g_c->title_callback = function;
}
-/* Set a function to be called when a new peer joins a group chat.
+/** Set a function to be called when a new peer joins a group chat.
*
* return 0 on success.
* return -1 on failure.
@@ -1656,12 +1659,12 @@ int callback_groupchat_peer_new(const Group_Chats *g_c, uint32_t groupnumber, pe
return 0;
}
-/* Set a function to be called when a peer leaves a group chat.
+/** Set a function to be called when a peer leaves a group chat.
*
* return 0 on success.
* return -1 on failure.
*/
-int callback_groupchat_peer_delete(Group_Chats *g_c, uint32_t groupnumber, peer_on_leave_cb *function)
+int callback_groupchat_peer_delete(const Group_Chats *g_c, uint32_t groupnumber, peer_on_leave_cb *function)
{
Group_c *g = get_group_c(g_c, groupnumber);
@@ -1673,12 +1676,12 @@ int callback_groupchat_peer_delete(Group_Chats *g_c, uint32_t groupnumber, peer_
return 0;
}
-/* Set a function to be called when the group chat is deleted.
+/** Set a function to be called when the group chat is deleted.
*
* return 0 on success.
* return -1 on failure.
*/
-int callback_groupchat_delete(Group_Chats *g_c, uint32_t groupnumber, group_on_delete_cb *function)
+int callback_groupchat_delete(const Group_Chats *g_c, uint32_t groupnumber, group_on_delete_cb *function)
{
Group_c *g = get_group_c(g_c, groupnumber);
@@ -1693,7 +1696,7 @@ int callback_groupchat_delete(Group_Chats *g_c, uint32_t groupnumber, group_on_d
static int send_message_group(const Group_Chats *g_c, uint32_t groupnumber, uint8_t message_id, const uint8_t *data,
uint16_t len);
-/* send a ping message
+/** send a ping message
* return true on success
*/
static bool group_ping_send(const Group_Chats *g_c, uint32_t groupnumber)
@@ -1705,11 +1708,11 @@ static bool group_ping_send(const Group_Chats *g_c, uint32_t groupnumber)
return false;
}
-/* send a new_peer message
+/** send a new_peer message
* return true on success
*/
static bool group_new_peer_send(const Group_Chats *g_c, uint32_t groupnumber, uint16_t peer_num, const uint8_t *real_pk,
- uint8_t *temp_pk)
+ const uint8_t *temp_pk)
{
uint8_t packet[GROUP_MESSAGE_NEW_PEER_LENGTH];
@@ -1725,7 +1728,7 @@ static bool group_new_peer_send(const Group_Chats *g_c, uint32_t groupnumber, ui
return false;
}
-/* send a kill_peer message
+/** send a kill_peer message
* return true on success
*/
static bool group_kill_peer_send(const Group_Chats *g_c, uint32_t groupnumber, uint16_t peer_num)
@@ -1742,7 +1745,7 @@ static bool group_kill_peer_send(const Group_Chats *g_c, uint32_t groupnumber, u
return false;
}
-/* send a freeze_peer message
+/** send a freeze_peer message
* return true on success
*/
static bool group_freeze_peer_send(const Group_Chats *g_c, uint32_t groupnumber, uint16_t peer_num)
@@ -1759,7 +1762,7 @@ static bool group_freeze_peer_send(const Group_Chats *g_c, uint32_t groupnumber,
return false;
}
-/* send a name message
+/** send a name message
* return true on success
*/
static bool group_name_send(const Group_Chats *g_c, uint32_t groupnumber, const uint8_t *nick, uint16_t nick_len)
@@ -1775,7 +1778,7 @@ static bool group_name_send(const Group_Chats *g_c, uint32_t groupnumber, const
return false;
}
-/* send message to announce leaving group
+/** send message to announce leaving group
* return true on success
*/
static bool group_leave(const Group_Chats *g_c, uint32_t groupnumber, bool permanent)
@@ -1794,7 +1797,7 @@ static bool group_leave(const Group_Chats *g_c, uint32_t groupnumber, bool perma
}
-/* set the group's title, limited to MAX_NAME_LENGTH
+/** set the group's title, limited to MAX_NAME_LENGTH
* return 0 on success
* return -1 if groupnumber is invalid.
* return -2 if title is too long or empty.
@@ -1831,7 +1834,7 @@ int group_title_send(const Group_Chats *g_c, uint32_t groupnumber, const uint8_t
return -3;
}
-/* return the group's title size.
+/** return the group's title size.
* return -1 of groupnumber is invalid.
* return -2 if title is too long or empty.
*/
@@ -1850,7 +1853,7 @@ int group_title_get_size(const Group_Chats *g_c, uint32_t groupnumber)
return g->title_len;
}
-/* Get group title from groupnumber and put it in title.
+/** Get group title from groupnumber and put it in title.
* Title needs to be a valid memory location with a size of at least MAX_NAME_LENGTH (128) bytes.
*
* return length of copied title if success.
@@ -1919,7 +1922,7 @@ static void handle_friend_invite_packet(Messenger *m, uint32_t friendnumber, con
return;
} else {
- Group_c *g = get_group_c(g_c, groupnumber);
+ const Group_c *g = get_group_c(g_c, groupnumber);
if (g && g->status == GROUPCHAT_STATUS_CONNECTED) {
send_invite_response(g_c, groupnumber, friendnumber, invite_data, invite_length);
@@ -1931,7 +1934,7 @@ static void handle_friend_invite_packet(Messenger *m, uint32_t friendnumber, con
case INVITE_ACCEPT_ID:
case INVITE_MEMBER_ID: {
- const bool member = (data[0] == INVITE_MEMBER_ID);
+ const bool member = data[0] == INVITE_MEMBER_ID;
if (length != (member ? INVITE_MEMBER_PACKET_SIZE : INVITE_ACCEPT_PACKET_SIZE)) {
return;
@@ -1952,7 +1955,7 @@ static void handle_friend_invite_packet(Messenger *m, uint32_t friendnumber, con
return;
}
- if (crypto_memcmp(data + 1 + sizeof(uint16_t) * 2 + 1, g->id, GROUP_ID_LENGTH) != 0) {
+ if (!group_id_eq(data + 1 + sizeof(uint16_t) * 2 + 1, g->id)) {
return;
}
@@ -2008,12 +2011,13 @@ static void handle_friend_invite_packet(Messenger *m, uint32_t friendnumber, con
break;
}
- default:
+ default: {
return;
+ }
}
}
-/* Find index of friend in the connections list.
+/** Find index of friend in the connections list.
*
* return index on success
* return -1 on failure.
@@ -2033,7 +2037,7 @@ static int friend_in_connections(const Group_c *g, int friendcon_id)
return -1;
}
-/* return number of connections.
+/** return number of connections.
*/
static unsigned int count_connected(const Group_c *g)
{
@@ -2048,8 +2052,8 @@ static unsigned int count_connected(const Group_c *g)
return count;
}
-static int send_packet_online(Friend_Connections *fr_c, int friendcon_id, uint16_t group_num, uint8_t type,
- const uint8_t *id)
+static int send_packet_online(const Friend_Connections *fr_c, int friendcon_id, uint16_t group_num,
+ uint8_t type, const uint8_t *id)
{
uint8_t packet[1 + ONLINE_PACKET_DATA_SIZE];
group_num = net_htons(group_num);
@@ -2061,9 +2065,9 @@ static int send_packet_online(Friend_Connections *fr_c, int friendcon_id, uint16
sizeof(packet), 0) != -1;
}
-static bool ping_groupchat(Group_Chats *g_c, uint32_t groupnumber);
+static bool ping_groupchat(const Group_Chats *g_c, uint32_t groupnumber);
-static int handle_packet_online(Group_Chats *g_c, int friendcon_id, const uint8_t *data, uint16_t length)
+static int handle_packet_online(const Group_Chats *g_c, int friendcon_id, const uint8_t *data, uint16_t length)
{
if (length != ONLINE_PACKET_DATA_SIZE) {
return -1;
@@ -2161,10 +2165,10 @@ static int handle_packet_rejoin(Group_Chats *g_c, int friendcon_id, const uint8_
// we could send title with invite, but then if it changes between sending and accepting inv, joinee won't see it
-/* return 1 on success.
+/** return 1 on success.
* return 0 on failure
*/
-static unsigned int send_peer_introduced(Group_Chats *g_c, int friendcon_id, uint16_t group_num)
+static unsigned int send_peer_introduced(const Group_Chats *g_c, int friendcon_id, uint16_t group_num)
{
uint8_t packet[1];
packet[0] = PEER_INTRODUCED_ID;
@@ -2172,20 +2176,20 @@ static unsigned int send_peer_introduced(Group_Chats *g_c, int friendcon_id, uin
}
-/* return 1 on success.
+/** return 1 on success.
* return 0 on failure
*/
-static unsigned int send_peer_query(Group_Chats *g_c, int friendcon_id, uint16_t group_num)
+static unsigned int send_peer_query(const Group_Chats *g_c, int friendcon_id, uint16_t group_num)
{
uint8_t packet[1];
packet[0] = PEER_QUERY_ID;
return send_packet_group_peer(g_c->fr_c, friendcon_id, PACKET_ID_DIRECT_CONFERENCE, group_num, packet, sizeof(packet));
}
-/* return number of peers sent on success.
+/** return number of peers sent on success.
* return 0 on failure.
*/
-static unsigned int send_peers(Group_Chats *g_c, const Group_c *g, int friendcon_id, uint16_t group_num)
+static unsigned int send_peers(const Group_Chats *g_c, const Group_c *g, int friendcon_id, uint16_t group_num)
{
uint8_t response_packet[MAX_CRYPTO_DATA_SIZE - (1 + sizeof(uint16_t))];
response_packet[0] = PEER_RESPONSE_ID;
@@ -2193,12 +2197,12 @@ static unsigned int send_peers(Group_Chats *g_c, const Group_c *g, int friendcon
uint16_t sent = 0;
- for (uint32_t i = 0;; ++i) {
+ for (uint32_t i = 0; i <= g->numpeers; ++i) {
if (i == g->numpeers
|| (p - response_packet) + sizeof(uint16_t) + CRYPTO_PUBLIC_KEY_SIZE * 2 + 1 + g->group[i].nick_len >
sizeof(response_packet)) {
if (send_packet_group_peer(g_c->fr_c, friendcon_id, PACKET_ID_DIRECT_CONFERENCE, group_num, response_packet,
- (p - response_packet))) {
+ p - response_packet)) {
sent = i;
} else {
return sent;
@@ -2308,37 +2312,36 @@ static void handle_direct_packet(Group_Chats *g_c, uint32_t groupnumber, const u
switch (data[0]) {
case PEER_INTRODUCED_ID: {
remove_connection_reason(g_c, g, connection_index, GROUPCHAT_CONNECTION_REASON_INTRODUCING);
+ break;
}
- break;
-
case PEER_QUERY_ID: {
if (g->connections[connection_index].type != GROUPCHAT_CONNECTION_ONLINE) {
return;
}
send_peers(g_c, g, g->connections[connection_index].number, g->connections[connection_index].group_number);
+ break;
}
- break;
case PEER_RESPONSE_ID: {
handle_send_peers(g_c, groupnumber, data + 1, length - 1, userdata);
+ break;
}
- break;
case PEER_TITLE_ID: {
if (!g->title_fresh) {
settitle(g_c, groupnumber, -1, data + 1, length - 1, userdata);
}
- }
- break;
+ break;
+ }
}
}
-/* Send message to all connections except receiver (if receiver isn't -1)
+/** Send message to all connections except receiver (if receiver isn't -1)
* NOTE: this function appends the group chat number to the data passed to it.
*
* return number of messages sent.
@@ -2366,18 +2369,17 @@ static unsigned int send_message_all_connections(const Group_Chats *g_c, const G
return sent;
}
-/* Send lossy message to all connections except receiver (if receiver isn't -1)
+/** Send lossy message to all connections except receiver (if receiver isn't -1)
* NOTE: this function appends the group chat number to the data passed to it.
*
* return number of messages sent.
*/
static unsigned int send_lossy_all_connections(const Group_Chats *g_c, const Group_c *g, const uint8_t *data,
- uint16_t length,
- int receiver)
+ uint16_t length, int receiver)
{
unsigned int sent = 0;
unsigned int num_connected_closest = 0;
- unsigned int connected_closest[DESIRED_CLOSEST];
+ unsigned int connected_closest[DESIRED_CLOSEST] = {0};
for (unsigned int i = 0; i < MAX_GROUP_CONNECTIONS; ++i) {
if (g->connections[i].type != GROUPCHAT_CONNECTION_ONLINE) {
@@ -2434,7 +2436,7 @@ static unsigned int send_lossy_all_connections(const Group_Chats *g_c, const Gro
return sent;
}
-/* Send data of len with message_id to groupnumber.
+/** Send data of len with message_id to groupnumber.
*
* return number of peers it was sent to on success.
* return -1 if groupnumber is invalid.
@@ -2487,7 +2489,7 @@ static int send_message_group(const Group_Chats *g_c, uint32_t groupnumber, uint
return ret;
}
-/* send a group message
+/** send a group message
* return 0 on success
* see: send_message_group() for error codes.
*/
@@ -2502,7 +2504,7 @@ int group_message_send(const Group_Chats *g_c, uint32_t groupnumber, const uint8
return ret;
}
-/* send a group action
+/** send a group action
* return 0 on success
* see: send_message_group() for error codes.
*/
@@ -2517,7 +2519,7 @@ int group_action_send(const Group_Chats *g_c, uint32_t groupnumber, const uint8_
return ret;
}
-/* High level function to send custom lossy packets.
+/** High level function to send custom lossy packets.
*
* return -1 on failure.
* return 0 on success.
@@ -2548,7 +2550,7 @@ int send_group_lossy_packet(const Group_Chats *g_c, uint32_t groupnumber, const
static Message_Info *find_message_slot_or_reject(uint32_t message_number, uint8_t message_id, Group_Peer *peer)
{
- const bool ignore_older = (message_id == GROUP_MESSAGE_NAME_ID || message_id == GROUP_MESSAGE_TITLE_ID);
+ const bool ignore_older = message_id == GROUP_MESSAGE_NAME_ID || message_id == GROUP_MESSAGE_TITLE_ID;
Message_Info *i;
@@ -2569,7 +2571,7 @@ static Message_Info *find_message_slot_or_reject(uint32_t message_number, uint8_
return i;
}
-/* Stores message info in peer->last_message_infos.
+/** Stores message info in peer->last_message_infos.
*
* return true if message should be processed.
* return false otherwise.
@@ -2672,8 +2674,9 @@ static void handle_message_packet_group(Group_Chats *g_c, uint32_t groupnumber,
const bool direct_from_sender = id_equal(g->group[index].real_pk, real_pk);
switch (message_id) {
- case GROUP_MESSAGE_PING_ID:
+ case GROUP_MESSAGE_PING_ID: {
break;
+ }
case GROUP_MESSAGE_NEW_PEER_ID: {
if (msg_data_len != GROUP_MESSAGE_NEW_PEER_LENGTH) {
@@ -2685,8 +2688,8 @@ static void handle_message_packet_group(Group_Chats *g_c, uint32_t groupnumber,
new_peer_number = net_ntohs(new_peer_number);
addpeer(g_c, groupnumber, msg_data + sizeof(uint16_t), msg_data + sizeof(uint16_t) + CRYPTO_PUBLIC_KEY_SIZE,
new_peer_number, userdata, true, true);
+ break;
}
- break;
case GROUP_MESSAGE_KILL_PEER_ID:
case GROUP_MESSAGE_FREEZE_PEER_ID: {
@@ -2708,22 +2711,25 @@ static void handle_message_packet_group(Group_Chats *g_c, uint32_t groupnumber,
return;
// TODO(irungentoo):
}
+
+ break;
}
- break;
case GROUP_MESSAGE_NAME_ID: {
if (!setnick(g_c, groupnumber, index, msg_data, msg_data_len, userdata, true)) {
return;
}
+
+ break;
}
- break;
case GROUP_MESSAGE_TITLE_ID: {
if (!settitle(g_c, groupnumber, index, msg_data, msg_data_len, userdata)) {
return;
}
+
+ break;
}
- break;
case PACKET_ID_MESSAGE: {
if (msg_data_len == 0) {
@@ -2759,8 +2765,9 @@ static void handle_message_packet_group(Group_Chats *g_c, uint32_t groupnumber,
break;
}
- default:
+ default: {
return;
+ }
}
/* If the packet was received from the peer who sent the message, relay it
@@ -2816,7 +2823,7 @@ static int g_handle_packet(void *object, int friendcon_id, const uint8_t *data,
return -1;
}
-/* Did we already receive the lossy packet or not.
+/** Did we already receive the lossy packet or not.
*
* return -1 on failure.
* return 0 if packet was not received.
@@ -2870,7 +2877,7 @@ static int lossy_packet_not_received(const Group_c *g, int peer_index, uint16_t
}
-/* Does this group type make use of lossy packets? */
+/** Does this group type make use of lossy packets? */
static bool type_uses_lossy(uint8_t type)
{
return (type == GROUPCHAT_TYPE_AV);
@@ -2878,7 +2885,7 @@ static bool type_uses_lossy(uint8_t type)
static int handle_lossy(void *object, int friendcon_id, const uint8_t *data, uint16_t length, void *userdata)
{
- Group_Chats *g_c = (Group_Chats *)object;
+ const Group_Chats *g_c = (const Group_Chats *)object;
if (data[0] != PACKET_ID_LOSSY_CONFERENCE) {
return -1;
@@ -2948,7 +2955,7 @@ static int handle_lossy(void *object, int friendcon_id, const uint8_t *data, uin
return 0;
}
-/* Set the object that is tied to the group chat.
+/** Set the object that is tied to the group chat.
*
* return 0 on success.
* return -1 on failure
@@ -2965,7 +2972,7 @@ int group_set_object(const Group_Chats *g_c, uint32_t groupnumber, void *object)
return 0;
}
-/* Set the object that is tied to the group peer.
+/** Set the object that is tied to the group peer.
*
* return 0 on success.
* return -1 on failure
@@ -2986,7 +2993,7 @@ int group_peer_set_object(const Group_Chats *g_c, uint32_t groupnumber, uint32_t
return 0;
}
-/* Return the object tied to the group chat previously set by group_set_object.
+/** Return the object tied to the group chat previously set by group_set_object.
*
* return NULL on failure.
* return object on success.
@@ -3002,7 +3009,7 @@ void *group_get_object(const Group_Chats *g_c, uint32_t groupnumber)
return g->object;
}
-/* Return the object tied to the group chat peer previously set by group_peer_set_object.
+/** Return the object tied to the group chat peer previously set by group_peer_set_object.
*
* return NULL on failure.
* return object on success.
@@ -3022,10 +3029,10 @@ void *group_peer_get_object(const Group_Chats *g_c, uint32_t groupnumber, uint32
return g->group[peernumber].object;
}
-/* Interval in seconds to send ping messages */
+/** Interval in seconds to send ping messages */
#define GROUP_PING_INTERVAL 20
-static bool ping_groupchat(Group_Chats *g_c, uint32_t groupnumber)
+static bool ping_groupchat(const Group_Chats *g_c, uint32_t groupnumber)
{
Group_c *g = get_group_c(g_c, groupnumber);
@@ -3042,7 +3049,7 @@ static bool ping_groupchat(Group_Chats *g_c, uint32_t groupnumber)
return true;
}
-/* Seconds of inactivity after which to freeze a peer */
+/** Seconds of inactivity after which to freeze a peer */
#define FREEZE_TIMEOUT (GROUP_PING_INTERVAL * 3)
static bool groupchat_freeze_timedout(Group_Chats *g_c, uint32_t groupnumber, void *userdata)
@@ -3070,30 +3077,26 @@ static bool groupchat_freeze_timedout(Group_Chats *g_c, uint32_t groupnumber, vo
return true;
}
-/* Push non-empty slots to start. */
+/** Push non-empty slots to start. */
static void squash_connections(Group_c *g)
{
- uint16_t i = 0;
+ uint16_t num_connected = 0;
- for (uint16_t j = 0; j < MAX_GROUP_CONNECTIONS; ++j) {
- if (g->connections[j].type != GROUPCHAT_CONNECTION_NONE) {
- g->connections[i] = g->connections[j];
- ++i;
+ for (uint16_t i = 0; i < MAX_GROUP_CONNECTIONS; ++i) {
+ if (g->connections[i].type != GROUPCHAT_CONNECTION_NONE) {
+ g->connections[num_connected] = g->connections[i];
+ ++num_connected;
}
}
- for (; i < MAX_GROUP_CONNECTIONS; ++i) {
+ for (uint16_t i = num_connected; i < MAX_GROUP_CONNECTIONS; ++i) {
g->connections[i].type = GROUPCHAT_CONNECTION_NONE;
}
}
#define MIN_EMPTY_CONNECTIONS (1 + MAX_GROUP_CONNECTIONS / 10)
-/* Remove old connections as necessary to ensure we have space for new
- * connections. This invalidates connections array indices (which is
- * why we do this periodically rather than on adding a connection).
- */
-static void clean_connections(Group_Chats *g_c, Group_c *g)
+static uint16_t empty_connection_count(const Group_c *g)
{
uint16_t to_clear = MIN_EMPTY_CONNECTIONS;
@@ -3107,7 +3110,16 @@ static void clean_connections(Group_Chats *g_c, Group_c *g)
}
}
- for (; to_clear > 0; --to_clear) {
+ return to_clear;
+}
+
+/** Remove old connections as necessary to ensure we have space for new
+ * connections. This invalidates connections array indices (which is
+ * why we do this periodically rather than on adding a connection).
+ */
+static void clean_connections(Group_Chats *g_c, Group_c *g)
+{
+ for (uint16_t to_clear = empty_connection_count(g); to_clear > 0; --to_clear) {
// Remove a connection. Prefer non-closest connections, and given
// that prefer non-online connections, and given that prefer earlier
// slots.
@@ -3137,9 +3149,9 @@ static void clean_connections(Group_Chats *g_c, Group_c *g)
squash_connections(g);
}
-/* Send current name (set in messenger) to all online groups.
+/** Send current name (set in messenger) to all online groups.
*/
-void send_name_all_groups(Group_Chats *g_c)
+void send_name_all_groups(const Group_Chats *g_c)
{
for (uint16_t i = 0; i < g_c->num_chats; ++i) {
Group_c *g = get_group_c(g_c, i);
@@ -3205,7 +3217,7 @@ static uint32_t saved_conf_size(const Group_c *g)
return len;
}
-/* Save a future message number. The save will remain valid until we have sent
+/** Save a future message number. The save will remain valid until we have sent
* this many more messages. */
#define SAVE_OFFSET_MESSAGE_NUMBER (1 << 16)
#define SAVE_OFFSET_LOSSY_MESSAGE_NUMBER (1 << 13)
@@ -3326,7 +3338,7 @@ static State_Load_Status load_conferences(Group_Chats *g_c, const uint8_t *data,
data += sizeof(uint32_t);
if (g->numfrozen > 0) {
- g->frozen = (Group_Peer *)malloc(sizeof(Group_Peer) * g->numfrozen);
+ g->frozen = (Group_Peer *)calloc(g->numfrozen, sizeof(Group_Peer));
if (g->frozen == nullptr) {
return STATE_LOAD_STATUS_ERROR;
@@ -3417,8 +3429,8 @@ bool conferences_load_state_section(Group_Chats *g_c, const uint8_t *data, uint3
}
-/* Create new groupchat instance. */
-Group_Chats *new_groupchats(Mono_Time *mono_time, Messenger *m)
+/** Create new groupchat instance. */
+Group_Chats *new_groupchats(const Mono_Time *mono_time, Messenger *m)
{
if (!m) {
return nullptr;
@@ -3441,7 +3453,7 @@ Group_Chats *new_groupchats(Mono_Time *mono_time, Messenger *m)
return temp;
}
-/* main groupchats loop. */
+/** main groupchats loop. */
void do_groupchats(Group_Chats *g_c, void *userdata)
{
for (uint16_t i = 0; i < g_c->num_chats; ++i) {
@@ -3467,7 +3479,7 @@ void do_groupchats(Group_Chats *g_c, void *userdata)
// TODO(irungentoo):
}
-/* Free everything related with group chats. */
+/** Free everything related with group chats. */
void kill_groupchats(Group_Chats *g_c)
{
for (uint16_t i = 0; i < g_c->num_chats; ++i) {
@@ -3480,7 +3492,7 @@ void kill_groupchats(Group_Chats *g_c)
free(g_c);
}
-/* Return the number of chats in the instance m.
+/** Return the number of chats in the instance m.
* You should use this to determine how much memory to allocate
* for copy_chatlist.
*/
@@ -3497,7 +3509,7 @@ uint32_t count_chatlist(const Group_Chats *g_c)
return ret;
}
-/* Copy a list of valid chat IDs into the array out_list.
+/** Copy a list of valid chat IDs into the array out_list.
* If out_list is NULL, returns 0.
* Otherwise, returns the number of elements copied.
* If the array was too small, the contents
diff --git a/protocols/Tox/libtox/src/toxcore/group.h b/protocols/Tox/libtox/src/toxcore/group.h
index eb8db55f10..a2e51cd443 100644
--- a/protocols/Tox/libtox/src/toxcore/group.h
+++ b/protocols/Tox/libtox/src/toxcore/group.h
@@ -3,7 +3,7 @@
* Copyright © 2014 Tox project.
*/
-/*
+/**
* Slightly better groupchats implementation.
*/
#ifndef C_TOXCORE_TOXCORE_GROUP_H
@@ -66,13 +66,13 @@ typedef enum Groupchat_Connection_Type {
GROUPCHAT_CONNECTION_ONLINE,
} Groupchat_Connection_Type;
-/* Connection is to one of the closest DESIRED_CLOSEST peers */
+/** Connection is to one of the closest DESIRED_CLOSEST peers */
#define GROUPCHAT_CONNECTION_REASON_CLOSEST (1 << 0)
-/* Connection is to a peer we are introducing to the conference */
+/** Connection is to a peer we are introducing to the conference */
#define GROUPCHAT_CONNECTION_REASON_INTRODUCING (1 << 1)
-/* Connection is to a peer who is introducing us to the conference */
+/** Connection is to a peer who is introducing us to the conference */
#define GROUPCHAT_CONNECTION_REASON_INTRODUCER (1 << 2)
typedef struct Groupchat_Connection {
@@ -136,35 +136,35 @@ typedef struct Group_c {
group_on_delete_cb *group_on_delete;
} Group_c;
-/* Callback for group invites.
+/** Callback for group invites.
*
* data of length is what needs to be passed to join_groupchat().
*/
typedef void g_conference_invite_cb(Messenger *m, uint32_t friend_number, int type, const uint8_t *cookie,
size_t length, void *user_data);
-/* Callback for group connection. */
+/** Callback for group connection. */
typedef void g_conference_connected_cb(Messenger *m, uint32_t conference_number, void *user_data);
-/* Callback for group messages. */
+/** Callback for group messages. */
typedef void g_conference_message_cb(Messenger *m, uint32_t conference_number, uint32_t peer_number, int type,
const uint8_t *message, size_t length, void *user_data);
-/* Callback for peer nickname changes. */
+/** Callback for peer nickname changes. */
typedef void peer_name_cb(Messenger *m, uint32_t conference_number, uint32_t peer_number, const uint8_t *name,
size_t length, void *user_data);
-/* Set callback function for peer list changes. */
+/** Set callback function for peer list changes. */
typedef void peer_list_changed_cb(Messenger *m, uint32_t conference_number, void *user_data);
-/* Callback for title changes.
+/** Callback for title changes.
*
* If peer_number == -1, then author is unknown (e.g. initial joining the group).
*/
typedef void title_cb(Messenger *m, uint32_t conference_number, uint32_t peer_number, const uint8_t *title,
size_t length, void *user_data);
-/* Callback for lossy packets.
+/** Callback for lossy packets.
*
* NOTE: Handler must return 0 if packet is to be relayed, -1 if the packet should not be relayed.
*/
@@ -194,32 +194,32 @@ typedef struct Group_Chats {
Group_Lossy_Handler lossy_packethandlers[256];
} Group_Chats;
-/* Set the callback for group invites. */
+/** Set the callback for group invites. */
void g_callback_group_invite(Group_Chats *g_c, g_conference_invite_cb *function);
-/* Set the callback for group connection. */
+/** Set the callback for group connection. */
void g_callback_group_connected(Group_Chats *g_c, g_conference_connected_cb *function);
-/* Set the callback for group messages. */
+/** Set the callback for group messages. */
void g_callback_group_message(Group_Chats *g_c, g_conference_message_cb *function);
-/* Set callback function for title changes. */
+/** Set callback function for title changes. */
void g_callback_group_title(Group_Chats *g_c, title_cb *function);
-/* Set callback function for peer nickname changes.
+/** Set callback function for peer nickname changes.
*
* It gets called every time a peer changes their nickname.
*/
void g_callback_peer_name(Group_Chats *g_c, peer_name_cb *function);
-/* Set callback function for peer list changes.
+/** Set callback function for peer list changes.
*
* It gets called every time the name list changes(new peer, deleted peer)
*/
void g_callback_peer_list_changed(Group_Chats *g_c, peer_list_changed_cb *function);
-/* Creates a new groupchat and puts it in the chats array.
+/** Creates a new groupchat and puts it in the chats array.
*
* type is one of `GROUPCHAT_TYPE_*`
*
@@ -228,7 +228,7 @@ void g_callback_peer_list_changed(Group_Chats *g_c, peer_list_changed_cb *functi
*/
int add_groupchat(Group_Chats *g_c, uint8_t type);
-/* Delete a groupchat from the chats array, informing the group first as
+/** Delete a groupchat from the chats array, informing the group first as
* appropriate.
*
* return 0 on success.
@@ -236,9 +236,8 @@ int add_groupchat(Group_Chats *g_c, uint8_t type);
*/
int del_groupchat(Group_Chats *g_c, uint32_t groupnumber, bool leave_permanently);
-/* Copy the public key of (frozen, if frozen is true) peernumber who is in
- * groupnumber to pk.
- * pk must be CRYPTO_PUBLIC_KEY_SIZE long.
+/** Copy the public key of (frozen, if frozen is true) peernumber who is in
+ * groupnumber to pk. pk must be CRYPTO_PUBLIC_KEY_SIZE long.
*
* return 0 on success
* return -1 if groupnumber is invalid.
@@ -246,7 +245,7 @@ int del_groupchat(Group_Chats *g_c, uint32_t groupnumber, bool leave_permanently
*/
int group_peer_pubkey(const Group_Chats *g_c, uint32_t groupnumber, uint32_t peernumber, uint8_t *pk, bool frozen);
-/*
+/**
* Return the size of (frozen, if frozen is true) peernumber's name.
*
* return -1 if groupnumber is invalid.
@@ -254,9 +253,8 @@ int group_peer_pubkey(const Group_Chats *g_c, uint32_t groupnumber, uint32_t pee
*/
int group_peername_size(const Group_Chats *g_c, uint32_t groupnumber, uint32_t peernumber, bool frozen);
-/* Copy the name of (frozen, if frozen is true) peernumber who is in
- * groupnumber to name.
- * name must be at least MAX_NAME_LENGTH long.
+/** Copy the name of (frozen, if frozen is true) peernumber who is in
+ * groupnumber to name. name must be at least MAX_NAME_LENGTH long.
*
* return length of name if success
* return -1 if groupnumber is invalid.
@@ -264,7 +262,7 @@ int group_peername_size(const Group_Chats *g_c, uint32_t groupnumber, uint32_t p
*/
int group_peername(const Group_Chats *g_c, uint32_t groupnumber, uint32_t peernumber, uint8_t *name, bool frozen);
-/* Copy last active timestamp of frozen peernumber who is in groupnumber to
+/** Copy last active timestamp of frozen peernumber who is in groupnumber to
* last_active.
*
* return 0 on success.
@@ -274,22 +272,23 @@ int group_peername(const Group_Chats *g_c, uint32_t groupnumber, uint32_t peernu
int group_frozen_last_active(const Group_Chats *g_c, uint32_t groupnumber, uint32_t peernumber,
uint64_t *last_active);
-/* Set maximum number of frozen peers.
+/** Set maximum number of frozen peers.
*
* return 0 on success.
* return -1 if groupnumber is invalid.
*/
int group_set_max_frozen(const Group_Chats *g_c, uint32_t groupnumber, uint32_t maxfrozen);
-/* invite friendnumber to groupnumber
+/** invite friendnumber to groupnumber.
*
* return 0 on success.
* return -1 if groupnumber is invalid.
* return -2 if invite packet failed to send.
+ * return -3 if we are not connected to the group chat.
*/
-int invite_friend(Group_Chats *g_c, uint32_t friendnumber, uint32_t groupnumber);
+int invite_friend(const Group_Chats *g_c, uint32_t friendnumber, uint32_t groupnumber);
-/* Join a group (you need to have been invited first.)
+/** Join a group (we need to have been invited first.)
*
* expected_type is the groupchat type we expect the chat we are joining to
* have.
@@ -305,19 +304,19 @@ int invite_friend(Group_Chats *g_c, uint32_t friendnumber, uint32_t groupnumber)
int join_groupchat(Group_Chats *g_c, uint32_t friendnumber, uint8_t expected_type, const uint8_t *data,
uint16_t length);
-/* send a group message
+/** send a group message
* return 0 on success
* see: send_message_group() for error codes.
*/
int group_message_send(const Group_Chats *g_c, uint32_t groupnumber, const uint8_t *message, uint16_t length);
-/* send a group action
+/** send a group action
* return 0 on success
* see: send_message_group() for error codes.
*/
int group_action_send(const Group_Chats *g_c, uint32_t groupnumber, const uint8_t *action, uint16_t length);
-/* set the group's title, limited to MAX_NAME_LENGTH
+/** set the group's title, limited to MAX_NAME_LENGTH
* return 0 on success
* return -1 if groupnumber is invalid.
* return -2 if title is too long or empty.
@@ -326,13 +325,13 @@ int group_action_send(const Group_Chats *g_c, uint32_t groupnumber, const uint8_
int group_title_send(const Group_Chats *g_c, uint32_t groupnumber, const uint8_t *title, uint8_t title_len);
-/* return the group's title size.
+/** return the group's title size.
* return -1 of groupnumber is invalid.
* return -2 if title is too long or empty.
*/
int group_title_get_size(const Group_Chats *g_c, uint32_t groupnumber);
-/* Get group title from groupnumber and put it in title.
+/** Get group title from groupnumber and put it in title.
* Title needs to be a valid memory location with a size of at least MAX_NAME_LENGTH (128) bytes.
*
* return length of copied title if success.
@@ -341,13 +340,13 @@ int group_title_get_size(const Group_Chats *g_c, uint32_t groupnumber);
*/
int group_title_get(const Group_Chats *g_c, uint32_t groupnumber, uint8_t *title);
-/* Return the number of (frozen, if frozen is true) peers in the group chat on
+/** Return the number of (frozen, if frozen is true) peers in the group chat on
* success.
* return -1 if groupnumber is invalid.
*/
int group_number_peers(const Group_Chats *g_c, uint32_t groupnumber, bool frozen);
-/* return 1 if the peernumber corresponds to ours.
+/** return 1 if the peernumber corresponds to ours.
* return 0 if the peernumber is not ours.
* return -1 if groupnumber is invalid.
* return -2 if peernumber is invalid.
@@ -355,37 +354,37 @@ int group_number_peers(const Group_Chats *g_c, uint32_t groupnumber, bool frozen
*/
int group_peernumber_is_ours(const Group_Chats *g_c, uint32_t groupnumber, uint32_t peernumber);
-/* Set handlers for custom lossy packets. */
+/** Set handlers for custom lossy packets. */
void group_lossy_packet_registerhandler(Group_Chats *g_c, uint8_t byte, lossy_packet_cb *function);
-/* High level function to send custom lossy packets.
+/** High level function to send custom lossy packets.
*
* return -1 on failure.
* return 0 on success.
*/
int send_group_lossy_packet(const Group_Chats *g_c, uint32_t groupnumber, const uint8_t *data, uint16_t length);
-/* Return the number of chats in the instance m.
+/** Return the number of chats in the instance m.
* You should use this to determine how much memory to allocate
* for copy_chatlist.
*/
uint32_t count_chatlist(const Group_Chats *g_c);
-/* Copy a list of valid chat IDs into the array out_list.
+/** Copy a list of valid chat IDs into the array out_list.
* If out_list is NULL, returns 0.
* Otherwise, returns the number of elements copied.
* If the array was too small, the contents
* of out_list will be truncated to list_size. */
uint32_t copy_chatlist(const Group_Chats *g_c, uint32_t *out_list, uint32_t list_size);
-/* return the type of groupchat (GROUPCHAT_TYPE_) that groupnumber is.
+/** return the type of groupchat (GROUPCHAT_TYPE_) that groupnumber is.
*
* return -1 on failure.
* return type on success.
*/
int group_get_type(const Group_Chats *g_c, uint32_t groupnumber);
-/* Copies the unique id of `group_chat[groupnumber]` into id.
+/** Copies the unique id of `group_chat[groupnumber]` into `id`.
*
* return false on failure.
* return true on success.
@@ -394,63 +393,63 @@ bool conference_get_id(const Group_Chats *g_c, uint32_t groupnumber, uint8_t *id
int32_t conference_by_id(const Group_Chats *g_c, const uint8_t *id);
-/* Send current name (set in messenger) to all online groups.
+/** Send current name (set in messenger) to all online groups.
*/
-void send_name_all_groups(Group_Chats *g_c);
+void send_name_all_groups(const Group_Chats *g_c);
-/* Set the object that is tied to the group chat.
+/** Set the object that is tied to the group chat.
*
* return 0 on success.
* return -1 on failure
*/
int group_set_object(const Group_Chats *g_c, uint32_t groupnumber, void *object);
-/* Set the object that is tied to the group peer.
+/** Set the object that is tied to the group peer.
*
* return 0 on success.
* return -1 on failure
*/
int group_peer_set_object(const Group_Chats *g_c, uint32_t groupnumber, uint32_t peernumber, void *object);
-/* Return the object tied to the group chat previously set by group_set_object.
+/** Return the object tied to the group chat previously set by group_set_object.
*
* return NULL on failure.
* return object on success.
*/
void *group_get_object(const Group_Chats *g_c, uint32_t groupnumber);
-/* Return the object tied to the group chat peer previously set by group_peer_set_object.
+/** Return the object tied to the group chat peer previously set by group_peer_set_object.
*
* return NULL on failure.
* return object on success.
*/
void *group_peer_get_object(const Group_Chats *g_c, uint32_t groupnumber, uint32_t peernumber);
-/* Set a function to be called when a new peer joins a group chat.
+/** Set a function to be called when a new peer joins a group chat.
*
* return 0 on success.
* return -1 on failure.
*/
int callback_groupchat_peer_new(const Group_Chats *g_c, uint32_t groupnumber, peer_on_join_cb *function);
-/* Set a function to be called when a peer leaves a group chat.
+/** Set a function to be called when a peer leaves a group chat.
*
* return 0 on success.
* return -1 on failure.
*/
-int callback_groupchat_peer_delete(Group_Chats *g_c, uint32_t groupnumber, peer_on_leave_cb *function);
+int callback_groupchat_peer_delete(const Group_Chats *g_c, uint32_t groupnumber, peer_on_leave_cb *function);
-/* Set a function to be called when the group chat is deleted.
+/** Set a function to be called when the group chat is deleted.
*
* return 0 on success.
* return -1 on failure.
*/
-int callback_groupchat_delete(Group_Chats *g_c, uint32_t groupnumber, group_on_delete_cb *function);
+int callback_groupchat_delete(const Group_Chats *g_c, uint32_t groupnumber, group_on_delete_cb *function);
-/* Return size of the conferences data (for saving). */
+/** Return size of the conferences data (for saving). */
uint32_t conferences_size(const Group_Chats *g_c);
-/* Save the conferences in data (must be allocated memory of size at least conferences_size()) */
+/** Save the conferences in data (must be allocated memory of size at least conferences_size()) */
uint8_t *conferences_save(const Group_Chats *g_c, uint8_t *data);
/**
@@ -465,13 +464,13 @@ uint8_t *conferences_save(const Group_Chats *g_c, uint8_t *data);
bool conferences_load_state_section(Group_Chats *g_c, const uint8_t *data, uint32_t length, uint16_t type,
State_Load_Status *status);
-/* Create new groupchat instance. */
-Group_Chats *new_groupchats(Mono_Time *mono_time, Messenger *m);
+/** Create new groupchat instance. */
+Group_Chats *new_groupchats(const Mono_Time *mono_time, Messenger *m);
-/* main groupchats loop. */
+/** main groupchats loop. */
void do_groupchats(Group_Chats *g_c, void *userdata);
-/* Free everything related with group chats. */
+/** Free everything related with group chats. */
void kill_groupchats(Group_Chats *g_c);
#endif
diff --git a/protocols/Tox/libtox/src/toxcore/list.c b/protocols/Tox/libtox/src/toxcore/list.c
index fca8cea898..02a0b1e536 100644
--- a/protocols/Tox/libtox/src/toxcore/list.c
+++ b/protocols/Tox/libtox/src/toxcore/list.c
@@ -3,15 +3,11 @@
* Copyright © 2014 Tox project.
*/
-/*
+/**
* Simple struct with functions to create a list which associates ids with data
* -Allows for finding ids associated with data such as IPs or public keys in a short time
* -Should only be used if there are relatively few add/remove calls to the list
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include "list.h"
#include <stdbool.h>
@@ -20,7 +16,7 @@
#include "ccompat.h"
-/* Basically, the elements in the list are placed in order so that they can be searched for easily
+/** Basically, the elements in the list are placed in order so that they can be searched for easily
* -each element is seen as a big-endian integer when ordering them
* -the ids array is maintained so that each id always matches
* -the search algorithm cuts down the time to find the id associated with a piece of data
@@ -37,7 +33,7 @@ list_index(uint32_t i)
return ~i;
}
-/* Find data in list
+/** Find data in list
*
* return value:
* >= 0 : index of data in array
@@ -78,7 +74,7 @@ static int find(const BS_List *list, const uint8_t *data)
return list_index(i);
}
- delta = (delta) / 2;
+ delta = delta / 2;
if (delta == 0) {
delta = 1;
@@ -94,7 +90,7 @@ static int find(const BS_List *list, const uint8_t *data)
// move up
i -= delta;
- delta = (delta) / 2;
+ delta = delta / 2;
if (delta == 0) {
delta = 1;
diff --git a/protocols/Tox/libtox/src/toxcore/list.h b/protocols/Tox/libtox/src/toxcore/list.h
index afe4240b76..1cbf142282 100644
--- a/protocols/Tox/libtox/src/toxcore/list.h
+++ b/protocols/Tox/libtox/src/toxcore/list.h
@@ -3,7 +3,7 @@
* Copyright © 2014 Tox project.
*/
-/*
+/**
* Simple struct with functions to create a list which associates ids with data
* -Allows for finding ids associated with data such as IPs or public keys in a short time
* -Should only be used if there are relatively few add/remove calls to the list
@@ -13,6 +13,10 @@
#include <stdint.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
typedef struct BS_List {
uint32_t n; // number of elements
uint32_t capacity; // number of elements memory is allocated for
@@ -21,7 +25,7 @@ typedef struct BS_List {
int *ids; // array of element ids
} BS_List;
-/* Initialize a list, element_size is the size of the elements in the list and
+/** Initialize a list, element_size is the size of the elements in the list and
* initial_capacity is the number of elements the memory will be initially allocated for
*
* return value:
@@ -30,10 +34,10 @@ typedef struct BS_List {
*/
int bs_list_init(BS_List *list, uint32_t element_size, uint32_t initial_capacity);
-/* Free a list initiated with list_init */
+/** Free a list initiated with list_init */
void bs_list_free(BS_List *list);
-/* Retrieve the id of an element in the list
+/** Retrieve the id of an element in the list
*
* return value:
* >= 0 : id associated with data
@@ -41,7 +45,7 @@ void bs_list_free(BS_List *list);
*/
int bs_list_find(const BS_List *list, const uint8_t *data);
-/* Add an element with associated id to the list
+/** Add an element with associated id to the list
*
* return value:
* 1 : success
@@ -49,7 +53,7 @@ int bs_list_find(const BS_List *list, const uint8_t *data);
*/
int bs_list_add(BS_List *list, const uint8_t *data, int id);
-/* Remove element from the list
+/** Remove element from the list
*
* return value:
* 1 : success
@@ -57,4 +61,8 @@ int bs_list_add(BS_List *list, const uint8_t *data, int id);
*/
int bs_list_remove(BS_List *list, const uint8_t *data, int id);
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
#endif
diff --git a/protocols/Tox/libtox/src/toxcore/logger.c b/protocols/Tox/libtox/src/toxcore/logger.c
index 00e85c36ff..67e4a3e5ce 100644
--- a/protocols/Tox/libtox/src/toxcore/logger.c
+++ b/protocols/Tox/libtox/src/toxcore/logger.c
@@ -1,15 +1,11 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright © 2016-2018 The TokTok team.
- * Copyright © 2013,2015 Tox project.
+ * Copyright © 2013-2015 Tox project.
*/
-/*
+/**
* Text logging abstraction.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include "logger.h"
#include <assert.h>
@@ -62,9 +58,10 @@ static const Logger logger_stderr = {
};
#endif
-/**
+/*
* Public Functions
*/
+
Logger *logger_new(void)
{
return (Logger *)calloc(1, sizeof(Logger));
@@ -102,7 +99,7 @@ void logger_write(const Logger *log, Logger_Level level, const char *file, int l
// The full path may contain PII of the person compiling toxcore (their
// username and directory layout).
const char *filename = strrchr(file, '/');
- file = filename ? filename + 1 : file;
+ file = filename != nullptr ? filename + 1 : file;
#if defined(_WIN32) || defined(__CYGWIN__)
// On Windows, the path separator *may* be a backslash, so we look for that
// one too.
diff --git a/protocols/Tox/libtox/src/toxcore/logger.h b/protocols/Tox/libtox/src/toxcore/logger.h
index cbd8752b9b..c3d8f66d61 100644
--- a/protocols/Tox/libtox/src/toxcore/logger.h
+++ b/protocols/Tox/libtox/src/toxcore/logger.h
@@ -3,7 +3,7 @@
* Copyright © 2013 Tox project.
*/
-/*
+/**
* Logger abstraction backed by callbacks for writing.
*/
#ifndef C_TOXCORE_TOXCORE_LOGGER_H
diff --git a/protocols/Tox/libtox/src/toxcore/mono_time.c b/protocols/Tox/libtox/src/toxcore/mono_time.c
index 876902f52f..e207996df6 100644
--- a/protocols/Tox/libtox/src/toxcore/mono_time.c
+++ b/protocols/Tox/libtox/src/toxcore/mono_time.c
@@ -8,6 +8,11 @@
#if !defined(OS_WIN32) && (defined(_WIN32) || defined(__WIN32__) || defined(WIN32))
#define OS_WIN32
+#endif
+
+#include "mono_time.h"
+
+#ifdef OS_WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif
@@ -21,15 +26,19 @@
#include <sys/time.h>
#endif
-#include "mono_time.h"
-
#include <pthread.h>
#include <stdlib.h>
#include <time.h>
#include "ccompat.h"
-/* don't call into system billions of times for no reason */
+//!TOKSTYLE-
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+#include "../testing/fuzzing/fuzz_adapter.h"
+#endif
+//!TOKSTYLE+
+
+/** don't call into system billions of times for no reason */
struct Mono_Time {
uint64_t time;
uint64_t base_time;
@@ -95,15 +104,23 @@ static uint64_t current_time_monotonic_default(Mono_Time *mono_time, void *user_
return time;
}
+
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+static uint64_t current_time_monotonic_dummy(Mono_Time *mono_time, void *user_data)
+{
+ return fuzz_get_count();
+}
+#endif
+
Mono_Time *mono_time_new(void)
{
- Mono_Time *mono_time = (Mono_Time *)malloc(sizeof(Mono_Time));
+ Mono_Time *mono_time = (Mono_Time *)calloc(1, sizeof(Mono_Time));
if (mono_time == nullptr) {
return nullptr;
}
- mono_time->time_update_lock = (pthread_rwlock_t *)malloc(sizeof(pthread_rwlock_t));
+ mono_time->time_update_lock = (pthread_rwlock_t *)calloc(1, sizeof(pthread_rwlock_t));
if (mono_time->time_update_lock == nullptr) {
free(mono_time);
@@ -116,7 +133,11 @@ Mono_Time *mono_time_new(void)
return nullptr;
}
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+ mono_time->current_time_callback = current_time_monotonic_dummy;
+#else
mono_time->current_time_callback = current_time_monotonic_default;
+#endif
mono_time->user_data = nullptr;
#ifdef OS_WIN32
@@ -133,7 +154,11 @@ Mono_Time *mono_time_new(void)
#endif
mono_time->time = 0;
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+ mono_time->base_time = 0; // Maximum reproducibility
+#else
mono_time->base_time = (uint64_t)time(nullptr) - (current_time_monotonic(mono_time) / 1000ULL);
+#endif
mono_time_update(mono_time);
@@ -171,11 +196,16 @@ void mono_time_update(Mono_Time *mono_time)
uint64_t mono_time_get(const Mono_Time *mono_time)
{
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+ // Fuzzing is only single thread for now, no locking needed */
+ return mono_time->time;
+#else
uint64_t time = 0;
pthread_rwlock_rdlock(mono_time->time_update_lock);
time = mono_time->time;
pthread_rwlock_unlock(mono_time->time_update_lock);
return time;
+#endif
}
bool mono_time_is_timeout(const Mono_Time *mono_time, uint64_t timestamp, uint64_t timeout)
@@ -195,7 +225,10 @@ void mono_time_set_current_time_callback(Mono_Time *mono_time,
}
}
-/* return current monotonic time in milliseconds (ms). */
+/**
+ * Return current monotonic time in milliseconds (ms). The starting point is
+ * unspecified.
+ */
uint64_t current_time_monotonic(Mono_Time *mono_time)
{
/* For WIN32 we don't want to change overflow state of mono_time here */
diff --git a/protocols/Tox/libtox/src/toxcore/mono_time.h b/protocols/Tox/libtox/src/toxcore/mono_time.h
index 0951fc7499..b27e9aaf13 100644
--- a/protocols/Tox/libtox/src/toxcore/mono_time.h
+++ b/protocols/Tox/libtox/src/toxcore/mono_time.h
@@ -12,8 +12,6 @@
extern "C" {
#endif
-#ifndef MONO_TIME_DEFINED
-#define MONO_TIME_DEFINED
/**
* The timer portion of the toxcore event loop.
*
@@ -44,7 +42,6 @@ extern "C" {
* implementation should at least theoretically match the specification.
*/
typedef struct Mono_Time Mono_Time;
-#endif /* MONO_TIME_DEFINED */
Mono_Time *mono_time_new(void);
void mono_time_free(Mono_Time *mono_time);
@@ -73,7 +70,8 @@ uint64_t current_time_monotonic(Mono_Time *mono_time);
typedef uint64_t mono_time_current_time_cb(Mono_Time *mono_time, void *user_data);
-/* Override implementation of current_time_monotonic() (for tests).
+/**
+ * Override implementation of current_time_monotonic() (for tests).
*
* The caller is obligated to ensure that current_time_monotonic() continues
* to increase monotonically.
diff --git a/protocols/Tox/libtox/src/toxcore/net_crypto.c b/protocols/Tox/libtox/src/toxcore/net_crypto.c
index 97383a059a..77ba2294ce 100644
--- a/protocols/Tox/libtox/src/toxcore/net_crypto.c
+++ b/protocols/Tox/libtox/src/toxcore/net_crypto.c
@@ -3,21 +3,18 @@
* Copyright © 2013 Tox project.
*/
-/*
+/**
* Functions for the core network crypto.
*
* NOTE: This code has to be perfect. We don't mess around with encryption.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include "net_crypto.h"
#include <math.h>
#include <stdlib.h>
#include <string.h>
+#include "list.h"
#include "mono_time.h"
#include "util.h"
@@ -34,14 +31,16 @@ typedef struct Packets_Array {
} Packets_Array;
typedef enum Crypto_Conn_State {
- CRYPTO_CONN_FREE = 0, /* the connection slot is free. This value is 0 so it is valid after
- * `crypto_memzero(...)` of the parent struct
- */
+ /* the connection slot is free. This value is 0 so it is valid after
+ * `crypto_memzero(...)` of the parent struct
+ */
+ CRYPTO_CONN_FREE = 0,
CRYPTO_CONN_NO_CONNECTION, /* the connection is allocated, but not yet used */
CRYPTO_CONN_COOKIE_REQUESTING, /* we are sending cookie request packets */
CRYPTO_CONN_HANDSHAKE_SENT, /* we are sending handshake packets */
- CRYPTO_CONN_NOT_CONFIRMED, /* we are sending handshake packets.
- * we have received one from the other, but no data */
+ /* we are sending handshake packets.
+ * we have received one from the other, but no data */
+ CRYPTO_CONN_NOT_CONFIRMED,
CRYPTO_CONN_ESTABLISHED, /* the connection is established */
} Crypto_Conn_State;
@@ -193,7 +192,7 @@ static bool crypt_connection_id_is_valid(const Net_Crypto *c, int crypt_connecti
return true;
}
-/* cookie timeout in seconds */
+/** cookie timeout in seconds */
#define COOKIE_TIMEOUT 15
#define COOKIE_DATA_LENGTH (uint16_t)(CRYPTO_PUBLIC_KEY_SIZE * 2)
#define COOKIE_CONTENTS_LENGTH (uint16_t)(sizeof(uint64_t) + COOKIE_DATA_LENGTH)
@@ -203,7 +202,7 @@ static bool crypt_connection_id_is_valid(const Net_Crypto *c, int crypt_connecti
#define COOKIE_REQUEST_LENGTH (uint16_t)(1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + COOKIE_REQUEST_PLAIN_LENGTH + CRYPTO_MAC_SIZE)
#define COOKIE_RESPONSE_LENGTH (uint16_t)(1 + CRYPTO_NONCE_SIZE + COOKIE_LENGTH + sizeof(uint64_t) + CRYPTO_MAC_SIZE)
-/* Create a cookie request packet and put it in packet.
+/** Create a cookie request packet and put it in packet.
* dht_public_key is the dht public key of the other
*
* packet must be of size COOKIE_REQUEST_LENGTH or bigger.
@@ -211,8 +210,8 @@ static bool crypt_connection_id_is_valid(const Net_Crypto *c, int crypt_connecti
* return -1 on failure.
* return COOKIE_REQUEST_LENGTH on success.
*/
-static int create_cookie_request(const Net_Crypto *c, uint8_t *packet, uint8_t *dht_public_key, uint64_t number,
- uint8_t *shared_key)
+static int create_cookie_request(const Net_Crypto *c, uint8_t *packet, const uint8_t *dht_public_key,
+ uint64_t number, uint8_t *shared_key)
{
uint8_t plain[COOKIE_REQUEST_PLAIN_LENGTH];
uint8_t padding[CRYPTO_PUBLIC_KEY_SIZE] = {0};
@@ -237,12 +236,12 @@ static int create_cookie_request(const Net_Crypto *c, uint8_t *packet, uint8_t *
return (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + len);
}
-/* Create cookie of length COOKIE_LENGTH from bytes of length COOKIE_DATA_LENGTH using encryption_key
+/** Create cookie of length COOKIE_LENGTH from bytes of length COOKIE_DATA_LENGTH using encryption_key
*
* return -1 on failure.
* return 0 on success.
*/
-static int create_cookie(const Logger *log, const Mono_Time *mono_time, uint8_t *cookie, const uint8_t *bytes,
+static int create_cookie(const Mono_Time *mono_time, uint8_t *cookie, const uint8_t *bytes,
const uint8_t *encryption_key)
{
uint8_t contents[COOKIE_CONTENTS_LENGTH];
@@ -259,12 +258,12 @@ static int create_cookie(const Logger *log, const Mono_Time *mono_time, uint8_t
return 0;
}
-/* Open cookie of length COOKIE_LENGTH to bytes of length COOKIE_DATA_LENGTH using encryption_key
+/** Open cookie of length COOKIE_LENGTH to bytes of length COOKIE_DATA_LENGTH using encryption_key
*
* return -1 on failure.
* return 0 on success.
*/
-static int open_cookie(const Logger *log, const Mono_Time *mono_time, uint8_t *bytes, const uint8_t *cookie,
+static int open_cookie(const Mono_Time *mono_time, uint8_t *bytes, const uint8_t *cookie,
const uint8_t *encryption_key)
{
uint8_t contents[COOKIE_CONTENTS_LENGTH];
@@ -288,7 +287,7 @@ static int open_cookie(const Logger *log, const Mono_Time *mono_time, uint8_t *b
}
-/* Create a cookie response packet and put it in packet.
+/** Create a cookie response packet and put it in packet.
* request_plain must be COOKIE_REQUEST_PLAIN_LENGTH bytes.
* packet must be of size COOKIE_RESPONSE_LENGTH or bigger.
*
@@ -303,7 +302,7 @@ static int create_cookie_response(const Net_Crypto *c, uint8_t *packet, const ui
memcpy(cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, dht_public_key, CRYPTO_PUBLIC_KEY_SIZE);
uint8_t plain[COOKIE_LENGTH + sizeof(uint64_t)];
- if (create_cookie(c->log, c->mono_time, plain, cookie_plain, c->secret_symmetric_key) != 0) {
+ if (create_cookie(c->mono_time, plain, cookie_plain, c->secret_symmetric_key) != 0) {
return -1;
}
@@ -319,7 +318,7 @@ static int create_cookie_response(const Net_Crypto *c, uint8_t *packet, const ui
return COOKIE_RESPONSE_LENGTH;
}
-/* Handle the cookie request packet of length length.
+/** Handle the cookie request packet of length length.
* Put what was in the request in request_plain (must be of size COOKIE_REQUEST_PLAIN_LENGTH)
* Put the key used to decrypt the request into shared_key (of size CRYPTO_SHARED_KEY_SIZE) for use in the response.
*
@@ -346,12 +345,12 @@ static int handle_cookie_request(const Net_Crypto *c, uint8_t *request_plain, ui
return 0;
}
-/* Handle the cookie request packet (for raw UDP)
+/** Handle the cookie request packet (for raw UDP)
*/
-static int udp_handle_cookie_request(void *object, IP_Port source, const uint8_t *packet, uint16_t length,
+static int udp_handle_cookie_request(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length,
void *userdata)
{
- Net_Crypto *c = (Net_Crypto *)object;
+ const Net_Crypto *c = (const Net_Crypto *)object;
uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH];
uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE];
uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE];
@@ -373,9 +372,10 @@ static int udp_handle_cookie_request(void *object, IP_Port source, const uint8_t
return 0;
}
-/* Handle the cookie request packet (for TCP)
+/** Handle the cookie request packet (for TCP)
*/
-static int tcp_handle_cookie_request(Net_Crypto *c, int connections_number, const uint8_t *packet, uint16_t length)
+static int tcp_handle_cookie_request(const Net_Crypto *c, int connections_number, const uint8_t *packet,
+ uint16_t length)
{
uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH];
uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE];
@@ -395,7 +395,7 @@ static int tcp_handle_cookie_request(Net_Crypto *c, int connections_number, cons
return ret;
}
-/* Handle the cookie request packet (for TCP oob packets)
+/** Handle the cookie request packet (for TCP oob packets)
*/
static int tcp_oob_handle_cookie_request(const Net_Crypto *c, unsigned int tcp_connections_number,
const uint8_t *dht_public_key, const uint8_t *packet, uint16_t length)
@@ -422,7 +422,7 @@ static int tcp_oob_handle_cookie_request(const Net_Crypto *c, unsigned int tcp_c
return ret;
}
-/* Handle a cookie response packet of length encrypted with shared_key.
+/** Handle a cookie response packet of length encrypted with shared_key.
* put the cookie in the response in cookie
*
* cookie must be of length COOKIE_LENGTH.
@@ -430,7 +430,7 @@ static int tcp_oob_handle_cookie_request(const Net_Crypto *c, unsigned int tcp_c
* return -1 on failure.
* return COOKIE_LENGTH on success.
*/
-static int handle_cookie_response(const Logger *log, uint8_t *cookie, uint64_t *number,
+static int handle_cookie_response(uint8_t *cookie, uint64_t *number,
const uint8_t *packet, uint16_t length,
const uint8_t *shared_key)
{
@@ -453,7 +453,7 @@ static int handle_cookie_response(const Logger *log, uint8_t *cookie, uint64_t *
#define HANDSHAKE_PACKET_LENGTH (1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH + CRYPTO_MAC_SIZE)
-/* Create a handshake packet and put it in packet.
+/** Create a handshake packet and put it in packet.
* cookie must be COOKIE_LENGTH bytes.
* packet must be of size HANDSHAKE_PACKET_LENGTH or bigger.
*
@@ -471,7 +471,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u
memcpy(cookie_plain, peer_real_pk, CRYPTO_PUBLIC_KEY_SIZE);
memcpy(cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, peer_dht_pubkey, CRYPTO_PUBLIC_KEY_SIZE);
- if (create_cookie(c->log, c->mono_time, plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE,
+ if (create_cookie(c->mono_time, plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE,
cookie_plain, c->secret_symmetric_key) != 0) {
return -1;
}
@@ -490,7 +490,7 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u
return HANDSHAKE_PACKET_LENGTH;
}
-/* Handle a crypto handshake packet of length.
+/** Handle a crypto handshake packet of length.
* put the nonce contained in the packet in nonce,
* the session public key in session_pk
* the real public key of the peer in peer_real_pk
@@ -517,14 +517,12 @@ static int handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t
uint8_t cookie_plain[COOKIE_DATA_LENGTH];
- if (open_cookie(c->log, c->mono_time, cookie_plain, packet + 1, c->secret_symmetric_key) != 0) {
+ if (open_cookie(c->mono_time, cookie_plain, packet + 1, c->secret_symmetric_key) != 0) {
return -1;
}
- if (expected_real_pk) {
- if (public_key_cmp(cookie_plain, expected_real_pk) != 0) {
- return -1;
- }
+ if (expected_real_pk && public_key_cmp(cookie_plain, expected_real_pk) != 0) {
+ return -1;
}
uint8_t cookie_hash[CRYPTO_SHA512_SIZE];
@@ -539,8 +537,7 @@ static int handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t
return -1;
}
- if (crypto_memcmp(cookie_hash, plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE,
- CRYPTO_SHA512_SIZE) != 0) {
+ if (crypto_sha512_cmp(cookie_hash, plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE) != 0) {
return -1;
}
@@ -563,12 +560,12 @@ static Crypto_Connection *get_crypto_connection(const Net_Crypto *c, int crypt_c
}
-/* Associate an ip_port to a connection.
+/** Associate an ip_port to a connection.
*
* return -1 on failure.
* return 0 on success.
*/
-static int add_ip_port_connection(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port)
+static int add_ip_port_connection(Net_Crypto *c, int crypt_connection_id, const IP_Port *ip_port)
{
Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
@@ -576,24 +573,24 @@ static int add_ip_port_connection(Net_Crypto *c, int crypt_connection_id, IP_Por
return -1;
}
- if (net_family_is_ipv4(ip_port.ip.family)) {
- if (!ipport_equal(&ip_port, &conn->ip_portv4) && !ip_is_lan(conn->ip_portv4.ip)) {
- if (!bs_list_add(&c->ip_port_list, (uint8_t *)&ip_port, crypt_connection_id)) {
+ if (net_family_is_ipv4(ip_port->ip.family)) {
+ if (!ipport_equal(ip_port, &conn->ip_portv4) && !ip_is_lan(&conn->ip_portv4.ip)) {
+ if (!bs_list_add(&c->ip_port_list, (const uint8_t *)ip_port, crypt_connection_id)) {
return -1;
}
bs_list_remove(&c->ip_port_list, (uint8_t *)&conn->ip_portv4, crypt_connection_id);
- conn->ip_portv4 = ip_port;
+ conn->ip_portv4 = *ip_port;
return 0;
}
- } else if (net_family_is_ipv6(ip_port.ip.family)) {
- if (!ipport_equal(&ip_port, &conn->ip_portv6)) {
- if (!bs_list_add(&c->ip_port_list, (uint8_t *)&ip_port, crypt_connection_id)) {
+ } else if (net_family_is_ipv6(ip_port->ip.family)) {
+ if (!ipport_equal(ip_port, &conn->ip_portv6)) {
+ if (!bs_list_add(&c->ip_port_list, (const uint8_t *)ip_port, crypt_connection_id)) {
return -1;
}
bs_list_remove(&c->ip_port_list, (uint8_t *)&conn->ip_portv6, crypt_connection_id);
- conn->ip_portv6 = ip_port;
+ conn->ip_portv6 = *ip_port;
return 0;
}
}
@@ -601,16 +598,16 @@ static int add_ip_port_connection(Net_Crypto *c, int crypt_connection_id, IP_Por
return -1;
}
-/* Return the IP_Port that should be used to send packets to the other peer.
+/** Return the IP_Port that should be used to send packets to the other peer.
*
* return IP_Port with family 0 on failure.
* return IP_Port on success.
*/
-static IP_Port return_ip_port_connection(Net_Crypto *c, int crypt_connection_id)
+static IP_Port return_ip_port_connection(const Net_Crypto *c, int crypt_connection_id)
{
- const IP_Port empty = {{{0}}};
+ const IP_Port empty = {0};
- Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
+ const Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
if (conn == nullptr) {
return empty;
@@ -631,7 +628,7 @@ static IP_Port return_ip_port_connection(Net_Crypto *c, int crypt_connection_id)
/* Prefer IP_Ports which haven't timed out to those which have.
* To break ties, prefer ipv4 lan, then ipv6, then non-lan ipv4.
*/
- if (v4 && ip_is_lan(conn->ip_portv4.ip)) {
+ if (v4 && ip_is_lan(&conn->ip_portv4.ip)) {
return conn->ip_portv4;
}
@@ -643,7 +640,7 @@ static IP_Port return_ip_port_connection(Net_Crypto *c, int crypt_connection_id)
return conn->ip_portv4;
}
- if (ip_is_lan(conn->ip_portv4.ip)) {
+ if (ip_is_lan(&conn->ip_portv4.ip)) {
return conn->ip_portv4;
}
@@ -658,7 +655,7 @@ static IP_Port return_ip_port_connection(Net_Crypto *c, int crypt_connection_id)
return empty;
}
-/* Sends a packet to the peer using the fastest route.
+/** Sends a packet to the peer using the fastest route.
*
* return -1 on failure.
* return 0 on success.
@@ -685,7 +682,7 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t
crypto_connection_status(c, crypt_connection_id, &direct_connected, nullptr);
if (direct_connected) {
- if ((uint32_t)sendpacket(dht_get_net(c->dht), ip_port, data, length) == length) {
+ if ((uint32_t)sendpacket(dht_get_net(c->dht), &ip_port, data, length) == length) {
pthread_mutex_unlock(conn->mutex);
return 0;
}
@@ -699,7 +696,7 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t
if ((((UDP_DIRECT_TIMEOUT / 2) + conn->direct_send_attempt_time) < current_time && length < 96)
|| data[0] == NET_PACKET_COOKIE_REQUEST || data[0] == NET_PACKET_CRYPTO_HS) {
- if ((uint32_t)sendpacket(dht_get_net(c->dht), ip_port, data, length) == length) {
+ if ((uint32_t)sendpacket(dht_get_net(c->dht), &ip_port, data, length) == length) {
direct_send_attempt = 1;
conn->direct_send_attempt_time = mono_time_get(c->mono_time);
}
@@ -726,10 +723,10 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t
return -1;
}
-/** START: Array Related functions */
+/*** START: Array Related functions */
-/* Return number of packets in array
+/** Return number of packets in array
* Note that holes are counted too.
*/
static uint32_t num_packets_array(const Packets_Array *array)
@@ -737,12 +734,12 @@ static uint32_t num_packets_array(const Packets_Array *array)
return array->buffer_end - array->buffer_start;
}
-/* Add data with packet number to array.
+/** Add data with packet number to array.
*
* return -1 on failure.
* return 0 on success.
*/
-static int add_data_to_buffer(const Logger *log, Packets_Array *array, uint32_t number, const Packet_Data *data)
+static int add_data_to_buffer(Packets_Array *array, uint32_t number, const Packet_Data *data)
{
if (number - array->buffer_start >= CRYPTO_PACKET_BUFFER_SIZE) {
return -1;
@@ -754,13 +751,13 @@ static int add_data_to_buffer(const Logger *log, Packets_Array *array, uint32_t
return -1;
}
- Packet_Data *new_d = (Packet_Data *)malloc(sizeof(Packet_Data));
+ Packet_Data *new_d = (Packet_Data *)calloc(1, sizeof(Packet_Data));
if (new_d == nullptr) {
return -1;
}
- memcpy(new_d, data, sizeof(Packet_Data));
+ *new_d = *data;
array->buffer[num] = new_d;
if (number - array->buffer_start >= num_packets_array(array)) {
@@ -770,13 +767,13 @@ static int add_data_to_buffer(const Logger *log, Packets_Array *array, uint32_t
return 0;
}
-/* Get pointer of data with packet number.
+/** Get pointer of data with packet number.
*
* return -1 on failure.
* return 0 if data at number is empty.
* return 1 if data pointer was put in data.
*/
-static int get_data_pointer(const Logger *log, const Packets_Array *array, Packet_Data **data, uint32_t number)
+static int get_data_pointer(const Packets_Array *array, Packet_Data **data, uint32_t number)
{
const uint32_t num_spots = num_packets_array(array);
@@ -794,12 +791,12 @@ static int get_data_pointer(const Logger *log, const Packets_Array *array, Packe
return 1;
}
-/* Add data to end of array.
+/** Add data to end of array.
*
* return -1 on failure.
* return packet number on success.
*/
-static int64_t add_data_end_of_buffer(const Logger *log, Packets_Array *array, const Packet_Data *data)
+static int64_t add_data_end_of_buffer(Packets_Array *array, const Packet_Data *data)
{
const uint32_t num_spots = num_packets_array(array);
@@ -807,25 +804,25 @@ static int64_t add_data_end_of_buffer(const Logger *log, Packets_Array *array, c
return -1;
}
- Packet_Data *new_d = (Packet_Data *)malloc(sizeof(Packet_Data));
+ Packet_Data *new_d = (Packet_Data *)calloc(1, sizeof(Packet_Data));
if (new_d == nullptr) {
return -1;
}
- memcpy(new_d, data, sizeof(Packet_Data));
+ *new_d = *data;
uint32_t id = array->buffer_end;
array->buffer[id % CRYPTO_PACKET_BUFFER_SIZE] = new_d;
++array->buffer_end;
return id;
}
-/* Read data from beginning of array.
+/** Read data from beginning of array.
*
* return -1 on failure.
* return packet number on success.
*/
-static int64_t read_data_beg_buffer(const Logger *log, Packets_Array *array, Packet_Data *data)
+static int64_t read_data_beg_buffer(Packets_Array *array, Packet_Data *data)
{
if (array->buffer_end == array->buffer_start) {
return -1;
@@ -837,7 +834,7 @@ static int64_t read_data_beg_buffer(const Logger *log, Packets_Array *array, Pac
return -1;
}
- memcpy(data, array->buffer[num], sizeof(Packet_Data));
+ *data = *array->buffer[num];
uint32_t id = array->buffer_start;
++array->buffer_start;
free(array->buffer[num]);
@@ -845,12 +842,12 @@ static int64_t read_data_beg_buffer(const Logger *log, Packets_Array *array, Pac
return id;
}
-/* Delete all packets in array before number (but not number)
+/** Delete all packets in array before number (but not number)
*
* return -1 on failure.
* return 0 on success
*/
-static int clear_buffer_until(const Logger *log, Packets_Array *array, uint32_t number)
+static int clear_buffer_until(Packets_Array *array, uint32_t number)
{
const uint32_t num_spots = num_packets_array(array);
@@ -890,12 +887,12 @@ static int clear_buffer(Packets_Array *array)
return 0;
}
-/* Set array buffer end to number.
+/** Set array buffer end to number.
*
* return -1 on failure.
* return 0 on success.
*/
-static int set_buffer_end(const Logger *log, Packets_Array *array, uint32_t number)
+static int set_buffer_end(Packets_Array *array, uint32_t number)
{
if (number - array->buffer_start > CRYPTO_PACKET_BUFFER_SIZE) {
return -1;
@@ -909,13 +906,13 @@ static int set_buffer_end(const Logger *log, Packets_Array *array, uint32_t numb
return 0;
}
-/* Create a packet request packet from recv_array and send_buffer_end into
+/** Create a packet request packet from recv_array and send_buffer_end into
* data of length.
*
* return -1 on failure.
* return length of packet on success.
*/
-static int generate_request_packet(const Logger *log, uint8_t *data, uint16_t length, const Packets_Array *recv_array)
+static int generate_request_packet(uint8_t *data, uint16_t length, const Packets_Array *recv_array)
{
if (length == 0) {
return -1;
@@ -962,14 +959,15 @@ static int generate_request_packet(const Logger *log, uint8_t *data, uint16_t le
return cur_len;
}
-/* Handle a request data packet.
+/** Handle a request data packet.
* Remove all the packets the other received from the array.
*
* return -1 on failure.
* return number of requested packets on success.
*/
-static int handle_request_packet(Mono_Time *mono_time, const Logger *log, Packets_Array *send_array,
- const uint8_t *data, uint16_t length, uint64_t *latest_send_time, uint64_t rtt_time)
+static int handle_request_packet(Mono_Time *mono_time, Packets_Array *send_array,
+ const uint8_t *data, uint16_t length,
+ uint64_t *latest_send_time, uint64_t rtt_time)
{
if (length == 0) {
return -1;
@@ -1014,11 +1012,7 @@ static int handle_request_packet(Mono_Time *mono_time, const Logger *log, Packet
++requested;
} else {
if (send_array->buffer[num]) {
- uint64_t sent_time = send_array->buffer[num]->sent_time;
-
- if (l_sent_time < sent_time) {
- l_sent_time = sent_time;
- }
+ l_sent_time = max_u64(l_sent_time, send_array->buffer[num]->sent_time);
free(send_array->buffer[num]);
send_array->buffer[num] = nullptr;
@@ -1039,9 +1033,7 @@ static int handle_request_packet(Mono_Time *mono_time, const Logger *log, Packet
}
}
- if (*latest_send_time < l_sent_time) {
- *latest_send_time = l_sent_time;
- }
+ *latest_send_time = max_u64(*latest_send_time, l_sent_time);
return requested;
}
@@ -1050,7 +1042,7 @@ static int handle_request_packet(Mono_Time *mono_time, const Logger *log, Packet
#define MAX_DATA_DATA_PACKET_SIZE (MAX_CRYPTO_PACKET_SIZE - (1 + sizeof(uint16_t) + CRYPTO_MAC_SIZE))
-/* Creates and sends a data packet to the peer using the fastest route.
+/** Creates and sends a data packet to the peer using the fastest route.
*
* return -1 on failure.
* return 0 on success.
@@ -1086,7 +1078,7 @@ static int send_data_packet(Net_Crypto *c, int crypt_connection_id, const uint8_
return send_packet_to(c, crypt_connection_id, packet, SIZEOF_VLA(packet));
}
-/* Creates and sends a data packet with buffer_start and num to the peer using the fastest route.
+/** Creates and sends a data packet with buffer_start and num to the peer using the fastest route.
*
* return -1 on failure.
* return 0 on success.
@@ -1123,7 +1115,7 @@ static int reset_max_speed_reached(Net_Crypto *c, int crypt_connection_id)
if (conn->maximum_speed_reached) {
Packet_Data *dt = nullptr;
const uint32_t packet_num = conn->send_array.buffer_end - 1;
- const int ret = get_data_pointer(c->log, &conn->send_array, &dt, packet_num);
+ const int ret = get_data_pointer(&conn->send_array, &dt, packet_num);
if (ret == 1 && dt->sent_time == 0) {
if (send_data_packet_helper(c, crypt_connection_id, conn->recv_array.buffer_start, packet_num,
@@ -1140,7 +1132,7 @@ static int reset_max_speed_reached(Net_Crypto *c, int crypt_connection_id)
return 0;
}
-/* return -1 if data could not be put in packet queue.
+/** return -1 if data could not be put in packet queue.
* return positive packet number if data was put into the queue.
*/
static int64_t send_lossless_packet(Net_Crypto *c, int crypt_connection_id, const uint8_t *data, uint16_t length,
@@ -1169,7 +1161,7 @@ static int64_t send_lossless_packet(Net_Crypto *c, int crypt_connection_id, cons
dt.length = length;
memcpy(dt.data, data, length);
pthread_mutex_lock(conn->mutex);
- int64_t packet_num = add_data_end_of_buffer(c->log, &conn->send_array, &dt);
+ int64_t packet_num = add_data_end_of_buffer(&conn->send_array, &dt);
pthread_mutex_unlock(conn->mutex);
if (packet_num == -1) {
@@ -1183,7 +1175,7 @@ static int64_t send_lossless_packet(Net_Crypto *c, int crypt_connection_id, cons
if (send_data_packet_helper(c, crypt_connection_id, conn->recv_array.buffer_start, packet_num, data, length) == 0) {
Packet_Data *dt1 = nullptr;
- if (get_data_pointer(c->log, &conn->send_array, &dt1, packet_num) == 1) {
+ if (get_data_pointer(&conn->send_array, &dt1, packet_num) == 1) {
dt1->sent_time = current_time_monotonic(c->mono_time);
}
} else {
@@ -1194,7 +1186,7 @@ static int64_t send_lossless_packet(Net_Crypto *c, int crypt_connection_id, cons
return packet_num;
}
-/* Get the lowest 2 bytes from the nonce and convert
+/** Get the lowest 2 bytes from the nonce and convert
* them to host byte format before returning them.
*/
static uint16_t get_nonce_uint16(const uint8_t *nonce)
@@ -1206,7 +1198,7 @@ static uint16_t get_nonce_uint16(const uint8_t *nonce)
#define DATA_NUM_THRESHOLD 21845
-/* Handle a data packet.
+/** Handle a data packet.
* Decrypt packet of length and put it into data.
* data must be at least MAX_DATA_DATA_PACKET_SIZE big.
*
@@ -1249,21 +1241,21 @@ static int handle_data_packet(const Net_Crypto *c, int crypt_connection_id, uint
return len;
}
-/* Send a request packet.
+/** Send a request packet.
*
* return -1 on failure.
* return 0 on success.
*/
static int send_request_packet(Net_Crypto *c, int crypt_connection_id)
{
- Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
+ const Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
if (conn == nullptr) {
return -1;
}
uint8_t data[MAX_CRYPTO_DATA_SIZE];
- int len = generate_request_packet(c->log, data, sizeof(data), &conn->recv_array);
+ int len = generate_request_packet(data, sizeof(data), &conn->recv_array);
if (len == -1) {
return -1;
@@ -1273,7 +1265,7 @@ static int send_request_packet(Net_Crypto *c, int crypt_connection_id)
len);
}
-/* Send up to max num previously requested data packets.
+/** Send up to max num previously requested data packets.
*
* return -1 on failure.
* return number of packets sent on success.
@@ -1284,7 +1276,7 @@ static int send_requested_packets(Net_Crypto *c, int crypt_connection_id, uint32
return -1;
}
- Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
+ const Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
if (conn == nullptr) {
return -1;
@@ -1297,7 +1289,7 @@ static int send_requested_packets(Net_Crypto *c, int crypt_connection_id, uint32
for (uint32_t i = 0; i < array_size; ++i) {
Packet_Data *dt;
const uint32_t packet_num = i + conn->send_array.buffer_start;
- const int ret = get_data_pointer(c->log, &conn->send_array, &dt, packet_num);
+ const int ret = get_data_pointer(&conn->send_array, &dt, packet_num);
if (ret == -1) {
return -1;
@@ -1326,7 +1318,7 @@ static int send_requested_packets(Net_Crypto *c, int crypt_connection_id, uint32
}
-/* Add a new temp packet to send repeatedly.
+/** Add a new temp packet to send repeatedly.
*
* return -1 on failure.
* return 0 on success.
@@ -1361,7 +1353,7 @@ static int new_temp_packet(const Net_Crypto *c, int crypt_connection_id, const u
return 0;
}
-/* Clear the temp packet.
+/** Clear the temp packet.
*
* return -1 on failure.
* return 0 on success.
@@ -1386,7 +1378,7 @@ static int clear_temp_packet(const Net_Crypto *c, int crypt_connection_id)
}
-/* Send the temp packet.
+/** Send the temp packet.
*
* return -1 on failure.
* return 0 on success.
@@ -1412,7 +1404,7 @@ static int send_temp_packet(Net_Crypto *c, int crypt_connection_id)
return 0;
}
-/* Create a handshake packet and set it as a temp packet.
+/** Create a handshake packet and set it as a temp packet.
* cookie must be COOKIE_LENGTH.
*
* return -1 on failure.
@@ -1421,7 +1413,7 @@ static int send_temp_packet(Net_Crypto *c, int crypt_connection_id)
static int create_send_handshake(Net_Crypto *c, int crypt_connection_id, const uint8_t *cookie,
const uint8_t *dht_public_key)
{
- Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
+ const Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
if (conn == nullptr) {
return -1;
@@ -1442,14 +1434,14 @@ static int create_send_handshake(Net_Crypto *c, int crypt_connection_id, const u
return 0;
}
-/* Send a kill packet.
+/** Send a kill packet.
*
* return -1 on failure.
* return 0 on success.
*/
static int send_kill_packet(Net_Crypto *c, int crypt_connection_id)
{
- Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
+ const Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
if (conn == nullptr) {
return -1;
@@ -1462,7 +1454,7 @@ static int send_kill_packet(Net_Crypto *c, int crypt_connection_id)
static void connection_kill(Net_Crypto *c, int crypt_connection_id, void *userdata)
{
- Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
+ const Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
if (conn == nullptr) {
return;
@@ -1487,7 +1479,7 @@ static void connection_kill(Net_Crypto *c, int crypt_connection_id, void *userda
pthread_mutex_unlock(&c->connections_mutex);
}
-/* Handle a received data packet.
+/** Handle a received data packet.
*
* return -1 on failure.
* return 0 on success.
@@ -1524,16 +1516,16 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const
if (buffer_start != conn->send_array.buffer_start) {
Packet_Data *packet_time;
- if (get_data_pointer(c->log, &conn->send_array, &packet_time, conn->send_array.buffer_start) == 1) {
+ if (get_data_pointer(&conn->send_array, &packet_time, conn->send_array.buffer_start) == 1) {
rtt_calc_time = packet_time->sent_time;
}
- if (clear_buffer_until(c->log, &conn->send_array, buffer_start) != 0) {
+ if (clear_buffer_until(&conn->send_array, buffer_start) != 0) {
return -1;
}
}
- uint8_t *real_data = data + (sizeof(uint32_t) * 2);
+ const uint8_t *real_data = data + (sizeof(uint32_t) * 2);
uint16_t real_length = len - (sizeof(uint32_t) * 2);
while (real_data[0] == PACKET_ID_PADDING) { /* Remove Padding */
@@ -1569,26 +1561,27 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const
rtt_time = DEFAULT_TCP_PING_CONNECTION;
}
- int requested = handle_request_packet(c->mono_time, c->log, &conn->send_array, real_data, real_length, &rtt_calc_time,
- rtt_time);
+ int requested = handle_request_packet(c->mono_time, &conn->send_array,
+ real_data, real_length,
+ &rtt_calc_time, rtt_time);
if (requested == -1) {
return -1;
}
- set_buffer_end(c->log, &conn->recv_array, num);
+ set_buffer_end(&conn->recv_array, num);
} else if (real_data[0] >= PACKET_ID_RANGE_LOSSLESS_START && real_data[0] <= PACKET_ID_RANGE_LOSSLESS_END) {
Packet_Data dt = {0};
dt.length = real_length;
memcpy(dt.data, real_data, real_length);
- if (add_data_to_buffer(c->log, &conn->recv_array, num, &dt) != 0) {
+ if (add_data_to_buffer(&conn->recv_array, num, &dt) != 0) {
return -1;
}
while (1) {
pthread_mutex_lock(conn->mutex);
- int ret = read_data_beg_buffer(c->log, &conn->recv_array, &dt);
+ const int ret = read_data_beg_buffer(&conn->recv_array, &dt);
pthread_mutex_unlock(conn->mutex);
if (ret == -1) {
@@ -1612,7 +1605,7 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const
++conn->packet_counter;
} else if (real_data[0] >= PACKET_ID_RANGE_LOSSY_START && real_data[0] <= PACKET_ID_RANGE_LOSSY_END) {
- set_buffer_end(c->log, &conn->recv_array, num);
+ set_buffer_end(&conn->recv_array, num);
if (conn->connection_lossy_data_callback) {
conn->connection_lossy_data_callback(conn->connection_lossy_data_callback_object,
@@ -1633,99 +1626,124 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const
return 0;
}
-/* Handle a packet that was received for the connection.
- *
- * return -1 on failure.
- * return 0 on success.
- */
-static int handle_packet_connection(Net_Crypto *c, int crypt_connection_id, const uint8_t *packet, uint16_t length,
- bool udp, void *userdata)
+static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, const uint8_t *packet, uint16_t length)
{
- if (length == 0 || length > MAX_CRYPTO_PACKET_SIZE) {
+ Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
+
+ if (conn == nullptr) {
return -1;
}
+ if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING) {
+ return -1;
+ }
+
+ uint8_t cookie[COOKIE_LENGTH];
+ uint64_t number;
+
+ if (handle_cookie_response(cookie, &number, packet, length, conn->shared_key) != sizeof(cookie)) {
+ return -1;
+ }
+
+ if (number != conn->cookie_request_number) {
+ return -1;
+ }
+
+ if (create_send_handshake(c, crypt_connection_id, cookie, conn->dht_public_key) != 0) {
+ return -1;
+ }
+
+ conn->status = CRYPTO_CONN_HANDSHAKE_SENT;
+ return 0;
+}
+
+static int handle_packet_crypto_hs(Net_Crypto *c, int crypt_connection_id, const uint8_t *packet, uint16_t length,
+ void *userdata)
+{
Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
if (conn == nullptr) {
return -1;
}
- switch (packet[0]) {
- case NET_PACKET_COOKIE_RESPONSE: {
- if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING) {
- return -1;
- }
+ if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING
+ && conn->status != CRYPTO_CONN_HANDSHAKE_SENT
+ && conn->status != CRYPTO_CONN_NOT_CONFIRMED) {
+ return -1;
+ }
- uint8_t cookie[COOKIE_LENGTH];
- uint64_t number;
+ uint8_t peer_real_pk[CRYPTO_PUBLIC_KEY_SIZE];
+ uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE];
+ uint8_t cookie[COOKIE_LENGTH];
- if (handle_cookie_response(c->log, cookie, &number, packet, length, conn->shared_key) != sizeof(cookie)) {
- return -1;
- }
+ if (handle_crypto_handshake(c, conn->recv_nonce, conn->peersessionpublic_key, peer_real_pk, dht_public_key, cookie,
+ packet, length, conn->public_key) != 0) {
+ return -1;
+ }
- if (number != conn->cookie_request_number) {
- return -1;
- }
+ if (public_key_cmp(dht_public_key, conn->dht_public_key) == 0) {
+ encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key);
- if (create_send_handshake(c, crypt_connection_id, cookie, conn->dht_public_key) != 0) {
+ if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING) {
+ if (create_send_handshake(c, crypt_connection_id, cookie, dht_public_key) != 0) {
return -1;
}
+ }
- conn->status = CRYPTO_CONN_HANDSHAKE_SENT;
- return 0;
+ conn->status = CRYPTO_CONN_NOT_CONFIRMED;
+ } else {
+ if (conn->dht_pk_callback) {
+ conn->dht_pk_callback(conn->dht_pk_callback_object, conn->dht_pk_callback_number, dht_public_key, userdata);
}
+ }
- case NET_PACKET_CRYPTO_HS: {
- if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING
- && conn->status != CRYPTO_CONN_HANDSHAKE_SENT
- && conn->status != CRYPTO_CONN_NOT_CONFIRMED) {
- return -1;
- }
+ return 0;
+}
- uint8_t peer_real_pk[CRYPTO_PUBLIC_KEY_SIZE];
- uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE];
- uint8_t cookie[COOKIE_LENGTH];
+static int handle_packet_crypto_data(Net_Crypto *c, int crypt_connection_id, const uint8_t *packet, uint16_t length,
+ bool udp, void *userdata)
+{
+ const Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
- if (handle_crypto_handshake(c, conn->recv_nonce, conn->peersessionpublic_key, peer_real_pk, dht_public_key, cookie,
- packet, length, conn->public_key) != 0) {
- return -1;
- }
+ if (conn == nullptr) {
+ return -1;
+ }
- if (public_key_cmp(dht_public_key, conn->dht_public_key) == 0) {
- encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key);
+ if (conn->status != CRYPTO_CONN_NOT_CONFIRMED && conn->status != CRYPTO_CONN_ESTABLISHED) {
+ return -1;
+ }
- if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING) {
- if (create_send_handshake(c, crypt_connection_id, cookie, dht_public_key) != 0) {
- return -1;
- }
- }
+ return handle_data_packet_core(c, crypt_connection_id, packet, length, udp, userdata);
+}
- conn->status = CRYPTO_CONN_NOT_CONFIRMED;
- } else {
- if (conn->dht_pk_callback) {
- conn->dht_pk_callback(conn->dht_pk_callback_object, conn->dht_pk_callback_number, dht_public_key, userdata);
- }
- }
+/** Handle a packet that was received for the connection.
+ *
+ * return -1 on failure.
+ * return 0 on success.
+ */
+static int handle_packet_connection(Net_Crypto *c, int crypt_connection_id, const uint8_t *packet, uint16_t length,
+ bool udp, void *userdata)
+{
+ if (length == 0 || length > MAX_CRYPTO_PACKET_SIZE) {
+ return -1;
+ }
- return 0;
- }
+ switch (packet[0]) {
+ case NET_PACKET_COOKIE_RESPONSE:
+ return handle_packet_cookie_response(c, crypt_connection_id, packet, length);
- case NET_PACKET_CRYPTO_DATA: {
- if (conn->status != CRYPTO_CONN_NOT_CONFIRMED && conn->status != CRYPTO_CONN_ESTABLISHED) {
- return -1;
- }
+ case NET_PACKET_CRYPTO_HS:
+ return handle_packet_crypto_hs(c, crypt_connection_id, packet, length, userdata);
- return handle_data_packet_core(c, crypt_connection_id, packet, length, udp, userdata);
- }
+ case NET_PACKET_CRYPTO_DATA:
+ return handle_packet_crypto_data(c, crypt_connection_id, packet, length, udp, userdata);
- default: {
+ default:
return -1;
- }
}
}
-/* Set the size of the friend list to numfriends.
+/** Set the size of the friend list to numfriends.
*
* return -1 if realloc fails.
* return 0 if it succeeds.
@@ -1750,7 +1768,7 @@ static int realloc_cryptoconnection(Net_Crypto *c, uint32_t num)
}
-/* Create a new empty crypto connection.
+/** Create a new empty crypto connection.
*
* return -1 on failure.
* return connection id on success.
@@ -1791,7 +1809,7 @@ static int create_crypto_connection(Net_Crypto *c)
c->crypto_connections[id].last_packets_left_rem = 0;
c->crypto_connections[id].packet_send_rate_requested = 0;
c->crypto_connections[id].last_packets_left_requested_rem = 0;
- c->crypto_connections[id].mutex = (pthread_mutex_t *) malloc(sizeof(pthread_mutex_t));
+ c->crypto_connections[id].mutex = (pthread_mutex_t *)calloc(1, sizeof(pthread_mutex_t));
if (c->crypto_connections[id].mutex == nullptr) {
pthread_mutex_unlock(&c->connections_mutex);
@@ -1811,7 +1829,7 @@ static int create_crypto_connection(Net_Crypto *c)
return id;
}
-/* Wipe a crypto connection.
+/** Wipe a crypto connection.
*
* return -1 on failure.
* return 0 on success.
@@ -1853,7 +1871,7 @@ static int wipe_crypto_connection(Net_Crypto *c, int crypt_connection_id)
return 0;
}
-/* Get crypto connection id from public key of peer.
+/** Get crypto connection id from public key of peer.
*
* return -1 if there are no connections like we are looking for.
* return id if it found it.
@@ -1873,14 +1891,14 @@ static int getcryptconnection_id(const Net_Crypto *c, const uint8_t *public_key)
return -1;
}
-/* Add a source to the crypto connection.
+/** Add a source to the crypto connection.
* This is to be used only when we have received a packet from that source.
*
* return -1 on failure.
* return positive number on success.
* 0 if source was a direct UDP connection.
*/
-static int crypto_connection_add_source(Net_Crypto *c, int crypt_connection_id, IP_Port source)
+static int crypto_connection_add_source(Net_Crypto *c, int crypt_connection_id, const IP_Port *source)
{
Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
@@ -1888,12 +1906,12 @@ static int crypto_connection_add_source(Net_Crypto *c, int crypt_connection_id,
return -1;
}
- if (net_family_is_ipv4(source.ip.family) || net_family_is_ipv6(source.ip.family)) {
+ if (net_family_is_ipv4(source->ip.family) || net_family_is_ipv6(source->ip.family)) {
if (add_ip_port_connection(c, crypt_connection_id, source) != 0) {
return -1;
}
- if (net_family_is_ipv4(source.ip.family)) {
+ if (net_family_is_ipv4(source->ip.family)) {
conn->direct_lastrecv_timev4 = mono_time_get(c->mono_time);
} else {
conn->direct_lastrecv_timev6 = mono_time_get(c->mono_time);
@@ -1902,8 +1920,8 @@ static int crypto_connection_add_source(Net_Crypto *c, int crypt_connection_id,
return 0;
}
- if (net_family_is_tcp_family(source.ip.family)) {
- if (add_tcp_number_relay_connection(c->tcp_c, conn->connection_number_tcp, source.ip.ip.v6.uint32[0]) == 0) {
+ if (net_family_is_tcp_family(source->ip.family)) {
+ if (add_tcp_number_relay_connection(c->tcp_c, conn->connection_number_tcp, source->ip.ip.v6.uint32[0]) == 0) {
return 1;
}
}
@@ -1912,7 +1930,7 @@ static int crypto_connection_add_source(Net_Crypto *c, int crypt_connection_id,
}
-/* Set function to be called when someone requests a new connection to us.
+/** Set function to be called when someone requests a new connection to us.
*
* The set function should return -1 on failure and 0 on success.
*
@@ -1924,13 +1942,13 @@ void new_connection_handler(Net_Crypto *c, new_connection_cb *new_connection_cal
c->new_connection_callback_object = object;
}
-/* Handle a handshake packet by someone who wants to initiate a new connection with us.
+/** Handle a handshake packet by someone who wants to initiate a new connection with us.
* This calls the callback set by new_connection_handler() if the handshake is ok.
*
* return -1 on failure.
* return 0 on success.
*/
-static int handle_new_connection_handshake(Net_Crypto *c, IP_Port source, const uint8_t *data, uint16_t length,
+static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, const uint8_t *data, uint16_t length,
void *userdata)
{
New_Connection n_c;
@@ -1940,7 +1958,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, IP_Port source, const
return -1;
}
- n_c.source = source;
+ n_c.source = *source;
n_c.cookie_length = COOKIE_LENGTH;
if (handle_crypto_handshake(c, n_c.recv_nonce, n_c.peersessionpublic_key, n_c.public_key, n_c.dht_public_key,
@@ -1988,12 +2006,12 @@ static int handle_new_connection_handshake(Net_Crypto *c, IP_Port source, const
return ret;
}
-/* Accept a crypto connection.
+/** Accept a crypto connection.
*
* return -1 on failure.
* return connection id on success.
*/
-int accept_crypto_connection(Net_Crypto *c, New_Connection *n_c)
+int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c)
{
if (getcryptconnection_id(c, n_c->public_key) != -1) {
return -1;
@@ -2044,11 +2062,11 @@ int accept_crypto_connection(Net_Crypto *c, New_Connection *n_c)
conn->packet_send_rate_requested = CRYPTO_PACKET_MIN_RATE;
conn->packets_left = CRYPTO_MIN_QUEUE_LENGTH;
conn->rtt_time = DEFAULT_PING_CONNECTION;
- crypto_connection_add_source(c, crypt_connection_id, n_c->source);
+ crypto_connection_add_source(c, crypt_connection_id, &n_c->source);
return crypt_connection_id;
}
-/* Create a crypto connection.
+/** Create a crypto connection.
* If one to that real public key already exists, return it.
*
* return -1 on failure.
@@ -2106,14 +2124,14 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u
return crypt_connection_id;
}
-/* Set the direct ip of the crypto connection.
+/** Set the direct ip of the crypto connection.
*
* Connected is 0 if we are not sure we are connected to that person, 1 if we are sure.
*
* return -1 on failure.
* return 0 on success.
*/
-int set_direct_ip_port(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port, bool connected)
+int set_direct_ip_port(Net_Crypto *c, int crypt_connection_id, const IP_Port *ip_port, bool connected)
{
Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
@@ -2127,7 +2145,7 @@ int set_direct_ip_port(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port,
const uint64_t direct_lastrecv_time = connected ? mono_time_get(c->mono_time) : 0;
- if (net_family_is_ipv4(ip_port.ip.family)) {
+ if (net_family_is_ipv4(ip_port->ip.family)) {
conn->direct_lastrecv_timev4 = direct_lastrecv_time;
} else {
conn->direct_lastrecv_timev6 = direct_lastrecv_time;
@@ -2146,7 +2164,7 @@ static int tcp_data_callback(void *object, int crypt_connection_id, const uint8_
return -1;
}
- Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
+ const Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
if (conn == nullptr) {
return -1;
@@ -2189,7 +2207,7 @@ static int tcp_oob_callback(void *object, const uint8_t *public_key, unsigned in
source.ip.family = net_family_tcp_family;
source.ip.ip.v6.uint32[0] = tcp_connections_number;
- if (handle_new_connection_handshake(c, source, data, length, userdata) != 0) {
+ if (handle_new_connection_handshake(c, &source, data, length, userdata) != 0) {
return -1;
}
@@ -2199,14 +2217,14 @@ static int tcp_oob_callback(void *object, const uint8_t *public_key, unsigned in
return -1;
}
-/* Add a tcp relay, associating it to a crypt_connection_id.
+/** Add a tcp relay, associating it to a crypt_connection_id.
*
* return 0 if it was added.
* return -1 if it wasn't.
*/
-int add_tcp_relay_peer(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port, const uint8_t *public_key)
+int add_tcp_relay_peer(Net_Crypto *c, int crypt_connection_id, const IP_Port *ip_port, const uint8_t *public_key)
{
- Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
+ const Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
if (conn == nullptr) {
return -1;
@@ -2218,12 +2236,12 @@ int add_tcp_relay_peer(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port,
return ret;
}
-/* Add a tcp relay to the array.
+/** Add a tcp relay to the array.
*
* return 0 if it was added.
* return -1 if it wasn't.
*/
-int add_tcp_relay(Net_Crypto *c, IP_Port ip_port, const uint8_t *public_key)
+int add_tcp_relay(Net_Crypto *c, const IP_Port *ip_port, const uint8_t *public_key)
{
pthread_mutex_lock(&c->tcp_mutex);
int ret = add_tcp_relay_global(c->tcp_c, ip_port, public_key);
@@ -2231,7 +2249,7 @@ int add_tcp_relay(Net_Crypto *c, IP_Port ip_port, const uint8_t *public_key)
return ret;
}
-/* Return a random TCP connection number for use in send_tcp_onion_request.
+/** Return a random TCP connection number for use in send_tcp_onion_request.
*
* TODO(irungentoo): This number is just the index of an array that the elements can
* change without warning.
@@ -2248,7 +2266,7 @@ int get_random_tcp_con_number(Net_Crypto *c)
return ret;
}
-/* Send an onion packet via the TCP relay corresponding to tcp_connections_number.
+/** Send an onion packet via the TCP relay corresponding to tcp_connections_number.
*
* return 0 on success.
* return -1 on failure.
@@ -2262,7 +2280,7 @@ int send_tcp_onion_request(Net_Crypto *c, unsigned int tcp_connections_number, c
return ret;
}
-/* Copy a maximum of num TCP relays we are connected to to tcp_relays.
+/** Copy a maximum of num TCP relays we are connected to to tcp_relays.
* NOTE that the family of the copied ip ports will be set to TCP_INET or TCP_INET6.
*
* return number of relays copied to tcp_relays on success.
@@ -2288,7 +2306,7 @@ static void do_tcp(Net_Crypto *c, void *userdata)
pthread_mutex_unlock(&c->tcp_mutex);
for (uint32_t i = 0; i < c->crypto_connections_length; ++i) {
- Crypto_Connection *conn = get_crypto_connection(c, i);
+ const Crypto_Connection *conn = get_crypto_connection(c, i);
if (conn == nullptr) {
continue;
@@ -2310,7 +2328,7 @@ static void do_tcp(Net_Crypto *c, void *userdata)
}
}
-/* Set function to be called when connection with crypt_connection_id goes connects/disconnects.
+/** Set function to be called when connection with crypt_connection_id goes connects/disconnects.
*
* The set function should return -1 on failure and 0 on success.
* Note that if this function is set, the connection will clear itself on disconnect.
@@ -2335,7 +2353,7 @@ int connection_status_handler(const Net_Crypto *c, int crypt_connection_id,
return 0;
}
-/* Set function to be called when connection with crypt_connection_id receives a data packet of length.
+/** Set function to be called when connection with crypt_connection_id receives a lossless data packet of length.
*
* The set function should return -1 on failure and 0 on success.
* Object and id will be passed to this function untouched.
@@ -2358,7 +2376,7 @@ int connection_data_handler(const Net_Crypto *c, int crypt_connection_id,
return 0;
}
-/* Set function to be called when connection with crypt_connection_id receives a lossy data packet of length.
+/** Set function to be called when connection with crypt_connection_id receives a lossy data packet of length.
*
* The set function should return -1 on failure and 0 on success.
* Object and id will be passed to this function untouched.
@@ -2366,7 +2384,7 @@ int connection_data_handler(const Net_Crypto *c, int crypt_connection_id,
* return -1 on failure.
* return 0 on success.
*/
-int connection_lossy_data_handler(Net_Crypto *c, int crypt_connection_id,
+int connection_lossy_data_handler(const Net_Crypto *c, int crypt_connection_id,
connection_lossy_data_cb *connection_lossy_data_callback,
void *object, int id)
{
@@ -2383,7 +2401,7 @@ int connection_lossy_data_handler(Net_Crypto *c, int crypt_connection_id,
}
-/* Set the function for this friend that will be callbacked with object and number if
+/** Set the function for this friend that will be callbacked with object and number if
* the friend sends us a different dht public key than we have associated to him.
*
* If this function is called, the connection should be recreated with the new public key.
@@ -2393,7 +2411,7 @@ int connection_lossy_data_handler(Net_Crypto *c, int crypt_connection_id,
* return -1 on failure.
* return 0 on success.
*/
-int nc_dht_pk_callback(Net_Crypto *c, int crypt_connection_id, dht_pk_cb *function, void *object, uint32_t number)
+int nc_dht_pk_callback(const Net_Crypto *c, int crypt_connection_id, dht_pk_cb *function, void *object, uint32_t number)
{
Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
@@ -2407,19 +2425,19 @@ int nc_dht_pk_callback(Net_Crypto *c, int crypt_connection_id, dht_pk_cb *functi
return 0;
}
-/* Get the crypto connection id from the ip_port.
+/** Get the crypto connection id from the ip_port.
*
* return -1 on failure.
* return connection id on success.
*/
-static int crypto_id_ip_port(const Net_Crypto *c, IP_Port ip_port)
+static int crypto_id_ip_port(const Net_Crypto *c, const IP_Port *ip_port)
{
- return bs_list_find(&c->ip_port_list, (uint8_t *)&ip_port);
+ return bs_list_find(&c->ip_port_list, (const uint8_t *)ip_port);
}
#define CRYPTO_MIN_PACKET_SIZE (1 + sizeof(uint16_t) + CRYPTO_MAC_SIZE)
-/* Handle raw UDP packets coming directly from the socket.
+/** Handle raw UDP packets coming directly from the socket.
*
* Handles:
* Cookie response packets.
@@ -2427,7 +2445,8 @@ static int crypto_id_ip_port(const Net_Crypto *c, IP_Port ip_port)
* Crypto data packets.
*
*/
-static int udp_handle_packet(void *object, IP_Port source, const uint8_t *packet, uint16_t length, void *userdata)
+static int udp_handle_packet(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length,
+ void *userdata)
{
Net_Crypto *c = (Net_Crypto *)object;
@@ -2461,7 +2480,7 @@ static int udp_handle_packet(void *object, IP_Port source, const uint8_t *packet
pthread_mutex_lock(conn->mutex);
- if (net_family_is_ipv4(source.ip.family)) {
+ if (net_family_is_ipv4(source->ip.family)) {
conn->direct_lastrecv_timev4 = mono_time_get(c->mono_time);
} else {
conn->direct_lastrecv_timev6 = mono_time_get(c->mono_time);
@@ -2471,19 +2490,19 @@ static int udp_handle_packet(void *object, IP_Port source, const uint8_t *packet
return 0;
}
-/* The dT for the average packet receiving rate calculations.
+/** The dT for the average packet receiving rate calculations.
* Also used as the */
#define PACKET_COUNTER_AVERAGE_INTERVAL 50
-/* Ratio of recv queue size / recv packet rate (in seconds) times
+/** Ratio of recv queue size / recv packet rate (in seconds) times
* the number of ms between request packets to send at that ratio
*/
#define REQUEST_PACKETS_COMPARE_CONSTANT (0.125 * 100.0)
-/* Timeout for increasing speed after congestion event (in ms). */
+/** Timeout for increasing speed after congestion event (in ms). */
#define CONGESTION_EVENT_TIMEOUT 1000
-/* If the send queue is SEND_QUEUE_RATIO times larger than the
+/** If the send queue is SEND_QUEUE_RATIO times larger than the
* calculated link speed the packet send speed will be reduced
* by a value depending on this number.
*/
@@ -2515,8 +2534,8 @@ static void send_crypto_packets(Net_Crypto *c)
if (conn->status == CRYPTO_CONN_ESTABLISHED) {
if (conn->packet_recv_rate > CRYPTO_PACKET_MIN_RATE) {
- double request_packet_interval = (REQUEST_PACKETS_COMPARE_CONSTANT / ((num_packets_array(
- &conn->recv_array) + 1.0) / (conn->packet_recv_rate + 1.0)));
+ double request_packet_interval = REQUEST_PACKETS_COMPARE_CONSTANT / ((num_packets_array(
+ &conn->recv_array) + 1.0) / (conn->packet_recv_rate + 1.0));
double request_packet_interval2 = ((CRYPTO_PACKET_MIN_RATE / conn->packet_recv_rate) *
(double)CRYPTO_SEND_PACKET_INTERVAL) + (double)PACKET_COUNTER_AVERAGE_INTERVAL;
@@ -2585,8 +2604,8 @@ static void send_crypto_packets(Net_Crypto *c)
long signed int total_resent = 0;
// TODO(irungentoo): use real delay
- unsigned int delay = (unsigned int)((conn->rtt_time / PACKET_COUNTER_AVERAGE_INTERVAL) + 0.5);
- unsigned int packets_set_rem_array = (CONGESTION_LAST_SENT_ARRAY_SIZE - CONGESTION_QUEUE_ARRAY_SIZE);
+ unsigned int delay = (unsigned int)(((double)conn->rtt_time / PACKET_COUNTER_AVERAGE_INTERVAL) + 0.5);
+ unsigned int packets_set_rem_array = CONGESTION_LAST_SENT_ARRAY_SIZE - CONGESTION_QUEUE_ARRAY_SIZE;
if (delay > packets_set_rem_array) {
delay = packets_set_rem_array;
@@ -2608,17 +2627,17 @@ static void send_crypto_packets(Net_Crypto *c)
/* if queue is too big only allow resending packets. */
uint32_t npackets = num_packets_array(&conn->send_array);
- double min_speed = 1000.0 * (((double)(total_sent)) / ((double)(CONGESTION_QUEUE_ARRAY_SIZE) *
+ double min_speed = 1000.0 * (((double)total_sent) / ((double)CONGESTION_QUEUE_ARRAY_SIZE *
PACKET_COUNTER_AVERAGE_INTERVAL));
- double min_speed_request = 1000.0 * (((double)(total_sent + total_resent)) / ((double)(
- CONGESTION_QUEUE_ARRAY_SIZE) * PACKET_COUNTER_AVERAGE_INTERVAL));
+ double min_speed_request = 1000.0 * (((double)(total_sent + total_resent)) / (
+ (double)CONGESTION_QUEUE_ARRAY_SIZE * PACKET_COUNTER_AVERAGE_INTERVAL));
if (min_speed < CRYPTO_PACKET_MIN_RATE) {
min_speed = CRYPTO_PACKET_MIN_RATE;
}
- double send_array_ratio = (((double)npackets) / min_speed);
+ double send_array_ratio = (double)npackets / min_speed;
// TODO(irungentoo): Improve formula?
if (send_array_ratio > SEND_QUEUE_RATIO && CRYPTO_MIN_QUEUE_LENGTH < npackets) {
@@ -2725,7 +2744,7 @@ static void send_crypto_packets(Net_Crypto *c)
}
}
-/* Return 1 if max speed was reached for this connection (no more data can be physically through the pipe).
+/** Return 1 if max speed was reached for this connection (no more data can be physically through the pipe).
* Return 0 if it wasn't reached.
*/
bool max_speed_reached(Net_Crypto *c, int crypt_connection_id)
@@ -2733,12 +2752,12 @@ bool max_speed_reached(Net_Crypto *c, int crypt_connection_id)
return reset_max_speed_reached(c, crypt_connection_id) != 0;
}
-/* returns the number of packet slots left in the sendbuffer.
+/** returns the number of packet slots left in the sendbuffer.
* return 0 if failure.
*/
uint32_t crypto_num_free_sendqueue_slots(const Net_Crypto *c, int crypt_connection_id)
{
- Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
+ const Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
if (conn == nullptr) {
return 0;
@@ -2753,12 +2772,12 @@ uint32_t crypto_num_free_sendqueue_slots(const Net_Crypto *c, int crypt_connecti
return max_packets;
}
-/* Sends a lossless cryptopacket.
+/** Sends a lossless cryptopacket.
*
* return -1 if data could not be put in packet queue.
* return positive packet number if data was put into the queue.
*
- * The first byte of data must in the PACKET_ID_RANGE_LOSSLESS.
+ * The first byte of data must be in the PACKET_ID_RANGE_LOSSLESS.
*
* congestion_control: should congestion control apply to this packet?
*/
@@ -2802,7 +2821,7 @@ int64_t write_cryptpacket(Net_Crypto *c, int crypt_connection_id, const uint8_t
return ret;
}
-/* Check if packet_number was received by the other side.
+/** Check if packet_number was received by the other side.
*
* packet_number must be a valid packet number of a packet sent on this connection.
*
@@ -2816,9 +2835,9 @@ int64_t write_cryptpacket(Net_Crypto *c, int crypt_connection_id, const uint8_t
* It CANNOT be simplified to `packet_number < buffer_start`, as it will fail
* when `buffer_end < buffer_start`.
*/
-int cryptpacket_received(Net_Crypto *c, int crypt_connection_id, uint32_t packet_number)
+int cryptpacket_received(const Net_Crypto *c, int crypt_connection_id, uint32_t packet_number)
{
- Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
+ const Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
if (conn == nullptr) {
return -1;
@@ -2834,12 +2853,12 @@ int cryptpacket_received(Net_Crypto *c, int crypt_connection_id, uint32_t packet
return 0;
}
-/* Sends a lossy cryptopacket.
+/** Sends a lossy cryptopacket.
*
* return -1 on failure.
* return 0 on success.
*
- * The first byte of data must in the PACKET_ID_RANGE_LOSSY.
+ * The first byte of data must be in the PACKET_ID_RANGE_LOSSY.
*/
int send_lossy_cryptpacket(Net_Crypto *c, int crypt_connection_id, const uint8_t *data, uint16_t length)
{
@@ -2874,7 +2893,7 @@ int send_lossy_cryptpacket(Net_Crypto *c, int crypt_connection_id, const uint8_t
return ret;
}
-/* Kill a crypto connection.
+/** Kill a crypto connection.
*
* return -1 on failure.
* return 0 on success.
@@ -2908,7 +2927,7 @@ int crypto_kill(Net_Crypto *c, int crypt_connection_id)
bool crypto_connection_status(const Net_Crypto *c, int crypt_connection_id, bool *direct_connected,
unsigned int *online_tcp_relays)
{
- Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
+ const Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
if (conn == nullptr) {
return false;
@@ -2938,8 +2957,8 @@ void new_keys(Net_Crypto *c)
crypto_new_keypair(c->self_public_key, c->self_secret_key);
}
-/* Save the public and private keys to the keys array.
- * Length must be CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SECRET_KEY_SIZE.
+/** Save the public and private keys to the keys array.
+ * Length must be CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SECRET_KEY_SIZE.
*
* TODO(irungentoo): Save only secret key.
*/
@@ -2949,7 +2968,7 @@ void save_keys(const Net_Crypto *c, uint8_t *keys)
memcpy(keys + CRYPTO_PUBLIC_KEY_SIZE, c->self_secret_key, CRYPTO_SECRET_KEY_SIZE);
}
-/* Load the secret key.
+/** Load the secret key.
* Length must be CRYPTO_SECRET_KEY_SIZE.
*/
void load_secret_key(Net_Crypto *c, const uint8_t *sk)
@@ -2958,10 +2977,10 @@ void load_secret_key(Net_Crypto *c, const uint8_t *sk)
crypto_derive_public_key(c->self_public_key, c->self_secret_key);
}
-/* Run this to (re)initialize net_crypto.
- * Sets all the global connection variables to their default values.
+/** Create new instance of Net_Crypto.
+ * Sets all the global connection variables to their default values.
*/
-Net_Crypto *new_net_crypto(const Logger *log, Mono_Time *mono_time, DHT *dht, TCP_Proxy_Info *proxy_info)
+Net_Crypto *new_net_crypto(const Logger *log, Mono_Time *mono_time, DHT *dht, const TCP_Proxy_Info *proxy_info)
{
if (dht == nullptr) {
return nullptr;
@@ -2976,7 +2995,7 @@ Net_Crypto *new_net_crypto(const Logger *log, Mono_Time *mono_time, DHT *dht, TC
temp->log = log;
temp->mono_time = mono_time;
- temp->tcp_c = new_tcp_connections(mono_time, dht_get_self_secret_key(dht), proxy_info);
+ temp->tcp_c = new_tcp_connections(log, mono_time, dht_get_self_secret_key(dht), proxy_info);
if (temp->tcp_c == nullptr) {
free(temp);
@@ -3013,7 +3032,7 @@ Net_Crypto *new_net_crypto(const Logger *log, Mono_Time *mono_time, DHT *dht, TC
static void kill_timedout(Net_Crypto *c, void *userdata)
{
for (uint32_t i = 0; i < c->crypto_connections_length; ++i) {
- Crypto_Connection *conn = get_crypto_connection(c, i);
+ const Crypto_Connection *conn = get_crypto_connection(c, i);
if (conn == nullptr) {
continue;
@@ -3039,14 +3058,14 @@ static void kill_timedout(Net_Crypto *c, void *userdata)
}
}
-/* return the optimal interval in ms for running do_net_crypto.
+/** return the optimal interval in ms for running do_net_crypto.
*/
uint32_t crypto_run_interval(const Net_Crypto *c)
{
return c->current_sleep_time;
}
-/* Main loop. */
+/** Main loop. */
void do_net_crypto(Net_Crypto *c, void *userdata)
{
kill_timedout(c, userdata);
@@ -3056,9 +3075,7 @@ void do_net_crypto(Net_Crypto *c, void *userdata)
void kill_net_crypto(Net_Crypto *c)
{
- uint32_t i;
-
- for (i = 0; i < c->crypto_connections_length; ++i) {
+ for (uint32_t i = 0; i < c->crypto_connections_length; ++i) {
crypto_kill(c, i);
}
diff --git a/protocols/Tox/libtox/src/toxcore/net_crypto.h b/protocols/Tox/libtox/src/toxcore/net_crypto.h
index 33275708af..9a3bd1e21c 100644
--- a/protocols/Tox/libtox/src/toxcore/net_crypto.h
+++ b/protocols/Tox/libtox/src/toxcore/net_crypto.h
@@ -3,45 +3,45 @@
* Copyright © 2013 Tox project.
*/
-/*
+/**
* Functions for the core network crypto.
*/
#ifndef C_TOXCORE_TOXCORE_NET_CRYPTO_H
#define C_TOXCORE_TOXCORE_NET_CRYPTO_H
+#include <pthread.h>
+
#include "DHT.h"
#include "LAN_discovery.h"
#include "TCP_connection.h"
#include "logger.h"
-#include <pthread.h>
-
-/** Crypto payloads. */
+/*** Crypto payloads. */
-/** Ranges. */
+/*** Ranges. */
-/* Packets in this range are reserved for net_crypto internal use. */
+/** Packets in this range are reserved for net_crypto internal use. */
#define PACKET_ID_RANGE_RESERVED_START 0
#define PACKET_ID_RANGE_RESERVED_END 15
-/* Packets in this range are reserved for Messenger use. */
+/** Packets in this range are reserved for Messenger use. */
#define PACKET_ID_RANGE_LOSSLESS_START 16
#define PACKET_ID_RANGE_LOSSLESS_NORMAL_START 16
#define PACKET_ID_RANGE_LOSSLESS_NORMAL_END 159
-/* Packets in this range can be used for anything. */
+/** Packets in this range can be used for anything. */
#define PACKET_ID_RANGE_LOSSLESS_CUSTOM_START 160
#define PACKET_ID_RANGE_LOSSLESS_CUSTOM_END 191
#define PACKET_ID_RANGE_LOSSLESS_END 191
-/* Packets in this range are reserved for AV use. */
+/** Packets in this range are reserved for AV use. */
#define PACKET_ID_RANGE_LOSSY_START 192
#define PACKET_ID_RANGE_LOSSY_AV_START 192
#define PACKET_ID_RANGE_LOSSY_AV_SIZE 8
#define PACKET_ID_RANGE_LOSSY_AV_END 199
-/* Packets in this range can be used for anything. */
+/** Packets in this range can be used for anything. */
#define PACKET_ID_RANGE_LOSSY_CUSTOM_START 200
#define PACKET_ID_RANGE_LOSSY_CUSTOM_END 254
#define PACKET_ID_RANGE_LOSSY_END 254
-/** Messages. */
+/*** Messages. */
#define PACKET_ID_PADDING 0 // Denotes padding
#define PACKET_ID_REQUEST 1 // Used to request unreceived packets
@@ -66,45 +66,45 @@
#define PACKET_ID_REJOIN_CONFERENCE 100
#define PACKET_ID_LOSSY_CONFERENCE 199
-/* Maximum size of receiving and sending packet buffers. */
+/** Maximum size of receiving and sending packet buffers. */
#define CRYPTO_PACKET_BUFFER_SIZE 32768 // Must be a power of 2
-/* Minimum packet rate per second. */
+/** Minimum packet rate per second. */
#define CRYPTO_PACKET_MIN_RATE 4.0
-/* Minimum packet queue max length. */
+/** Minimum packet queue max length. */
#define CRYPTO_MIN_QUEUE_LENGTH 64
-/* Maximum total size of packets that net_crypto sends. */
+/** Maximum total size of packets that net_crypto sends. */
#define MAX_CRYPTO_PACKET_SIZE (uint16_t)1400
#define CRYPTO_DATA_PACKET_MIN_SIZE (uint16_t)(1 + sizeof(uint16_t) + (sizeof(uint32_t) + sizeof(uint32_t)) + CRYPTO_MAC_SIZE)
-/* Max size of data in packets */
+/** Max size of data in packets */
#define MAX_CRYPTO_DATA_SIZE (uint16_t)(MAX_CRYPTO_PACKET_SIZE - CRYPTO_DATA_PACKET_MIN_SIZE)
-/* Interval in ms between sending cookie request/handshake packets. */
+/** Interval in ms between sending cookie request/handshake packets. */
#define CRYPTO_SEND_PACKET_INTERVAL 1000
-/* The maximum number of times we try to send the cookie request and handshake
+/** The maximum number of times we try to send the cookie request and handshake
* before giving up. */
#define MAX_NUM_SENDPACKET_TRIES 8
-/* The timeout of no received UDP packets before the direct UDP connection is considered dead. */
+/** The timeout of no received UDP packets before the direct UDP connection is considered dead. */
#define UDP_DIRECT_TIMEOUT 8
#define MAX_TCP_CONNECTIONS 64
#define MAX_TCP_RELAYS_PEER 4
-/* All packets will be padded a number of bytes based on this number. */
+/** All packets will be padded a number of bytes based on this number. */
#define CRYPTO_MAX_PADDING 8
-/* Base current transfer speed on last CONGESTION_QUEUE_ARRAY_SIZE number of points taken
+/** Base current transfer speed on last CONGESTION_QUEUE_ARRAY_SIZE number of points taken
* at the dT defined in net_crypto.c */
#define CONGESTION_QUEUE_ARRAY_SIZE 12
#define CONGESTION_LAST_SENT_ARRAY_SIZE (CONGESTION_QUEUE_ARRAY_SIZE * 2)
-/* Default connection ping in ms. */
+/** Default connection ping in ms. */
#define DEFAULT_PING_CONNECTION 1000
#define DEFAULT_TCP_PING_CONNECTION 500
@@ -129,9 +129,9 @@ typedef int connection_status_cb(void *object, int id, uint8_t status, void *use
typedef int connection_data_cb(void *object, int id, const uint8_t *data, uint16_t length, void *userdata);
typedef int connection_lossy_data_cb(void *object, int id, const uint8_t *data, uint16_t length, void *userdata);
typedef void dht_pk_cb(void *data, int32_t number, const uint8_t *dht_public_key, void *userdata);
-typedef int new_connection_cb(void *object, New_Connection *n_c);
+typedef int new_connection_cb(void *object, const New_Connection *n_c);
-/* Set function to be called when someone requests a new connection to us.
+/** Set function to be called when someone requests a new connection to us.
*
* The set function should return -1 on failure and 0 on success.
*
@@ -139,14 +139,14 @@ typedef int new_connection_cb(void *object, New_Connection *n_c);
*/
void new_connection_handler(Net_Crypto *c, new_connection_cb *new_connection_callback, void *object);
-/* Accept a crypto connection.
+/** Accept a crypto connection.
*
* return -1 on failure.
* return connection id on success.
*/
-int accept_crypto_connection(Net_Crypto *c, New_Connection *n_c);
+int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c);
-/* Create a crypto connection.
+/** Create a crypto connection.
* If one to that real public key already exists, return it.
*
* return -1 on failure.
@@ -154,16 +154,16 @@ int accept_crypto_connection(Net_Crypto *c, New_Connection *n_c);
*/
int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const uint8_t *dht_public_key);
-/* Set the direct ip of the crypto connection.
+/** Set the direct ip of the crypto connection.
*
* Connected is 0 if we are not sure we are connected to that person, 1 if we are sure.
*
* return -1 on failure.
* return 0 on success.
*/
-int set_direct_ip_port(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port, bool connected);
+int set_direct_ip_port(Net_Crypto *c, int crypt_connection_id, const IP_Port *ip_port, bool connected);
-/* Set function to be called when connection with crypt_connection_id goes connects/disconnects.
+/** Set function to be called when connection with crypt_connection_id goes connects/disconnects.
*
* The set function should return -1 on failure and 0 on success.
* Note that if this function is set, the connection will clear itself on disconnect.
@@ -176,7 +176,7 @@ int set_direct_ip_port(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port,
int connection_status_handler(const Net_Crypto *c, int crypt_connection_id,
connection_status_cb *connection_status_callback, void *object, int id);
-/* Set function to be called when connection with crypt_connection_id receives a lossless data packet of length.
+/** Set function to be called when connection with crypt_connection_id receives a lossless data packet of length.
*
* The set function should return -1 on failure and 0 on success.
* Object and id will be passed to this function untouched.
@@ -188,7 +188,7 @@ int connection_data_handler(const Net_Crypto *c, int crypt_connection_id,
connection_data_cb *connection_data_callback, void *object, int id);
-/* Set function to be called when connection with crypt_connection_id receives a lossy data packet of length.
+/** Set function to be called when connection with crypt_connection_id receives a lossy data packet of length.
*
* The set function should return -1 on failure and 0 on success.
* Object and id will be passed to this function untouched.
@@ -196,10 +196,10 @@ int connection_data_handler(const Net_Crypto *c, int crypt_connection_id,
* return -1 on failure.
* return 0 on success.
*/
-int connection_lossy_data_handler(Net_Crypto *c, int crypt_connection_id,
+int connection_lossy_data_handler(const Net_Crypto *c, int crypt_connection_id,
connection_lossy_data_cb *connection_lossy_data_callback, void *object, int id);
-/* Set the function for this friend that will be callbacked with object and number if
+/** Set the function for this friend that will be callbacked with object and number if
* the friend sends us a different dht public key than we have associated to him.
*
* If this function is called, the connection should be recreated with the new public key.
@@ -209,19 +209,20 @@ int connection_lossy_data_handler(Net_Crypto *c, int crypt_connection_id,
* return -1 on failure.
* return 0 on success.
*/
-int nc_dht_pk_callback(Net_Crypto *c, int crypt_connection_id, dht_pk_cb *function, void *object, uint32_t number);
+int nc_dht_pk_callback(const Net_Crypto *c, int crypt_connection_id, dht_pk_cb *function, void *object,
+ uint32_t number);
-/* returns the number of packet slots left in the sendbuffer.
+/** returns the number of packet slots left in the sendbuffer.
* return 0 if failure.
*/
uint32_t crypto_num_free_sendqueue_slots(const Net_Crypto *c, int crypt_connection_id);
-/* Return 1 if max speed was reached for this connection (no more data can be physically through the pipe).
+/** Return 1 if max speed was reached for this connection (no more data can be physically through the pipe).
* Return 0 if it wasn't reached.
*/
bool max_speed_reached(Net_Crypto *c, int crypt_connection_id);
-/* Sends a lossless cryptopacket.
+/** Sends a lossless cryptopacket.
*
* return -1 if data could not be put in packet queue.
* return positive packet number if data was put into the queue.
@@ -233,16 +234,23 @@ bool max_speed_reached(Net_Crypto *c, int crypt_connection_id);
int64_t write_cryptpacket(Net_Crypto *c, int crypt_connection_id, const uint8_t *data, uint16_t length,
uint8_t congestion_control);
-/* Check if packet_number was received by the other side.
+/** Check if packet_number was received by the other side.
*
* packet_number must be a valid packet number of a packet sent on this connection.
*
* return -1 on failure.
* return 0 on success.
+ *
+ * Note: The condition `buffer_end - buffer_start < packet_number - buffer_start` is
+ * a trick which handles situations `buffer_end >= buffer_start` and
+ * `buffer_end < buffer_start` (when buffer_end overflowed) both correctly.
+ *
+ * It CANNOT be simplified to `packet_number < buffer_start`, as it will fail
+ * when `buffer_end < buffer_start`.
*/
-int cryptpacket_received(Net_Crypto *c, int crypt_connection_id, uint32_t packet_number);
+int cryptpacket_received(const Net_Crypto *c, int crypt_connection_id, uint32_t packet_number);
-/* Sends a lossy cryptopacket.
+/** Sends a lossy cryptopacket.
*
* return -1 on failure.
* return 0 on success.
@@ -251,35 +259,38 @@ int cryptpacket_received(Net_Crypto *c, int crypt_connection_id, uint32_t packet
*/
int send_lossy_cryptpacket(Net_Crypto *c, int crypt_connection_id, const uint8_t *data, uint16_t length);
-/* Add a tcp relay, associating it to a crypt_connection_id.
+/** Add a tcp relay, associating it to a crypt_connection_id.
*
* return 0 if it was added.
* return -1 if it wasn't.
*/
-int add_tcp_relay_peer(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port, const uint8_t *public_key);
+int add_tcp_relay_peer(Net_Crypto *c, int crypt_connection_id, const IP_Port *ip_port, const uint8_t *public_key);
-/* Add a tcp relay to the array.
+/** Add a tcp relay to the array.
*
* return 0 if it was added.
* return -1 if it wasn't.
*/
-int add_tcp_relay(Net_Crypto *c, IP_Port ip_port, const uint8_t *public_key);
+int add_tcp_relay(Net_Crypto *c, const IP_Port *ip_port, const uint8_t *public_key);
-/* Return a random TCP connection number for use in send_tcp_onion_request.
+/** Return a random TCP connection number for use in send_tcp_onion_request.
+ *
+ * TODO(irungentoo): This number is just the index of an array that the elements can
+ * change without warning.
*
* return TCP connection number on success.
* return -1 on failure.
*/
int get_random_tcp_con_number(Net_Crypto *c);
-/* Send an onion packet via the TCP relay corresponding to TCP_conn_number.
+/** Send an onion packet via the TCP relay corresponding to tcp_connections_number.
*
* return 0 on success.
* return -1 on failure.
*/
int send_tcp_onion_request(Net_Crypto *c, unsigned int tcp_connections_number, const uint8_t *data, uint16_t length);
-/* Copy a maximum of num TCP relays we are connected to to tcp_relays.
+/** Copy a maximum of num TCP relays we are connected to to tcp_relays.
* NOTE that the family of the copied ip ports will be set to TCP_INET or TCP_INET6.
*
* return number of relays copied to tcp_relays on success.
@@ -287,14 +298,14 @@ int send_tcp_onion_request(Net_Crypto *c, unsigned int tcp_connections_number, c
*/
unsigned int copy_connected_tcp_relays(Net_Crypto *c, Node_format *tcp_relays, uint16_t num);
-/* Kill a crypto connection.
+/** Kill a crypto connection.
*
* return -1 on failure.
* return 0 on success.
*/
int crypto_kill(Net_Crypto *c, int crypt_connection_id);
-/* return true if connection is valid, false otherwise
+/** return true if connection is valid, false otherwise
*
* sets direct_connected to 1 if connection connects directly to other, 0 if it isn't.
* sets online_tcp_relays to the number of connected tcp relays this connection has.
@@ -302,31 +313,33 @@ int crypto_kill(Net_Crypto *c, int crypt_connection_id);
bool crypto_connection_status(const Net_Crypto *c, int crypt_connection_id, bool *direct_connected,
unsigned int *online_tcp_relays);
-/* Generate our public and private keys.
+/** Generate our public and private keys.
* Only call this function the first time the program starts.
*/
void new_keys(Net_Crypto *c);
-/* Save the public and private keys to the keys array.
+/** Save the public and private keys to the keys array.
* Length must be CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SECRET_KEY_SIZE.
+ *
+ * TODO(irungentoo): Save only secret key.
*/
void save_keys(const Net_Crypto *c, uint8_t *keys);
-/* Load the secret key.
+/** Load the secret key.
* Length must be CRYPTO_SECRET_KEY_SIZE.
*/
void load_secret_key(Net_Crypto *c, const uint8_t *sk);
-/* Create new instance of Net_Crypto.
+/** Create new instance of Net_Crypto.
* Sets all the global connection variables to their default values.
*/
-Net_Crypto *new_net_crypto(const Logger *log, Mono_Time *mono_time, DHT *dht, TCP_Proxy_Info *proxy_info);
+Net_Crypto *new_net_crypto(const Logger *log, Mono_Time *mono_time, DHT *dht, const TCP_Proxy_Info *proxy_info);
-/* return the optimal interval in ms for running do_net_crypto.
+/** return the optimal interval in ms for running do_net_crypto.
*/
uint32_t crypto_run_interval(const Net_Crypto *c);
-/* Main loop. */
+/** Main loop. */
void do_net_crypto(Net_Crypto *c, void *userdata);
void kill_net_crypto(Net_Crypto *c);
diff --git a/protocols/Tox/libtox/src/toxcore/network.c b/protocols/Tox/libtox/src/toxcore/network.c
index 88b4695a21..8569fc17e5 100644
--- a/protocols/Tox/libtox/src/toxcore/network.c
+++ b/protocols/Tox/libtox/src/toxcore/network.c
@@ -3,12 +3,9 @@
* Copyright © 2013 Tox project.
*/
-/*
+/**
* Functions for the core networking.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
#ifdef __APPLE__
#define _DARWIN_C_SOURCE
@@ -33,12 +30,12 @@
#define OS_WIN32
#endif
-#ifdef OS_WIN32
-#ifndef WINVER
+#if defined(OS_WIN32) && !defined(WINVER)
// Windows XP
#define WINVER 0x0501
#endif
-#endif
+
+#include "network.h"
#ifdef PLAN9
#include <u.h> // Plan 9 requires this is imported first
@@ -46,7 +43,7 @@
#include <libc.h>
#endif
-#ifdef OS_WIN32 /* Put win32 includes here */
+#ifdef OS_WIN32 // Put win32 includes here
// The mingw32/64 Windows library warns about including winsock2.h after
// windows.h even though with the above it's a valid thing to do. So, to make
// mingw32 headers happy, we include winsock2.h first.
@@ -56,15 +53,12 @@
#include <ws2tcpip.h>
#endif
-#include "network.h"
-
#ifdef __APPLE__
#include <mach/clock.h>
#include <mach/mach.h>
#endif
#if !defined(OS_WIN32)
-
#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
@@ -81,7 +75,50 @@
#include <sys/filio.h>
#endif
-#define TOX_EWOULDBLOCK EWOULDBLOCK
+#else
+#ifndef IPV6_V6ONLY
+#define IPV6_V6ONLY 27
+#endif
+#endif
+
+#include <assert.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef VANILLA_NACL
+// Used for sodium_init()
+#include <sodium.h>
+#endif
+
+#include "logger.h"
+#include "mono_time.h"
+#include "util.h"
+
+//!TOKSTYLE-
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+#include "../testing/fuzzing/fuzz_adapter.h"
+#endif
+//!TOKSTYLE+
+
+// Disable MSG_NOSIGNAL on systems not supporting it, e.g. Windows, FreeBSD
+#if !defined(MSG_NOSIGNAL)
+#define MSG_NOSIGNAL 0
+#endif
+
+#ifndef IPV6_ADD_MEMBERSHIP
+#ifdef IPV6_JOIN_GROUP
+#define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
+#endif
+#endif
+
+#if !defined(OS_WIN32)
+
+static bool should_ignore_recv_error(int err)
+{
+ return err == EWOULDBLOCK;
+}
static const char *inet_ntop4(const struct in_addr *addr, char *buf, size_t bufsize)
{
@@ -108,7 +145,12 @@ static int inet_pton6(const char *addrString, struct in6_addr *addrbuf)
#define IPV6_V6ONLY 27
#endif
-#define TOX_EWOULDBLOCK WSAEWOULDBLOCK
+static bool should_ignore_recv_error(int err)
+{
+ // We ignore WSAECONNRESET as Windows helpfully* sends that error if a
+ // previously sent UDP packet wasn't delivered.
+ return err == WSAEWOULDBLOCK || err == WSAECONNRESET;
+}
static const char *inet_ntop4(const struct in_addr *addr, char *buf, size_t bufsize)
{
@@ -117,7 +159,7 @@ static const char *inet_ntop4(const struct in_addr *addr, char *buf, size_t bufs
saddr.sin_family = AF_INET;
saddr.sin_addr = *addr;
- uint32_t len = bufsize;
+ DWORD len = bufsize;
if (WSAAddressToString((LPSOCKADDR)&saddr, sizeof(saddr), nullptr, buf, &len)) {
return nullptr;
@@ -133,7 +175,7 @@ static const char *inet_ntop6(const struct in6_addr *addr, char *buf, size_t buf
saddr.sin6_family = AF_INET6;
saddr.sin6_addr = *addr;
- uint32_t len = bufsize;
+ DWORD len = bufsize;
if (WSAAddressToString((LPSOCKADDR)&saddr, sizeof(saddr), nullptr, buf, &len)) {
return nullptr;
@@ -174,34 +216,12 @@ static int inet_pton6(const char *addrString, struct in6_addr *addrbuf)
#endif
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "logger.h"
-#include "mono_time.h"
-#include "util.h"
-
-// Disable MSG_NOSIGNAL on systems not supporting it, e.g. Windows, FreeBSD
-#if !defined(MSG_NOSIGNAL)
-#define MSG_NOSIGNAL 0
-#endif
-
-#ifndef IPV6_ADD_MEMBERSHIP
-#ifdef IPV6_JOIN_GROUP
-#define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
-#endif
-#endif
-
-#if TOX_INET6_ADDRSTRLEN < INET6_ADDRSTRLEN
-#error "TOX_INET6_ADDRSTRLEN should be greater or equal to INET6_ADDRSTRLEN (#INET6_ADDRSTRLEN)"
-#endif
-
-#if TOX_INET_ADDRSTRLEN < INET_ADDRSTRLEN
-#error "TOX_INET_ADDRSTRLEN should be greater or equal to INET_ADDRSTRLEN (#INET_ADDRSTRLEN)"
-#endif
+static_assert(TOX_INET6_ADDRSTRLEN >= INET6_ADDRSTRLEN,
+ "TOX_INET6_ADDRSTRLEN should be greater or equal to INET6_ADDRSTRLEN (#INET6_ADDRSTRLEN)");
+static_assert(TOX_INET_ADDRSTRLEN >= INET_ADDRSTRLEN,
+ "TOX_INET_ADDRSTRLEN should be greater or equal to INET_ADDRSTRLEN (#INET_ADDRSTRLEN)");
+#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
static int make_proto(int proto)
{
switch (proto) {
@@ -229,6 +249,7 @@ static int make_socktype(int type)
return type;
}
}
+#endif // FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
static int make_family(Family tox_family)
{
@@ -275,15 +296,15 @@ static void get_ip6(IP6 *result, const struct in6_addr *addr)
memcpy(result->uint8, addr->s6_addr, sizeof(result->uint8));
}
-static void fill_addr4(IP4 ip, struct in_addr *addr)
+static void fill_addr4(const IP4 *ip, struct in_addr *addr)
{
- addr->s_addr = ip.uint32;
+ addr->s_addr = ip->uint32;
}
-static void fill_addr6(IP6 ip, struct in6_addr *addr)
+static void fill_addr6(const IP6 *ip, struct in6_addr *addr)
{
- assert(sizeof(ip.uint8) == sizeof(addr->s6_addr));
- memcpy(addr->s6_addr, ip.uint8, sizeof(ip.uint8));
+ assert(sizeof(ip->uint8) == sizeof(addr->s6_addr));
+ memcpy(addr->s6_addr, ip->uint8, sizeof(ip->uint8));
}
#if !defined(INADDR_LOOPBACK)
@@ -375,25 +396,33 @@ bool sock_valid(Socket sock)
return sock.socket != net_invalid_socket.socket;
}
-/* Close the socket.
+/** Close the socket.
*/
void kill_sock(Socket sock)
{
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+ return;
+#else
#ifdef OS_WIN32
closesocket(sock.socket);
#else
close(sock.socket);
-#endif
+#endif /* OS_WIN32 */
+#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */
}
bool set_socket_nonblock(Socket sock)
{
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+ return true;
+#else
#ifdef OS_WIN32
u_long mode = 1;
return ioctlsocket(sock.socket, FIONBIO, &mode) == 0;
#else
return fcntl(sock.socket, F_SETFL, O_NONBLOCK, 1) == 0;
-#endif
+#endif /* OS_WIN32 */
+#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */
}
bool set_socket_nosigpipe(Socket sock)
@@ -408,12 +437,19 @@ bool set_socket_nosigpipe(Socket sock)
bool set_socket_reuseaddr(Socket sock)
{
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+ return false;
+#else
int set = 1;
return setsockopt(sock.socket, SOL_SOCKET, SO_REUSEADDR, (const char *)&set, sizeof(set)) == 0;
+#endif
}
bool set_socket_dualstack(Socket sock)
{
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+ return false;
+#else
int ipv6only = 0;
socklen_t optsize = sizeof(ipv6only);
int res = getsockopt(sock.socket, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&ipv6only, &optsize);
@@ -424,6 +460,7 @@ bool set_socket_dualstack(Socket sock)
ipv6only = 0;
return setsockopt(sock.socket, IPPROTO_IPV6, IPV6_V6ONLY, (const char *)&ipv6only, sizeof(ipv6only)) == 0;
+#endif
}
@@ -449,28 +486,28 @@ static uint32_t data_1(uint16_t buflen, const uint8_t *buffer)
}
static void loglogdata(const Logger *log, const char *message, const uint8_t *buffer,
- uint16_t buflen, IP_Port ip_port, int res)
+ uint16_t buflen, const IP_Port *ip_port, long res)
{
char ip_str[IP_NTOA_LEN];
if (res < 0) { /* Windows doesn't necessarily know `%zu` */
int error = net_error();
- const char *strerror = net_new_strerror(error);
- LOGGER_TRACE(log, "[%2u] %s %3u%c %s:%u (%u: %s) | %04x%04x",
+ char *strerror = net_new_strerror(error);
+ LOGGER_TRACE(log, "[%2u] %s %3u%c %s:%u (%u: %s) | %08x%08x...%02x",
buffer[0], message, min_u16(buflen, 999), 'E',
- ip_ntoa(&ip_port.ip, ip_str, sizeof(ip_str)), net_ntohs(ip_port.port), error,
- strerror, data_0(buflen, buffer), data_1(buflen, buffer));
+ ip_ntoa(&ip_port->ip, ip_str, sizeof(ip_str)), net_ntohs(ip_port->port), error,
+ strerror, data_0(buflen, buffer), data_1(buflen, buffer), buffer[buflen - 1]);
net_kill_strerror(strerror);
} else if ((res > 0) && ((size_t)res <= buflen)) {
- LOGGER_TRACE(log, "[%2u] %s %3u%c %s:%u (%u: %s) | %04x%04x",
- buffer[0], message, min_u16(res, 999), ((size_t)res < buflen ? '<' : '='),
- ip_ntoa(&ip_port.ip, ip_str, sizeof(ip_str)), net_ntohs(ip_port.port), 0, "OK",
- data_0(buflen, buffer), data_1(buflen, buffer));
+ LOGGER_TRACE(log, "[%2u] %s %3u%c %s:%u (%u: %s) | %08x%08x...%02x",
+ buffer[0], message, min_u16(res, 999), (size_t)res < buflen ? '<' : '=',
+ ip_ntoa(&ip_port->ip, ip_str, sizeof(ip_str)), net_ntohs(ip_port->port), 0, "OK",
+ data_0(buflen, buffer), data_1(buflen, buffer), buffer[buflen - 1]);
} else { /* empty or overwrite */
- LOGGER_TRACE(log, "[%2u] %s %u%c%u %s:%u (%u: %s) | %04x%04x",
- buffer[0], message, res, (!res ? '!' : '>'), buflen,
- ip_ntoa(&ip_port.ip, ip_str, sizeof(ip_str)), net_ntohs(ip_port.port), 0, "OK",
- data_0(buflen, buffer), data_1(buflen, buffer));
+ LOGGER_TRACE(log, "[%2u] %s %lu%c%u %s:%u (%u: %s) | %08x%08x...%02x",
+ buffer[0], message, res, !res ? '!' : '>', buflen,
+ ip_ntoa(&ip_port->ip, ip_str, sizeof(ip_str)), net_ntohs(ip_port->port), 0, "OK",
+ data_0(buflen, buffer), data_1(buflen, buffer), buffer[buflen - 1]);
}
}
@@ -500,23 +537,29 @@ uint16_t net_port(const Networking_Core *net)
}
/* Basic network functions:
- * Function to send packet(data) of length length to ip_port.
*/
-int sendpacket(Networking_Core *net, IP_Port ip_port, const uint8_t *data, uint16_t length)
+
+int send_packet(const Networking_Core *net, const IP_Port *ip_port, Packet packet)
{
+ IP_Port ipp_copy = *ip_port;
+
if (net_family_is_unspec(net->family)) { /* Socket not initialized */
- LOGGER_ERROR(net->log, "attempted to send message of length %u on uninitialised socket", (unsigned)length);
+ // TODO(iphydf): Make this an error. Currently, the onion client calls
+ // this via DHT getnodes.
+ LOGGER_WARNING(net->log, "attempted to send message of length %u on uninitialised socket", packet.length);
return -1;
}
/* socket TOX_AF_INET, but target IP NOT: can't send */
- if (net_family_is_ipv4(net->family) && !net_family_is_ipv4(ip_port.ip.family)) {
- LOGGER_ERROR(net->log, "attempted to send message with network family %d (probably IPv6) on IPv4 socket",
- ip_port.ip.family.value);
+ if (net_family_is_ipv4(net->family) && !net_family_is_ipv4(ipp_copy.ip.family)) {
+ // TODO(iphydf): Make this an error. Occasionally we try to send to an
+ // all-zero ip_port.
+ LOGGER_WARNING(net->log, "attempted to send message with network family %d (probably IPv6) on IPv4 socket",
+ ipp_copy.ip.family.value);
return -1;
}
- if (net_family_is_ipv4(ip_port.ip.family) && net_family_is_ipv6(net->family)) {
+ if (net_family_is_ipv4(ipp_copy.ip.family) && net_family_is_ipv6(net->family)) {
/* must convert to IPV4-in-IPV6 address */
IP6 ip6;
@@ -525,46 +568,66 @@ int sendpacket(Networking_Core *net, IP_Port ip_port, const uint8_t *data, uint1
ip6.uint32[0] = 0;
ip6.uint32[1] = 0;
ip6.uint32[2] = net_htonl(0xFFFF);
- ip6.uint32[3] = ip_port.ip.ip.v4.uint32;
+ ip6.uint32[3] = ipp_copy.ip.ip.v4.uint32;
- ip_port.ip.family = net_family_ipv6;
- ip_port.ip.ip.v6 = ip6;
+ ipp_copy.ip.family = net_family_ipv6;
+ ipp_copy.ip.ip.v6 = ip6;
}
struct sockaddr_storage addr;
size_t addrsize;
- if (net_family_is_ipv4(ip_port.ip.family)) {
+ if (net_family_is_ipv4(ipp_copy.ip.family)) {
struct sockaddr_in *const addr4 = (struct sockaddr_in *)&addr;
addrsize = sizeof(struct sockaddr_in);
addr4->sin_family = AF_INET;
- addr4->sin_port = ip_port.port;
- fill_addr4(ip_port.ip.ip.v4, &addr4->sin_addr);
- } else if (net_family_is_ipv6(ip_port.ip.family)) {
+ addr4->sin_port = ipp_copy.port;
+ fill_addr4(&ipp_copy.ip.ip.v4, &addr4->sin_addr);
+ } else if (net_family_is_ipv6(ipp_copy.ip.family)) {
struct sockaddr_in6 *const addr6 = (struct sockaddr_in6 *)&addr;
addrsize = sizeof(struct sockaddr_in6);
addr6->sin6_family = AF_INET6;
- addr6->sin6_port = ip_port.port;
- fill_addr6(ip_port.ip.ip.v6, &addr6->sin6_addr);
+ addr6->sin6_port = ipp_copy.port;
+ fill_addr6(&ipp_copy.ip.ip.v6, &addr6->sin6_addr);
addr6->sin6_flowinfo = 0;
addr6->sin6_scope_id = 0;
} else {
- LOGGER_WARNING(net->log, "unknown address type: %d", ip_port.ip.family.value);
+ // TODO(iphydf): Make this an error. Currently this fails sometimes when
+ // called from DHT.c:do_ping_and_sendnode_requests.
+ LOGGER_WARNING(net->log, "unknown address type: %d", ipp_copy.ip.family.value);
return -1;
}
- const int res = sendto(net->sock.socket, (const char *)data, length, 0, (struct sockaddr *)&addr, addrsize);
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+ const long res = fuzz_sendto(net->sock.socket, (const char *)packet.data, packet.length, 0,
+ (struct sockaddr *)&addr, addrsize);
+#else
+ const long res = sendto(net->sock.socket, (const char *)packet.data, packet.length, 0,
+ (struct sockaddr *)&addr, addrsize);
+#endif
+
+ loglogdata(net->log, "O=>", packet.data, packet.length, &ipp_copy, res);
- loglogdata(net->log, "O=>", data, length, ip_port, res);
+ assert(res <= INT_MAX);
+ return (int)res;
+}
- return res;
+/**
+ * Function to send packet(data) of length length to ip_port.
+ *
+ * @deprecated Use send_packet instead.
+ */
+int sendpacket(const Networking_Core *net, const IP_Port *ip_port, const uint8_t *data, uint16_t length)
+{
+ const Packet packet = {data, length};
+ return send_packet(net, ip_port, packet);
}
-/* Function to receive data
+/** Function to receive data
* ip and port of sender is put into ip_port.
* Packet data is put into data.
* Packet length is put into length.
@@ -579,13 +642,18 @@ static int receivepacket(const Logger *log, Socket sock, IP_Port *ip_port, uint8
socklen_t addrlen = sizeof(addr);
#endif
*length = 0;
+
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+ int fail_or_len = fuzz_recvfrom(sock.socket, (char *) data, MAX_UDP_PACKET_SIZE, 0, (struct sockaddr *)&addr, &addrlen);
+#else
int fail_or_len = recvfrom(sock.socket, (char *) data, MAX_UDP_PACKET_SIZE, 0, (struct sockaddr *)&addr, &addrlen);
+#endif
if (fail_or_len < 0) {
int error = net_error();
- if (fail_or_len < 0 && error != TOX_EWOULDBLOCK) {
- const char *strerror = net_new_strerror(error);
+ if (!should_ignore_recv_error(error)) {
+ char *strerror = net_new_strerror(error);
LOGGER_ERROR(log, "Unexpected error reading from socket: %u, %s", error, strerror);
net_kill_strerror(strerror);
}
@@ -596,7 +664,7 @@ static int receivepacket(const Logger *log, Socket sock, IP_Port *ip_port, uint8
*length = (uint32_t)fail_or_len;
if (addr.ss_family == AF_INET) {
- struct sockaddr_in *addr_in = (struct sockaddr_in *)&addr;
+ const struct sockaddr_in *addr_in = (const struct sockaddr_in *)&addr;
const Family *const family = make_tox_family(addr_in->sin_family);
assert(family != nullptr);
@@ -609,7 +677,7 @@ static int receivepacket(const Logger *log, Socket sock, IP_Port *ip_port, uint8
get_ip4(&ip_port->ip.ip.v4, &addr_in->sin_addr);
ip_port->port = addr_in->sin_port;
} else if (addr.ss_family == AF_INET6) {
- struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *)&addr;
+ const struct sockaddr_in6 *addr_in6 = (const struct sockaddr_in6 *)&addr;
const Family *const family = make_tox_family(addr_in6->sin6_family);
assert(family != nullptr);
@@ -621,7 +689,7 @@ static int receivepacket(const Logger *log, Socket sock, IP_Port *ip_port, uint8
get_ip6(&ip_port->ip.ip.v6, &addr_in6->sin6_addr);
ip_port->port = addr_in6->sin6_port;
- if (ipv6_ipv4_in_v6(ip_port->ip.ip.v6)) {
+ if (ipv6_ipv4_in_v6(&ip_port->ip.ip.v6)) {
ip_port->ip.family = net_family_ipv4;
ip_port->ip.ip.v4.uint32 = ip_port->ip.ip.v6.uint32[3];
}
@@ -629,7 +697,7 @@ static int receivepacket(const Logger *log, Socket sock, IP_Port *ip_port, uint8
return -1;
}
- loglogdata(log, "=>O", data, MAX_UDP_PACKET_SIZE, *ip_port, *length);
+ loglogdata(log, "=>O", data, MAX_UDP_PACKET_SIZE, ip_port, *length);
return 0;
}
@@ -640,7 +708,7 @@ void networking_registerhandler(Networking_Core *net, uint8_t byte, packet_handl
net->packethandlers[byte].object = object;
}
-void networking_poll(Networking_Core *net, void *userdata)
+void networking_poll(const Networking_Core *net, void *userdata)
{
if (net_family_is_unspec(net->family)) {
/* Socket not initialized */
@@ -656,20 +724,18 @@ void networking_poll(Networking_Core *net, void *userdata)
continue;
}
- if (!(net->packethandlers[data[0]].function)) {
+ packet_handler_cb *const cb = net->packethandlers[data[0]].function;
+ void *const object = net->packethandlers[data[0]].object;
+
+ if (cb == nullptr) {
LOGGER_WARNING(net->log, "[%02u] -- Packet has no handler", data[0]);
continue;
}
- net->packethandlers[data[0]].function(net->packethandlers[data[0]].object, ip_port, data, length, userdata);
+ cb(object, &ip_port, data, length, userdata);
}
}
-#ifndef VANILLA_NACL
-/* Used for sodium_init() */
-#include <sodium.h>
-#endif
-
//!TOKSTYLE-
// Global mutable state is not allowed in Tokstyle.
static uint8_t at_startup_ran = 0;
@@ -716,15 +782,15 @@ static void at_shutdown(void)
}
#endif
-/* Initialize networking.
+/** Initialize networking.
* Added for reverse compatibility with old new_networking calls.
*/
-Networking_Core *new_networking(const Logger *log, IP ip, uint16_t port)
+Networking_Core *new_networking(const Logger *log, const IP *ip, uint16_t port)
{
return new_networking_ex(log, ip, port, port + (TOX_PORTRANGE_TO - TOX_PORTRANGE_FROM), nullptr);
}
-/* Initialize networking.
+/** Initialize networking.
* Bind to ip and port.
* ip must be in network order EX: 127.0.0.1 = (7F000001).
* port is in host byte order (this means don't worry about it).
@@ -734,7 +800,8 @@ Networking_Core *new_networking(const Logger *log, IP ip, uint16_t port)
*
* If error is non NULL it is set to 0 if no issues, 1 if socket related error, 2 if other.
*/
-Networking_Core *new_networking_ex(const Logger *log, IP ip, uint16_t port_from, uint16_t port_to, unsigned int *error)
+Networking_Core *new_networking_ex(const Logger *log, const IP *ip, uint16_t port_from, uint16_t port_to,
+ unsigned int *error)
{
/* If both from and to are 0, use default port range
* If one is 0 and the other is non-0, use the non-0 value as only port
@@ -758,8 +825,8 @@ Networking_Core *new_networking_ex(const Logger *log, IP ip, uint16_t port_from,
}
/* maybe check for invalid IPs like 224+.x.y.z? if there is any IP set ever */
- if (!net_family_is_ipv4(ip.family) && !net_family_is_ipv6(ip.family)) {
- LOGGER_ERROR(log, "invalid address family: %u", ip.family.value);
+ if (!net_family_is_ipv4(ip->family) && !net_family_is_ipv6(ip->family)) {
+ LOGGER_ERROR(log, "invalid address family: %u", ip->family.value);
return nullptr;
}
@@ -774,7 +841,7 @@ Networking_Core *new_networking_ex(const Logger *log, IP ip, uint16_t port_from,
}
temp->log = log;
- temp->family = ip.family;
+ temp->family = ip->family;
temp->port = 0;
/* Initialize our socket. */
@@ -784,7 +851,7 @@ Networking_Core *new_networking_ex(const Logger *log, IP ip, uint16_t port_from,
/* Check for socket error. */
if (!sock_valid(temp->sock)) {
int neterror = net_error();
- const char *strerror = net_new_strerror(neterror);
+ char *strerror = net_new_strerror(neterror);
LOGGER_ERROR(log, "Failed to get a socket?! %d, %s", neterror, strerror);
net_kill_strerror(strerror);
free(temp);
@@ -796,15 +863,30 @@ Networking_Core *new_networking_ex(const Logger *log, IP ip, uint16_t port_from,
return nullptr;
}
+#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
/* Functions to increase the size of the send and receive UDP buffers.
*/
int n = 1024 * 1024 * 2;
- setsockopt(temp->sock.socket, SOL_SOCKET, SO_RCVBUF, (const char *)&n, sizeof(n));
- setsockopt(temp->sock.socket, SOL_SOCKET, SO_SNDBUF, (const char *)&n, sizeof(n));
+ if (setsockopt(temp->sock.socket, SOL_SOCKET, SO_RCVBUF, (const char *)&n, sizeof(n)) != 0) {
+ LOGGER_WARNING(log, "Failed to set socket option %d", SO_RCVBUF);
+ }
+
+ if (setsockopt(temp->sock.socket, SOL_SOCKET, SO_SNDBUF, (const char *)&n, sizeof(n)) != 0) {
+ LOGGER_WARNING(log, "Failed to set socket option %d", SO_SNDBUF);
+ }
+
+#endif
+
+#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
/* Enable broadcast on socket */
int broadcast = 1;
- setsockopt(temp->sock.socket, SOL_SOCKET, SO_BROADCAST, (const char *)&broadcast, sizeof(broadcast));
+
+ if (setsockopt(temp->sock.socket, SOL_SOCKET, SO_BROADCAST, (const char *)&broadcast, sizeof(broadcast)) != 0) {
+ LOGGER_WARNING(log, "Failed to set socket option %d", SO_BROADCAST);
+ }
+
+#endif
/* iOS UDP sockets are weird and apparently can SIGPIPE */
if (!set_socket_nosigpipe(temp->sock)) {
@@ -841,7 +923,7 @@ Networking_Core *new_networking_ex(const Logger *log, IP ip, uint16_t port_from,
addrsize = sizeof(struct sockaddr_in);
addr4->sin_family = AF_INET;
addr4->sin_port = 0;
- fill_addr4(ip.ip.v4, &addr4->sin_addr);
+ fill_addr4(&ip->ip.v4, &addr4->sin_addr);
portptr = &addr4->sin_port;
} else if (net_family_is_ipv6(temp->family)) {
@@ -850,7 +932,7 @@ Networking_Core *new_networking_ex(const Logger *log, IP ip, uint16_t port_from,
addrsize = sizeof(struct sockaddr_in6);
addr6->sin6_family = AF_INET6;
addr6->sin6_port = 0;
- fill_addr6(ip.ip.v6, &addr6->sin6_addr);
+ fill_addr6(&ip->ip.v6, &addr6->sin6_addr);
addr6->sin6_flowinfo = 0;
addr6->sin6_scope_id = 0;
@@ -861,7 +943,9 @@ Networking_Core *new_networking_ex(const Logger *log, IP ip, uint16_t port_from,
return nullptr;
}
- if (net_family_is_ipv6(ip.family)) {
+#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+
+ if (net_family_is_ipv6(ip->family)) {
const int is_dualstack = set_socket_dualstack(temp->sock);
LOGGER_DEBUG(log, "Dual-stack socket: %s",
is_dualstack ? "enabled" : "Failed to enable, won't be able to receive from/send to IPv4 addresses");
@@ -872,10 +956,11 @@ Networking_Core *new_networking_ex(const Logger *log, IP ip, uint16_t port_from,
mreq.ipv6mr_multiaddr.s6_addr[ 1] = 0x02;
mreq.ipv6mr_multiaddr.s6_addr[15] = 0x01;
mreq.ipv6mr_interface = 0;
+
const int res = setsockopt(temp->sock.socket, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, (const char *)&mreq, sizeof(mreq));
int neterror = net_error();
- const char *strerror = net_new_strerror(neterror);
+ char *strerror = net_new_strerror(neterror);
if (res < 0) {
LOGGER_DEBUG(log, "Failed to activate local multicast membership. (%d, %s)", neterror, strerror);
@@ -886,6 +971,8 @@ Networking_Core *new_networking_ex(const Logger *log, IP ip, uint16_t port_from,
net_kill_strerror(strerror);
}
+#endif
+
/* A hanging program or a different user might block the standard port.
* As long as it isn't a parameter coming from the commandline,
* try a few ports after it, to see if we can find a "free" one.
@@ -904,16 +991,19 @@ Networking_Core *new_networking_ex(const Logger *log, IP ip, uint16_t port_from,
*/
uint16_t port_to_try = port_from;
*portptr = net_htons(port_to_try);
- int tries;
- for (tries = port_from; tries <= port_to; ++tries) {
+ for (uint16_t tries = port_from; tries <= port_to; ++tries) {
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+ int res = 0;
+#else
int res = bind(temp->sock.socket, (struct sockaddr *)&addr, addrsize);
+#endif
if (!res) {
temp->port = *portptr;
char ip_str[IP_NTOA_LEN];
- LOGGER_DEBUG(log, "Bound successfully to %s:%u", ip_ntoa(&ip, ip_str, sizeof(ip_str)),
+ LOGGER_DEBUG(log, "Bound successfully to %s:%u", ip_ntoa(ip, ip_str, sizeof(ip_str)),
net_ntohs(temp->port));
/* errno isn't reset on success, only set on failure, the failed
@@ -941,9 +1031,9 @@ Networking_Core *new_networking_ex(const Logger *log, IP ip, uint16_t port_from,
char ip_str[IP_NTOA_LEN];
int neterror = net_error();
- const char *strerror = net_new_strerror(neterror);
+ char *strerror = net_new_strerror(neterror);
LOGGER_ERROR(log, "Failed to bind socket: %d, %s IP: %s port_from: %u port_to: %u", neterror, strerror,
- ip_ntoa(&ip, ip_str, sizeof(ip_str)), port_from, port_to);
+ ip_ntoa(ip, ip_str, sizeof(ip_str)), port_from, port_to);
net_kill_strerror(strerror);
kill_networking(temp);
@@ -972,7 +1062,7 @@ Networking_Core *new_networking_no_udp(const Logger *log)
return net;
}
-/* Function to cleanup networking stuff. */
+/** Function to cleanup networking stuff (doesn't do much right now). */
void kill_networking(Networking_Core *net)
{
if (!net) {
@@ -999,8 +1089,8 @@ bool ip_equal(const IP *a, const IP *b)
if (net_family_is_ipv4(a->family) || net_family_is_tcp_ipv4(a->family)) {
struct in_addr addr_a;
struct in_addr addr_b;
- fill_addr4(a->ip.v4, &addr_a);
- fill_addr4(b->ip.v4, &addr_b);
+ fill_addr4(&a->ip.v4, &addr_a);
+ fill_addr4(&b->ip.v4, &addr_b);
return addr_a.s_addr == addr_b.s_addr;
}
@@ -1014,15 +1104,15 @@ bool ip_equal(const IP *a, const IP *b)
/* different family: check on the IPv6 one if it is the IPv4 one embedded */
if (net_family_is_ipv4(a->family) && net_family_is_ipv6(b->family)) {
- if (ipv6_ipv4_in_v6(b->ip.v6)) {
+ if (ipv6_ipv4_in_v6(&b->ip.v6)) {
struct in_addr addr_a;
- fill_addr4(a->ip.v4, &addr_a);
+ fill_addr4(&a->ip.v4, &addr_a);
return addr_a.s_addr == b->ip.v6.uint32[3];
}
} else if (net_family_is_ipv6(a->family) && net_family_is_ipv4(b->family)) {
- if (ipv6_ipv4_in_v6(a->ip.v6)) {
+ if (ipv6_ipv4_in_v6(&a->ip.v6)) {
struct in_addr addr_b;
- fill_addr4(b->ip.v4, &addr_b);
+ fill_addr4(&b->ip.v4, &addr_b);
return a->ip.v6.uint32[3] == addr_b.s_addr;
}
}
@@ -1043,7 +1133,7 @@ bool ipport_equal(const IP_Port *a, const IP_Port *b)
return ip_equal(&a->ip, &b->ip);
}
-/* nulls out ip */
+/** nulls out ip */
void ip_reset(IP *ip)
{
if (!ip) {
@@ -1053,7 +1143,17 @@ void ip_reset(IP *ip)
memset(ip, 0, sizeof(IP));
}
-/* nulls out ip, sets family according to flag */
+/** nulls out ip_port */
+void ipport_reset(IP_Port *ipport)
+{
+ if (!ipport) {
+ return;
+ }
+
+ memset(ipport, 0, sizeof(IP_Port));
+}
+
+/** nulls out ip, sets family according to flag */
void ip_init(IP *ip, bool ipv6enabled)
{
if (!ip) {
@@ -1064,7 +1164,7 @@ void ip_init(IP *ip, bool ipv6enabled)
ip->family = ipv6enabled ? net_family_ipv6 : net_family_ipv4;
}
-/* checks if ip is valid */
+/** checks if ip is valid */
bool ip_isset(const IP *ip)
{
if (!ip) {
@@ -1074,7 +1174,7 @@ bool ip_isset(const IP *ip)
return !net_family_is_unspec(ip->family);
}
-/* checks if ip is valid */
+/** checks if ip is valid */
bool ipport_isset(const IP_Port *ipport)
{
if (!ipport) {
@@ -1088,7 +1188,7 @@ bool ipport_isset(const IP_Port *ipport)
return ip_isset(&ipport->ip);
}
-/* copies an ip structure (careful about direction!) */
+/** copies an ip structure (careful about direction!) */
void ip_copy(IP *target, const IP *source)
{
if (!source || !target) {
@@ -1098,7 +1198,7 @@ void ip_copy(IP *target, const IP *source)
*target = *source;
}
-/* copies an ip_port structure (careful about direction!) */
+/** copies an ip_port structure (careful about direction!) */
void ipport_copy(IP_Port *target, const IP_Port *source)
{
if (!source || !target) {
@@ -1108,11 +1208,10 @@ void ipport_copy(IP_Port *target, const IP_Port *source)
*target = *source;
}
-/* ip_ntoa
+/** ip_ntoa
* converts ip into a string
* ip_str must be of length at least IP_NTOA_LEN
*
- * IPv6 addresses are enclosed into square brackets, i.e. "[IPv6]"
* writes error message into the buffer on error
*
* returns ip_str
@@ -1128,22 +1227,18 @@ const char *ip_ntoa(const IP *ip, char *ip_str, size_t length)
if (net_family_is_ipv4(ip->family)) {
/* returns standard quad-dotted notation */
struct in_addr addr;
- fill_addr4(ip->ip.v4, &addr);
+ fill_addr4(&ip->ip.v4, &addr);
- ip_str[0] = 0;
+ ip_str[0] = '\0';
assert(make_family(ip->family) == AF_INET);
inet_ntop4(&addr, ip_str, length);
} else if (net_family_is_ipv6(ip->family)) {
/* returns hex-groups enclosed into square brackets */
struct in6_addr addr;
- fill_addr6(ip->ip.v6, &addr);
+ fill_addr6(&ip->ip.v6, &addr);
- ip_str[0] = '[';
assert(make_family(ip->family) == AF_INET6);
- inet_ntop6(&addr, &ip_str[1], length - 3);
- const size_t len = strlen(ip_str);
- ip_str[len] = ']';
- ip_str[len + 1] = 0;
+ inet_ntop6(&addr, ip_str, length);
} else {
snprintf(ip_str, length, "(IP invalid, family %u)", ip->family.value);
}
@@ -1152,7 +1247,7 @@ const char *ip_ntoa(const IP *ip, char *ip_str, size_t length)
}
/* brute force protection against lacking termination */
- ip_str[length - 1] = 0;
+ ip_str[length - 1] = '\0';
return ip_str;
}
@@ -1204,6 +1299,10 @@ bool addr_parse_ip(const char *address, IP *to)
int addr_resolve(const char *address, IP *to, IP *extra)
{
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+ return false;
+#else
+
if (!address || !to) {
return 0;
}
@@ -1211,13 +1310,7 @@ int addr_resolve(const char *address, IP *to, IP *extra)
Family tox_family = to->family;
int family = make_family(tox_family);
- struct addrinfo *server = nullptr;
- struct addrinfo *walker = nullptr;
- struct addrinfo hints;
- int rc;
- int result = 0;
- int done = 0;
-
+ struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
hints.ai_family = family;
hints.ai_socktype = SOCK_DGRAM; // type of socket Tox uses.
@@ -1226,7 +1319,9 @@ int addr_resolve(const char *address, IP *to, IP *extra)
return 0;
}
- rc = getaddrinfo(address, nullptr, &hints, &server);
+ struct addrinfo *server = nullptr;
+
+ const int rc = getaddrinfo(address, nullptr, &hints, &server);
// Lookup failed.
if (rc != 0) {
@@ -1238,39 +1333,44 @@ int addr_resolve(const char *address, IP *to, IP *extra)
IP ip6;
ip_init(&ip6, 1); // ipv6enabled = 1
- for (walker = server; (walker != nullptr) && !done; walker = walker->ai_next) {
+ int result = 0;
+ bool done = false;
+
+ for (struct addrinfo *walker = server; walker != nullptr && !done; walker = walker->ai_next) {
switch (walker->ai_family) {
- case AF_INET:
+ case AF_INET: {
if (walker->ai_family == family) { /* AF_INET requested, done */
- struct sockaddr_in *addr = (struct sockaddr_in *)(void *)walker->ai_addr;
+ const struct sockaddr_in *addr = (const struct sockaddr_in *)(void *)walker->ai_addr;
get_ip4(&to->ip.v4, &addr->sin_addr);
result = TOX_ADDR_RESOLVE_INET;
- done = 1;
+ done = true;
} else if (!(result & TOX_ADDR_RESOLVE_INET)) { /* AF_UNSPEC requested, store away */
- struct sockaddr_in *addr = (struct sockaddr_in *)(void *)walker->ai_addr;
+ const struct sockaddr_in *addr = (const struct sockaddr_in *)(void *)walker->ai_addr;
get_ip4(&ip4.ip.v4, &addr->sin_addr);
result |= TOX_ADDR_RESOLVE_INET;
}
break; /* switch */
+ }
- case AF_INET6:
+ case AF_INET6: {
if (walker->ai_family == family) { /* AF_INET6 requested, done */
if (walker->ai_addrlen == sizeof(struct sockaddr_in6)) {
- struct sockaddr_in6 *addr = (struct sockaddr_in6 *)(void *)walker->ai_addr;
+ const struct sockaddr_in6 *addr = (const struct sockaddr_in6 *)(void *)walker->ai_addr;
get_ip6(&to->ip.v6, &addr->sin6_addr);
result = TOX_ADDR_RESOLVE_INET6;
- done = 1;
+ done = true;
}
} else if (!(result & TOX_ADDR_RESOLVE_INET6)) { /* AF_UNSPEC requested, store away */
if (walker->ai_addrlen == sizeof(struct sockaddr_in6)) {
- struct sockaddr_in6 *addr = (struct sockaddr_in6 *)(void *)walker->ai_addr;
+ const struct sockaddr_in6 *addr = (const struct sockaddr_in6 *)(void *)walker->ai_addr;
get_ip6(&ip6.ip.v6, &addr->sin6_addr);
result |= TOX_ADDR_RESOLVE_INET6;
}
}
break; /* switch */
+ }
}
}
@@ -1290,6 +1390,7 @@ int addr_resolve(const char *address, IP *to, IP *extra)
freeaddrinfo(server);
return result;
+#endif
}
bool addr_resolve_or_parse_ip(const char *address, IP *to, IP *extra)
@@ -1303,49 +1404,78 @@ bool addr_resolve_or_parse_ip(const char *address, IP *to, IP *extra)
return true;
}
-int net_connect(Socket sock, IP_Port ip_port)
+int net_connect(const Logger *log, Socket sock, const IP_Port *ip_port)
{
struct sockaddr_storage addr = {0};
size_t addrsize;
- if (net_family_is_ipv4(ip_port.ip.family)) {
+ if (net_family_is_ipv4(ip_port->ip.family)) {
struct sockaddr_in *addr4 = (struct sockaddr_in *)&addr;
addrsize = sizeof(struct sockaddr_in);
addr4->sin_family = AF_INET;
- fill_addr4(ip_port.ip.ip.v4, &addr4->sin_addr);
- addr4->sin_port = ip_port.port;
- } else if (net_family_is_ipv6(ip_port.ip.family)) {
+ fill_addr4(&ip_port->ip.ip.v4, &addr4->sin_addr);
+ addr4->sin_port = ip_port->port;
+ } else if (net_family_is_ipv6(ip_port->ip.family)) {
struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr;
addrsize = sizeof(struct sockaddr_in6);
addr6->sin6_family = AF_INET6;
- fill_addr6(ip_port.ip.ip.v6, &addr6->sin6_addr);
- addr6->sin6_port = ip_port.port;
+ fill_addr6(&ip_port->ip.ip.v6, &addr6->sin6_addr);
+ addr6->sin6_port = ip_port->port;
} else {
return 0;
}
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+ return 0;
+#else
+ LOGGER_DEBUG(log, "connecting socket %d", (int)sock.socket);
return connect(sock.socket, (struct sockaddr *)&addr, addrsize);
+#endif
}
int32_t net_getipport(const char *node, IP_Port **res, int tox_type)
{
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+ *res = (IP_Port *)calloc(1, sizeof(IP_Port));
+ assert(*res != nullptr);
+ IP_Port *ip_port = *res;
+ ip_port->ip.ip.v4.uint32 = 0x7F000003; // 127.0.0.3
+ ip_port->ip.family = *make_tox_family(AF_INET);
+
+ return 1;
+#else
+ // Try parsing as IP address first.
+ IP_Port parsed = {0};
+
+ if (addr_parse_ip(node, &parsed.ip)) {
+ IP_Port *tmp = (IP_Port *)calloc(1, sizeof(IP_Port));
+
+ if (tmp == nullptr) {
+ return -1;
+ }
+
+ tmp[0] = parsed;
+ *res = tmp;
+ return 1;
+ }
+
+ // It's not an IP address, so now we try doing a DNS lookup.
struct addrinfo *infos;
- int ret = getaddrinfo(node, nullptr, nullptr, &infos);
+ const int ret = getaddrinfo(node, nullptr, nullptr, &infos);
*res = nullptr;
if (ret != 0) {
return -1;
}
- // Used to avoid malloc parameter overflow
+ // Used to avoid calloc parameter overflow
const size_t max_count = min_u64(SIZE_MAX, INT32_MAX) / sizeof(IP_Port);
- int type = make_socktype(tox_type);
- struct addrinfo *cur;
+ const int type = make_socktype(tox_type);
size_t count = 0;
- for (cur = infos; count < max_count && cur != nullptr; cur = cur->ai_next) {
+ for (struct addrinfo *cur = infos; count < max_count && cur != nullptr; cur = cur->ai_next) {
if (cur->ai_socktype && type > 0 && cur->ai_socktype != type) {
continue;
}
@@ -1364,7 +1494,7 @@ int32_t net_getipport(const char *node, IP_Port **res, int tox_type)
return 0;
}
- *res = (IP_Port *)malloc(sizeof(IP_Port) * count);
+ *res = (IP_Port *)calloc(count, sizeof(IP_Port));
if (*res == nullptr) {
freeaddrinfo(infos);
@@ -1373,16 +1503,16 @@ int32_t net_getipport(const char *node, IP_Port **res, int tox_type)
IP_Port *ip_port = *res;
- for (cur = infos; cur != nullptr; cur = cur->ai_next) {
+ for (struct addrinfo *cur = infos; cur != nullptr; cur = cur->ai_next) {
if (cur->ai_socktype && type > 0 && cur->ai_socktype != type) {
continue;
}
if (cur->ai_family == AF_INET) {
- struct sockaddr_in *addr = (struct sockaddr_in *)(void *)cur->ai_addr;
+ const struct sockaddr_in *addr = (const struct sockaddr_in *)(const void *)cur->ai_addr;
memcpy(&ip_port->ip.ip.v4, &addr->sin_addr, sizeof(IP4));
} else if (cur->ai_family == AF_INET6) {
- struct sockaddr_in6 *addr = (struct sockaddr_in6 *)(void *)cur->ai_addr;
+ const struct sockaddr_in6 *addr = (const struct sockaddr_in6 *)(const void *)cur->ai_addr;
memcpy(&ip_port->ip.ip.v6, &addr->sin6_addr, sizeof(IP6));
} else {
continue;
@@ -1404,6 +1534,7 @@ int32_t net_getipport(const char *node, IP_Port **res, int tox_type)
freeaddrinfo(infos);
return count;
+#endif
}
void net_freeipport(IP_Port *ip_ports)
@@ -1432,50 +1563,85 @@ bool bind_to_port(Socket sock, Family family, uint16_t port)
return false;
}
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+ return true;
+#else
return bind(sock.socket, (struct sockaddr *)&addr, addrsize) == 0;
+#endif
}
Socket net_socket(Family domain, int type, int protocol)
{
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+ const Socket sock = {1};
+ return sock;
+#else
const int platform_domain = make_family(domain);
const int platform_type = make_socktype(type);
const int platform_prot = make_proto(protocol);
const Socket sock = {(int)socket(platform_domain, platform_type, platform_prot)};
return sock;
+#endif
}
-int net_send(Socket sock, const void *buf, size_t len)
+int net_send(const Logger *log, Socket sock, const uint8_t *buf, size_t len, const IP_Port *ip_port)
{
- return send(sock.socket, (const char *)buf, len, MSG_NOSIGNAL);
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+ int res = fuzz_send(sock.socket, (const char *)buf, len, MSG_NOSIGNAL);
+#else
+ int res = send(sock.socket, (const char *)buf, len, MSG_NOSIGNAL);
+#endif
+ loglogdata(log, "T=>", buf, len, ip_port, res);
+ return res;
}
-int net_recv(Socket sock, void *buf, size_t len)
+int net_recv(const Logger *log, Socket sock, uint8_t *buf, size_t len, const IP_Port *ip_port)
{
- return recv(sock.socket, (char *)buf, len, MSG_NOSIGNAL);
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+ int res = fuzz_recv(sock.socket, (char *)buf, len, MSG_NOSIGNAL);
+#else
+ int res = recv(sock.socket, (char *)buf, len, MSG_NOSIGNAL);
+#endif
+ loglogdata(log, "=>T", buf, len, ip_port, res);
+ return res;
}
int net_listen(Socket sock, int backlog)
{
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+ return 0;
+#else
return listen(sock.socket, backlog);
+#endif
}
Socket net_accept(Socket sock)
{
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+ const Socket newsock = {2};
+ return newsock;
+#else
const Socket newsock = {accept(sock.socket, nullptr, nullptr)};
return newsock;
+#endif
}
-size_t net_socket_data_recv_buffer(Socket sock)
+uint16_t net_socket_data_recv_buffer(Socket sock)
{
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+ return 0;
+#else
+
#ifdef OS_WIN32
- unsigned long count = 0;
+ u_long count = 0;
ioctlsocket(sock.socket, FIONREAD, &count);
#else
int count = 0;
ioctl(sock.socket, FIONREAD, &count);
#endif
- return count;
+ return (uint16_t)count;
+#endif
}
uint32_t net_htonl(uint32_t hostlong)
@@ -1551,9 +1717,9 @@ size_t net_unpack_u64(const uint8_t *bytes, uint64_t *v)
return p - bytes;
}
-bool ipv6_ipv4_in_v6(IP6 a)
+bool ipv6_ipv4_in_v6(const IP6 *a)
{
- return a.uint64[0] == 0 && a.uint32[2] == net_htonl(0xffff);
+ return a->uint64[0] == 0 && a->uint32[2] == net_htonl(0xffff);
}
int net_error(void)
@@ -1565,7 +1731,7 @@ int net_error(void)
#endif
}
-const char *net_new_strerror(int error)
+char *net_new_strerror(int error)
{
#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
char *str = nullptr;
@@ -1580,13 +1746,45 @@ const char *net_new_strerror(int error)
error, 0, (char *)&str, 0, nullptr);
return str;
#else
- return strerror(error);
+ char tmp[256];
+
+ errno = 0;
+
+#ifdef _GNU_SOURCE
+ const char *retstr = strerror_r(error, tmp, sizeof(tmp));
+
+ if (errno != 0) {
+ snprintf(tmp, sizeof(tmp), "error %d (strerror_r failed with errno %d)", error, errno);
+ }
+
+#else
+ const int fmt_error = strerror_r(error, tmp, sizeof(tmp));
+
+ if (fmt_error != 0) {
+ snprintf(tmp, sizeof(tmp), "error %d (strerror_r failed with error %d, errno %d)", error, fmt_error, errno);
+ }
+
+ const char *retstr = tmp;
+#endif
+
+ const size_t retstr_len = strlen(retstr);
+ char *str = (char *)malloc(retstr_len + 1);
+
+ if (str == nullptr) {
+ return nullptr;
+ }
+
+ memcpy(str, retstr, retstr_len + 1);
+
+ return str;
#endif
}
-void net_kill_strerror(const char *strerror)
+void net_kill_strerror(char *strerror)
{
#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
LocalFree((char *)strerror);
+#else
+ free(strerror);
#endif
}
diff --git a/protocols/Tox/libtox/src/toxcore/network.h b/protocols/Tox/libtox/src/toxcore/network.h
index b7e8ede2b9..47a93bf0fa 100644
--- a/protocols/Tox/libtox/src/toxcore/network.h
+++ b/protocols/Tox/libtox/src/toxcore/network.h
@@ -3,18 +3,18 @@
* Copyright © 2013 Tox project.
*/
-/*
+/**
* Datatypes, functions and includes for the core networking.
*/
#ifndef C_TOXCORE_TOXCORE_NETWORK_H
#define C_TOXCORE_TOXCORE_NETWORK_H
-#include "logger.h"
-
#include <stdbool.h> // bool
#include <stddef.h> // size_t
#include <stdint.h> // uint*_t
+#include "logger.h"
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -43,44 +43,6 @@ extern const Family net_family_tcp_ipv6;
extern const Family net_family_tox_tcp_ipv4;
extern const Family net_family_tox_tcp_ipv6;
-typedef struct Socket {
- int socket;
-} Socket;
-
-Socket net_socket(Family domain, int type, int protocol);
-
-/**
- * Check if socket is valid.
- *
- * @return true if valid, false otherwise.
- */
-bool sock_valid(Socket sock);
-
-extern const Socket net_invalid_socket;
-
-/**
- * Calls send(sockfd, buf, len, MSG_NOSIGNAL).
- */
-int net_send(Socket sock, const void *buf, size_t len);
-/**
- * Calls recv(sockfd, buf, len, MSG_NOSIGNAL).
- */
-int net_recv(Socket sock, void *buf, size_t len);
-/**
- * Calls listen(sockfd, backlog).
- */
-int net_listen(Socket sock, int backlog);
-/**
- * Calls accept(sockfd, nullptr, nullptr).
- */
-Socket net_accept(Socket sock);
-
-/**
- * return the amount of data in the tcp recv buffer.
- * return 0 on failure.
- */
-size_t net_socket_data_recv_buffer(Socket sock);
-
#define MAX_UDP_PACKET_SIZE 2048
typedef enum Net_Packet_Type {
@@ -119,7 +81,7 @@ typedef enum Net_Packet_Type {
#define TOX_PORTRANGE_TO 33545
#define TOX_PORT_DEFAULT TOX_PORTRANGE_FROM
-/* Redefinitions of variables for safe transfer over wire. */
+/** Redefinitions of variables for safe transfer over wire. */
#define TOX_AF_UNSPEC 0
#define TOX_AF_INET 2
#define TOX_AF_INET6 10
@@ -132,18 +94,26 @@ typedef enum Net_Packet_Type {
#define TOX_PROTO_TCP 1
#define TOX_PROTO_UDP 2
-/* TCP related */
+/** TCP related */
#define TCP_ONION_FAMILY (TOX_AF_INET6 + 1)
#define TCP_INET (TOX_AF_INET6 + 2)
#define TCP_INET6 (TOX_AF_INET6 + 3)
#define TCP_FAMILY (TOX_AF_INET6 + 4)
+#define SIZE_IP4 4
+#define SIZE_IP6 16
+#define SIZE_IP (1 + SIZE_IP6)
+#define SIZE_PORT 2
+#define SIZE_IPPORT (SIZE_IP + SIZE_PORT)
+
typedef union IP4 {
uint32_t uint32;
uint16_t uint16[2];
uint8_t uint8[4];
} IP4;
+static_assert(sizeof(IP4) == SIZE_IP4, "IP4 size must be 4");
+
IP4 get_ip4_loopback(void);
extern const IP4 ip4_broadcast;
@@ -154,6 +124,10 @@ typedef union IP6 {
uint64_t uint64[2];
} IP6;
+// TODO(iphydf): Stop relying on this. We memcpy this struct (and IP4 above)
+// into packets but really should be serialising it properly.
+static_assert(sizeof(IP6) == SIZE_IP6, "IP6 size must be 16");
+
IP6 get_ip6_loopback(void);
extern const IP6 ip6_broadcast;
@@ -162,19 +136,55 @@ typedef union IP_Union {
IP6 v6;
} IP_Union;
-#define IP_DEFINED
typedef struct IP {
Family family;
IP_Union ip;
} IP;
-#define IP_PORT_DEFINED
typedef struct IP_Port {
IP ip;
uint16_t port;
} IP_Port;
-/* Convert values between host and network byte order.
+typedef struct Socket {
+ int socket;
+} Socket;
+
+Socket net_socket(Family domain, int type, int protocol);
+
+/**
+ * Check if socket is valid.
+ *
+ * @return true if valid, false otherwise.
+ */
+bool sock_valid(Socket sock);
+
+extern const Socket net_invalid_socket;
+
+/**
+ * Calls send(sockfd, buf, len, MSG_NOSIGNAL).
+ */
+int net_send(const Logger *log, Socket sock, const uint8_t *buf, size_t len, const IP_Port *ip_port);
+/**
+ * Calls recv(sockfd, buf, len, MSG_NOSIGNAL).
+ */
+int net_recv(const Logger *log, Socket sock, uint8_t *buf, size_t len, const IP_Port *ip_port);
+/**
+ * Calls listen(sockfd, backlog).
+ */
+int net_listen(Socket sock, int backlog);
+/**
+ * Calls accept(sockfd, nullptr, nullptr).
+ */
+Socket net_accept(Socket sock);
+
+/**
+ * return the size of data in the tcp recv buffer.
+ * return 0 on failure.
+ */
+uint16_t net_socket_data_recv_buffer(Socket sock);
+
+/** Convert values between host and network byte order.
*/
uint32_t net_htonl(uint32_t hostlong);
uint16_t net_htons(uint16_t hostshort);
@@ -189,35 +199,28 @@ size_t net_unpack_u16(const uint8_t *bytes, uint16_t *v);
size_t net_unpack_u32(const uint8_t *bytes, uint32_t *v);
size_t net_unpack_u64(const uint8_t *bytes, uint64_t *v);
-/* Does the IP6 struct a contain an IPv4 address in an IPv6 one? */
-bool ipv6_ipv4_in_v6(IP6 a);
-
-#define SIZE_IP4 4
-#define SIZE_IP6 16
-#define SIZE_IP (1 + SIZE_IP6)
-#define SIZE_PORT 2
-#define SIZE_IPPORT (SIZE_IP + SIZE_PORT)
+/** Does the IP6 struct a contain an IPv4 address in an IPv6 one? */
+bool ipv6_ipv4_in_v6(const IP6 *a);
#define TOX_ENABLE_IPV6_DEFAULT true
-/* addr_resolve return values */
+/** addr_resolve return values */
#define TOX_ADDR_RESOLVE_INET 1
#define TOX_ADDR_RESOLVE_INET6 2
#define TOX_INET6_ADDRSTRLEN 66
#define TOX_INET_ADDRSTRLEN 22
-/* ip_ntoa
+/** this would be TOX_INET6_ADDRSTRLEN, but it might be too short for the error message */
+#define IP_NTOA_LEN 96 // TODO(irungentoo): magic number. Why not INET6_ADDRSTRLEN ?
+/** ip_ntoa
* converts ip into a string
* ip_str must be of length at least IP_NTOA_LEN
*
- * IPv6 addresses are enclosed into square brackets, i.e. "[IPv6]"
* writes error message into the buffer on error
*
* returns ip_str
*/
-/* this would be TOX_INET6_ADDRSTRLEN, but it might be too short for the error message */
-#define IP_NTOA_LEN 96 // TODO(irungentoo): magic number. Why not INET6_ADDRSTRLEN ?
const char *ip_ntoa(const IP *ip, char *ip_str, size_t length);
/**
@@ -264,17 +267,19 @@ bool ip_equal(const IP *a, const IP *b);
*/
bool ipport_equal(const IP_Port *a, const IP_Port *b);
-/* nulls out ip */
+/** nulls out ip */
void ip_reset(IP *ip);
-/* nulls out ip, sets family according to flag */
+/** nulls out ip_port */
+void ipport_reset(IP_Port *ipport);
+/** nulls out ip, sets family according to flag */
void ip_init(IP *ip, bool ipv6enabled);
-/* checks if ip is valid */
+/** checks if ip is valid */
bool ip_isset(const IP *ip);
-/* checks if ip is valid */
+/** checks if ip is valid */
bool ipport_isset(const IP_Port *ipport);
-/* copies an ip structure */
+/** copies an ip structure (careful about direction!) */
void ip_copy(IP *target, const IP *source);
-/* copies an ip_port structure */
+/** copies an ip_port structure (careful about direction!) */
void ipport_copy(IP_Port *target, const IP_Port *source);
/**
@@ -312,25 +317,25 @@ int addr_resolve(const char *address, IP *to, IP *extra);
*/
bool addr_resolve_or_parse_ip(const char *address, IP *to, IP *extra);
-/* Function to receive data, ip and port of sender is put into ip_port.
+/** Function to receive data, ip and port of sender is put into ip_port.
* Packet data is put into data.
* Packet length is put into length.
*/
-typedef int packet_handler_cb(void *object, IP_Port ip_port, const uint8_t *data, uint16_t len, void *userdata);
+typedef int packet_handler_cb(void *object, const IP_Port *ip_port, const uint8_t *data, uint16_t len, void *userdata);
typedef struct Networking_Core Networking_Core;
Family net_family(const Networking_Core *net);
uint16_t net_port(const Networking_Core *net);
-/* Run this before creating sockets.
+/** Run this before creating sockets.
*
* return 0 on success
* return -1 on failure
*/
int networking_at_startup(void);
-/* Close the socket.
+/** Close the socket.
*/
void kill_sock(Socket sock);
@@ -364,19 +369,42 @@ bool set_socket_dualstack(Socket sock);
/* Basic network functions: */
-/* Function to send packet(data) of length length to ip_port. */
-int sendpacket(Networking_Core *net, IP_Port ip_port, const uint8_t *data, uint16_t length);
+/**
+ * An outgoing network packet.
+ *
+ * Use `send_packet` to send it to an IP/port endpoint.
+ */
+typedef struct Packet {
+ const uint8_t *data;
+ uint16_t length;
+} Packet;
+
+/**
+ * Function to send a network packet to a given IP/port.
+ */
+int send_packet(const Networking_Core *net, const IP_Port *ip_port, Packet packet);
+
+/**
+ * Function to send packet(data) of length length to ip_port.
+ *
+ * @deprecated Use send_packet instead.
+ */
+int sendpacket(const Networking_Core *net, const IP_Port *ip_port, const uint8_t *data, uint16_t length);
-/* Function to call when packet beginning with byte is received. */
+/** Function to call when packet beginning with byte is received. */
void networking_registerhandler(Networking_Core *net, uint8_t byte, packet_handler_cb *cb, void *object);
-/* Call this several times a second. */
-void networking_poll(Networking_Core *net, void *userdata);
+/** Call this several times a second. */
+void networking_poll(const Networking_Core *net, void *userdata);
-/* Connect a socket to the address specified by the ip_port. */
-int net_connect(Socket sock, IP_Port ip_port);
+/** Connect a socket to the address specified by the ip_port.
+ *
+ * Return 0 on success.
+ * Return -1 on failure.
+ */
+int net_connect(const Logger *log, Socket sock, const IP_Port *ip_port);
-/* High-level getaddrinfo implementation.
+/** High-level getaddrinfo implementation.
* Given node, which identifies an Internet host, net_getipport() fills an array
* with one or more IP_Port structures, each of which contains an Internet
* address that can be specified by calling net_connect(), the port is ignored.
@@ -389,7 +417,7 @@ int net_connect(Socket sock, IP_Port ip_port);
*/
int32_t net_getipport(const char *node, IP_Port **res, int tox_type);
-/* Deallocates memory allocated by net_getipport
+/** Deallocates memory allocated by net_getipport
*/
void net_freeipport(IP_Port *ip_ports);
@@ -398,7 +426,7 @@ void net_freeipport(IP_Port *ip_ports);
*/
bool bind_to_port(Socket sock, Family family, uint16_t port);
-/* Get the last networking error code.
+/** Get the last networking error code.
*
* Similar to Unix's errno, but cross-platform, as not all platforms use errno
* to indicate networking errors.
@@ -412,35 +440,39 @@ bool bind_to_port(Socket sock, Family family, uint16_t port);
*/
int net_error(void);
-/* Get a text explanation for the error code from net_error().
+/** Get a text explanation for the error code from net_error().
*
* return NULL on failure.
* return pointer to a NULL-terminated string describing the error code on
* success. The returned string must be freed using net_kill_strerror().
*/
-const char *net_new_strerror(int error);
+char *net_new_strerror(int error);
-/* Frees the string returned by net_new_strerror().
+/** Frees the string returned by net_new_strerror().
* It's valid to pass NULL as the argument, the function does nothing in this
* case.
*/
-void net_kill_strerror(const char *strerror);
+void net_kill_strerror(char *strerror);
-/* Initialize networking.
- * bind to ip and port.
+/** Initialize networking.
+ * Added for reverse compatibility with old new_networking calls.
+ */
+Networking_Core *new_networking(const Logger *log, const IP *ip, uint16_t port);
+/** Initialize networking.
+ * Bind to ip and port.
* ip must be in network order EX: 127.0.0.1 = (7F000001).
* port is in host byte order (this means don't worry about it).
*
- * return Networking_Core object if no problems
- * return NULL if there are problems.
+ * return Networking_Core object if no problems
+ * return NULL if there are problems.
*
* If error is non NULL it is set to 0 if no issues, 1 if socket related error, 2 if other.
*/
-Networking_Core *new_networking(const Logger *log, IP ip, uint16_t port);
-Networking_Core *new_networking_ex(const Logger *log, IP ip, uint16_t port_from, uint16_t port_to, unsigned int *error);
+Networking_Core *new_networking_ex(const Logger *log, const IP *ip, uint16_t port_from, uint16_t port_to,
+ unsigned int *error);
Networking_Core *new_networking_no_udp(const Logger *log);
-/* Function to cleanup networking stuff (doesn't do much right now). */
+/** Function to cleanup networking stuff (doesn't do much right now). */
void kill_networking(Networking_Core *net);
#ifdef __cplusplus
diff --git a/protocols/Tox/libtox/src/toxcore/onion.c b/protocols/Tox/libtox/src/toxcore/onion.c
index 32a3e88d6e..663c7b1b5c 100644
--- a/protocols/Tox/libtox/src/toxcore/onion.c
+++ b/protocols/Tox/libtox/src/toxcore/onion.c
@@ -3,13 +3,9 @@
* Copyright © 2013 Tox project.
*/
-/*
+/**
* Implementation of the onion part of docs/Prevent_Tracking.txt
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include "onion.h"
#include <stdlib.h>
@@ -27,8 +23,8 @@
#define SEND_2 ONION_SEND_2
#define SEND_1 ONION_SEND_1
-/* Change symmetric keys every 2 hours to make paths expire eventually. */
#define KEY_REFRESH_INTERVAL (2 * 60 * 60)
+/** Change symmetric keys every 2 hours to make paths expire eventually. */
static void change_symmetric_key(Onion *onion)
{
if (mono_time_is_timeout(onion->mono_time, onion->timestamp, KEY_REFRESH_INTERVAL)) {
@@ -37,20 +33,20 @@ static void change_symmetric_key(Onion *onion)
}
}
-/* packing and unpacking functions */
-static void ip_pack(uint8_t *data, IP source)
+/** packing and unpacking functions */
+static void ip_pack(uint8_t *data, const IP *source)
{
- data[0] = source.family.value;
+ data[0] = source->family.value;
- if (net_family_is_ipv4(source.family) || net_family_is_tox_tcp_ipv4(source.family)) {
+ if (net_family_is_ipv4(source->family) || net_family_is_tox_tcp_ipv4(source->family)) {
memset(data + 1, 0, SIZE_IP6);
- memcpy(data + 1, source.ip.v4.uint8, SIZE_IP4);
+ memcpy(data + 1, source->ip.v4.uint8, SIZE_IP4);
} else {
- memcpy(data + 1, source.ip.v6.uint8, SIZE_IP6);
+ memcpy(data + 1, source->ip.v6.uint8, SIZE_IP6);
}
}
-/* return 0 on success, -1 on failure. */
+/** return 0 on success, -1 on failure. */
static int ip_unpack(IP *target, const uint8_t *data, unsigned int data_size, bool disable_family_check)
{
if (data_size < (1 + SIZE_IP6)) {
@@ -75,11 +71,11 @@ static int ip_unpack(IP *target, const uint8_t *data, unsigned int data_size, bo
static void ipport_pack(uint8_t *data, const IP_Port *source)
{
- ip_pack(data, source->ip);
+ ip_pack(data, &source->ip);
memcpy(data + SIZE_IP, &source->port, SIZE_PORT);
}
-/* return 0 on success, -1 on failure. */
+/** return 0 on success, -1 on failure. */
static int ipport_unpack(IP_Port *target, const uint8_t *data, unsigned int data_size, bool disable_family_check)
{
if (data_size < (SIZE_IP + SIZE_PORT)) {
@@ -95,7 +91,7 @@ static int ipport_unpack(IP_Port *target, const uint8_t *data, unsigned int data
}
-/* Create a new onion path.
+/** Create a new onion path.
*
* Create a new onion path out of nodes (nodes is a list of ONION_PATH_LENGTH nodes)
*
@@ -124,6 +120,8 @@ int create_onion_path(const DHT *dht, Onion_Path *new_path, const Node_format *n
encrypt_precompute(nodes[2].public_key, random_secret_key, new_path->shared_key3);
memcpy(new_path->public_key3, random_public_key, CRYPTO_PUBLIC_KEY_SIZE);
+ crypto_memzero(random_secret_key, sizeof(random_secret_key));
+
new_path->ip_port1 = nodes[0].ip_port;
new_path->ip_port2 = nodes[1].ip_port;
new_path->ip_port3 = nodes[2].ip_port;
@@ -135,7 +133,7 @@ int create_onion_path(const DHT *dht, Onion_Path *new_path, const Node_format *n
return 0;
}
-/* Dump nodes in onion path to nodes of length num_nodes.
+/** Dump nodes in onion path to nodes of length num_nodes.
*
* return -1 on failure.
* return 0 on success.
@@ -156,7 +154,7 @@ int onion_path_to_nodes(Node_format *nodes, unsigned int num_nodes, const Onion_
return 0;
}
-/* Create a onion packet.
+/** Create a onion packet.
*
* Use Onion_Path path to create packet for data of length to dest.
* Maximum length of data is ONION_MAX_DATA_SIZE.
@@ -165,7 +163,7 @@ int onion_path_to_nodes(Node_format *nodes, unsigned int num_nodes, const Onion_
* return -1 on failure.
* return length of created packet on success.
*/
-int create_onion_packet(uint8_t *packet, uint16_t max_packet_length, const Onion_Path *path, IP_Port dest,
+int create_onion_packet(uint8_t *packet, uint16_t max_packet_length, const Onion_Path *path, const IP_Port *dest,
const uint8_t *data, uint16_t length)
{
if (1 + length + SEND_1 > max_packet_length || length == 0) {
@@ -174,7 +172,7 @@ int create_onion_packet(uint8_t *packet, uint16_t max_packet_length, const Onion
VLA(uint8_t, step1, SIZE_IPPORT + length);
- ipport_pack(step1, &dest);
+ ipport_pack(step1, dest);
memcpy(step1 + SIZE_IPPORT, data, length);
uint8_t nonce[CRYPTO_NONCE_SIZE];
@@ -215,7 +213,7 @@ int create_onion_packet(uint8_t *packet, uint16_t max_packet_length, const Onion
return 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + len;
}
-/* Create a onion packet to be sent over tcp.
+/** Create a onion packet to be sent over tcp.
*
* Use Onion_Path path to create packet for data of length to dest.
* Maximum length of data is ONION_MAX_DATA_SIZE.
@@ -224,7 +222,7 @@ int create_onion_packet(uint8_t *packet, uint16_t max_packet_length, const Onion
* return -1 on failure.
* return length of created packet on success.
*/
-int create_onion_packet_tcp(uint8_t *packet, uint16_t max_packet_length, const Onion_Path *path, IP_Port dest,
+int create_onion_packet_tcp(uint8_t *packet, uint16_t max_packet_length, const Onion_Path *path, const IP_Port *dest,
const uint8_t *data, uint16_t length)
{
if (CRYPTO_NONCE_SIZE + SIZE_IPPORT + SEND_BASE * 2 + length > max_packet_length || length == 0) {
@@ -233,7 +231,7 @@ int create_onion_packet_tcp(uint8_t *packet, uint16_t max_packet_length, const O
VLA(uint8_t, step1, SIZE_IPPORT + length);
- ipport_pack(step1, &dest);
+ ipport_pack(step1, dest);
memcpy(step1 + SIZE_IPPORT, data, length);
uint8_t nonce[CRYPTO_NONCE_SIZE];
@@ -264,7 +262,7 @@ int create_onion_packet_tcp(uint8_t *packet, uint16_t max_packet_length, const O
return CRYPTO_NONCE_SIZE + SIZE_IPPORT + CRYPTO_PUBLIC_KEY_SIZE + len;
}
-/* Create and send a onion packet.
+/** Create and send a onion packet.
*
* Use Onion_Path path to send data of length to dest.
* Maximum length of data is ONION_MAX_DATA_SIZE.
@@ -272,7 +270,8 @@ int create_onion_packet_tcp(uint8_t *packet, uint16_t max_packet_length, const O
* return -1 on failure.
* return 0 on success.
*/
-int send_onion_packet(Networking_Core *net, const Onion_Path *path, IP_Port dest, const uint8_t *data, uint16_t length)
+int send_onion_packet(const Networking_Core *net, const Onion_Path *path, const IP_Port *dest, const uint8_t *data,
+ uint16_t length)
{
uint8_t packet[ONION_MAX_PACKET_SIZE];
int len = create_onion_packet(packet, sizeof(packet), path, dest, data, length);
@@ -281,20 +280,21 @@ int send_onion_packet(Networking_Core *net, const Onion_Path *path, IP_Port dest
return -1;
}
- if (sendpacket(net, path->ip_port1, packet, len) != len) {
+ if (sendpacket(net, &path->ip_port1, packet, len) != len) {
return -1;
}
return 0;
}
-/* Create and send a onion response sent initially to dest with.
+/** Create and send a onion response sent initially to dest with.
* Maximum length of data is ONION_RESPONSE_MAX_DATA_SIZE.
*
* return -1 on failure.
* return 0 on success.
*/
-int send_onion_response(Networking_Core *net, IP_Port dest, const uint8_t *data, uint16_t length, const uint8_t *ret)
+int send_onion_response(const Networking_Core *net, const IP_Port *dest, const uint8_t *data, uint16_t length,
+ const uint8_t *ret)
{
if (length > ONION_RESPONSE_MAX_DATA_SIZE || length == 0) {
return -1;
@@ -312,7 +312,8 @@ int send_onion_response(Networking_Core *net, IP_Port dest, const uint8_t *data,
return 0;
}
-static int handle_send_initial(void *object, IP_Port source, const uint8_t *packet, uint16_t length, void *userdata)
+static int handle_send_initial(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length,
+ void *userdata)
{
Onion *onion = (Onion *)object;
@@ -340,7 +341,7 @@ static int handle_send_initial(void *object, IP_Port source, const uint8_t *pack
return onion_send_1(onion, plain, len, source, packet + 1);
}
-int onion_send_1(const Onion *onion, const uint8_t *plain, uint16_t len, IP_Port source, const uint8_t *nonce)
+int onion_send_1(const Onion *onion, const uint8_t *plain, uint16_t len, const IP_Port *source, const uint8_t *nonce)
{
if (len > ONION_MAX_PACKET_SIZE + SIZE_IPPORT - (1 + CRYPTO_NONCE_SIZE + ONION_RETURN_1)) {
return 1;
@@ -357,9 +358,9 @@ int onion_send_1(const Onion *onion, const uint8_t *plain, uint16_t len, IP_Port
}
uint8_t ip_port[SIZE_IPPORT];
- ipport_pack(ip_port, &source);
+ ipport_pack(ip_port, source);
- uint8_t data[ONION_MAX_PACKET_SIZE];
+ uint8_t data[ONION_MAX_PACKET_SIZE] = {0};
data[0] = NET_PACKET_ONION_SEND_1;
memcpy(data + 1, nonce, CRYPTO_NONCE_SIZE);
memcpy(data + 1 + CRYPTO_NONCE_SIZE, plain + SIZE_IPPORT, len - SIZE_IPPORT);
@@ -375,14 +376,14 @@ int onion_send_1(const Onion *onion, const uint8_t *plain, uint16_t len, IP_Port
data_len += CRYPTO_NONCE_SIZE + len;
- if ((uint32_t)sendpacket(onion->net, send_to, data, data_len) != data_len) {
+ if ((uint32_t)sendpacket(onion->net, &send_to, data, data_len) != data_len) {
return 1;
}
return 0;
}
-static int handle_send_1(void *object, IP_Port source, const uint8_t *packet, uint16_t length, void *userdata)
+static int handle_send_1(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length, void *userdata)
{
Onion *onion = (Onion *)object;
@@ -413,7 +414,7 @@ static int handle_send_1(void *object, IP_Port source, const uint8_t *packet, ui
return 1;
}
- uint8_t data[ONION_MAX_PACKET_SIZE];
+ uint8_t data[ONION_MAX_PACKET_SIZE] = {0};
data[0] = NET_PACKET_ONION_SEND_2;
memcpy(data + 1, packet + 1, CRYPTO_NONCE_SIZE);
memcpy(data + 1 + CRYPTO_NONCE_SIZE, plain + SIZE_IPPORT, len - SIZE_IPPORT);
@@ -421,7 +422,7 @@ static int handle_send_1(void *object, IP_Port source, const uint8_t *packet, ui
uint8_t *ret_part = data + data_len;
random_nonce(ret_part);
uint8_t ret_data[RETURN_1 + SIZE_IPPORT];
- ipport_pack(ret_data, &source);
+ ipport_pack(ret_data, source);
memcpy(ret_data + SIZE_IPPORT, packet + (length - RETURN_1), RETURN_1);
len = encrypt_data_symmetric(onion->secret_symmetric_key, ret_part, ret_data, sizeof(ret_data),
ret_part + CRYPTO_NONCE_SIZE);
@@ -432,14 +433,14 @@ static int handle_send_1(void *object, IP_Port source, const uint8_t *packet, ui
data_len += CRYPTO_NONCE_SIZE + len;
- if ((uint32_t)sendpacket(onion->net, send_to, data, data_len) != data_len) {
+ if ((uint32_t)sendpacket(onion->net, &send_to, data, data_len) != data_len) {
return 1;
}
return 0;
}
-static int handle_send_2(void *object, IP_Port source, const uint8_t *packet, uint16_t length, void *userdata)
+static int handle_send_2(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length, void *userdata)
{
Onion *onion = (Onion *)object;
@@ -468,8 +469,9 @@ static int handle_send_2(void *object, IP_Port source, const uint8_t *packet, ui
return 1;
}
- if (plain[SIZE_IPPORT] != NET_PACKET_ANNOUNCE_REQUEST &&
- plain[SIZE_IPPORT] != NET_PACKET_ONION_DATA_REQUEST) {
+ const uint8_t packet_id = plain[SIZE_IPPORT];
+
+ if (packet_id != NET_PACKET_ANNOUNCE_REQUEST && packet_id != NET_PACKET_ONION_DATA_REQUEST) {
return 1;
}
@@ -479,13 +481,13 @@ static int handle_send_2(void *object, IP_Port source, const uint8_t *packet, ui
return 1;
}
- uint8_t data[ONION_MAX_PACKET_SIZE];
+ uint8_t data[ONION_MAX_PACKET_SIZE] = {0};
memcpy(data, plain + SIZE_IPPORT, len - SIZE_IPPORT);
- uint16_t data_len = (len - SIZE_IPPORT);
+ uint16_t data_len = len - SIZE_IPPORT;
uint8_t *ret_part = data + (len - SIZE_IPPORT);
random_nonce(ret_part);
uint8_t ret_data[RETURN_2 + SIZE_IPPORT];
- ipport_pack(ret_data, &source);
+ ipport_pack(ret_data, source);
memcpy(ret_data + SIZE_IPPORT, packet + (length - RETURN_2), RETURN_2);
len = encrypt_data_symmetric(onion->secret_symmetric_key, ret_part, ret_data, sizeof(ret_data),
ret_part + CRYPTO_NONCE_SIZE);
@@ -496,7 +498,7 @@ static int handle_send_2(void *object, IP_Port source, const uint8_t *packet, ui
data_len += RETURN_3;
- if ((uint32_t)sendpacket(onion->net, send_to, data, data_len) != data_len) {
+ if ((uint32_t)sendpacket(onion->net, &send_to, data, data_len) != data_len) {
return 1;
}
@@ -504,7 +506,7 @@ static int handle_send_2(void *object, IP_Port source, const uint8_t *packet, ui
}
-static int handle_recv_3(void *object, IP_Port source, const uint8_t *packet, uint16_t length, void *userdata)
+static int handle_recv_3(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length, void *userdata)
{
Onion *onion = (Onion *)object;
@@ -516,8 +518,9 @@ static int handle_recv_3(void *object, IP_Port source, const uint8_t *packet, ui
return 1;
}
- if (packet[1 + RETURN_3] != NET_PACKET_ANNOUNCE_RESPONSE &&
- packet[1 + RETURN_3] != NET_PACKET_ONION_DATA_RESPONSE) {
+ const uint8_t packet_id = packet[1 + RETURN_3];
+
+ if (packet_id != NET_PACKET_ANNOUNCE_RESPONSE && packet_id != NET_PACKET_ONION_DATA_RESPONSE) {
return 1;
}
@@ -537,20 +540,20 @@ static int handle_recv_3(void *object, IP_Port source, const uint8_t *packet, ui
return 1;
}
- uint8_t data[ONION_MAX_PACKET_SIZE];
+ uint8_t data[ONION_MAX_PACKET_SIZE] = {0};
data[0] = NET_PACKET_ONION_RECV_2;
memcpy(data + 1, plain + SIZE_IPPORT, RETURN_2);
memcpy(data + 1 + RETURN_2, packet + 1 + RETURN_3, length - (1 + RETURN_3));
uint16_t data_len = 1 + RETURN_2 + (length - (1 + RETURN_3));
- if ((uint32_t)sendpacket(onion->net, send_to, data, data_len) != data_len) {
+ if ((uint32_t)sendpacket(onion->net, &send_to, data, data_len) != data_len) {
return 1;
}
return 0;
}
-static int handle_recv_2(void *object, IP_Port source, const uint8_t *packet, uint16_t length, void *userdata)
+static int handle_recv_2(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length, void *userdata)
{
Onion *onion = (Onion *)object;
@@ -562,8 +565,9 @@ static int handle_recv_2(void *object, IP_Port source, const uint8_t *packet, ui
return 1;
}
- if (packet[1 + RETURN_2] != NET_PACKET_ANNOUNCE_RESPONSE &&
- packet[1 + RETURN_2] != NET_PACKET_ONION_DATA_RESPONSE) {
+ const uint8_t packet_id = packet[1 + RETURN_2];
+
+ if (packet_id != NET_PACKET_ANNOUNCE_RESPONSE && packet_id != NET_PACKET_ONION_DATA_RESPONSE) {
return 1;
}
@@ -583,20 +587,20 @@ static int handle_recv_2(void *object, IP_Port source, const uint8_t *packet, ui
return 1;
}
- uint8_t data[ONION_MAX_PACKET_SIZE];
+ uint8_t data[ONION_MAX_PACKET_SIZE] = {0};
data[0] = NET_PACKET_ONION_RECV_1;
memcpy(data + 1, plain + SIZE_IPPORT, RETURN_1);
memcpy(data + 1 + RETURN_1, packet + 1 + RETURN_2, length - (1 + RETURN_2));
uint16_t data_len = 1 + RETURN_1 + (length - (1 + RETURN_2));
- if ((uint32_t)sendpacket(onion->net, send_to, data, data_len) != data_len) {
+ if ((uint32_t)sendpacket(onion->net, &send_to, data, data_len) != data_len) {
return 1;
}
return 0;
}
-static int handle_recv_1(void *object, IP_Port source, const uint8_t *packet, uint16_t length, void *userdata)
+static int handle_recv_1(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length, void *userdata)
{
Onion *onion = (Onion *)object;
@@ -608,8 +612,9 @@ static int handle_recv_1(void *object, IP_Port source, const uint8_t *packet, ui
return 1;
}
- if (packet[1 + RETURN_1] != NET_PACKET_ANNOUNCE_RESPONSE &&
- packet[1 + RETURN_1] != NET_PACKET_ONION_DATA_RESPONSE) {
+ const uint8_t packet_id = packet[1 + RETURN_1];
+
+ if (packet_id != NET_PACKET_ANNOUNCE_RESPONSE && packet_id != NET_PACKET_ONION_DATA_RESPONSE) {
return 1;
}
@@ -634,10 +639,10 @@ static int handle_recv_1(void *object, IP_Port source, const uint8_t *packet, ui
if (onion->recv_1_function &&
!net_family_is_ipv4(send_to.ip.family) &&
!net_family_is_ipv6(send_to.ip.family)) {
- return onion->recv_1_function(onion->callback_object, send_to, packet + (1 + RETURN_1), data_len);
+ return onion->recv_1_function(onion->callback_object, &send_to, packet + (1 + RETURN_1), data_len);
}
- if ((uint32_t)sendpacket(onion->net, send_to, packet + (1 + RETURN_1), data_len) != data_len) {
+ if ((uint32_t)sendpacket(onion->net, &send_to, packet + (1 + RETURN_1), data_len) != data_len) {
return 1;
}
@@ -650,7 +655,7 @@ void set_callback_handle_recv_1(Onion *onion, onion_recv_1_cb *function, void *o
onion->callback_object = object;
}
-Onion *new_onion(Mono_Time *mono_time, DHT *dht)
+Onion *new_onion(const Logger *log, Mono_Time *mono_time, DHT *dht)
{
if (dht == nullptr) {
return nullptr;
@@ -662,6 +667,7 @@ Onion *new_onion(Mono_Time *mono_time, DHT *dht)
return nullptr;
}
+ onion->log = log;
onion->dht = dht;
onion->net = dht_get_net(dht);
onion->mono_time = mono_time;
@@ -693,5 +699,7 @@ void kill_onion(Onion *onion)
networking_registerhandler(onion->net, NET_PACKET_ONION_RECV_2, nullptr, nullptr);
networking_registerhandler(onion->net, NET_PACKET_ONION_RECV_1, nullptr, nullptr);
+ crypto_memzero(onion->secret_symmetric_key, sizeof(onion->secret_symmetric_key));
+
free(onion);
}
diff --git a/protocols/Tox/libtox/src/toxcore/onion.h b/protocols/Tox/libtox/src/toxcore/onion.h
index da1450818f..970ef5b139 100644
--- a/protocols/Tox/libtox/src/toxcore/onion.h
+++ b/protocols/Tox/libtox/src/toxcore/onion.h
@@ -3,18 +3,20 @@
* Copyright © 2013 Tox project.
*/
-/*
+/**
* Implementation of the onion part of docs/Prevent_Tracking.txt
*/
#ifndef C_TOXCORE_TOXCORE_ONION_H
#define C_TOXCORE_TOXCORE_ONION_H
#include "DHT.h"
+#include "logger.h"
#include "mono_time.h"
-typedef int onion_recv_1_cb(void *object, IP_Port dest, const uint8_t *data, uint16_t length);
+typedef int onion_recv_1_cb(void *object, const IP_Port *dest, const uint8_t *data, uint16_t length);
typedef struct Onion {
+ const Logger *log;
Mono_Time *mono_time;
DHT *dht;
Networking_Core *net;
@@ -66,7 +68,7 @@ typedef struct Onion_Path {
uint32_t path_num;
} Onion_Path;
-/* Create a new onion path.
+/** Create a new onion path.
*
* Create a new onion path out of nodes (nodes is a list of ONION_PATH_LENGTH nodes)
*
@@ -77,14 +79,14 @@ typedef struct Onion_Path {
*/
int create_onion_path(const DHT *dht, Onion_Path *new_path, const Node_format *nodes);
-/* Dump nodes in onion path to nodes of length num_nodes;
+/** Dump nodes in onion path to nodes of length num_nodes.
*
* return -1 on failure.
* return 0 on success.
*/
int onion_path_to_nodes(Node_format *nodes, unsigned int num_nodes, const Onion_Path *path);
-/* Create a onion packet.
+/** Create a onion packet.
*
* Use Onion_Path path to create packet for data of length to dest.
* Maximum length of data is ONION_MAX_DATA_SIZE.
@@ -93,11 +95,11 @@ int onion_path_to_nodes(Node_format *nodes, unsigned int num_nodes, const Onion_
* return -1 on failure.
* return length of created packet on success.
*/
-int create_onion_packet(uint8_t *packet, uint16_t max_packet_length, const Onion_Path *path, IP_Port dest,
+int create_onion_packet(uint8_t *packet, uint16_t max_packet_length, const Onion_Path *path, const IP_Port *dest,
const uint8_t *data, uint16_t length);
-/* Create a onion packet to be sent over tcp.
+/** Create a onion packet to be sent over tcp.
*
* Use Onion_Path path to create packet for data of length to dest.
* Maximum length of data is ONION_MAX_DATA_SIZE.
@@ -106,10 +108,10 @@ int create_onion_packet(uint8_t *packet, uint16_t max_packet_length, const Onion
* return -1 on failure.
* return length of created packet on success.
*/
-int create_onion_packet_tcp(uint8_t *packet, uint16_t max_packet_length, const Onion_Path *path, IP_Port dest,
+int create_onion_packet_tcp(uint8_t *packet, uint16_t max_packet_length, const Onion_Path *path, const IP_Port *dest,
const uint8_t *data, uint16_t length);
-/* Create and send a onion packet.
+/** Create and send a onion packet.
*
* Use Onion_Path path to send data of length to dest.
* Maximum length of data is ONION_MAX_DATA_SIZE.
@@ -117,17 +119,19 @@ int create_onion_packet_tcp(uint8_t *packet, uint16_t max_packet_length, const O
* return -1 on failure.
* return 0 on success.
*/
-int send_onion_packet(Networking_Core *net, const Onion_Path *path, IP_Port dest, const uint8_t *data, uint16_t length);
+int send_onion_packet(const Networking_Core *net, const Onion_Path *path, const IP_Port *dest, const uint8_t *data,
+ uint16_t length);
-/* Create and send a onion response sent initially to dest with.
+/** Create and send a onion response sent initially to dest with.
* Maximum length of data is ONION_RESPONSE_MAX_DATA_SIZE.
*
* return -1 on failure.
* return 0 on success.
*/
-int send_onion_response(Networking_Core *net, IP_Port dest, const uint8_t *data, uint16_t length, const uint8_t *ret);
+int send_onion_response(const Networking_Core *net, const IP_Port *dest, const uint8_t *data, uint16_t length,
+ const uint8_t *ret);
-/* Function to handle/send received decrypted versions of the packet sent with send_onion_packet.
+/** Function to handle/send received decrypted versions of the packet sent with send_onion_packet.
*
* return 0 on success.
* return 1 on failure.
@@ -137,13 +141,13 @@ int send_onion_response(Networking_Core *net, IP_Port dest, const uint8_t *data,
* Source family must be set to something else than TOX_AF_INET6 or TOX_AF_INET so that the callback gets called
* when the response is received.
*/
-int onion_send_1(const Onion *onion, const uint8_t *plain, uint16_t len, IP_Port source, const uint8_t *nonce);
+int onion_send_1(const Onion *onion, const uint8_t *plain, uint16_t len, const IP_Port *source, const uint8_t *nonce);
-/* Set the callback to be called when the dest ip_port doesn't have TOX_AF_INET6 or TOX_AF_INET as the family.
+/** Set the callback to be called when the dest ip_port doesn't have TOX_AF_INET6 or TOX_AF_INET as the family.
*/
void set_callback_handle_recv_1(Onion *onion, onion_recv_1_cb *function, void *object);
-Onion *new_onion(Mono_Time *mono_time, DHT *dht);
+Onion *new_onion(const Logger *log, Mono_Time *mono_time, DHT *dht);
void kill_onion(Onion *onion);
diff --git a/protocols/Tox/libtox/src/toxcore/onion_announce.c b/protocols/Tox/libtox/src/toxcore/onion_announce.c
index 0a04a4b834..5c37fbe18c 100644
--- a/protocols/Tox/libtox/src/toxcore/onion_announce.c
+++ b/protocols/Tox/libtox/src/toxcore/onion_announce.c
@@ -3,13 +3,9 @@
* Copyright © 2013 Tox project.
*/
-/*
+/**
* Implementation of the announce part of docs/Prevent_Tracking.txt
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include "onion_announce.h"
#include <stdlib.h>
@@ -26,6 +22,9 @@
#define DATA_REQUEST_MIN_SIZE ONION_DATA_REQUEST_MIN_SIZE
#define DATA_REQUEST_MIN_SIZE_RECV (DATA_REQUEST_MIN_SIZE + ONION_RETURN_3)
+static_assert(ONION_PING_ID_SIZE == CRYPTO_PUBLIC_KEY_SIZE,
+ "announce response packets assume that ONION_PING_ID_SIZE is equal to CRYPTO_PUBLIC_KEY_SIZE");
+
typedef struct Onion_Announce_Entry {
uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE];
IP_Port ret_ip_port;
@@ -35,6 +34,7 @@ typedef struct Onion_Announce_Entry {
} Onion_Announce_Entry;
struct Onion_Announce {
+ const Logger *log;
Mono_Time *mono_time;
DHT *dht;
Networking_Core *net;
@@ -45,6 +45,11 @@ struct Onion_Announce {
Shared_Keys shared_keys_recv;
};
+static bool onion_ping_id_eq(const uint8_t *a, const uint8_t *b)
+{
+ return public_key_cmp(a, b) == 0;
+}
+
uint8_t *onion_announce_entry_public_key(Onion_Announce *onion_a, uint32_t entry)
{
return onion_a->entries[entry].public_key;
@@ -55,7 +60,7 @@ void onion_announce_entry_set_time(Onion_Announce *onion_a, uint32_t entry, uint
onion_a->entries[entry].time = time;
}
-/* Create an onion announce request packet in packet of max_packet_length (recommended size ONION_ANNOUNCE_REQUEST_SIZE).
+/** Create an onion announce request packet in packet of max_packet_length (recommended size ONION_ANNOUNCE_REQUEST_SIZE).
*
* dest_client_id is the public key of the node the packet will be sent to.
* public_key and secret_key is the kepair which will be used to encrypt the request.
@@ -99,7 +104,7 @@ int create_announce_request(uint8_t *packet, uint16_t max_packet_length, const u
return ONION_ANNOUNCE_REQUEST_SIZE;
}
-/* Create an onion data request packet in packet of max_packet_length (recommended size ONION_MAX_PACKET_SIZE).
+/** Create an onion data request packet in packet of max_packet_length (recommended size ONION_MAX_PACKET_SIZE).
*
* public_key is the real public key of the node which we want to send the data of length length to.
* encrypt_public_key is the public key used to encrypt the data packet.
@@ -141,7 +146,7 @@ int create_data_request(uint8_t *packet, uint16_t max_packet_length, const uint8
return DATA_REQUEST_MIN_SIZE + length;
}
-/* Create and send an onion announce request packet.
+/** Create and send an onion announce request packet.
*
* path is the path the request will take before it is sent to dest.
*
@@ -155,9 +160,10 @@ int create_data_request(uint8_t *packet, uint16_t max_packet_length, const uint8
* return -1 on failure.
* return 0 on success.
*/
-int send_announce_request(Networking_Core *net, const Onion_Path *path, Node_format dest, const uint8_t *public_key,
- const uint8_t *secret_key, const uint8_t *ping_id, const uint8_t *client_id, const uint8_t *data_public_key,
- uint64_t sendback_data)
+int send_announce_request(const Networking_Core *net, const Onion_Path *path, Node_format dest,
+ const uint8_t *public_key, const uint8_t *secret_key,
+ const uint8_t *ping_id, const uint8_t *client_id,
+ const uint8_t *data_public_key, uint64_t sendback_data)
{
uint8_t request[ONION_ANNOUNCE_REQUEST_SIZE];
int len = create_announce_request(request, sizeof(request), dest.public_key, public_key, secret_key, ping_id, client_id,
@@ -168,20 +174,20 @@ int send_announce_request(Networking_Core *net, const Onion_Path *path, Node_for
}
uint8_t packet[ONION_MAX_PACKET_SIZE];
- len = create_onion_packet(packet, sizeof(packet), path, dest.ip_port, request, sizeof(request));
+ len = create_onion_packet(packet, sizeof(packet), path, &dest.ip_port, request, sizeof(request));
if (len == -1) {
return -1;
}
- if (sendpacket(net, path->ip_port1, packet, len) != len) {
+ if (sendpacket(net, &path->ip_port1, packet, len) != len) {
return -1;
}
return 0;
}
-/* Create and send an onion data request packet.
+/** Create and send an onion data request packet.
*
* path is the path the request will take before it is sent to dest.
* (if dest knows the person with the public_key they should
@@ -192,10 +198,13 @@ int send_announce_request(Networking_Core *net, const Onion_Path *path, Node_for
*
* nonce is the nonce to encrypt this packet with
*
+ * The maximum length of data is MAX_DATA_REQUEST_SIZE.
+ *
* return -1 on failure.
* return 0 on success.
*/
-int send_data_request(Networking_Core *net, const Onion_Path *path, IP_Port dest, const uint8_t *public_key,
+int send_data_request(const Networking_Core *net, const Onion_Path *path, const IP_Port *dest,
+ const uint8_t *public_key,
const uint8_t *encrypt_public_key, const uint8_t *nonce, const uint8_t *data, uint16_t length)
{
uint8_t request[ONION_MAX_DATA_SIZE];
@@ -212,36 +221,34 @@ int send_data_request(Networking_Core *net, const Onion_Path *path, IP_Port dest
return -1;
}
- if (sendpacket(net, path->ip_port1, packet, len) != len) {
+ if (sendpacket(net, &path->ip_port1, packet, len) != len) {
return -1;
}
return 0;
}
-/* Generate a ping_id and put it in ping_id */
+/** Generate a ping_id and put it in ping_id */
static void generate_ping_id(const Onion_Announce *onion_a, uint64_t time, const uint8_t *public_key,
- IP_Port ret_ip_port, uint8_t *ping_id)
+ const IP_Port *ret_ip_port, uint8_t *ping_id)
{
time /= PING_ID_TIMEOUT;
- uint8_t data[CRYPTO_SYMMETRIC_KEY_SIZE + sizeof(time) + CRYPTO_PUBLIC_KEY_SIZE + sizeof(ret_ip_port)];
+ uint8_t data[CRYPTO_SYMMETRIC_KEY_SIZE + sizeof(time) + CRYPTO_PUBLIC_KEY_SIZE + sizeof(IP_Port)];
memcpy(data, onion_a->secret_bytes, CRYPTO_SYMMETRIC_KEY_SIZE);
memcpy(data + CRYPTO_SYMMETRIC_KEY_SIZE, &time, sizeof(time));
memcpy(data + CRYPTO_SYMMETRIC_KEY_SIZE + sizeof(time), public_key, CRYPTO_PUBLIC_KEY_SIZE);
- memcpy(data + CRYPTO_SYMMETRIC_KEY_SIZE + sizeof(time) + CRYPTO_PUBLIC_KEY_SIZE, &ret_ip_port, sizeof(ret_ip_port));
+ memcpy(data + CRYPTO_SYMMETRIC_KEY_SIZE + sizeof(time) + CRYPTO_PUBLIC_KEY_SIZE, ret_ip_port, sizeof(IP_Port));
crypto_sha256(ping_id, data, sizeof(data));
}
-/* check if public key is in entries list
+/** check if public key is in entries list
*
* return -1 if no
* return position in list if yes
*/
static int in_entries(const Onion_Announce *onion_a, const uint8_t *public_key)
{
- unsigned int i;
-
- for (i = 0; i < ONION_ANNOUNCE_MAX_ENTRIES; ++i) {
+ for (unsigned int i = 0; i < ONION_ANNOUNCE_MAX_ENTRIES; ++i) {
if (!mono_time_is_timeout(onion_a->mono_time, onion_a->entries[i].time, ONION_ANNOUNCE_TIMEOUT)
&& public_key_cmp(onion_a->entries[i].public_key, public_key) == 0) {
return i;
@@ -251,24 +258,22 @@ static int in_entries(const Onion_Announce *onion_a, const uint8_t *public_key)
return -1;
}
-typedef struct Cmp_data {
+typedef struct Cmp_Data {
const Mono_Time *mono_time;
const uint8_t *base_public_key;
Onion_Announce_Entry entry;
-} Cmp_data;
+} Cmp_Data;
static int cmp_entry(const void *a, const void *b)
{
- Cmp_data cmp1;
- Cmp_data cmp2;
- memcpy(&cmp1, a, sizeof(Cmp_data));
- memcpy(&cmp2, b, sizeof(Cmp_data));
- Onion_Announce_Entry entry1 = cmp1.entry;
- Onion_Announce_Entry entry2 = cmp2.entry;
- const uint8_t *cmp_public_key = cmp1.base_public_key;
+ const Cmp_Data *cmp1 = (const Cmp_Data *)a;
+ const Cmp_Data *cmp2 = (const Cmp_Data *)b;
+ const Onion_Announce_Entry entry1 = cmp1->entry;
+ const Onion_Announce_Entry entry2 = cmp2->entry;
+ const uint8_t *cmp_public_key = cmp1->base_public_key;
- int t1 = mono_time_is_timeout(cmp1.mono_time, entry1.time, ONION_ANNOUNCE_TIMEOUT);
- int t2 = mono_time_is_timeout(cmp1.mono_time, entry2.time, ONION_ANNOUNCE_TIMEOUT);
+ const int t1 = mono_time_is_timeout(cmp1->mono_time, entry1.time, ONION_ANNOUNCE_TIMEOUT);
+ const int t2 = mono_time_is_timeout(cmp1->mono_time, entry2.time, ONION_ANNOUNCE_TIMEOUT);
if (t1 && t2) {
return 0;
@@ -282,7 +287,7 @@ static int cmp_entry(const void *a, const void *b)
return 1;
}
- int close = id_closest(cmp_public_key, entry1.public_key, entry2.public_key);
+ const int close = id_closest(cmp_public_key, entry1.public_key, entry2.public_key);
if (close == 1) {
return 1;
@@ -300,7 +305,7 @@ static void sort_onion_announce_list(Onion_Announce_Entry *list, unsigned int le
{
// Pass comp_public_key to qsort with each Client_data entry, so the
// comparison function can use it as the base of comparison.
- VLA(Cmp_data, cmp_list, length);
+ VLA(Cmp_Data, cmp_list, length);
for (uint32_t i = 0; i < length; ++i) {
cmp_list[i].mono_time = mono_time;
@@ -308,19 +313,19 @@ static void sort_onion_announce_list(Onion_Announce_Entry *list, unsigned int le
cmp_list[i].entry = list[i];
}
- qsort(cmp_list, length, sizeof(Cmp_data), cmp_entry);
+ qsort(cmp_list, length, sizeof(Cmp_Data), cmp_entry);
for (uint32_t i = 0; i < length; ++i) {
list[i] = cmp_list[i].entry;
}
}
-/* add entry to entries list
+/** add entry to entries list
*
* return -1 if failure
* return position if added
*/
-static int add_to_entries(Onion_Announce *onion_a, IP_Port ret_ip_port, const uint8_t *public_key,
+static int add_to_entries(Onion_Announce *onion_a, const IP_Port *ret_ip_port, const uint8_t *public_key,
const uint8_t *data_public_key, const uint8_t *ret)
{
@@ -345,7 +350,7 @@ static int add_to_entries(Onion_Announce *onion_a, IP_Port ret_ip_port, const ui
}
memcpy(onion_a->entries[pos].public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE);
- onion_a->entries[pos].ret_ip_port = ret_ip_port;
+ onion_a->entries[pos].ret_ip_port = *ret_ip_port;
memcpy(onion_a->entries[pos].ret, ret, ONION_RETURN_3);
memcpy(onion_a->entries[pos].data_public_key, data_public_key, CRYPTO_PUBLIC_KEY_SIZE);
onion_a->entries[pos].time = mono_time_get(onion_a->mono_time);
@@ -355,7 +360,8 @@ static int add_to_entries(Onion_Announce *onion_a, IP_Port ret_ip_port, const ui
return in_entries(onion_a, public_key);
}
-static int handle_announce_request(void *object, IP_Port source, const uint8_t *packet, uint16_t length, void *userdata)
+static int handle_announce_request(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length,
+ void *userdata)
{
Onion_Announce *onion_a = (Onion_Announce *)object;
@@ -386,10 +392,10 @@ static int handle_announce_request(void *object, IP_Port source, const uint8_t *
int index;
- uint8_t *data_public_key = plain + ONION_PING_ID_SIZE + CRYPTO_PUBLIC_KEY_SIZE;
+ const uint8_t *data_public_key = plain + ONION_PING_ID_SIZE + CRYPTO_PUBLIC_KEY_SIZE;
- if (crypto_memcmp(ping_id1, plain, ONION_PING_ID_SIZE) == 0
- || crypto_memcmp(ping_id2, plain, ONION_PING_ID_SIZE) == 0) {
+ if (onion_ping_id_eq(ping_id1, plain)
+ || onion_ping_id_eq(ping_id2, plain)) {
index = add_to_entries(onion_a, source, packet_public_key, data_public_key,
packet + (ANNOUNCE_REQUEST_SIZE_RECV - ONION_RETURN_3));
} else {
@@ -399,7 +405,7 @@ static int handle_announce_request(void *object, IP_Port source, const uint8_t *
/*Respond with a announce response packet*/
Node_format nodes_list[MAX_SENT_NODES];
unsigned int num_nodes =
- get_close_nodes(onion_a->dht, plain + ONION_PING_ID_SIZE, nodes_list, net_family_unspec, ip_is_lan(source.ip), 1);
+ get_close_nodes(onion_a->dht, plain + ONION_PING_ID_SIZE, nodes_list, net_family_unspec, ip_is_lan(&source->ip));
uint8_t nonce[CRYPTO_NONCE_SIZE];
random_nonce(nonce);
@@ -455,9 +461,10 @@ static int handle_announce_request(void *object, IP_Port source, const uint8_t *
return 0;
}
-static int handle_data_request(void *object, IP_Port source, const uint8_t *packet, uint16_t length, void *userdata)
+static int handle_data_request(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length,
+ void *userdata)
{
- Onion_Announce *onion_a = (Onion_Announce *)object;
+ const Onion_Announce *onion_a = (const Onion_Announce *)object;
if (length <= DATA_REQUEST_MIN_SIZE_RECV) {
return 1;
@@ -477,7 +484,7 @@ static int handle_data_request(void *object, IP_Port source, const uint8_t *pack
data[0] = NET_PACKET_ONION_DATA_RESPONSE;
memcpy(data + 1, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, length - (1 + CRYPTO_PUBLIC_KEY_SIZE + ONION_RETURN_3));
- if (send_onion_response(onion_a->net, onion_a->entries[index].ret_ip_port, data, SIZEOF_VLA(data),
+ if (send_onion_response(onion_a->net, &onion_a->entries[index].ret_ip_port, data, SIZEOF_VLA(data),
onion_a->entries[index].ret) == -1) {
return 1;
}
@@ -485,7 +492,7 @@ static int handle_data_request(void *object, IP_Port source, const uint8_t *pack
return 0;
}
-Onion_Announce *new_onion_announce(Mono_Time *mono_time, DHT *dht)
+Onion_Announce *new_onion_announce(const Logger *log, Mono_Time *mono_time, DHT *dht)
{
if (dht == nullptr) {
return nullptr;
@@ -497,6 +504,7 @@ Onion_Announce *new_onion_announce(Mono_Time *mono_time, DHT *dht)
return nullptr;
}
+ onion_a->log = log;
onion_a->mono_time = mono_time;
onion_a->dht = dht;
onion_a->net = dht_get_net(dht);
diff --git a/protocols/Tox/libtox/src/toxcore/onion_announce.h b/protocols/Tox/libtox/src/toxcore/onion_announce.h
index 3145803c15..c4159d2bf6 100644
--- a/protocols/Tox/libtox/src/toxcore/onion_announce.h
+++ b/protocols/Tox/libtox/src/toxcore/onion_announce.h
@@ -3,12 +3,13 @@
* Copyright © 2013 Tox project.
*/
-/*
+/**
* Implementation of the announce part of docs/Prevent_Tracking.txt
*/
#ifndef C_TOXCORE_TOXCORE_ONION_ANNOUNCE_H
#define C_TOXCORE_TOXCORE_ONION_ANNOUNCE_H
+#include "logger.h"
#include "onion.h"
#define ONION_ANNOUNCE_MAX_ENTRIES 160
@@ -24,20 +25,16 @@
#define ONION_DATA_RESPONSE_MIN_SIZE (1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE)
-#if ONION_PING_ID_SIZE != CRYPTO_PUBLIC_KEY_SIZE
-#error "announce response packets assume that ONION_PING_ID_SIZE is equal to CRYPTO_PUBLIC_KEY_SIZE"
-#endif
-
#define ONION_DATA_REQUEST_MIN_SIZE (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE)
#define MAX_DATA_REQUEST_SIZE (ONION_MAX_DATA_SIZE - ONION_DATA_REQUEST_MIN_SIZE)
typedef struct Onion_Announce Onion_Announce;
-/* These two are not public; they are for tests only! */
+/** These two are not public; they are for tests only! */
uint8_t *onion_announce_entry_public_key(Onion_Announce *onion_a, uint32_t entry);
void onion_announce_entry_set_time(Onion_Announce *onion_a, uint32_t entry, uint64_t time);
-/* Create an onion announce request packet in packet of max_packet_length (recommended size ONION_ANNOUNCE_REQUEST_SIZE).
+/** Create an onion announce request packet in packet of max_packet_length (recommended size ONION_ANNOUNCE_REQUEST_SIZE).
*
* dest_client_id is the public key of the node the packet will be sent to.
* public_key and secret_key is the kepair which will be used to encrypt the request.
@@ -54,7 +51,7 @@ int create_announce_request(uint8_t *packet, uint16_t max_packet_length, const u
const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *ping_id, const uint8_t *client_id,
const uint8_t *data_public_key, uint64_t sendback_data);
-/* Create an onion data request packet in packet of max_packet_length (recommended size ONION_MAX_PACKET_SIZE).
+/** Create an onion data request packet in packet of max_packet_length (recommended size ONION_MAX_PACKET_SIZE).
*
* public_key is the real public key of the node which we want to send the data of length length to.
* encrypt_public_key is the public key used to encrypt the data packet.
@@ -67,7 +64,7 @@ int create_announce_request(uint8_t *packet, uint16_t max_packet_length, const u
int create_data_request(uint8_t *packet, uint16_t max_packet_length, const uint8_t *public_key,
const uint8_t *encrypt_public_key, const uint8_t *nonce, const uint8_t *data, uint16_t length);
-/* Create and send an onion announce request packet.
+/** Create and send an onion announce request packet.
*
* path is the path the request will take before it is sent to dest.
*
@@ -81,11 +78,12 @@ int create_data_request(uint8_t *packet, uint16_t max_packet_length, const uint8
* return -1 on failure.
* return 0 on success.
*/
-int send_announce_request(Networking_Core *net, const Onion_Path *path, Node_format dest, const uint8_t *public_key,
- const uint8_t *secret_key, const uint8_t *ping_id, const uint8_t *client_id, const uint8_t *data_public_key,
- uint64_t sendback_data);
+int send_announce_request(const Networking_Core *net, const Onion_Path *path, Node_format dest,
+ const uint8_t *public_key, const uint8_t *secret_key,
+ const uint8_t *ping_id, const uint8_t *client_id,
+ const uint8_t *data_public_key, uint64_t sendback_data);
-/* Create and send an onion data request packet.
+/** Create and send an onion data request packet.
*
* path is the path the request will take before it is sent to dest.
* (if dest knows the person with the public_key they should
@@ -101,11 +99,12 @@ int send_announce_request(Networking_Core *net, const Onion_Path *path, Node_for
* return -1 on failure.
* return 0 on success.
*/
-int send_data_request(Networking_Core *net, const Onion_Path *path, IP_Port dest, const uint8_t *public_key,
+int send_data_request(const Networking_Core *net, const Onion_Path *path, const IP_Port *dest,
+ const uint8_t *public_key,
const uint8_t *encrypt_public_key, const uint8_t *nonce, const uint8_t *data, uint16_t length);
-Onion_Announce *new_onion_announce(Mono_Time *mono_time, DHT *dht);
+Onion_Announce *new_onion_announce(const Logger *log, Mono_Time *mono_time, DHT *dht);
void kill_onion_announce(Onion_Announce *onion_a);
diff --git a/protocols/Tox/libtox/src/toxcore/onion_client.c b/protocols/Tox/libtox/src/toxcore/onion_client.c
index d3a56af73b..592cb4f57d 100644
--- a/protocols/Tox/libtox/src/toxcore/onion_client.c
+++ b/protocols/Tox/libtox/src/toxcore/onion_client.c
@@ -3,16 +3,13 @@
* Copyright © 2013 Tox project.
*/
-/*
+/**
* Implementation of the client part of docs/Prevent_Tracking.txt (The part that
* uses the onion stuff to connect to the friend)
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include "onion_client.h"
+#include <assert.h>
#include <stdlib.h>
#include <string.h>
@@ -20,7 +17,7 @@
#include "mono_time.h"
#include "util.h"
-/* defines for the array size and
+/** defines for the array size and
* timeout for onion announce packets. */
#define ANNOUNCE_ARRAY_SIZE 256
#define ANNOUNCE_TIMEOUT 10
@@ -146,26 +143,24 @@ Net_Crypto *onion_get_net_crypto(const Onion_Client *onion_c)
return onion_c->c;
}
-/* Add a node to the path_nodes bootstrap array.
+/** Add a node to the path_nodes bootstrap array.
*
* return -1 on failure
* return 0 on success
*/
-int onion_add_bs_path_node(Onion_Client *onion_c, IP_Port ip_port, const uint8_t *public_key)
+int onion_add_bs_path_node(Onion_Client *onion_c, const IP_Port *ip_port, const uint8_t *public_key)
{
- if (!net_family_is_ipv4(ip_port.ip.family) && !net_family_is_ipv6(ip_port.ip.family)) {
+ if (!net_family_is_ipv4(ip_port->ip.family) && !net_family_is_ipv6(ip_port->ip.family)) {
return -1;
}
- unsigned int i;
-
- for (i = 0; i < MAX_PATH_NODES; ++i) {
+ for (unsigned int i = 0; i < MAX_PATH_NODES; ++i) {
if (public_key_cmp(public_key, onion_c->path_nodes_bs[i].public_key) == 0) {
return -1;
}
}
- onion_c->path_nodes_bs[onion_c->path_nodes_index_bs % MAX_PATH_NODES].ip_port = ip_port;
+ onion_c->path_nodes_bs[onion_c->path_nodes_index_bs % MAX_PATH_NODES].ip_port = *ip_port;
memcpy(onion_c->path_nodes_bs[onion_c->path_nodes_index_bs % MAX_PATH_NODES].public_key, public_key,
CRYPTO_PUBLIC_KEY_SIZE);
@@ -179,26 +174,24 @@ int onion_add_bs_path_node(Onion_Client *onion_c, IP_Port ip_port, const uint8_t
return 0;
}
-/* Add a node to the path_nodes array.
+/** Add a node to the path_nodes array.
*
* return -1 on failure
* return 0 on success
*/
-static int onion_add_path_node(Onion_Client *onion_c, IP_Port ip_port, const uint8_t *public_key)
+static int onion_add_path_node(Onion_Client *onion_c, const IP_Port *ip_port, const uint8_t *public_key)
{
- if (!net_family_is_ipv4(ip_port.ip.family) && !net_family_is_ipv6(ip_port.ip.family)) {
+ if (!net_family_is_ipv4(ip_port->ip.family) && !net_family_is_ipv6(ip_port->ip.family)) {
return -1;
}
- unsigned int i;
-
- for (i = 0; i < MAX_PATH_NODES; ++i) {
+ for (unsigned int i = 0; i < MAX_PATH_NODES; ++i) {
if (public_key_cmp(public_key, onion_c->path_nodes[i].public_key) == 0) {
return -1;
}
}
- onion_c->path_nodes[onion_c->path_nodes_index % MAX_PATH_NODES].ip_port = ip_port;
+ onion_c->path_nodes[onion_c->path_nodes_index % MAX_PATH_NODES].ip_port = *ip_port;
memcpy(onion_c->path_nodes[onion_c->path_nodes_index % MAX_PATH_NODES].public_key, public_key,
CRYPTO_PUBLIC_KEY_SIZE);
@@ -212,7 +205,7 @@ static int onion_add_path_node(Onion_Client *onion_c, IP_Port ip_port, const uin
return 0;
}
-/* Put up to max_num nodes in nodes.
+/** Put up to max_num nodes in nodes.
*
* return the number of nodes.
*/
@@ -249,14 +242,12 @@ uint16_t onion_backup_nodes(const Onion_Client *onion_c, Node_format *nodes, uin
return i;
}
-/* Put up to max_num random nodes in nodes.
+/** Put up to max_num random nodes in nodes.
*
* return the number of nodes.
*/
static uint16_t random_nodes_path_onion(const Onion_Client *onion_c, Node_format *nodes, uint16_t max_num)
{
- unsigned int i;
-
if (!max_num) {
return 0;
}
@@ -269,8 +260,9 @@ static uint16_t random_nodes_path_onion(const Onion_Client *onion_c, Node_format
return 0;
}
- for (i = 0; i < max_num; ++i) {
- nodes[i] = onion_c->path_nodes[random_u32() % num_nodes];
+ for (unsigned int i = 0; i < max_num; ++i) {
+ const uint32_t rand_idx = random_range_u32(num_nodes);
+ nodes[i] = onion_c->path_nodes[rand_idx];
}
} else {
int random_tcp = get_random_tcp_con_number(onion_c->c);
@@ -280,11 +272,15 @@ static uint16_t random_nodes_path_onion(const Onion_Client *onion_c, Node_format
}
if (num_nodes >= 2) {
+ nodes[0] = (Node_format) {
+ 0
+ };
nodes[0].ip_port.ip.family = net_family_tcp_family;
nodes[0].ip_port.ip.ip.v4.uint32 = random_tcp;
- for (i = 1; i < max_num; ++i) {
- nodes[i] = onion_c->path_nodes[random_u32() % num_nodes];
+ for (unsigned int i = 1; i < max_num; ++i) {
+ const uint32_t rand_idx = random_range_u32(num_nodes);
+ nodes[i] = onion_c->path_nodes[rand_idx];
}
} else {
const uint16_t num_nodes_bs = min_u16(onion_c->path_nodes_index_bs, MAX_PATH_NODES);
@@ -293,11 +289,15 @@ static uint16_t random_nodes_path_onion(const Onion_Client *onion_c, Node_format
return 0;
}
+ nodes[0] = (Node_format) {
+ 0
+ };
nodes[0].ip_port.ip.family = net_family_tcp_family;
nodes[0].ip_port.ip.ip.v4.uint32 = random_tcp;
- for (i = 1; i < max_num; ++i) {
- nodes[i] = onion_c->path_nodes_bs[random_u32() % num_nodes_bs];
+ for (unsigned int i = 1; i < max_num; ++i) {
+ const uint32_t rand_idx = random_range_u32(num_nodes_bs);
+ nodes[i] = onion_c->path_nodes_bs[rand_idx];
}
}
}
@@ -305,15 +305,13 @@ static uint16_t random_nodes_path_onion(const Onion_Client *onion_c, Node_format
return max_num;
}
-/*
+/**
* return -1 if nodes are suitable for creating a new path.
* return path number of already existing similar path if one already exists.
*/
static int is_path_used(const Mono_Time *mono_time, const Onion_Client_Paths *onion_paths, const Node_format *nodes)
{
- unsigned int i;
-
- for (i = 0; i < NUMBER_ONION_PATHS; ++i) {
+ for (unsigned int i = 0; i < NUMBER_ONION_PATHS; ++i) {
if (mono_time_is_timeout(mono_time, onion_paths->last_path_success[i], ONION_PATH_TIMEOUT)) {
continue;
}
@@ -331,8 +329,8 @@ static int is_path_used(const Mono_Time *mono_time, const Onion_Client_Paths *on
return -1;
}
-/* is path timed out */
-static bool path_timed_out(const Mono_Time *mono_time, Onion_Client_Paths *onion_paths, uint32_t pathnum)
+/** is path timed out */
+static bool path_timed_out(const Mono_Time *mono_time, const Onion_Client_Paths *onion_paths, uint32_t pathnum)
{
pathnum = pathnum % NUMBER_ONION_PATHS;
@@ -344,7 +342,7 @@ static bool path_timed_out(const Mono_Time *mono_time, Onion_Client_Paths *onion
|| mono_time_is_timeout(mono_time, onion_paths->path_creation_time[pathnum], ONION_PATH_MAX_LIFETIME));
}
-/* should node be considered to have timed out */
+/** should node be considered to have timed out */
static bool onion_node_timed_out(const Onion_Node *node, const Mono_Time *mono_time)
{
return (node->timestamp == 0
@@ -352,7 +350,7 @@ static bool onion_node_timed_out(const Onion_Node *node, const Mono_Time *mono_t
&& mono_time_is_timeout(mono_time, node->last_pinged, ONION_NODE_TIMEOUT)));
}
-/* Create a new path or use an old suitable one (if pathnum is valid)
+/** Create a new path or use an old suitable one (if pathnum is valid)
* or a random one from onion_paths.
*
* return -1 on failure
@@ -364,7 +362,7 @@ static bool onion_node_timed_out(const Onion_Node *node, const Mono_Time *mono_t
static int random_path(const Onion_Client *onion_c, Onion_Client_Paths *onion_paths, uint32_t pathnum, Onion_Path *path)
{
if (pathnum == UINT32_MAX) {
- pathnum = random_u32() % NUMBER_ONION_PATHS;
+ pathnum = random_range_u32(NUMBER_ONION_PATHS);
} else {
pathnum = pathnum % NUMBER_ONION_PATHS;
}
@@ -403,12 +401,12 @@ static int random_path(const Onion_Client *onion_c, Onion_Client_Paths *onion_pa
}
++onion_paths->last_path_used_times[pathnum];
- memcpy(path, &onion_paths->paths[pathnum], sizeof(Onion_Path));
+ *path = onion_paths->paths[pathnum];
return 0;
}
-/* Does path with path_num exist. */
-static bool path_exists(const Mono_Time *mono_time, Onion_Client_Paths *onion_paths, uint32_t path_num)
+/** Does path with path_num exist. */
+static bool path_exists(const Mono_Time *mono_time, const Onion_Client_Paths *onion_paths, uint32_t path_num)
{
if (path_timed_out(mono_time, onion_paths, path_num)) {
return 0;
@@ -417,7 +415,7 @@ static bool path_exists(const Mono_Time *mono_time, Onion_Client_Paths *onion_pa
return onion_paths->paths[path_num % NUMBER_ONION_PATHS].path_num == path_num;
}
-/* Set path timeouts, return the path number.
+/** Set path timeouts, return the path number.
*
*/
static uint32_t set_path_timeouts(Onion_Client *onion_c, uint32_t num, uint32_t path_num)
@@ -441,10 +439,8 @@ static uint32_t set_path_timeouts(Onion_Client *onion_c, uint32_t num, uint32_t
Node_format nodes[ONION_PATH_LENGTH];
if (onion_path_to_nodes(nodes, ONION_PATH_LENGTH, &onion_paths->paths[path_num % NUMBER_ONION_PATHS]) == 0) {
- unsigned int i;
-
- for (i = 0; i < ONION_PATH_LENGTH; ++i) {
- onion_add_path_node(onion_c, nodes[i].ip_port, nodes[i].public_key);
+ for (unsigned int i = 0; i < ONION_PATH_LENGTH; ++i) {
+ onion_add_path_node(onion_c, &nodes[i].ip_port, nodes[i].public_key);
}
}
@@ -454,12 +450,12 @@ static uint32_t set_path_timeouts(Onion_Client *onion_c, uint32_t num, uint32_t
return -1;
}
-/* Function to send onion packet via TCP and UDP.
+/** Function to send onion packet via TCP and UDP.
*
* return -1 on failure.
* return 0 on success.
*/
-static int send_onion_packet_tcp_udp(const Onion_Client *onion_c, const Onion_Path *path, IP_Port dest,
+static int send_onion_packet_tcp_udp(const Onion_Client *onion_c, const Onion_Path *path, const IP_Port *dest,
const uint8_t *data, uint16_t length)
{
if (net_family_is_ipv4(path->ip_port1.ip.family) || net_family_is_ipv6(path->ip_port1.ip.family)) {
@@ -470,7 +466,7 @@ static int send_onion_packet_tcp_udp(const Onion_Client *onion_c, const Onion_Pa
return -1;
}
- if (sendpacket(onion_c->net, path->ip_port1, packet, len) != len) {
+ if (sendpacket(onion_c->net, &path->ip_port1, packet, len) != len) {
return -1;
}
@@ -491,7 +487,7 @@ static int send_onion_packet_tcp_udp(const Onion_Client *onion_c, const Onion_Pa
return -1;
}
-/* Creates a sendback for use in an announce request.
+/** Creates a sendback for use in an announce request.
*
* num is 0 if we used our secret public key for the announce
* num is 1 + friendnum if we use a temporary one.
@@ -506,13 +502,13 @@ static int send_onion_packet_tcp_udp(const Onion_Client *onion_c, const Onion_Pa
* return 0 on success
*
*/
-static int new_sendback(Onion_Client *onion_c, uint32_t num, const uint8_t *public_key, IP_Port ip_port,
+static int new_sendback(Onion_Client *onion_c, uint32_t num, const uint8_t *public_key, const IP_Port *ip_port,
uint32_t path_num, uint64_t *sendback)
{
uint8_t data[sizeof(uint32_t) + CRYPTO_PUBLIC_KEY_SIZE + sizeof(IP_Port) + sizeof(uint32_t)];
memcpy(data, &num, sizeof(uint32_t));
memcpy(data + sizeof(uint32_t), public_key, CRYPTO_PUBLIC_KEY_SIZE);
- memcpy(data + sizeof(uint32_t) + CRYPTO_PUBLIC_KEY_SIZE, &ip_port, sizeof(IP_Port));
+ memcpy(data + sizeof(uint32_t) + CRYPTO_PUBLIC_KEY_SIZE, ip_port, sizeof(IP_Port));
memcpy(data + sizeof(uint32_t) + CRYPTO_PUBLIC_KEY_SIZE + sizeof(IP_Port), &path_num, sizeof(uint32_t));
*sendback = ping_array_add(onion_c->announce_ping_array, onion_c->mono_time, data, sizeof(data));
@@ -523,7 +519,7 @@ static int new_sendback(Onion_Client *onion_c, uint32_t num, const uint8_t *publ
return 0;
}
-/* Checks if the sendback is valid and returns the public key contained in it in ret_pubkey and the
+/** Checks if the sendback is valid and returns the public key contained in it in ret_pubkey and the
* ip contained in it in ret_ip_port
*
* sendback is the sendback ONION_ANNOUNCE_SENDBACK_DATA_LENGTH big
@@ -553,8 +549,8 @@ static uint32_t check_sendback(Onion_Client *onion_c, const uint8_t *sendback, u
return num;
}
-static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, IP_Port dest, const uint8_t *dest_pubkey,
- const uint8_t *ping_id, uint32_t pathnum)
+static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, const IP_Port *dest,
+ const uint8_t *dest_pubkey, const uint8_t *ping_id, uint32_t pathnum)
{
if (num > onion_c->num_friends) {
return -1;
@@ -603,24 +599,22 @@ static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, IP_
return send_onion_packet_tcp_udp(onion_c, &path, dest, request, len);
}
-typedef struct Onion_Client_Cmp_data {
+typedef struct Onion_Client_Cmp_Data {
const Mono_Time *mono_time;
const uint8_t *base_public_key;
Onion_Node entry;
-} Onion_Client_Cmp_data;
+} Onion_Client_Cmp_Data;
static int onion_client_cmp_entry(const void *a, const void *b)
{
- Onion_Client_Cmp_data cmp1;
- Onion_Client_Cmp_data cmp2;
- memcpy(&cmp1, a, sizeof(Onion_Client_Cmp_data));
- memcpy(&cmp2, b, sizeof(Onion_Client_Cmp_data));
- Onion_Node entry1 = cmp1.entry;
- Onion_Node entry2 = cmp2.entry;
- const uint8_t *cmp_public_key = cmp1.base_public_key;
+ const Onion_Client_Cmp_Data *cmp1 = (const Onion_Client_Cmp_Data *)a;
+ const Onion_Client_Cmp_Data *cmp2 = (const Onion_Client_Cmp_Data *)b;
+ const Onion_Node entry1 = cmp1->entry;
+ const Onion_Node entry2 = cmp2->entry;
+ const uint8_t *cmp_public_key = cmp1->base_public_key;
- int t1 = onion_node_timed_out(&entry1, cmp1.mono_time);
- int t2 = onion_node_timed_out(&entry2, cmp2.mono_time);
+ const int t1 = onion_node_timed_out(&entry1, cmp1->mono_time);
+ const int t2 = onion_node_timed_out(&entry2, cmp2->mono_time);
if (t1 && t2) {
return 0;
@@ -634,7 +628,7 @@ static int onion_client_cmp_entry(const void *a, const void *b)
return 1;
}
- int close = id_closest(cmp_public_key, entry1.public_key, entry2.public_key);
+ const int close = id_closest(cmp_public_key, entry1.public_key, entry2.public_key);
if (close == 1) {
return 1;
@@ -652,7 +646,7 @@ static void sort_onion_node_list(Onion_Node *list, unsigned int length, const Mo
{
// Pass comp_public_key to qsort with each Client_data entry, so the
// comparison function can use it as the base of comparison.
- VLA(Onion_Client_Cmp_data, cmp_list, length);
+ VLA(Onion_Client_Cmp_Data, cmp_list, length);
for (uint32_t i = 0; i < length; ++i) {
cmp_list[i].mono_time = mono_time;
@@ -660,14 +654,14 @@ static void sort_onion_node_list(Onion_Node *list, unsigned int length, const Mo
cmp_list[i].entry = list[i];
}
- qsort(cmp_list, length, sizeof(Onion_Client_Cmp_data), onion_client_cmp_entry);
+ qsort(cmp_list, length, sizeof(Onion_Client_Cmp_Data), onion_client_cmp_entry);
for (uint32_t i = 0; i < length; ++i) {
list[i] = cmp_list[i].entry;
}
}
-static int client_add_to_list(Onion_Client *onion_c, uint32_t num, const uint8_t *public_key, IP_Port ip_port,
+static int client_add_to_list(Onion_Client *onion_c, uint32_t num, const uint8_t *public_key, const IP_Port *ip_port,
uint8_t is_stored, const uint8_t *pingid_or_key, uint32_t path_used)
{
if (num > onion_c->num_friends) {
@@ -704,14 +698,13 @@ static int client_add_to_list(Onion_Client *onion_c, uint32_t num, const uint8_t
int index = -1;
int stored = 0;
- unsigned int i;
if (onion_node_timed_out(&list_nodes[0], onion_c->mono_time)
|| id_closest(reference_id, list_nodes[0].public_key, public_key) == 2) {
index = 0;
}
- for (i = 0; i < list_length; ++i) {
+ for (unsigned int i = 0; i < list_length; ++i) {
if (public_key_cmp(list_nodes[i].public_key, public_key) == 0) {
index = i;
stored = 1;
@@ -724,7 +717,7 @@ static int client_add_to_list(Onion_Client *onion_c, uint32_t num, const uint8_t
}
memcpy(list_nodes[index].public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE);
- list_nodes[index].ip_port = ip_port;
+ list_nodes[index].ip_port = *ip_port;
// TODO(irungentoo): remove this and find a better source of nodes to use for paths.
onion_add_path_node(onion_c, ip_port, public_key);
@@ -748,12 +741,10 @@ static int client_add_to_list(Onion_Client *onion_c, uint32_t num, const uint8_t
return 0;
}
-static int good_to_ping(Mono_Time *mono_time, Last_Pinged *last_pinged, uint8_t *last_pinged_index,
+static int good_to_ping(const Mono_Time *mono_time, Last_Pinged *last_pinged, uint8_t *last_pinged_index,
const uint8_t *public_key)
{
- unsigned int i;
-
- for (i = 0; i < MAX_STORED_PINGED_NODES; ++i) {
+ for (unsigned int i = 0; i < MAX_STORED_PINGED_NODES; ++i) {
if (!mono_time_is_timeout(mono_time, last_pinged[i].timestamp, MIN_NODE_PING_TIME)) {
if (public_key_cmp(last_pinged[i].public_key, public_key) == 0) {
return 0;
@@ -768,7 +759,7 @@ static int good_to_ping(Mono_Time *mono_time, Last_Pinged *last_pinged, uint8_t
}
static int client_ping_nodes(Onion_Client *onion_c, uint32_t num, const Node_format *nodes, uint16_t num_nodes,
- IP_Port source)
+ const IP_Port *source)
{
if (num > onion_c->num_friends) {
return -1;
@@ -778,7 +769,7 @@ static int client_ping_nodes(Onion_Client *onion_c, uint32_t num, const Node_for
return 0;
}
- Onion_Node *list_nodes = nullptr;
+ const Onion_Node *list_nodes = nullptr;
const uint8_t *reference_id = nullptr;
unsigned int list_length;
@@ -799,11 +790,11 @@ static int client_ping_nodes(Onion_Client *onion_c, uint32_t num, const Node_for
last_pinged_index = &onion_c->friends_list[num - 1].last_pinged_index;
}
- const bool lan_ips_accepted = ip_is_lan(source.ip);
+ const bool lan_ips_accepted = ip_is_lan(&source->ip);
for (uint32_t i = 0; i < num_nodes; ++i) {
if (!lan_ips_accepted) {
- if (ip_is_lan(nodes[i].ip_port.ip)) {
+ if (ip_is_lan(&nodes[i].ip_port.ip)) {
continue;
}
}
@@ -822,7 +813,7 @@ static int client_ping_nodes(Onion_Client *onion_c, uint32_t num, const Node_for
}
if (j == list_length && good_to_ping(onion_c->mono_time, last_pinged, last_pinged_index, nodes[i].public_key)) {
- client_send_announce_request(onion_c, num, nodes[i].ip_port, nodes[i].public_key, nullptr, -1);
+ client_send_announce_request(onion_c, num, &nodes[i].ip_port, nodes[i].public_key, nullptr, -1);
}
}
}
@@ -830,7 +821,7 @@ static int client_ping_nodes(Onion_Client *onion_c, uint32_t num, const Node_for
return 0;
}
-static int handle_announce_response(void *object, IP_Port source, const uint8_t *packet, uint16_t length,
+static int handle_announce_response(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length,
void *userdata)
{
Onion_Client *onion_c = (Onion_Client *)object;
@@ -875,7 +866,7 @@ static int handle_announce_response(void *object, IP_Port source, const uint8_t
uint32_t path_used = set_path_timeouts(onion_c, num, path_num);
- if (client_add_to_list(onion_c, num, public_key, ip_port, plain[0], plain + 1, path_used) == -1) {
+ if (client_add_to_list(onion_c, num, public_key, &ip_port, plain[0], plain + 1, path_used) == -1) {
return 1;
}
@@ -899,7 +890,8 @@ static int handle_announce_response(void *object, IP_Port source, const uint8_t
#define DATA_IN_RESPONSE_MIN_SIZE ONION_DATA_IN_RESPONSE_MIN_SIZE
-static int handle_data_response(void *object, IP_Port source, const uint8_t *packet, uint16_t length, void *userdata)
+static int handle_data_response(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length,
+ void *userdata)
{
Onion_Client *onion_c = (Onion_Client *)object;
@@ -986,9 +978,7 @@ static int handle_dhtpk_announce(void *object, const uint8_t *source_pubkey, con
return 1;
}
- int i;
-
- for (i = 0; i < num_nodes; ++i) {
+ for (int i = 0; i < num_nodes; ++i) {
const Family family = nodes[i].ip_port.ip.family;
if (net_family_is_ipv4(family) || net_family_is_ipv6(family)) {
@@ -997,7 +987,7 @@ static int handle_dhtpk_announce(void *object, const uint8_t *source_pubkey, con
if (onion_c->friends_list[friend_num].tcp_relay_node_callback) {
void *obj = onion_c->friends_list[friend_num].tcp_relay_node_callback_object;
uint32_t number = onion_c->friends_list[friend_num].tcp_relay_node_callback_number;
- onion_c->friends_list[friend_num].tcp_relay_node_callback(obj, number, nodes[i].ip_port, nodes[i].public_key);
+ onion_c->friends_list[friend_num].tcp_relay_node_callback(obj, number, &nodes[i].ip_port, nodes[i].public_key);
}
}
}
@@ -1012,22 +1002,23 @@ static int handle_tcp_onion(void *object, const uint8_t *data, uint16_t length,
return 1;
}
- IP_Port ip_port = {{{0}}};
+ IP_Port ip_port = {0};
ip_port.ip.family = net_family_tcp_family;
if (data[0] == NET_PACKET_ANNOUNCE_RESPONSE) {
- return handle_announce_response(object, ip_port, data, length, userdata);
+ return handle_announce_response(object, &ip_port, data, length, userdata);
}
if (data[0] == NET_PACKET_ONION_DATA_RESPONSE) {
- return handle_data_response(object, ip_port, data, length, userdata);
+ return handle_data_response(object, &ip_port, data, length, userdata);
}
return 1;
}
-/* Send data of length length to friendnum.
- * This data will be received by the friend using the onion_data_handlers callbacks.
+/** Send data of length length to friendnum.
+ * Maximum length of data is ONION_CLIENT_MAX_DATA_SIZE.
+ * This data will be received by the friend using the Onion_Data_Handlers callbacks.
*
* Even if this function succeeds, the friend might not receive any data.
*
@@ -1051,7 +1042,7 @@ int send_onion_data(Onion_Client *onion_c, int friend_num, const uint8_t *data,
unsigned int good_nodes[MAX_ONION_CLIENTS];
unsigned int num_good = 0;
unsigned int num_nodes = 0;
- Onion_Node *list_nodes = onion_c->friends_list[friend_num].clients_list;
+ const Onion_Node *list_nodes = onion_c->friends_list[friend_num].clients_list;
for (unsigned int i = 0; i < MAX_ONION_CLIENTS; ++i) {
if (onion_node_timed_out(&list_nodes[i], onion_c->mono_time)) {
@@ -1100,7 +1091,7 @@ int send_onion_data(Onion_Client *onion_c, int friend_num, const uint8_t *data,
continue;
}
- if (send_onion_packet_tcp_udp(onion_c, &path, list_nodes[good_nodes[i]].ip_port, o_packet, len) == 0) {
+ if (send_onion_packet_tcp_udp(onion_c, &path, &list_nodes[good_nodes[i]].ip_port, o_packet, len) == 0) {
++good;
}
}
@@ -1108,7 +1099,7 @@ int send_onion_data(Onion_Client *onion_c, int friend_num, const uint8_t *data,
return good;
}
-/* Try to send the dht public key via the DHT instead of onion
+/** Try to send the dht public key via the DHT instead of onion
*
* Even if this function succeeds, the friend might not receive any data.
*
@@ -1139,18 +1130,20 @@ static int send_dht_dhtpk(const Onion_Client *onion_c, int friend_num, const uin
return -1;
}
- uint8_t packet[MAX_CRYPTO_REQUEST_SIZE];
- len = create_request(dht_get_self_public_key(onion_c->dht), dht_get_self_secret_key(onion_c->dht), packet,
+ uint8_t packet_data[MAX_CRYPTO_REQUEST_SIZE];
+ len = create_request(dht_get_self_public_key(onion_c->dht), dht_get_self_secret_key(onion_c->dht), packet_data,
onion_c->friends_list[friend_num].dht_public_key, temp, SIZEOF_VLA(temp), CRYPTO_PACKET_DHTPK);
+ assert(len <= UINT16_MAX);
+ const Packet packet = {packet_data, (uint16_t)len};
if (len == -1) {
return -1;
}
- return route_tofriend(onion_c->dht, onion_c->friends_list[friend_num].dht_public_key, packet, len);
+ return route_to_friend(onion_c->dht, onion_c->friends_list[friend_num].dht_public_key, &packet);
}
-static int handle_dht_dhtpk(void *object, IP_Port source, const uint8_t *source_pubkey, const uint8_t *packet,
+static int handle_dht_dhtpk(void *object, const IP_Port *source, const uint8_t *source_pubkey, const uint8_t *packet,
uint16_t length, void *userdata)
{
Onion_Client *onion_c = (Onion_Client *)object;
@@ -1179,7 +1172,7 @@ static int handle_dht_dhtpk(void *object, IP_Port source, const uint8_t *source_
return handle_dhtpk_announce(onion_c, packet, plain, len, userdata);
}
-/* Send the packets to tell our friends what our DHT public key is.
+/** Send the packets to tell our friends what our DHT public key is.
*
* if onion_dht_both is 0, use only the onion to send the packet.
* if it is 1, use only the dht.
@@ -1200,7 +1193,7 @@ static int send_dhtpk_announce(Onion_Client *onion_c, uint16_t friend_num, uint8
net_pack_u64(data + 1, no_replay);
memcpy(data + 1 + sizeof(uint64_t), dht_get_self_public_key(onion_c->dht), CRYPTO_PUBLIC_KEY_SIZE);
Node_format nodes[MAX_SENT_NODES];
- uint16_t num_relays = copy_connected_tcp_relays(onion_c->c, nodes, (MAX_SENT_NODES / 2));
+ uint16_t num_relays = copy_connected_tcp_relays(onion_c->c, nodes, MAX_SENT_NODES / 2);
uint16_t num_nodes = closelist_nodes(onion_c->dht, &nodes[num_relays], MAX_SENT_NODES - num_relays);
num_nodes += num_relays;
int nodes_len = 0;
@@ -1236,16 +1229,14 @@ static int send_dhtpk_announce(Onion_Client *onion_c, uint16_t friend_num, uint8
return num1 + num2;
}
-/* Get the friend_num of a friend.
+/** Get the friend_num of a friend.
*
* return -1 on failure.
* return friend number on success.
*/
int onion_friend_num(const Onion_Client *onion_c, const uint8_t *public_key)
{
- unsigned int i;
-
- for (i = 0; i < onion_c->num_friends; ++i) {
+ for (unsigned int i = 0; i < onion_c->num_friends; ++i) {
if (onion_c->friends_list[i].status == 0) {
continue;
}
@@ -1258,7 +1249,7 @@ int onion_friend_num(const Onion_Client *onion_c, const uint8_t *public_key)
return -1;
}
-/* Set the size of the friend list to num.
+/** Set the size of the friend list to num.
*
* return -1 if realloc fails.
* return 0 if it succeeds.
@@ -1281,7 +1272,7 @@ static int realloc_onion_friends(Onion_Client *onion_c, uint32_t num)
return 0;
}
-/* Add a friend who we want to connect to.
+/** Add a friend who we want to connect to.
*
* return -1 on failure.
* return the friend number on success or if the friend was already added.
@@ -1319,7 +1310,7 @@ int onion_addfriend(Onion_Client *onion_c, const uint8_t *public_key)
return index;
}
-/* Delete a friend.
+/** Delete a friend.
*
* return -1 on failure.
* return the deleted friend number on success.
@@ -1355,7 +1346,7 @@ int onion_delfriend(Onion_Client *onion_c, int friend_num)
return friend_num;
}
-/* Set the function for this friend that will be callbacked with object and number
+/** Set the function for this friend that will be callbacked with object and number
* when that friends gives us one of the TCP relays he is connected to.
*
* object and number will be passed as argument to this function.
@@ -1376,7 +1367,7 @@ int recv_tcp_relay_handler(Onion_Client *onion_c, int friend_num,
return 0;
}
-/* Set the function for this friend that will be callbacked with object and number
+/** Set the function for this friend that will be callbacked with object and number
* when that friend gives us his DHT temporary public key.
*
* object and number will be passed as argument to this function.
@@ -1397,7 +1388,7 @@ int onion_dht_pk_callback(Onion_Client *onion_c, int friend_num,
return 0;
}
-/* Set a friend's DHT public key.
+/** Set a friend's DHT public key.
*
* return -1 on failure.
* return 0 on success.
@@ -1425,7 +1416,7 @@ int onion_set_friend_DHT_pubkey(Onion_Client *onion_c, int friend_num, const uin
return 0;
}
-/* Copy friends DHT public key into dht_key.
+/** Copy friends DHT public key into dht_key.
*
* return 0 on failure (no key copied).
* return 1 on success (key copied).
@@ -1448,7 +1439,7 @@ unsigned int onion_getfriend_DHT_pubkey(const Onion_Client *onion_c, int friend_
return 1;
}
-/* Get the ip of friend friendnum and put it in ip_port
+/** Get the ip of friend friendnum and put it in ip_port
*
* return -1, -- if public_key does NOT refer to a friend
* return 0, -- if public_key refers to a friend and we failed to find the friend (yet)
@@ -1467,7 +1458,7 @@ int onion_getfriendip(const Onion_Client *onion_c, int friend_num, IP_Port *ip_p
}
-/* Set if friend is online or not.
+/** Set if friend is online or not.
* NOTE: This function is there and should be used so that we don't send useless packets to the friend if he is online.
*
* is_online 1 means friend is online.
@@ -1503,10 +1494,8 @@ static void populate_path_nodes(Onion_Client *onion_c)
unsigned int num_nodes = randfriends_nodes(onion_c->dht, nodes_list, MAX_FRIEND_CLIENTS);
- unsigned int i;
-
- for (i = 0; i < num_nodes; ++i) {
- onion_add_path_node(onion_c, nodes_list[i].ip_port, nodes_list[i].public_key);
+ for (unsigned int i = 0; i < num_nodes; ++i) {
+ onion_add_path_node(onion_c, &nodes_list[i].ip_port, nodes_list[i].public_key);
}
}
@@ -1515,10 +1504,9 @@ static void populate_path_nodes_tcp(Onion_Client *onion_c)
Node_format nodes_list[MAX_SENT_NODES];
unsigned int num_nodes = copy_connected_tcp_relays(onion_c->c, nodes_list, MAX_SENT_NODES);
- unsigned int i;
- for (i = 0; i < num_nodes; ++i) {
- onion_add_bs_path_node(onion_c, nodes_list[i].ip_port, nodes_list[i].public_key);
+ for (unsigned int i = 0; i < num_nodes; ++i) {
+ onion_add_bs_path_node(onion_c, &nodes_list[i].ip_port, nodes_list[i].public_key);
}
}
@@ -1596,8 +1584,8 @@ static void do_friend(Onion_Client *onion_c, uint16_t friendnum)
}
if (mono_time_is_timeout(onion_c->mono_time, list_nodes[i].last_pinged, interval)
- || (ping_random && random_u32() % (MAX_ONION_CLIENTS - i) == 0)) {
- if (client_send_announce_request(onion_c, friendnum + 1, list_nodes[i].ip_port,
+ || (ping_random && random_range_u32(MAX_ONION_CLIENTS - i) == 0)) {
+ if (client_send_announce_request(onion_c, friendnum + 1, &list_nodes[i].ip_port,
list_nodes[i].public_key, nullptr, -1) == 0) {
list_nodes[i].last_pinged = mono_time_get(onion_c->mono_time);
++list_nodes[i].unsuccessful_pings;
@@ -1614,13 +1602,11 @@ static void do_friend(Onion_Client *onion_c, uint16_t friendnum)
n = (MAX_ONION_CLIENTS / 2);
}
- if (count <= random_u32() % MAX_ONION_CLIENTS) {
+ if (count <= random_range_u32(MAX_ONION_CLIENTS)) {
if (num_nodes != 0) {
- unsigned int j;
-
- for (j = 0; j < n; ++j) {
- const uint32_t num = random_u32() % num_nodes;
- client_send_announce_request(onion_c, friendnum + 1, onion_c->path_nodes[num].ip_port,
+ for (unsigned int j = 0; j < n; ++j) {
+ const uint32_t num = random_range_u32(num_nodes);
+ client_send_announce_request(onion_c, friendnum + 1, &onion_c->path_nodes[num].ip_port,
onion_c->path_nodes[num].public_key, nullptr, -1);
}
@@ -1649,7 +1635,7 @@ static void do_friend(Onion_Client *onion_c, uint16_t friendnum)
}
-/* Function to call when onion data packet with contents beginning with byte is received. */
+/** Function to call when onion data packet with contents beginning with byte is received. */
void oniondata_registerhandler(Onion_Client *onion_c, uint8_t byte, oniondata_handler_cb *cb, void *object)
{
onion_c->onion_data_handlers[byte].function = cb;
@@ -1708,7 +1694,7 @@ static void do_announce(Onion_Client *onion_c)
if (mono_time_is_timeout(onion_c->mono_time, list_nodes[i].last_pinged, interval)
|| (mono_time_is_timeout(onion_c->mono_time, onion_c->last_announce, ONION_NODE_PING_INTERVAL)
- && random_u32() % (MAX_ONION_CLIENTS_ANNOUNCE - i) == 0)) {
+ && random_range_u32(MAX_ONION_CLIENTS_ANNOUNCE - i) == 0)) {
uint32_t path_to_use = list_nodes[i].path_used;
if (list_nodes[i].unsuccessful_pings == ONION_NODE_MAX_PINGS - 1
@@ -1717,7 +1703,7 @@ static void do_announce(Onion_Client *onion_c)
path_to_use = -1;
}
- if (client_send_announce_request(onion_c, 0, list_nodes[i].ip_port, list_nodes[i].public_key,
+ if (client_send_announce_request(onion_c, 0, &list_nodes[i].ip_port, list_nodes[i].public_key,
list_nodes[i].ping_id, path_to_use) == 0) {
list_nodes[i].last_pinged = mono_time_get(onion_c->mono_time);
++list_nodes[i].unsuccessful_pings;
@@ -1728,7 +1714,7 @@ static void do_announce(Onion_Client *onion_c)
if (count != MAX_ONION_CLIENTS_ANNOUNCE) {
uint16_t num_nodes;
- Node_format *path_nodes;
+ const Node_format *path_nodes;
if (random_u08() % 2 == 0 || onion_c->path_nodes_index == 0) {
num_nodes = min_u16(onion_c->path_nodes_index_bs, MAX_PATH_NODES);
@@ -1738,18 +1724,18 @@ static void do_announce(Onion_Client *onion_c)
path_nodes = onion_c->path_nodes;
}
- if (count <= random_u32() % MAX_ONION_CLIENTS_ANNOUNCE) {
+ if (count <= random_range_u32(MAX_ONION_CLIENTS_ANNOUNCE)) {
if (num_nodes != 0) {
for (unsigned int i = 0; i < (MAX_ONION_CLIENTS_ANNOUNCE / 2); ++i) {
- const uint32_t num = random_u32() % num_nodes;
- client_send_announce_request(onion_c, 0, path_nodes[num].ip_port, path_nodes[num].public_key, nullptr, -1);
+ const uint32_t num = random_range_u32(num_nodes);
+ client_send_announce_request(onion_c, 0, &path_nodes[num].ip_port, path_nodes[num].public_key, nullptr, -1);
}
}
}
}
}
-/* return 0 if we are not connected to the network.
+/** return 0 if we are not connected to the network.
* return 1 if we are.
*/
static int onion_isconnected(const Onion_Client *onion_c)
@@ -1794,7 +1780,7 @@ static int onion_isconnected(const Onion_Client *onion_c)
#define ONION_CONNECTION_SECONDS 3
-/* return 0 if we are not connected to the network.
+/** return 0 if we are not connected to the network.
* return 1 if we are connected with TCP only.
* return 2 if we are also connected with UDP.
*/
diff --git a/protocols/Tox/libtox/src/toxcore/onion_client.h b/protocols/Tox/libtox/src/toxcore/onion_client.h
index c0f8f52c8b..c724e97344 100644
--- a/protocols/Tox/libtox/src/toxcore/onion_client.h
+++ b/protocols/Tox/libtox/src/toxcore/onion_client.h
@@ -3,7 +3,7 @@
* Copyright © 2013 Tox project.
*/
-/*
+/**
* Implementation of the client part of docs/Prevent_Tracking.txt (The part that
* uses the onion stuff to connect to the friend)
*/
@@ -19,13 +19,13 @@
#define ONION_NODE_PING_INTERVAL 15
#define ONION_NODE_TIMEOUT ONION_NODE_PING_INTERVAL
-/* The interval in seconds at which to tell our friends where we are */
+/** The interval in seconds at which to tell our friends where we are */
#define ONION_DHTPK_SEND_INTERVAL 30
#define DHT_DHTPK_SEND_INTERVAL 20
#define NUMBER_ONION_PATHS 6
-/* The timeout the first time the path is added and
+/** The timeout the first time the path is added and
* then for all the next consecutive times */
#define ONION_PATH_FIRST_TIMEOUT 4
#define ONION_PATH_TIMEOUT 10
@@ -39,14 +39,14 @@
#define MAX_PATH_NODES 32
-/* If no announce response packets are received within this interval tox will
+/** If no announce response packets are received within this interval tox will
* be considered offline. We give time for a node to be pinged often enough
* that it times out, which leads to the network being thoroughly tested as it
* is replaced.
*/
#define ONION_OFFLINE_TIMEOUT (ONION_NODE_PING_INTERVAL * (ONION_NODE_MAX_PINGS+2))
-/* Onion data packet ids. */
+/** Onion data packet ids. */
#define ONION_DATA_FRIEND_REQ CRYPTO_PACKET_FRIEND_REQ
#define ONION_DATA_DHTPK CRYPTO_PACKET_DHTPK
@@ -55,41 +55,41 @@ typedef struct Onion_Client Onion_Client;
DHT *onion_get_dht(const Onion_Client *onion_c);
Net_Crypto *onion_get_net_crypto(const Onion_Client *onion_c);
-/* Add a node to the path_nodes bootstrap array.
+/** Add a node to the path_nodes bootstrap array.
*
* return -1 on failure
* return 0 on success
*/
-int onion_add_bs_path_node(Onion_Client *onion_c, IP_Port ip_port, const uint8_t *public_key);
+int onion_add_bs_path_node(Onion_Client *onion_c, const IP_Port *ip_port, const uint8_t *public_key);
-/* Put up to max_num nodes in nodes.
+/** Put up to max_num nodes in nodes.
*
* return the number of nodes.
*/
uint16_t onion_backup_nodes(const Onion_Client *onion_c, Node_format *nodes, uint16_t max_num);
-/* Add a friend who we want to connect to.
+/** Get the friend_num of a friend.
*
* return -1 on failure.
- * return the friend number on success or if the friend was already added.
+ * return friend number on success.
*/
int onion_friend_num(const Onion_Client *onion_c, const uint8_t *public_key);
-/* Add a friend who we want to connect to.
+/** Add a friend who we want to connect to.
*
* return -1 on failure.
- * return the friend number on success.
+ * return the friend number on success or if the friend was already added.
*/
int onion_addfriend(Onion_Client *onion_c, const uint8_t *public_key);
-/* Delete a friend.
+/** Delete a friend.
*
* return -1 on failure.
* return the deleted friend number on success.
*/
int onion_delfriend(Onion_Client *onion_c, int friend_num);
-/* Set if friend is online or not.
+/** Set if friend is online or not.
* NOTE: This function is there and should be used so that we don't send useless packets to the friend if he is online.
*
* is_online 1 means friend is online.
@@ -100,7 +100,7 @@ int onion_delfriend(Onion_Client *onion_c, int friend_num);
*/
int onion_set_friend_online(Onion_Client *onion_c, int friend_num, uint8_t is_online);
-/* Get the ip of friend friendnum and put it in ip_port
+/** Get the ip of friend friendnum and put it in ip_port
*
* return -1, -- if public_key does NOT refer to a friend
* return 0, -- if public_key refers to a friend and we failed to find the friend (yet)
@@ -109,9 +109,9 @@ int onion_set_friend_online(Onion_Client *onion_c, int friend_num, uint8_t is_on
*/
int onion_getfriendip(const Onion_Client *onion_c, int friend_num, IP_Port *ip_port);
-typedef int recv_tcp_relay_cb(void *object, uint32_t number, IP_Port ip_port, const uint8_t *public_key);
+typedef int recv_tcp_relay_cb(void *object, uint32_t number, const IP_Port *ip_port, const uint8_t *public_key);
-/* Set the function for this friend that will be callbacked with object and number
+/** Set the function for this friend that will be callbacked with object and number
* when that friends gives us one of the TCP relays he is connected to.
*
* object and number will be passed as argument to this function.
@@ -124,7 +124,7 @@ int recv_tcp_relay_handler(Onion_Client *onion_c, int friend_num,
typedef void onion_dht_pk_cb(void *data, int32_t number, const uint8_t *dht_public_key, void *userdata);
-/* Set the function for this friend that will be callbacked with object and number
+/** Set the function for this friend that will be callbacked with object and number
* when that friend gives us his DHT temporary public key.
*
* object and number will be passed as argument to this function.
@@ -135,14 +135,14 @@ typedef void onion_dht_pk_cb(void *data, int32_t number, const uint8_t *dht_publ
int onion_dht_pk_callback(Onion_Client *onion_c, int friend_num, onion_dht_pk_cb *function, void *object,
uint32_t number);
-/* Set a friends DHT public key.
+/** Set a friend's DHT public key.
*
* return -1 on failure.
* return 0 on success.
*/
int onion_set_friend_DHT_pubkey(Onion_Client *onion_c, int friend_num, const uint8_t *dht_key);
-/* Copy friends DHT public key into dht_key.
+/** Copy friends DHT public key into dht_key.
*
* return 0 on failure (no key copied).
* return 1 on success (key copied).
@@ -152,7 +152,7 @@ unsigned int onion_getfriend_DHT_pubkey(const Onion_Client *onion_c, int friend_
#define ONION_DATA_IN_RESPONSE_MIN_SIZE (CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE)
#define ONION_CLIENT_MAX_DATA_SIZE (MAX_DATA_REQUEST_SIZE - ONION_DATA_IN_RESPONSE_MIN_SIZE)
-/* Send data of length length to friendnum.
+/** Send data of length length to friendnum.
* Maximum length of data is ONION_CLIENT_MAX_DATA_SIZE.
* This data will be received by the friend using the Onion_Data_Handlers callbacks.
*
@@ -166,7 +166,7 @@ int send_onion_data(Onion_Client *onion_c, int friend_num, const uint8_t *data,
typedef int oniondata_handler_cb(void *object, const uint8_t *source_pubkey, const uint8_t *data,
uint16_t len, void *userdata);
-/* Function to call when onion data packet with contents beginning with byte is received. */
+/** Function to call when onion data packet with contents beginning with byte is received. */
void oniondata_registerhandler(Onion_Client *onion_c, uint8_t byte, oniondata_handler_cb *cb, void *object);
void do_onion_client(Onion_Client *onion_c);
@@ -176,7 +176,7 @@ Onion_Client *new_onion_client(const Logger *logger, Mono_Time *mono_time, Net_C
void kill_onion_client(Onion_Client *onion_c);
-/* return 0 if we are not connected to the network.
+/** return 0 if we are not connected to the network.
* return 1 if we are connected with TCP only.
* return 2 if we are also connected with UDP.
*/
diff --git a/protocols/Tox/libtox/src/toxcore/ping.api.h b/protocols/Tox/libtox/src/toxcore/ping.api.h
deleted file mode 100644
index d4d071b11d..0000000000
--- a/protocols/Tox/libtox/src/toxcore/ping.api.h
+++ /dev/null
@@ -1,50 +0,0 @@
-%{
-/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2018 The TokTok team.
- * Copyright © 2013 Tox project.
- * Copyright © 2013 plutooo
- */
-
-/*
- * Buffered pinging using cyclic arrays.
- */
-#ifndef C_TOXCORE_TOXCORE_PING_H
-#define C_TOXCORE_TOXCORE_PING_H
-
-#include "DHT.h"
-#include "network.h"
-
-#include <stdint.h>
-%}
-
-class iP_Port { struct this; }
-class dHT { struct this; }
-class mono_Time { struct this; }
-
-class ping {
-
-struct this;
-
-static this new(const mono_Time::this *mono_time, dHT::this *dht);
-void kill();
-
-/** Add nodes to the to_ping list.
- * All nodes in this list are pinged every TIME_TOPING seconds
- * and are then removed from the list.
- * If the list is full the nodes farthest from our public_key are replaced.
- * The purpose of this list is to enable quick integration of new nodes into the
- * network while preventing amplification attacks.
- *
- * return 0 if node was added.
- * return -1 if node was not added.
- */
-int32_t add(const uint8_t *public_key, iP_Port::this ip_port);
-void iterate();
-
-int32_t send_request(iP_Port::this ipp, const uint8_t *public_key);
-
-}
-
-%{
-#endif // C_TOXCORE_TOXCORE_PING_H
-%}
diff --git a/protocols/Tox/libtox/src/toxcore/ping.c b/protocols/Tox/libtox/src/toxcore/ping.c
index 305cce47c4..249d4a0647 100644
--- a/protocols/Tox/libtox/src/toxcore/ping.c
+++ b/protocols/Tox/libtox/src/toxcore/ping.c
@@ -4,13 +4,9 @@
* Copyright © 2013 plutooo
*/
-/*
+/**
* Buffered pinging using cyclic arrays.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include "ping.h"
#include <stdlib.h>
@@ -24,10 +20,10 @@
#define PING_NUM_MAX 512
-/* Maximum newly announced nodes to ping per TIME_TO_PING seconds. */
+/** Maximum newly announced nodes to ping per TIME_TO_PING seconds. */
#define MAX_TO_PING 32
-/* Ping newly announced nodes to ping per TIME_TO_PING seconds*/
+/** Ping newly announced nodes to ping per TIME_TO_PING seconds*/
#define TIME_TO_PING 2
@@ -45,14 +41,14 @@ struct Ping {
#define DHT_PING_SIZE (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + PING_PLAIN_SIZE + CRYPTO_MAC_SIZE)
#define PING_DATA_SIZE (CRYPTO_PUBLIC_KEY_SIZE + sizeof(IP_Port))
-int32_t ping_send_request(Ping *ping, IP_Port ipp, const uint8_t *public_key)
+void ping_send_request(Ping *ping, const IP_Port *ipp, const uint8_t *public_key)
{
uint8_t pk[DHT_PING_SIZE];
int rc;
uint64_t ping_id;
if (id_equal(public_key, dht_get_self_public_key(ping->dht))) {
- return 1;
+ return;
}
uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE];
@@ -62,11 +58,12 @@ int32_t ping_send_request(Ping *ping, IP_Port ipp, const uint8_t *public_key)
// Generate random ping_id.
uint8_t data[PING_DATA_SIZE];
id_copy(data, public_key);
- memcpy(data + CRYPTO_PUBLIC_KEY_SIZE, &ipp, sizeof(IP_Port));
+ memcpy(data + CRYPTO_PUBLIC_KEY_SIZE, ipp, sizeof(IP_Port));
ping_id = ping_array_add(ping->ping_array, ping->mono_time, data, sizeof(data));
if (ping_id == 0) {
- return 1;
+ crypto_memzero(shared_key, sizeof(shared_key));
+ return;
}
uint8_t ping_plain[PING_PLAIN_SIZE];
@@ -83,18 +80,20 @@ int32_t ping_send_request(Ping *ping, IP_Port ipp, const uint8_t *public_key)
ping_plain, sizeof(ping_plain),
pk + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE);
+ crypto_memzero(shared_key, sizeof(shared_key));
+
if (rc != PING_PLAIN_SIZE + CRYPTO_MAC_SIZE) {
- return 1;
+ return;
}
- return sendpacket(dht_get_net(ping->dht), ipp, pk, sizeof(pk));
+ // We never check this return value and failures in sendpacket are already logged
+ sendpacket(dht_get_net(ping->dht), ipp, pk, sizeof(pk));
}
-static int ping_send_response(Ping *ping, IP_Port ipp, const uint8_t *public_key, uint64_t ping_id,
- uint8_t *shared_encryption_key)
+static int ping_send_response(const Ping *ping, const IP_Port *ipp, const uint8_t *public_key,
+ uint64_t ping_id, const uint8_t *shared_encryption_key)
{
- uint8_t pk[DHT_PING_SIZE];
- int rc;
+ uint8_t pk[DHT_PING_SIZE];
if (id_equal(public_key, dht_get_self_public_key(ping->dht))) {
return 1;
@@ -109,10 +108,10 @@ static int ping_send_response(Ping *ping, IP_Port ipp, const uint8_t *public_key
random_nonce(pk + 1 + CRYPTO_PUBLIC_KEY_SIZE); // Generate new nonce
// Encrypt ping_id using recipient privkey
- rc = encrypt_data_symmetric(shared_encryption_key,
- pk + 1 + CRYPTO_PUBLIC_KEY_SIZE,
- ping_plain, sizeof(ping_plain),
- pk + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE);
+ const int rc = encrypt_data_symmetric(shared_encryption_key,
+ pk + 1 + CRYPTO_PUBLIC_KEY_SIZE,
+ ping_plain, sizeof(ping_plain),
+ pk + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE);
if (rc != PING_PLAIN_SIZE + CRYPTO_MAC_SIZE) {
return 1;
@@ -121,10 +120,10 @@ static int ping_send_response(Ping *ping, IP_Port ipp, const uint8_t *public_key
return sendpacket(dht_get_net(ping->dht), ipp, pk, sizeof(pk));
}
-static int handle_ping_request(void *object, IP_Port source, const uint8_t *packet, uint16_t length, void *userdata)
+static int handle_ping_request(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length,
+ void *userdata)
{
- DHT *dht = (DHT *)object;
- int rc;
+ DHT *dht = (DHT *)object;
if (length != DHT_PING_SIZE) {
return 1;
@@ -137,34 +136,39 @@ static int handle_ping_request(void *object, IP_Port source, const uint8_t *pack
}
uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE];
-
uint8_t ping_plain[PING_PLAIN_SIZE];
+
// Decrypt ping_id
dht_get_shared_key_recv(dht, shared_key, packet + 1);
- rc = decrypt_data_symmetric(shared_key,
- packet + 1 + CRYPTO_PUBLIC_KEY_SIZE,
- packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE,
- PING_PLAIN_SIZE + CRYPTO_MAC_SIZE,
- ping_plain);
+ const int rc = decrypt_data_symmetric(shared_key,
+ packet + 1 + CRYPTO_PUBLIC_KEY_SIZE,
+ packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE,
+ PING_PLAIN_SIZE + CRYPTO_MAC_SIZE,
+ ping_plain);
if (rc != sizeof(ping_plain)) {
+ crypto_memzero(shared_key, sizeof(shared_key));
return 1;
}
if (ping_plain[0] != NET_PACKET_PING_REQUEST) {
+ crypto_memzero(shared_key, sizeof(shared_key));
return 1;
}
- uint64_t ping_id;
+ uint64_t ping_id;
memcpy(&ping_id, ping_plain + 1, sizeof(ping_id));
// Send response
ping_send_response(ping, source, packet + 1, ping_id, shared_key);
ping_add(ping, packet + 1, source);
+ crypto_memzero(shared_key, sizeof(shared_key));
+
return 0;
}
-static int handle_ping_response(void *object, IP_Port source, const uint8_t *packet, uint16_t length, void *userdata)
+static int handle_ping_response(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length,
+ void *userdata)
{
DHT *dht = (DHT *)object;
int rc;
@@ -192,6 +196,8 @@ static int handle_ping_response(void *object, IP_Port source, const uint8_t *pac
PING_PLAIN_SIZE + CRYPTO_MAC_SIZE,
ping_plain);
+ crypto_memzero(shared_key, sizeof(shared_key));
+
if (rc != sizeof(ping_plain)) {
return 1;
}
@@ -215,7 +221,7 @@ static int handle_ping_response(void *object, IP_Port source, const uint8_t *pac
IP_Port ipp;
memcpy(&ipp, data + CRYPTO_PUBLIC_KEY_SIZE, sizeof(IP_Port));
- if (!ipport_equal(&ipp, &source)) {
+ if (!ipport_equal(&ipp, source)) {
return 1;
}
@@ -223,27 +229,26 @@ static int handle_ping_response(void *object, IP_Port source, const uint8_t *pac
return 0;
}
-/* Check if public_key with ip_port is in the list.
+/** Check if public_key with ip_port is in the list.
*
* return 1 if it is.
* return 0 if it isn't.
*/
static int in_list(const Client_data *list, uint16_t length, const Mono_Time *mono_time, const uint8_t *public_key,
- IP_Port ip_port)
+ const IP_Port *ip_port)
{
- unsigned int i;
-
- for (i = 0; i < length; ++i) {
+ for (unsigned int i = 0; i < length; ++i) {
if (id_equal(list[i].public_key, public_key)) {
const IPPTsPng *ipptp;
- if (net_family_is_ipv4(ip_port.ip.family)) {
+ if (net_family_is_ipv4(ip_port->ip.family)) {
ipptp = &list[i].assoc4;
} else {
ipptp = &list[i].assoc6;
}
- if (!mono_time_is_timeout(mono_time, ipptp->timestamp, BAD_NODE_TIMEOUT) && ipport_equal(&ipptp->ip_port, &ip_port)) {
+ if (!mono_time_is_timeout(mono_time, ipptp->timestamp, BAD_NODE_TIMEOUT)
+ && ipport_equal(&ipptp->ip_port, ip_port)) {
return 1;
}
}
@@ -252,7 +257,7 @@ static int in_list(const Client_data *list, uint16_t length, const Mono_Time *mo
return 0;
}
-/* Add nodes to the to_ping list.
+/** Add nodes to the to_ping list.
* All nodes in this list are pinged every TIME_TO_PING seconds
* and are then removed from the list.
* If the list is full the nodes farthest from our public_key are replaced.
@@ -262,9 +267,9 @@ static int in_list(const Client_data *list, uint16_t length, const Mono_Time *mo
* return 0 if node was added.
* return -1 if node was not added.
*/
-int32_t ping_add(Ping *ping, const uint8_t *public_key, IP_Port ip_port)
+int32_t ping_add(Ping *ping, const uint8_t *public_key, const IP_Port *ip_port)
{
- if (!ip_isset(&ip_port.ip)) {
+ if (!ip_isset(&ip_port->ip)) {
return -1;
}
@@ -283,12 +288,10 @@ int32_t ping_add(Ping *ping, const uint8_t *public_key, IP_Port ip_port)
return -1;
}
- unsigned int i;
-
- for (i = 0; i < MAX_TO_PING; ++i) {
+ for (unsigned int i = 0; i < MAX_TO_PING; ++i) {
if (!ip_isset(&ping->to_ping[i].ip_port.ip)) {
memcpy(ping->to_ping[i].public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE);
- ipport_copy(&ping->to_ping[i].ip_port, &ip_port);
+ ipport_copy(&ping->to_ping[i].ip_port, ip_port);
return 0;
}
@@ -305,7 +308,7 @@ int32_t ping_add(Ping *ping, const uint8_t *public_key, IP_Port ip_port)
}
-/* Ping all the valid nodes in the to_ping list every TIME_TO_PING seconds.
+/** Ping all the valid nodes in the to_ping list every TIME_TO_PING seconds.
* This function must be run at least once every TIME_TO_PING seconds.
*/
void ping_iterate(Ping *ping)
@@ -325,11 +328,11 @@ void ping_iterate(Ping *ping)
break;
}
- if (!node_addable_to_close_list(ping->dht, ping->to_ping[i].public_key, ping->to_ping[i].ip_port)) {
+ if (!node_addable_to_close_list(ping->dht, ping->to_ping[i].public_key, &ping->to_ping[i].ip_port)) {
continue;
}
- ping_send_request(ping, ping->to_ping[i].ip_port, ping->to_ping[i].public_key);
+ ping_send_request(ping, &ping->to_ping[i].ip_port, ping->to_ping[i].public_key);
ip_reset(&ping->to_ping[i].ip_port.ip);
}
diff --git a/protocols/Tox/libtox/src/toxcore/ping.h b/protocols/Tox/libtox/src/toxcore/ping.h
index 9badd5aa1b..4e8192323a 100644
--- a/protocols/Tox/libtox/src/toxcore/ping.h
+++ b/protocols/Tox/libtox/src/toxcore/ping.h
@@ -4,43 +4,25 @@
* Copyright © 2013 plutooo
*/
-/*
+/**
* Buffered pinging using cyclic arrays.
*/
#ifndef C_TOXCORE_TOXCORE_PING_H
#define C_TOXCORE_TOXCORE_PING_H
-#include "DHT.h"
-#include "network.h"
-
#include <stdint.h>
-#ifndef IP_PORT_DEFINED
-#define IP_PORT_DEFINED
-typedef struct IP_Port IP_Port;
-#endif /* IP_PORT_DEFINED */
-
-#ifndef DHT_DEFINED
-#define DHT_DEFINED
-typedef struct DHT DHT;
-#endif /* DHT_DEFINED */
-
-#ifndef MONO_TIME_DEFINED
-#define MONO_TIME_DEFINED
-typedef struct Mono_Time Mono_Time;
-#endif /* MONO_TIME_DEFINED */
+#include "DHT.h"
+#include "network.h"
-#ifndef PING_DEFINED
-#define PING_DEFINED
typedef struct Ping Ping;
-#endif /* PING_DEFINED */
Ping *ping_new(const struct Mono_Time *mono_time, DHT *dht);
void ping_kill(Ping *ping);
/** Add nodes to the to_ping list.
- * All nodes in this list are pinged every TIME_TOPING seconds
+ * All nodes in this list are pinged every TIME_TO_PING seconds
* and are then removed from the list.
* If the list is full the nodes farthest from our public_key are replaced.
* The purpose of this list is to enable quick integration of new nodes into the
@@ -49,10 +31,10 @@ void ping_kill(Ping *ping);
* return 0 if node was added.
* return -1 if node was not added.
*/
-int32_t ping_add(Ping *ping, const uint8_t *public_key, struct IP_Port ip_port);
+int32_t ping_add(Ping *ping, const uint8_t *public_key, const IP_Port *ip_port);
void ping_iterate(Ping *ping);
-int32_t ping_send_request(Ping *ping, struct IP_Port ipp, const uint8_t *public_key);
+void ping_send_request(Ping *ping, const IP_Port *ipp, const uint8_t *public_key);
#endif // C_TOXCORE_TOXCORE_PING_H
diff --git a/protocols/Tox/libtox/src/toxcore/ping_array.api.h b/protocols/Tox/libtox/src/toxcore/ping_array.api.h
deleted file mode 100644
index d36e56dcf6..0000000000
--- a/protocols/Tox/libtox/src/toxcore/ping_array.api.h
+++ /dev/null
@@ -1,66 +0,0 @@
-%{
-/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2018 The TokTok team.
- * Copyright © 2013 Tox project.
- */
-
-/*
- * Implementation of an efficient array to store that we pinged something.
- */
-#ifndef C_TOXCORE_TOXCORE_PING_ARRAY_H
-#define C_TOXCORE_TOXCORE_PING_ARRAY_H
-
-#include <stddef.h>
-#include <stdint.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-%}
-
-class mono_Time { struct this; }
-
-class ping { class array {
-
-struct this;
-
-/**
- * Initialize a Ping_Array.
- *
- * @param size represents the total size of the array and should be a power of 2.
- * @param timeout represents the maximum timeout in seconds for the entry.
- *
- * @return 0 on success, -1 on failure.
- */
-static this new(uint32_t size, uint32_t timeout);
-
-/**
- * Free all the allocated memory in a Ping_Array.
- */
-void kill();
-
-/**
- * Add a data with length to the Ping_Array list and return a ping_id.
- *
- * @return ping_id on success, 0 on failure.
- */
-uint64_t add(const mono_Time::this *mono_time, const uint8_t *data, uint32_t length);
-
-/**
- * Check if ping_id is valid and not timed out.
- *
- * On success, copies the data into data of length,
- *
- * @return length of data copied on success, -1 on failure.
- */
-int32_t check(const mono_Time::this *mono_time, uint8_t[length] data, uint64_t ping_id);
-
-} }
-
-%{
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#endif // C_TOXCORE_TOXCORE_PING_ARRAY_H
-%}
diff --git a/protocols/Tox/libtox/src/toxcore/ping_array.c b/protocols/Tox/libtox/src/toxcore/ping_array.c
index 201b507d4c..fe067d2b29 100644
--- a/protocols/Tox/libtox/src/toxcore/ping_array.c
+++ b/protocols/Tox/libtox/src/toxcore/ping_array.c
@@ -3,13 +3,9 @@
* Copyright © 2014 Tox project.
*/
-/*
+/**
* Implementation of an efficient array to store that we pinged something.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include "ping_array.h"
#include <stdlib.h>
@@ -20,7 +16,7 @@
#include "util.h"
typedef struct Ping_Array_Entry {
- void *data;
+ uint8_t *data;
uint32_t length;
uint64_t time;
uint64_t ping_id;
@@ -89,7 +85,7 @@ void ping_array_kill(Ping_Array *array)
free(array);
}
-/* Clear timed out entries.
+/** Clear timed out entries.
*/
static void ping_array_clear_timedout(Ping_Array *array, const Mono_Time *mono_time)
{
@@ -116,7 +112,7 @@ uint64_t ping_array_add(Ping_Array *array, const Mono_Time *mono_time, const uin
clear_entry(array, index);
}
- array->entries[index].data = malloc(length);
+ array->entries[index].data = (uint8_t *)malloc(length);
if (array->entries[index].data == nullptr) {
return 0;
diff --git a/protocols/Tox/libtox/src/toxcore/ping_array.h b/protocols/Tox/libtox/src/toxcore/ping_array.h
index 70c517de9e..98dceaba0c 100644
--- a/protocols/Tox/libtox/src/toxcore/ping_array.h
+++ b/protocols/Tox/libtox/src/toxcore/ping_array.h
@@ -3,8 +3,8 @@
* Copyright © 2013 Tox project.
*/
-/*
- * Implementation of an efficient array to store that we pinged something.
+/** @file
+ * @brief Implementation of an efficient array to store that we pinged something.
*/
#ifndef C_TOXCORE_TOXCORE_PING_ARRAY_H
#define C_TOXCORE_TOXCORE_PING_ARRAY_H
@@ -12,22 +12,16 @@
#include <stddef.h>
#include <stdint.h>
+#include "mono_time.h"
+
#ifdef __cplusplus
extern "C" {
#endif
-#ifndef MONO_TIME_DEFINED
-#define MONO_TIME_DEFINED
-typedef struct Mono_Time Mono_Time;
-#endif /* MONO_TIME_DEFINED */
-
-#ifndef PING_ARRAY_DEFINED
-#define PING_ARRAY_DEFINED
typedef struct Ping_Array Ping_Array;
-#endif /* PING_ARRAY_DEFINED */
/**
- * Initialize a Ping_Array.
+ * @brief Initialize a Ping_Array.
*
* @param size represents the total size of the array and should be a power of 2.
* @param timeout represents the maximum timeout in seconds for the entry.
@@ -37,12 +31,12 @@ typedef struct Ping_Array Ping_Array;
struct Ping_Array *ping_array_new(uint32_t size, uint32_t timeout);
/**
- * Free all the allocated memory in a Ping_Array.
+ * @brief Free all the allocated memory in a @ref Ping_Array.
*/
void ping_array_kill(struct Ping_Array *array);
/**
- * Add a data with length to the Ping_Array list and return a ping_id.
+ * @brief Add a data with length to the @ref Ping_Array list and return a ping_id.
*
* @return ping_id on success, 0 on failure.
*/
@@ -50,7 +44,7 @@ uint64_t ping_array_add(struct Ping_Array *array, const struct Mono_Time *mono_t
uint32_t length);
/**
- * Check if ping_id is valid and not timed out.
+ * @brief Check if @p ping_id is valid and not timed out.
*
* On success, copies the data into data of length,
*
diff --git a/protocols/Tox/libtox/src/toxcore/state.c b/protocols/Tox/libtox/src/toxcore/state.c
index 13ae8e7189..a31768131a 100644
--- a/protocols/Tox/libtox/src/toxcore/state.c
+++ b/protocols/Tox/libtox/src/toxcore/state.c
@@ -6,7 +6,7 @@
#include <string.h>
-/* state load/save */
+/** state load/save */
int state_load(const Logger *log, state_load_cb *state_load_callback, void *outer,
const uint8_t *data, uint32_t length, uint16_t cookie_inner)
{
@@ -34,7 +34,7 @@ int state_load(const Logger *log, state_load_cb *state_load_callback, void *oute
return -1;
}
- if (lendian_to_host16((cookie_type >> 16)) != cookie_inner) {
+ if (lendian_to_host16(cookie_type >> 16) != cookie_inner) {
/* something is not matching up in a bad way, give up */
LOGGER_ERROR(log, "state file garbled: %04x != %04x", cookie_type >> 16, cookie_inner);
return -1;
@@ -43,17 +43,20 @@ int state_load(const Logger *log, state_load_cb *state_load_callback, void *oute
const uint16_t type = lendian_to_host16(cookie_type & 0xFFFF);
switch (state_load_callback(outer, data, length_sub, type)) {
- case STATE_LOAD_STATUS_CONTINUE:
+ case STATE_LOAD_STATUS_CONTINUE: {
data += length_sub;
length -= length_sub;
break;
+ }
- case STATE_LOAD_STATUS_ERROR:
+ case STATE_LOAD_STATUS_ERROR: {
LOGGER_ERROR(log, "Error occcured in state file (type: %u).", type);
return -1;
+ }
- case STATE_LOAD_STATUS_END:
+ case STATE_LOAD_STATUS_END: {
return 0;
+ }
}
}
diff --git a/protocols/Tox/libtox/src/toxcore/state.h b/protocols/Tox/libtox/src/toxcore/state.h
index cbe97b49da..c539828b11 100644
--- a/protocols/Tox/libtox/src/toxcore/state.h
+++ b/protocols/Tox/libtox/src/toxcore/state.h
@@ -52,7 +52,7 @@ typedef enum State_Load_Status {
typedef State_Load_Status state_load_cb(void *outer, const uint8_t *data, uint32_t len, uint16_t type);
-// state load/save
+/** state load/save */
int state_load(const Logger *log, state_load_cb *state_load_callback, void *outer,
const uint8_t *data, uint32_t length, uint16_t cookie_inner);
diff --git a/protocols/Tox/libtox/src/toxcore/tox.api.h b/protocols/Tox/libtox/src/toxcore/tox.api.h
deleted file mode 100644
index 90a6ffc8f8..0000000000
--- a/protocols/Tox/libtox/src/toxcore/tox.api.h
+++ /dev/null
@@ -1,2862 +0,0 @@
-%{
-/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2018 The TokTok team.
- * Copyright © 2013 Tox project.
- */
-
-/*
- * The Tox public API.
- */
-#ifndef C_TOXCORE_TOXCORE_TOX_H
-#define C_TOXCORE_TOXCORE_TOX_H
-
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdint.h>
-
-//!TOKSTYLE-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-%}
-
-
-/*****************************************************************************
- * `tox.h` SHOULD *NOT* BE EDITED MANUALLY – any changes should be made to *
- * `tox.api.h`, located in `toxcore/`. For instructions on how to *
- * generate `tox.h` from `tox.api.h` please refer to `docs/apidsl.md` *
- *****************************************************************************/
-
-
-/**
- * @page core Public core API for Tox clients.
- *
- * Every function that can fail takes a function-specific error code pointer
- * that can be used to diagnose problems with the Tox state or the function
- * arguments. The error code pointer can be NULL, which does not influence the
- * function's behaviour, but can be done if the reason for failure is irrelevant
- * to the client.
- *
- * The exception to this rule are simple allocation functions whose only failure
- * mode is allocation failure. They return NULL in that case, and do not set an
- * error code.
- *
- * Every error code type has an OK value to which functions will set their error
- * code value on success. Clients can keep their error code uninitialised before
- * passing it to a function. The library guarantees that after returning, the
- * value pointed to by the error code pointer has been initialised.
- *
- * Functions with pointer parameters often have a NULL error code, meaning they
- * could not perform any operation, because one of the required parameters was
- * NULL. Some functions operate correctly or are defined as effectless on NULL.
- *
- * Some functions additionally return a value outside their
- * return type domain, or a bool containing true on success and false on
- * failure.
- *
- * All functions that take a Tox instance pointer will cause undefined behaviour
- * when passed a NULL Tox pointer.
- *
- * All integer values are expected in host byte order.
- *
- * Functions with parameters with enum types cause unspecified behaviour if the
- * enumeration value is outside the valid range of the type. If possible, the
- * function will try to use a sane default, but there will be no error code,
- * and one possible action for the function to take is to have no effect.
- *
- * Integer constants and the memory layout of publicly exposed structs are not
- * part of the ABI.
- */
-
-/**
- * @subsection events Events and callbacks
- *
- * Events are handled by callbacks. One callback can be registered per event.
- * All events have a callback function type named `tox_{event}_cb` and a
- * function to register it named `tox_callback_{event}`. Passing a NULL
- * callback will result in no callback being registered for that event. Only
- * one callback per event can be registered, so if a client needs multiple
- * event listeners, it needs to implement the dispatch functionality itself.
- *
- * The last argument to a callback is the user data pointer. It is passed from
- * ${tox.iterate} to each callback in sequence.
- *
- * The user data pointer is never stored or dereferenced by any library code, so
- * can be any pointer, including NULL. Callbacks must all operate on the same
- * object type. In the apidsl code (tox.in.h), this is denoted with `any`. The
- * `any` in ${tox.iterate} must be the same `any` as in all callbacks. In C,
- * lacking parametric polymorphism, this is a pointer to void.
- *
- * Old style callbacks that are registered together with a user data pointer
- * receive that pointer as argument when they are called. They can each have
- * their own user data pointer of their own type.
- */
-
-/**
- * @subsection threading Threading implications
- *
- * It is possible to run multiple concurrent threads with a Tox instance for
- * each thread. It is also possible to run all Tox instances in the same thread.
- * A common way to run Tox (multiple or single instance) is to have one thread
- * running a simple ${tox.iterate} loop, sleeping for ${tox.iteration_interval}
- * milliseconds on each iteration.
- *
- * If you want to access a single Tox instance from multiple threads, access
- * to the instance must be synchronised. While multiple threads can concurrently
- * access multiple different Tox instances, no more than one API function can
- * operate on a single instance at any given time.
- *
- * Functions that write to variable length byte arrays will always have a size
- * function associated with them. The result of this size function is only valid
- * until another mutating function (one that takes a pointer to non-const Tox)
- * is called. Thus, clients must ensure that no other thread calls a mutating
- * function between the call to the size function and the call to the retrieval
- * function.
- *
- * E.g. to get the current nickname, one would write
- *
- * @code
- * size_t length = ${tox.self.name.size}(tox);
- * uint8_t *name = malloc(length);
- * if (!name) abort();
- * ${tox.self.name.get}(tox, name);
- * @endcode
- *
- * If any other thread calls ${tox.self.name.set} while this thread is allocating
- * memory, the length may have become invalid, and the call to
- * ${tox.self.name.get} may cause undefined behaviour.
- */
-
-// The rest of this file is in class tox.
-class tox {
-
-/**
- * The Tox instance type. All the state associated with a connection is held
- * within the instance. Multiple instances can exist and operate concurrently.
- * The maximum number of Tox instances that can exist on a single network
- * device is limited. Note that this is not just a per-process limit, since the
- * limiting factor is the number of usable ports on a device.
- */
-struct this;
-
-
-/*******************************************************************************
- *
- * :: API version
- *
- ******************************************************************************/
-
-
-/**
- * The major version number. Incremented when the API or ABI changes in an
- * incompatible way.
- *
- * The function variants of these constants return the version number of the
- * library. They can be used to display the Tox library version or to check
- * whether the client is compatible with the dynamically linked version of Tox.
- */
-const VERSION_MAJOR = 0;
-
-/**
- * The minor version number. Incremented when functionality is added without
- * breaking the API or ABI. Set to 0 when the major version number is
- * incremented.
- */
-const VERSION_MINOR = 2;
-
-/**
- * The patch or revision number. Incremented when bugfixes are applied without
- * changing any functionality or API or ABI.
- */
-const VERSION_PATCH = 13;
-
-/**
- * A macro to check at preprocessing time whether the client code is compatible
- * with the installed version of Tox. Leading zeros in the version number are
- * ignored. E.g. 0.1.5 is to 0.1.4 what 1.5 is to 1.4, that is: it can add new
- * features, but can't break the API.
- */
-#define TOX_VERSION_IS_API_COMPATIBLE(MAJOR, MINOR, PATCH) \
- ((TOX_VERSION_MAJOR > 0 && TOX_VERSION_MAJOR == MAJOR) && ( \
- /* 1.x.x, 2.x.x, etc. with matching major version. */ \
- TOX_VERSION_MINOR > MINOR || \
- (TOX_VERSION_MINOR == MINOR && TOX_VERSION_PATCH >= PATCH) \
- )) || ((TOX_VERSION_MAJOR == 0 && MAJOR == 0) && ( \
- /* 0.x.x makes minor behave like major above. */ \
- ((TOX_VERSION_MINOR > 0 && TOX_VERSION_MINOR == MINOR) && ( \
- TOX_VERSION_PATCH >= PATCH \
- )) || ((TOX_VERSION_MINOR == 0 && MINOR == 0) && ( \
- /* 0.0.x and 0.0.y are only compatible if x == y. */ \
- TOX_VERSION_PATCH == PATCH \
- )) \
- ))
-
-static namespace version {
-
- /**
- * Return whether the compiled library version is compatible with the passed
- * version numbers.
- */
- bool is_compatible(uint32_t major, uint32_t minor, uint32_t patch);
-
-}
-
-/**
- * A convenience macro to call tox_version_is_compatible with the currently
- * compiling API version.
- */
-#define TOX_VERSION_IS_ABI_COMPATIBLE() \
- tox_version_is_compatible(TOX_VERSION_MAJOR, TOX_VERSION_MINOR, TOX_VERSION_PATCH)
-
-/*******************************************************************************
- *
- * :: Numeric constants
- *
- * The values of these are not part of the ABI. Prefer to use the function
- * versions of them for code that should remain compatible with future versions
- * of toxcore.
- *
- ******************************************************************************/
-
-
-/**
- * The size of a Tox Public Key in bytes.
- */
-const PUBLIC_KEY_SIZE = 32;
-
-/**
- * The size of a Tox Secret Key in bytes.
- */
-const SECRET_KEY_SIZE = 32;
-
-/**
- * The size of a Tox Conference unique id in bytes.
- *
- * @deprecated Use $CONFERENCE_ID_SIZE instead.
- */
-const CONFERENCE_UID_SIZE = 32;
-
-/**
- * The size of a Tox Conference unique id in bytes.
- */
-const CONFERENCE_ID_SIZE = 32;
-
-/**
- * The size of the nospam in bytes when written in a Tox address.
- */
-const NOSPAM_SIZE = sizeof(uint32_t);
-
-/**
- * The size of a Tox address in bytes. Tox addresses are in the format
- * [Public Key ($PUBLIC_KEY_SIZE bytes)][nospam (4 bytes)][checksum (2 bytes)].
- *
- * The checksum is computed over the Public Key and the nospam value. The first
- * byte is an XOR of all the even bytes (0, 2, 4, ...), the second byte is an
- * XOR of all the odd bytes (1, 3, 5, ...) of the Public Key and nospam.
- */
-const ADDRESS_SIZE = PUBLIC_KEY_SIZE + NOSPAM_SIZE + sizeof(uint16_t);
-
-/**
- * Maximum length of a nickname in bytes.
- *
- * @deprecated The macro will be removed in 0.3.0. Use the function instead.
- */
-const MAX_NAME_LENGTH = 128;
-
-/**
- * Maximum length of a status message in bytes.
- *
- * @deprecated The macro will be removed in 0.3.0. Use the function instead.
- */
-const MAX_STATUS_MESSAGE_LENGTH = 1007;
-
-/**
- * Maximum length of a friend request message in bytes.
- *
- * @deprecated The macro will be removed in 0.3.0. Use the function instead.
- */
-const MAX_FRIEND_REQUEST_LENGTH = 1016;
-
-/**
- * Maximum length of a single message after which it should be split.
- *
- * @deprecated The macro will be removed in 0.3.0. Use the function instead.
- */
-const MAX_MESSAGE_LENGTH = 1372;
-
-/**
- * Maximum size of custom packets. TODO(iphydf): should be LENGTH?
- *
- * @deprecated The macro will be removed in 0.3.0. Use the function instead.
- */
-const MAX_CUSTOM_PACKET_SIZE = 1373;
-
-/**
- * The number of bytes in a hash generated by $hash.
- */
-const HASH_LENGTH = 32;
-
-/**
- * The number of bytes in a file id.
- */
-const FILE_ID_LENGTH = 32;
-
-/**
- * Maximum file name length for file transfers.
- *
- * @deprecated The macro will be removed in 0.3.0. Use the function instead.
- */
-const MAX_FILENAME_LENGTH = 255;
-
-/**
- * Maximum length of a hostname, e.g. proxy or bootstrap node names.
- *
- * This length does not include the NUL byte. Hostnames are NUL-terminated C
- * strings, so they are 255 characters plus one NUL byte.
- *
- * @deprecated The macro will be removed in 0.3.0. Use the function instead.
- */
-const MAX_HOSTNAME_LENGTH = 255;
-
-
-/*******************************************************************************
- *
- * :: Global enumerations
- *
- ******************************************************************************/
-
-
-/**
- * Represents the possible statuses a client can have.
- *
- * @deprecated All UPPER_CASE enum type names are deprecated. Use the
- * Camel_Snake_Case versions, instead.
- */
-enum class USER_STATUS {
- /**
- * User is online and available.
- */
- NONE,
- /**
- * User is away. Clients can set this e.g. after a user defined
- * inactivity time.
- */
- AWAY,
- /**
- * User is busy. Signals to other clients that this client does not
- * currently wish to communicate.
- */
- BUSY,
-}
-
-
-/**
- * Represents message types for ${tox.friend.send.message} and conference
- * messages.
- *
- * @deprecated All UPPER_CASE enum type names are deprecated. Use the
- * Camel_Snake_Case versions, instead.
- */
-enum class MESSAGE_TYPE {
- /**
- * Normal text message. Similar to PRIVMSG on IRC.
- */
- NORMAL,
- /**
- * A message describing an user action. This is similar to /me (CTCP ACTION)
- * on IRC.
- */
- ACTION,
-}
-
-
-/*******************************************************************************
- *
- * :: Startup options
- *
- ******************************************************************************/
-
-
-/**
- * Type of proxy used to connect to TCP relays.
- *
- * @deprecated All UPPER_CASE enum type names are deprecated. Use the
- * Camel_Snake_Case versions, instead.
- */
-enum class PROXY_TYPE {
- /**
- * Don't use a proxy.
- */
- NONE,
- /**
- * HTTP proxy using CONNECT.
- */
- HTTP,
- /**
- * SOCKS proxy for simple socket pipes.
- */
- SOCKS5,
-}
-
-/**
- * Type of savedata to create the Tox instance from.
- *
- * @deprecated All UPPER_CASE enum type names are deprecated. Use the
- * Camel_Snake_Case versions, instead.
- */
-enum class SAVEDATA_TYPE {
- /**
- * No savedata.
- */
- NONE,
- /**
- * Savedata is one that was obtained from ${savedata.get}.
- */
- TOX_SAVE,
- /**
- * Savedata is a secret key of length $SECRET_KEY_SIZE.
- */
- SECRET_KEY,
-}
-
-
-/**
- * Severity level of log messages.
- *
- * @deprecated All UPPER_CASE enum type names are deprecated. Use the
- * Camel_Snake_Case versions, instead.
- */
-enum class LOG_LEVEL {
- /**
- * Very detailed traces including all network activity.
- */
- TRACE,
- /**
- * Debug messages such as which port we bind to.
- */
- DEBUG,
- /**
- * Informational log messages such as video call status changes.
- */
- INFO,
- /**
- * Warnings about internal inconsistency or logic errors.
- */
- WARNING,
- /**
- * Severe unexpected errors caused by external or internal inconsistency.
- */
- ERROR,
-}
-
-/**
- * This event is triggered when the toxcore library logs an internal message.
- * This is mostly useful for debugging. This callback can be called from any
- * function, not just $iterate. This means the user data lifetime must at
- * least extend between registering and unregistering it or $kill.
- *
- * Other toxcore modules such as toxav may concurrently call this callback at
- * any time. Thus, user code must make sure it is equipped to handle concurrent
- * execution, e.g. by employing appropriate mutex locking.
- *
- * @param level The severity of the log message.
- * @param file The source file from which the message originated.
- * @param line The source line from which the message originated.
- * @param func The function from which the message originated.
- * @param message The log message.
- * @param user_data The user data pointer passed to $new in options.
- */
-typedef void log_cb(LOG_LEVEL level, string file, uint32_t line, string func, string message, any user_data);
-
-
-static class options {
- /**
- * This struct contains all the startup options for Tox. You must $new to
- * allocate an object of this type.
- *
- * WARNING: Although this struct happens to be visible in the API, it is
- * effectively private. Do not allocate this yourself or access members
- * directly, as it *will* break binary compatibility frequently.
- *
- * @deprecated The memory layout of this struct (size, alignment, and field
- * order) is not part of the ABI. To remain compatible, prefer to use $new to
- * allocate the object and accessor functions to set the members. The struct
- * will become opaque (i.e. the definition will become private) in v0.3.0.
- */
- struct this [get, set] {
- /**
- * The type of socket to create.
- *
- * If this is set to false, an IPv4 socket is created, which subsequently
- * only allows IPv4 communication.
- * If it is set to true, an IPv6 socket is created, allowing both IPv4 and
- * IPv6 communication.
- */
- bool ipv6_enabled;
-
- /**
- * Enable the use of UDP communication when available.
- *
- * Setting this to false will force Tox to use TCP only. Communications will
- * need to be relayed through a TCP relay node, potentially slowing them down.
- *
- * If a proxy is enabled, UDP will be disabled if either toxcore or the
- * proxy don't support proxying UDP messages.
- */
- bool udp_enabled;
-
- /**
- * Enable local network peer discovery.
- *
- * Disabling this will cause Tox to not look for peers on the local network.
- */
- bool local_discovery_enabled;
-
- namespace proxy {
- /**
- * Pass communications through a proxy.
- */
- PROXY_TYPE type;
-
- /**
- * The IP address or DNS name of the proxy to be used.
- *
- * If used, this must be non-NULL and be a valid DNS name. The name must not
- * exceed $MAX_HOSTNAME_LENGTH characters, and be in a NUL-terminated C string
- * format ($MAX_HOSTNAME_LENGTH includes the NUL byte).
- *
- * This member is ignored (it can be NULL) if proxy_type is ${PROXY_TYPE.NONE}.
- *
- * The data pointed at by this member is owned by the user, so must
- * outlive the options object.
- */
- string host;
-
- /**
- * The port to use to connect to the proxy server.
- *
- * Ports must be in the range (1, 65535). The value is ignored if
- * proxy_type is ${PROXY_TYPE.NONE}.
- */
- uint16_t port;
- }
-
- /**
- * The start port of the inclusive port range to attempt to use.
- *
- * If both start_port and end_port are 0, the default port range will be
- * used: [33445, 33545].
- *
- * If either start_port or end_port is 0 while the other is non-zero, the
- * non-zero port will be the only port in the range.
- *
- * Having start_port > end_port will yield the same behavior as if start_port
- * and end_port were swapped.
- */
- uint16_t start_port;
-
- /**
- * The end port of the inclusive port range to attempt to use.
- */
- uint16_t end_port;
-
- /**
- * The port to use for the TCP server (relay). If 0, the TCP server is
- * disabled.
- *
- * Enabling it is not required for Tox to function properly.
- *
- * When enabled, your Tox instance can act as a TCP relay for other Tox
- * instance. This leads to increased traffic, thus when writing a client
- * it is recommended to enable TCP server only if the user has an option
- * to disable it.
- */
- uint16_t tcp_port;
-
- /**
- * Enables or disables UDP hole-punching in toxcore. (Default: enabled).
- */
- bool hole_punching_enabled;
-
- namespace savedata {
- /**
- * The type of savedata to load from.
- */
- SAVEDATA_TYPE type;
-
- /**
- * The savedata.
- *
- * The data pointed at by this member is owned by the user, so must
- * outlive the options object.
- */
- const uint8_t[length] data;
-
- /**
- * The length of the savedata.
- */
- size_t length;
- }
-
- namespace log {
- /**
- * Logging callback for the new tox instance.
- */
- log_cb *callback;
-
- /**
- * User data pointer passed to the logging callback.
- */
- any user_data;
- }
-
- /**
- * These options are experimental, so avoid writing code that depends on
- * them. Options marked "experimental" may change their behaviour or go away
- * entirely in the future, or may be renamed to something non-experimental
- * if they become part of the supported API.
- */
- namespace experimental {
- /**
- * Make public API functions thread-safe using a per-instance lock.
- *
- * Default: false.
- */
- bool thread_safety;
- }
- }
-
-
- /**
- * Initialises a $this object with the default options.
- *
- * The result of this function is independent of the original options. All
- * values will be overwritten, no values will be read (so it is permissible
- * to pass an uninitialised object).
- *
- * If options is NULL, this function has no effect.
- *
- * @param options An options object to be filled with default options.
- */
- void default();
-
-
- /**
- * Allocates a new $this object and initialises it with the default
- * options. This function can be used to preserve long term ABI compatibility by
- * giving the responsibility of allocation and deallocation to the Tox library.
- *
- * Objects returned from this function must be freed using the $free
- * function.
- *
- * @return A new $this object with default options or NULL on failure.
- */
- static this new() {
- /**
- * The function failed to allocate enough memory for the options struct.
- */
- MALLOC,
- }
-
-
- /**
- * Releases all resources associated with an options objects.
- *
- * Passing a pointer that was not returned by $new results in
- * undefined behaviour.
- */
- void free();
-}
-
-
-/*******************************************************************************
- *
- * :: Creation and destruction
- *
- ******************************************************************************/
-
-
-/**
- * @brief Creates and initialises a new Tox instance with the options passed.
- *
- * This function will bring the instance into a valid state. Running the event
- * loop with a new instance will operate correctly.
- *
- * If loading failed or succeeded only partially, the new or partially loaded
- * instance is returned and an error code is set.
- *
- * @param options An options object as described above. If this parameter is
- * NULL, the default options are used.
- *
- * @see $iterate for the event loop.
- *
- * @return A new Tox instance pointer on success or NULL on failure.
- */
-static this new(const options_t *options) {
- NULL,
- /**
- * The function was unable to allocate enough memory to store the internal
- * structures for the Tox object.
- */
- MALLOC,
- /**
- * The function was unable to bind to a port. This may mean that all ports
- * have already been bound, e.g. by other Tox instances, or it may mean
- * a permission error. You may be able to gather more information from errno.
- */
- PORT_ALLOC,
-
- namespace PROXY {
- /**
- * proxy_type was invalid.
- */
- BAD_TYPE,
- /**
- * proxy_type was valid but the proxy_host passed had an invalid format
- * or was NULL.
- */
- BAD_HOST,
- /**
- * proxy_type was valid, but the proxy_port was invalid.
- */
- BAD_PORT,
- /**
- * The proxy address passed could not be resolved.
- */
- NOT_FOUND,
- }
-
- namespace LOAD {
- /**
- * The byte array to be loaded contained an encrypted save.
- */
- ENCRYPTED,
- /**
- * The data format was invalid. This can happen when loading data that was
- * saved by an older version of Tox, or when the data has been corrupted.
- * When loading from badly formatted data, some data may have been loaded,
- * and the rest is discarded. Passing an invalid length parameter also
- * causes this error.
- */
- BAD_FORMAT,
- }
-}
-
-
-/**
- * Releases all resources associated with the Tox instance and disconnects from
- * the network.
- *
- * After calling this function, the Tox pointer becomes invalid. No other
- * functions can be called, and the pointer value can no longer be read.
- */
-void kill();
-
-
-uint8_t[size] savedata {
- /**
- * Calculates the number of bytes required to store the tox instance with
- * $get. This function cannot fail. The result is always greater than 0.
- *
- * @see threading for concurrency implications.
- */
- size();
-
- /**
- * Store all information associated with the tox instance to a byte array.
- *
- * @param savedata A memory region large enough to store the tox instance
- * data. Call $size to find the number of bytes required. If this parameter
- * is NULL, this function has no effect.
- */
- get();
-}
-
-
-/*******************************************************************************
- *
- * :: Connection lifecycle and event loop
- *
- ******************************************************************************/
-
-
-/**
- * Sends a "get nodes" request to the given bootstrap node with IP, port, and
- * public key to setup connections.
- *
- * This function will attempt to connect to the node using UDP. You must use
- * this function even if ${options.this.udp_enabled} was set to false.
- *
- * @param host The hostname or IP address (IPv4 or IPv6) of the node. Must be
- * at most $MAX_HOSTNAME_LENGTH chars, including the NUL byte.
- * @param port The port on the host on which the bootstrap Tox instance is
- * listening.
- * @param public_key The long term public key of the bootstrap node
- * ($PUBLIC_KEY_SIZE bytes).
- * @return true on success.
- */
-bool bootstrap(string host, uint16_t port, const uint8_t[PUBLIC_KEY_SIZE] public_key) {
- NULL,
- /**
- * The hostname could not be resolved to an IP address, or the IP address
- * passed was invalid.
- */
- BAD_HOST,
- /**
- * The port passed was invalid. The valid port range is (1, 65535).
- */
- BAD_PORT,
-}
-
-
-/**
- * Adds additional host:port pair as TCP relay.
- *
- * This function can be used to initiate TCP connections to different ports on
- * the same bootstrap node, or to add TCP relays without using them as
- * bootstrap nodes.
- *
- * @param host The hostname or IP address (IPv4 or IPv6) of the TCP relay.
- * Must be at most $MAX_HOSTNAME_LENGTH chars, including the NUL byte.
- * @param port The port on the host on which the TCP relay is listening.
- * @param public_key The long term public key of the TCP relay
- * ($PUBLIC_KEY_SIZE bytes).
- * @return true on success.
- */
-bool add_tcp_relay(string host, uint16_t port, const uint8_t[PUBLIC_KEY_SIZE] public_key)
- with error for bootstrap;
-
-
-/**
- * Protocols that can be used to connect to the network or friends.
- *
- * @deprecated All UPPER_CASE enum type names are deprecated. Use the
- * Camel_Snake_Case versions, instead.
- */
-enum class CONNECTION {
- /**
- * There is no connection. This instance, or the friend the state change is
- * about, is now offline.
- */
- NONE,
- /**
- * A TCP connection has been established. For the own instance, this means it
- * is connected through a TCP relay, only. For a friend, this means that the
- * connection to that particular friend goes through a TCP relay.
- */
- TCP,
- /**
- * A UDP connection has been established. For the own instance, this means it
- * is able to send UDP packets to DHT nodes, but may still be connected to
- * a TCP relay. For a friend, this means that the connection to that
- * particular friend was built using direct UDP packets.
- */
- UDP,
-}
-
-
-namespace self {
-
- CONNECTION connection_status {
- /**
- * Return whether we are connected to the DHT. The return value is equal to the
- * last value received through the `${event connection_status}` callback.
- *
- * @deprecated This getter is deprecated. Use the event and store the status
- * in the client state.
- */
- get();
- }
-
-
- /**
- * This event is triggered whenever there is a change in the DHT connection
- * state. When disconnected, a client may choose to call $bootstrap again, to
- * reconnect to the DHT. Note that this state may frequently change for short
- * amounts of time. Clients should therefore not immediately bootstrap on
- * receiving a disconnect.
- *
- * TODO(iphydf): how long should a client wait before bootstrapping again?
- */
- event connection_status const {
- /**
- * @param connection_status Whether we are connected to the DHT.
- */
- typedef void(CONNECTION connection_status);
- }
-
-}
-
-
-/**
- * Return the time in milliseconds before $iterate() should be called again
- * for optimal performance.
- */
-const uint32_t iteration_interval();
-
-
-/**
- * The main loop that needs to be run in intervals of $iteration_interval()
- * milliseconds.
- */
-void iterate(any user_data);
-
-
-/*******************************************************************************
- *
- * :: Internal client information (Tox address/id)
- *
- ******************************************************************************/
-
-
-namespace self {
-
- uint8_t[ADDRESS_SIZE] address {
- /**
- * Writes the Tox friend address of the client to a byte array. The address is
- * not in human-readable format. If a client wants to display the address,
- * formatting is required.
- *
- * @param address A memory region of at least $ADDRESS_SIZE bytes. If this
- * parameter is NULL, this function has no effect.
- * @see $ADDRESS_SIZE for the address format.
- */
- get();
- }
-
-
- uint32_t nospam {
- /**
- * Set the 4-byte nospam part of the address. This value is expected in host
- * byte order. I.e. 0x12345678 will form the bytes [12, 34, 56, 78] in the
- * nospam part of the Tox friend address.
- *
- * @param nospam Any 32 bit unsigned integer.
- */
- set();
-
- /**
- * Get the 4-byte nospam part of the address. This value is returned in host
- * byte order.
- */
- get();
- }
-
-
- uint8_t[PUBLIC_KEY_SIZE] public_key {
- /**
- * Copy the Tox Public Key (long term) from the Tox object.
- *
- * @param public_key A memory region of at least $PUBLIC_KEY_SIZE bytes. If
- * this parameter is NULL, this function has no effect.
- */
- get();
- }
-
-
- uint8_t[SECRET_KEY_SIZE] secret_key {
- /**
- * Copy the Tox Secret Key from the Tox object.
- *
- * @param secret_key A memory region of at least $SECRET_KEY_SIZE bytes. If
- * this parameter is NULL, this function has no effect.
- */
- get();
- }
-
-}
-
-
-/*******************************************************************************
- *
- * :: User-visible client information (nickname/status)
- *
- ******************************************************************************/
-
-
-/**
- * Common error codes for all functions that set a piece of user-visible
- * client information.
- */
-error for set_info {
- NULL,
- /**
- * Information length exceeded maximum permissible size.
- */
- TOO_LONG,
-}
-
-
-namespace self {
-
- uint8_t[length <= MAX_NAME_LENGTH] name {
- /**
- * Set the nickname for the Tox client.
- *
- * Nickname length cannot exceed $MAX_NAME_LENGTH. If length is 0, the name
- * parameter is ignored (it can be NULL), and the nickname is set back to empty.
- *
- * @param name A byte array containing the new nickname.
- * @param length The size of the name byte array.
- *
- * @return true on success.
- */
- set() with error for set_info;
-
- /**
- * Return the length of the current nickname as passed to $set.
- *
- * If no nickname was set before calling this function, the name is empty,
- * and this function returns 0.
- *
- * @see threading for concurrency implications.
- */
- size();
-
- /**
- * Write the nickname set by $set to a byte array.
- *
- * If no nickname was set before calling this function, the name is empty,
- * and this function has no effect.
- *
- * Call $size to find out how much memory to allocate for
- * the result.
- *
- * @param name A valid memory location large enough to hold the nickname.
- * If this parameter is NULL, the function has no effect.
- */
- get();
- }
-
-
- uint8_t[length <= MAX_STATUS_MESSAGE_LENGTH] status_message {
- /**
- * Set the client's status message.
- *
- * Status message length cannot exceed $MAX_STATUS_MESSAGE_LENGTH. If
- * length is 0, the status parameter is ignored (it can be NULL), and the
- * user status is set back to empty.
- */
- set() with error for set_info;
-
- /**
- * Return the length of the current status message as passed to $set.
- *
- * If no status message was set before calling this function, the status
- * is empty, and this function returns 0.
- *
- * @see threading for concurrency implications.
- */
- size();
-
- /**
- * Write the status message set by $set to a byte array.
- *
- * If no status message was set before calling this function, the status is
- * empty, and this function has no effect.
- *
- * Call $size to find out how much memory to allocate for
- * the result.
- *
- * @param status_message A valid memory location large enough to hold the
- * status message. If this parameter is NULL, the function has no effect.
- */
- get();
- }
-
-
- USER_STATUS status {
- /**
- * Set the client's user status.
- *
- * @param status One of the user statuses listed in the enumeration above.
- */
- set();
-
- /**
- * Returns the client's user status.
- */
- get();
- }
-
-}
-
-
-/*******************************************************************************
- *
- * :: Friend list management
- *
- ******************************************************************************/
-
-
-namespace friend {
-
- /**
- * Add a friend to the friend list and send a friend request.
- *
- * A friend request message must be at least 1 byte long and at most
- * $MAX_FRIEND_REQUEST_LENGTH.
- *
- * Friend numbers are unique identifiers used in all functions that operate on
- * friends. Once added, a friend number is stable for the lifetime of the Tox
- * object. After saving the state and reloading it, the friend numbers may not
- * be the same as before. Deleting a friend creates a gap in the friend number
- * set, which is filled by the next adding of a friend. Any pattern in friend
- * numbers should not be relied on.
- *
- * If more than INT32_MAX friends are added, this function causes undefined
- * behaviour.
- *
- * @param address The address of the friend (returned by ${self.address.get} of
- * the friend you wish to add) it must be $ADDRESS_SIZE bytes.
- * @param message The message that will be sent along with the friend request.
- * @param length The length of the data byte array.
- *
- * @return the friend number on success, an unspecified value on failure.
- */
- uint32_t add(
- const uint8_t[ADDRESS_SIZE] address,
- const uint8_t[length <= MAX_FRIEND_REQUEST_LENGTH] message
- ) {
- NULL,
- /**
- * The length of the friend request message exceeded
- * $MAX_FRIEND_REQUEST_LENGTH.
- */
- TOO_LONG,
- /**
- * The friend request message was empty. This, and the TOO_LONG code will
- * never be returned from $add_norequest.
- */
- NO_MESSAGE,
- /**
- * The friend address belongs to the sending client.
- */
- OWN_KEY,
- /**
- * A friend request has already been sent, or the address belongs to a friend
- * that is already on the friend list.
- */
- ALREADY_SENT,
- /**
- * The friend address checksum failed.
- */
- BAD_CHECKSUM,
- /**
- * The friend was already there, but the nospam value was different.
- */
- SET_NEW_NOSPAM,
- /**
- * A memory allocation failed when trying to increase the friend list size.
- */
- MALLOC,
- }
-
-
- /**
- * Add a friend without sending a friend request.
- *
- * This function is used to add a friend in response to a friend request. If the
- * client receives a friend request, it can be reasonably sure that the other
- * client added this client as a friend, eliminating the need for a friend
- * request.
- *
- * This function is also useful in a situation where both instances are
- * controlled by the same entity, so that this entity can perform the mutual
- * friend adding. In this case, there is no need for a friend request, either.
- *
- * @param public_key A byte array of length $PUBLIC_KEY_SIZE containing the
- * Public Key (not the Address) of the friend to add.
- *
- * @return the friend number on success, an unspecified value on failure.
- * @see $add for a more detailed description of friend numbers.
- */
- uint32_t add_norequest(const uint8_t[PUBLIC_KEY_SIZE] public_key)
- with error for add;
-
-
- /**
- * Remove a friend from the friend list.
- *
- * This does not notify the friend of their deletion. After calling this
- * function, this client will appear offline to the friend and no communication
- * can occur between the two.
- *
- * @param friend_number Friend number for the friend to be deleted.
- *
- * @return true on success.
- */
- bool delete(uint32_t friend_number) {
- /**
- * There was no friend with the given friend number. No friends were deleted.
- */
- FRIEND_NOT_FOUND,
- }
-
-}
-
-
-/*******************************************************************************
- *
- * :: Friend list queries
- *
- ******************************************************************************/
-
-namespace friend {
-
- /**
- * Return the friend number associated with that Public Key.
- *
- * @return the friend number on success, an unspecified value on failure.
- * @param public_key A byte array containing the Public Key.
- */
- const uint32_t by_public_key(const uint8_t[PUBLIC_KEY_SIZE] public_key) {
- NULL,
- /**
- * No friend with the given Public Key exists on the friend list.
- */
- NOT_FOUND,
- }
-
-
- /**
- * Checks if a friend with the given friend number exists and returns true if
- * it does.
- */
- const bool exists(uint32_t friend_number);
-
-}
-
-namespace self {
-
- uint32_t[size] friend_list {
- /**
- * Return the number of friends on the friend list.
- *
- * This function can be used to determine how much memory to allocate for
- * $get.
- */
- size();
-
-
- /**
- * Copy a list of valid friend numbers into an array.
- *
- * Call $size to determine the number of elements to allocate.
- *
- * @param friend_list A memory region with enough space to hold the friend
- * list. If this parameter is NULL, this function has no effect.
- */
- get();
- }
-
-}
-
-
-
-namespace friend {
-
- uint8_t[PUBLIC_KEY_SIZE] public_key {
- /**
- * Copies the Public Key associated with a given friend number to a byte array.
- *
- * @param friend_number The friend number you want the Public Key of.
- * @param public_key A memory region of at least $PUBLIC_KEY_SIZE bytes. If
- * this parameter is NULL, this function has no effect.
- *
- * @return true on success.
- */
- get(uint32_t friend_number) {
- /**
- * No friend with the given number exists on the friend list.
- */
- FRIEND_NOT_FOUND,
- }
- }
-
-}
-
-namespace friend {
-
- uint64_t last_online {
- /**
- * Return a unix-time timestamp of the last time the friend associated with a given
- * friend number was seen online. This function will return UINT64_MAX on error.
- *
- * @param friend_number The friend number you want to query.
- */
- get(uint32_t friend_number) {
- /**
- * No friend with the given number exists on the friend list.
- */
- FRIEND_NOT_FOUND,
- }
- }
-
-}
-
-/*******************************************************************************
- *
- * :: Friend-specific state queries (can also be received through callbacks)
- *
- ******************************************************************************/
-
-
-namespace friend {
-
- /**
- * Common error codes for friend state query functions.
- */
- error for query {
- /**
- * The pointer parameter for storing the query result (name, message) was
- * NULL. Unlike the `_self_` variants of these functions, which have no effect
- * when a parameter is NULL, these functions return an error in that case.
- */
- NULL,
- /**
- * The friend_number did not designate a valid friend.
- */
- FRIEND_NOT_FOUND,
- }
-
-
- uint8_t[length <= MAX_NAME_LENGTH] name {
- /**
- * Return the length of the friend's name. If the friend number is invalid, the
- * return value is unspecified.
- *
- * The return value is equal to the `length` argument received by the last
- * `${event name}` callback.
- */
- size(uint32_t friend_number)
- with error for query;
-
- /**
- * Write the name of the friend designated by the given friend number to a byte
- * array.
- *
- * Call $size to determine the allocation size for the `name`
- * parameter.
- *
- * The data written to `name` is equal to the data received by the last
- * `${event name}` callback.
- *
- * @param name A valid memory region large enough to store the friend's name.
- *
- * @return true on success.
- */
- get(uint32_t friend_number)
- with error for query;
- }
-
-
- /**
- * This event is triggered when a friend changes their name.
- */
- event name const {
- /**
- * @param friend_number The friend number of the friend whose name changed.
- * @param name A byte array containing the same data as
- * ${name.get} would write to its `name` parameter.
- * @param length A value equal to the return value of
- * ${name.size}.
- */
- typedef void(uint32_t friend_number, const uint8_t[length <= MAX_NAME_LENGTH] name);
- }
-
-
- uint8_t[length <= MAX_STATUS_MESSAGE_LENGTH] status_message {
- /**
- * Return the length of the friend's status message. If the friend number is
- * invalid, the return value is SIZE_MAX.
- */
- size(uint32_t friend_number)
- with error for query;
-
- /**
- * Write the status message of the friend designated by the given friend number to a byte
- * array.
- *
- * Call $size to determine the allocation size for the `status_message`
- * parameter.
- *
- * The data written to `status_message` is equal to the data received by the last
- * `${event status_message}` callback.
- *
- * @param status_message A valid memory region large enough to store the friend's status message.
- */
- get(uint32_t friend_number)
- with error for query;
- }
-
-
- /**
- * This event is triggered when a friend changes their status message.
- */
- event status_message const {
- /**
- * @param friend_number The friend number of the friend whose status message
- * changed.
- * @param message A byte array containing the same data as
- * ${status_message.get} would write to its `status_message` parameter.
- * @param length A value equal to the return value of
- * ${status_message.size}.
- */
- typedef void(uint32_t friend_number, const uint8_t[length <= MAX_STATUS_MESSAGE_LENGTH] message);
- }
-
-
- USER_STATUS status {
- /**
- * Return the friend's user status (away/busy/...). If the friend number is
- * invalid, the return value is unspecified.
- *
- * The status returned is equal to the last status received through the
- * `${event status}` callback.
- *
- * @deprecated This getter is deprecated. Use the event and store the status
- * in the client state.
- */
- get(uint32_t friend_number)
- with error for query;
- }
-
-
- /**
- * This event is triggered when a friend changes their user status.
- */
- event status const {
- /**
- * @param friend_number The friend number of the friend whose user status
- * changed.
- * @param status The new user status.
- */
- typedef void(uint32_t friend_number, USER_STATUS status);
- }
-
-
- CONNECTION connection_status {
- /**
- * Check whether a friend is currently connected to this client.
- *
- * The result of this function is equal to the last value received by the
- * `${event connection_status}` callback.
- *
- * @param friend_number The friend number for which to query the connection
- * status.
- *
- * @return the friend's connection status as it was received through the
- * `${event connection_status}` event.
- *
- * @deprecated This getter is deprecated. Use the event and store the status
- * in the client state.
- */
- get(uint32_t friend_number)
- with error for query;
- }
-
-
- /**
- * This event is triggered when a friend goes offline after having been online,
- * or when a friend goes online.
- *
- * This callback is not called when adding friends. It is assumed that when
- * adding friends, their connection status is initially offline.
- */
- event connection_status const {
- /**
- * @param friend_number The friend number of the friend whose connection status
- * changed.
- * @param connection_status The result of calling
- * ${connection_status.get} on the passed friend_number.
- */
- typedef void(uint32_t friend_number, CONNECTION connection_status);
- }
-
-
- bool typing {
- /**
- * Check whether a friend is currently typing a message.
- *
- * @param friend_number The friend number for which to query the typing status.
- *
- * @return true if the friend is typing.
- * @return false if the friend is not typing, or the friend number was
- * invalid. Inspect the error code to determine which case it is.
- *
- * @deprecated This getter is deprecated. Use the event and store the status
- * in the client state.
- */
- get(uint32_t friend_number)
- with error for query;
- }
-
-
- /**
- * This event is triggered when a friend starts or stops typing.
- */
- event typing const {
- /**
- * @param friend_number The friend number of the friend who started or stopped
- * typing.
- * @param is_typing The result of calling ${typing.get} on the passed
- * friend_number.
- */
- typedef void(uint32_t friend_number, bool is_typing);
- }
-
-}
-
-
-/*******************************************************************************
- *
- * :: Sending private messages
- *
- ******************************************************************************/
-
-error for set_typing {
- /**
- * The friend number did not designate a valid friend.
- */
- FRIEND_NOT_FOUND,
-}
-
-namespace self {
-
- bool typing {
- /**
- * Set the client's typing status for a friend.
- *
- * The client is responsible for turning it on or off.
- *
- * @param friend_number The friend to which the client is typing a message.
- * @param typing The typing status. True means the client is typing.
- *
- * @return true on success.
- */
- set(uint32_t friend_number) with error for set_typing;
- }
-
-}
-
-
-namespace friend {
-
- namespace send {
-
- /**
- * Send a text chat message to an online friend.
- *
- * This function creates a chat message packet and pushes it into the send
- * queue.
- *
- * The message length may not exceed $MAX_MESSAGE_LENGTH. Larger messages
- * must be split by the client and sent as separate messages. Other clients can
- * then reassemble the fragments. Messages may not be empty.
- *
- * The return value of this function is the message ID. If a read receipt is
- * received, the triggered `${event read_receipt}` event will be passed this message ID.
- *
- * Message IDs are unique per friend. The first message ID is 0. Message IDs are
- * incremented by 1 each time a message is sent. If UINT32_MAX messages were
- * sent, the next message ID is 0.
- *
- * @param type Message type (normal, action, ...).
- * @param friend_number The friend number of the friend to send the message to.
- * @param message A non-NULL pointer to the first element of a byte array
- * containing the message text.
- * @param length Length of the message to be sent.
- */
- uint32_t message(uint32_t friend_number, MESSAGE_TYPE type,
- const uint8_t[length <= MAX_MESSAGE_LENGTH] message) {
- NULL,
- /**
- * The friend number did not designate a valid friend.
- */
- FRIEND_NOT_FOUND,
- /**
- * This client is currently not connected to the friend.
- */
- FRIEND_NOT_CONNECTED,
- /**
- * An allocation error occurred while increasing the send queue size.
- */
- SENDQ,
- /**
- * Message length exceeded $MAX_MESSAGE_LENGTH.
- */
- TOO_LONG,
- /**
- * Attempted to send a zero-length message.
- */
- EMPTY,
- }
-
- }
-
-
- /**
- * This event is triggered when the friend receives the message sent with
- * ${send.message} with the corresponding message ID.
- */
- event read_receipt const {
- /**
- * @param friend_number The friend number of the friend who received the message.
- * @param message_id The message ID as returned from ${send.message}
- * corresponding to the message sent.
- */
- typedef void(uint32_t friend_number, uint32_t message_id);
- }
-
-}
-
-
-/*******************************************************************************
- *
- * :: Receiving private messages and friend requests
- *
- ******************************************************************************/
-
-
-namespace friend {
-
- /**
- * This event is triggered when a friend request is received.
- */
- event request const {
- /**
- * @param public_key The Public Key of the user who sent the friend request.
- * @param message The message they sent along with the request.
- * @param length The size of the message byte array.
- */
- typedef void(const uint8_t[PUBLIC_KEY_SIZE] public_key,
- const uint8_t[length <= MAX_MESSAGE_LENGTH] message);
- }
-
-
- /**
- * This event is triggered when a message from a friend is received.
- */
- event message const {
- /**
- * @param friend_number The friend number of the friend who sent the message.
- * @param message The message data they sent.
- * @param length The size of the message byte array.
- */
- typedef void(uint32_t friend_number, MESSAGE_TYPE type,
- const uint8_t[length <= MAX_MESSAGE_LENGTH] message);
- }
-
-}
-
-
-/*******************************************************************************
- *
- * :: File transmission: common between sending and receiving
- *
- ******************************************************************************/
-
-
-/**
- * Generates a cryptographic hash of the given data.
- *
- * This function may be used by clients for any purpose, but is provided
- * primarily for validating cached avatars. This use is highly recommended to
- * avoid unnecessary avatar updates.
- *
- * If hash is NULL or data is NULL while length is not 0 the function returns false,
- * otherwise it returns true.
- *
- * This function is a wrapper to internal message-digest functions.
- *
- * @param hash A valid memory location the hash data. It must be at least
- * $HASH_LENGTH bytes in size.
- * @param data Data to be hashed or NULL.
- * @param length Size of the data array or 0.
- *
- * @return true if hash was not NULL.
- */
-static bool hash(uint8_t[HASH_LENGTH] hash, const uint8_t[length] data);
-
-
-namespace file {
-
- /**
- * A list of pre-defined file kinds. Toxcore itself does not behave
- * differently for different file kinds. These are a hint to the client
- * telling it what use the sender intended for the file. The `kind` parameter
- * in the send function and recv callback are `uint32_t`, not $KIND, because
- * clients can invent their own file kind. Unknown file kinds should be
- * treated as ${KIND.DATA}.
- */
- enum KIND {
- /**
- * Arbitrary file data. Clients can choose to handle it based on the file name
- * or magic or any other way they choose.
- */
- DATA,
- /**
- * Avatar file_id. This consists of $hash(image).
- * Avatar data. This consists of the image data.
- *
- * Avatars can be sent at any time the client wishes. Generally, a client will
- * send the avatar to a friend when that friend comes online, and to all
- * friends when the avatar changed. A client can save some traffic by
- * remembering which friend received the updated avatar already and only send
- * it if the friend has an out of date avatar.
- *
- * Clients who receive avatar send requests can reject it (by sending
- * ${CONTROL.CANCEL} before any other controls), or accept it (by
- * sending ${CONTROL.RESUME}). The file_id of length $HASH_LENGTH bytes
- * (same length as $FILE_ID_LENGTH) will contain the hash. A client can compare
- * this hash with a saved hash and send ${CONTROL.CANCEL} to terminate the avatar
- * transfer if it matches.
- *
- * When file_size is set to 0 in the transfer request it means that the client
- * has no avatar.
- */
- AVATAR,
- }
-
-
- enum class CONTROL {
- /**
- * Sent by the receiving side to accept a file send request. Also sent after a
- * $PAUSE command to continue sending or receiving.
- */
- RESUME,
- /**
- * Sent by clients to pause the file transfer. The initial state of a file
- * transfer is always paused on the receiving side and running on the sending
- * side. If both the sending and receiving side pause the transfer, then both
- * need to send $RESUME for the transfer to resume.
- */
- PAUSE,
- /**
- * Sent by the receiving side to reject a file send request before any other
- * commands are sent. Also sent by either side to terminate a file transfer.
- */
- CANCEL,
- }
-
-
- /**
- * Sends a file control command to a friend for a given file transfer.
- *
- * @param friend_number The friend number of the friend the file is being
- * transferred to or received from.
- * @param file_number The friend-specific identifier for the file transfer.
- * @param control The control command to send.
- *
- * @return true on success.
- */
- bool control(uint32_t friend_number, uint32_t file_number, CONTROL control) {
- /**
- * The friend_number passed did not designate a valid friend.
- */
- FRIEND_NOT_FOUND,
- /**
- * This client is currently not connected to the friend.
- */
- FRIEND_NOT_CONNECTED,
- /**
- * No file transfer with the given file number was found for the given friend.
- */
- NOT_FOUND,
- /**
- * A RESUME control was sent, but the file transfer is running normally.
- */
- NOT_PAUSED,
- /**
- * A RESUME control was sent, but the file transfer was paused by the other
- * party. Only the party that paused the transfer can resume it.
- */
- DENIED,
- /**
- * A PAUSE control was sent, but the file transfer was already paused.
- */
- ALREADY_PAUSED,
- /**
- * Packet queue is full.
- */
- SENDQ,
- }
-
-
- /**
- * This event is triggered when a file control command is received from a
- * friend.
- */
- event recv_control const {
- /**
- * When receiving ${CONTROL.CANCEL}, the client should release the
- * resources associated with the file number and consider the transfer failed.
- *
- * @param friend_number The friend number of the friend who is sending the file.
- * @param file_number The friend-specific file number the data received is
- * associated with.
- * @param control The file control command received.
- */
- typedef void(uint32_t friend_number, uint32_t file_number, CONTROL control);
- }
-
- /**
- * Sends a file seek control command to a friend for a given file transfer.
- *
- * This function can only be called to resume a file transfer right before
- * ${CONTROL.RESUME} is sent.
- *
- * @param friend_number The friend number of the friend the file is being
- * received from.
- * @param file_number The friend-specific identifier for the file transfer.
- * @param position The position that the file should be seeked to.
- */
- bool seek(uint32_t friend_number, uint32_t file_number, uint64_t position) {
- /**
- * The friend_number passed did not designate a valid friend.
- */
- FRIEND_NOT_FOUND,
- /**
- * This client is currently not connected to the friend.
- */
- FRIEND_NOT_CONNECTED,
- /**
- * No file transfer with the given file number was found for the given friend.
- */
- NOT_FOUND,
- /**
- * File was not in a state where it could be seeked.
- */
- DENIED,
- /**
- * Seek position was invalid
- */
- INVALID_POSITION,
- /**
- * Packet queue is full.
- */
- SENDQ,
- }
-
-
- error for get {
- NULL,
- /**
- * The friend_number passed did not designate a valid friend.
- */
- FRIEND_NOT_FOUND,
- /**
- * No file transfer with the given file number was found for the given friend.
- */
- NOT_FOUND,
- }
-
- uint8_t[FILE_ID_LENGTH] file_id {
- /**
- * Copy the file id associated to the file transfer to a byte array.
- *
- * @param friend_number The friend number of the friend the file is being
- * transferred to or received from.
- * @param file_number The friend-specific identifier for the file transfer.
- * @param file_id A memory region of at least $FILE_ID_LENGTH bytes. If
- * this parameter is NULL, this function has no effect.
- *
- * @return true on success.
- */
- get(uint32_t friend_number, uint32_t file_number)
- with error for get;
- }
-
-}
-
-
-/*******************************************************************************
- *
- * :: File transmission: sending
- *
- ******************************************************************************/
-
-
-namespace file {
-
- /**
- * Send a file transmission request.
- *
- * Maximum filename length is $MAX_FILENAME_LENGTH bytes. The filename
- * should generally just be a file name, not a path with directory names.
- *
- * If a non-UINT64_MAX file size is provided, it can be used by both sides to
- * determine the sending progress. File size can be set to UINT64_MAX for streaming
- * data of unknown size.
- *
- * File transmission occurs in chunks, which are requested through the
- * `${event chunk_request}` event.
- *
- * When a friend goes offline, all file transfers associated with the friend are
- * purged from core.
- *
- * If the file contents change during a transfer, the behaviour is unspecified
- * in general. What will actually happen depends on the mode in which the file
- * was modified and how the client determines the file size.
- *
- * - If the file size was increased
- * - and sending mode was streaming (file_size = UINT64_MAX), the behaviour
- * will be as expected.
- * - and sending mode was file (file_size != UINT64_MAX), the
- * ${event chunk_request} callback will receive length = 0 when Core thinks
- * the file transfer has finished. If the client remembers the file size as
- * it was when sending the request, it will terminate the transfer normally.
- * If the client re-reads the size, it will think the friend cancelled the
- * transfer.
- * - If the file size was decreased
- * - and sending mode was streaming, the behaviour is as expected.
- * - and sending mode was file, the callback will return 0 at the new
- * (earlier) end-of-file, signalling to the friend that the transfer was
- * cancelled.
- * - If the file contents were modified
- * - at a position before the current read, the two files (local and remote)
- * will differ after the transfer terminates.
- * - at a position after the current read, the file transfer will succeed as
- * expected.
- * - In either case, both sides will regard the transfer as complete and
- * successful.
- *
- * @param friend_number The friend number of the friend the file send request
- * should be sent to.
- * @param kind The meaning of the file to be sent.
- * @param file_size Size in bytes of the file the client wants to send, UINT64_MAX if
- * unknown or streaming.
- * @param file_id A file identifier of length $FILE_ID_LENGTH that can be used to
- * uniquely identify file transfers across core restarts. If NULL, a random one will
- * be generated by core. It can then be obtained by using ${file_id.get}().
- * @param filename Name of the file. Does not need to be the actual name. This
- * name will be sent along with the file send request.
- * @param filename_length Size in bytes of the filename.
- *
- * @return A file number used as an identifier in subsequent callbacks. This
- * number is per friend. File numbers are reused after a transfer terminates.
- * On failure, this function returns an unspecified value. Any pattern in file numbers
- * should not be relied on.
- */
- uint32_t send(uint32_t friend_number, uint32_t kind, uint64_t file_size,
- const uint8_t[FILE_ID_LENGTH] file_id,
- const uint8_t[filename_length <= MAX_FILENAME_LENGTH] filename) {
- NULL,
- /**
- * The friend_number passed did not designate a valid friend.
- */
- FRIEND_NOT_FOUND,
- /**
- * This client is currently not connected to the friend.
- */
- FRIEND_NOT_CONNECTED,
- /**
- * Filename length exceeded $MAX_FILENAME_LENGTH bytes.
- */
- NAME_TOO_LONG,
- /**
- * Too many ongoing transfers. The maximum number of concurrent file transfers
- * is 256 per friend per direction (sending and receiving).
- */
- TOO_MANY,
- }
-
-
- /**
- * Send a chunk of file data to a friend.
- *
- * This function is called in response to the `${event chunk_request}` callback. The
- * length parameter should be equal to the one received though the callback.
- * If it is zero, the transfer is assumed complete. For files with known size,
- * Core will know that the transfer is complete after the last byte has been
- * received, so it is not necessary (though not harmful) to send a zero-length
- * chunk to terminate. For streams, core will know that the transfer is finished
- * if a chunk with length less than the length requested in the callback is sent.
- *
- * @param friend_number The friend number of the receiving friend for this file.
- * @param file_number The file transfer identifier returned by tox_file_send.
- * @param position The file or stream position from which to continue reading.
- * @return true on success.
- */
- bool send_chunk(uint32_t friend_number, uint32_t file_number, uint64_t position, const uint8_t[length] data) {
- /**
- * The length parameter was non-zero, but data was NULL.
- */
- NULL,
- /**
- * The friend_number passed did not designate a valid friend.
- */
- FRIEND_NOT_FOUND,
- /**
- * This client is currently not connected to the friend.
- */
- FRIEND_NOT_CONNECTED,
- /**
- * No file transfer with the given file number was found for the given friend.
- */
- NOT_FOUND,
- /**
- * File transfer was found but isn't in a transferring state: (paused, done,
- * broken, etc...) (happens only when not called from the request chunk callback).
- */
- NOT_TRANSFERRING,
- /**
- * Attempted to send more or less data than requested. The requested data size is
- * adjusted according to maximum transmission unit and the expected end of
- * the file. Trying to send less or more than requested will return this error.
- */
- INVALID_LENGTH,
- /**
- * Packet queue is full.
- */
- SENDQ,
- /**
- * Position parameter was wrong.
- */
- WRONG_POSITION,
- }
-
-
- /**
- * This event is triggered when Core is ready to send more file data.
- */
- event chunk_request const {
- /**
- * If the length parameter is 0, the file transfer is finished, and the client's
- * resources associated with the file number should be released. After a call
- * with zero length, the file number can be reused for future file transfers.
- *
- * If the requested position is not equal to the client's idea of the current
- * file or stream position, it will need to seek. In case of read-once streams,
- * the client should keep the last read chunk so that a seek back can be
- * supported. A seek-back only ever needs to read from the last requested chunk.
- * This happens when a chunk was requested, but the send failed. A seek-back
- * request can occur an arbitrary number of times for any given chunk.
- *
- * In response to receiving this callback, the client should call the function
- * `$send_chunk` with the requested chunk. If the number of bytes sent
- * through that function is zero, the file transfer is assumed complete. A
- * client must send the full length of data requested with this callback.
- *
- * @param friend_number The friend number of the receiving friend for this file.
- * @param file_number The file transfer identifier returned by $send.
- * @param position The file or stream position from which to continue reading.
- * @param length The number of bytes requested for the current chunk.
- */
- typedef void(uint32_t friend_number, uint32_t file_number, uint64_t position, size_t length);
- }
-
-}
-
-
-/*******************************************************************************
- *
- * :: File transmission: receiving
- *
- ******************************************************************************/
-
-
-namespace file {
-
- /**
- * This event is triggered when a file transfer request is received.
- */
- event recv const {
- /**
- * The client should acquire resources to be associated with the file transfer.
- * Incoming file transfers start in the PAUSED state. After this callback
- * returns, a transfer can be rejected by sending a ${CONTROL.CANCEL}
- * control command before any other control commands. It can be accepted by
- * sending ${CONTROL.RESUME}.
- *
- * @param friend_number The friend number of the friend who is sending the file
- * transfer request.
- * @param file_number The friend-specific file number the data received is
- * associated with.
- * @param kind The meaning of the file that was sent.
- * @param file_size Size in bytes of the file the client wants to send,
- * UINT64_MAX if unknown or streaming.
- * @param filename Name of the file. Does not need to be the actual name. This
- * name will be sent along with the file send request.
- * @param filename_length Size in bytes of the filename.
- */
- typedef void(uint32_t friend_number, uint32_t file_number, uint32_t kind,
- uint64_t file_size, const uint8_t[filename_length <= MAX_FILENAME_LENGTH] filename);
- }
-
-
- /**
- * This event is first triggered when a file transfer request is received, and
- * subsequently when a chunk of file data for an accepted request was received.
- */
- event recv_chunk const {
- /**
- * When length is 0, the transfer is finished and the client should release the
- * resources it acquired for the transfer. After a call with length = 0, the
- * file number can be reused for new file transfers.
- *
- * If position is equal to file_size (received in the file_receive callback)
- * when the transfer finishes, the file was received completely. Otherwise, if
- * file_size was UINT64_MAX, streaming ended successfully when length is 0.
- *
- * @param friend_number The friend number of the friend who is sending the file.
- * @param file_number The friend-specific file number the data received is
- * associated with.
- * @param position The file position of the first byte in data.
- * @param data A byte array containing the received chunk.
- * @param length The length of the received chunk.
- */
- typedef void(uint32_t friend_number, uint32_t file_number, uint64_t position,
- const uint8_t[length] data);
- }
-
-}
-
-
-/*******************************************************************************
- *
- * :: Conference management
- *
- ******************************************************************************/
-
-namespace conference {
-
- /**
- * Conference types for the ${event invite} event.
- *
- * @deprecated All UPPER_CASE enum type names are deprecated. Use the
- * Camel_Snake_Case versions, instead.
- */
- enum class TYPE {
- /**
- * Text-only conferences that must be accepted with the $join function.
- */
- TEXT,
- /**
- * Video conference. The function to accept these is in toxav.
- */
- AV,
- }
-
-
- /**
- * This event is triggered when the client is invited to join a conference.
- */
- event invite const {
- /**
- * The invitation will remain valid until the inviting friend goes offline
- * or exits the conference.
- *
- * @param friend_number The friend who invited us.
- * @param type The conference type (text only or audio/video).
- * @param cookie A piece of data of variable length required to join the
- * conference.
- * @param length The length of the cookie.
- */
- typedef void(uint32_t friend_number, TYPE type, const uint8_t[length] cookie);
- }
-
-
- /**
- * This event is triggered when the client successfully connects to a
- * conference after joining it with the $join function.
- */
- event connected const {
- /**
- * @param conference_number The conference number of the conference to which we have connected.
- */
- typedef void(uint32_t conference_number);
- }
-
-
- /**
- * This event is triggered when the client receives a conference message.
- */
- event message const {
- /**
- * @param conference_number The conference number of the conference the message is intended for.
- * @param peer_number The ID of the peer who sent the message.
- * @param type The type of message (normal, action, ...).
- * @param message The message data.
- * @param length The length of the message.
- */
- typedef void(uint32_t conference_number, uint32_t peer_number, MESSAGE_TYPE type,
- const uint8_t[length] message);
- }
-
-
- /**
- * This event is triggered when a peer changes the conference title.
- *
- * If peer_number == UINT32_MAX, then author is unknown (e.g. initial joining the conference).
- */
- event title const {
- /**
- * @param conference_number The conference number of the conference the title change is intended for.
- * @param peer_number The ID of the peer who changed the title.
- * @param title The title data.
- * @param length The title length.
- */
- typedef void(uint32_t conference_number, uint32_t peer_number, const uint8_t[length] title);
- }
-
- namespace peer {
-
- /**
- * This event is triggered when a peer changes their name.
- */
- event name const {
- /**
- * @param conference_number The conference number of the conference the
- * peer is in.
- * @param peer_number The ID of the peer who changed their nickname.
- * @param name A byte array containing the new nickname.
- * @param length The size of the name byte array.
- */
- typedef void(uint32_t conference_number, uint32_t peer_number, const uint8_t[length] name);
- }
-
- /**
- * This event is triggered when a peer joins or leaves the conference.
- */
- event list_changed const {
- /**
- * @param conference_number The conference number of the conference the
- * peer is in.
- */
- typedef void(uint32_t conference_number);
- }
-
- }
-
-
- /**
- * Creates a new conference.
- *
- * This function creates and connects to a new text conference.
- *
- * @return conference number on success, or an unspecified value on failure.
- */
- uint32_t new() {
- /**
- * The conference instance failed to initialize.
- */
- INIT,
- }
-
- /**
- * This function deletes a conference.
- *
- * @param conference_number The conference number of the conference to be deleted.
- *
- * @return true on success.
- */
- bool delete(uint32_t conference_number) {
- /**
- * The conference number passed did not designate a valid conference.
- */
- CONFERENCE_NOT_FOUND,
- }
-
- /**
- * Error codes for peer info queries.
- */
- error for peer_query {
- /**
- * The conference number passed did not designate a valid conference.
- */
- CONFERENCE_NOT_FOUND,
- /**
- * The peer number passed did not designate a valid peer.
- */
- PEER_NOT_FOUND,
- /**
- * The client is not connected to the conference.
- */
- NO_CONNECTION,
- }
-
-
- namespace peer {
-
- /**
- * Return the number of online peers in the conference. The unsigned
- * integers less than this number are the valid values of peer_number for
- * the functions querying these peers. Return value is unspecified on
- * failure.
- */
- const uint32_t count(uint32_t conference_number)
- with error for peer_query;
-
- uint8_t[size] name {
-
- /**
- * Return the length of the peer's name. Return value is unspecified on failure.
- */
- size(uint32_t conference_number, uint32_t peer_number)
- with error for peer_query;
-
- /**
- * Copy the name of peer_number who is in conference_number to name.
- *
- * Call $size to determine the allocation size for the `name` parameter.
- *
- * @param name A valid memory region large enough to store the peer's name.
- *
- * @return true on success.
- */
- get(uint32_t conference_number, uint32_t peer_number)
- with error for peer_query;
- }
-
- /**
- * Copy the public key of peer_number who is in conference_number to public_key.
- * public_key must be $PUBLIC_KEY_SIZE long.
- *
- * @return true on success.
- */
- uint8_t[PUBLIC_KEY_SIZE] public_key {
- get(uint32_t conference_number, uint32_t peer_number)
- with error for peer_query;
- }
-
- /**
- * Return true if passed peer_number corresponds to our own.
- */
- const bool number_is_ours(uint32_t conference_number, uint32_t peer_number)
- with error for peer_query;
-
- }
-
- namespace offline_peer {
-
- /**
- * Return the number of offline peers in the conference. The unsigned
- * integers less than this number are the valid values of offline_peer_number for
- * the functions querying these peers. Return value is unspecified on failure.
- */
- const uint32_t count(uint32_t conference_number)
- with error for peer_query;
-
- uint8_t[size] name {
-
- /**
- * Return the length of the offline peer's name. Return value is unspecified on failure.
- */
- size(uint32_t conference_number, uint32_t offline_peer_number)
- with error for peer_query;
-
- /**
- * Copy the name of offline_peer_number who is in conference_number to name.
- *
- * Call $size to determine the allocation size for the `name` parameter.
- *
- * @param name A valid memory region large enough to store the peer's name.
- *
- * @return true on success.
- */
- get(uint32_t conference_number, uint32_t offline_peer_number)
- with error for peer_query;
- }
-
- /**
- * Copy the public key of offline_peer_number who is in conference_number to public_key.
- * public_key must be $PUBLIC_KEY_SIZE long.
- *
- * @return true on success.
- */
- uint8_t[PUBLIC_KEY_SIZE] public_key {
- get(uint32_t conference_number, uint32_t offline_peer_number)
- with error for peer_query;
- }
-
- /**
- * Return a unix-time timestamp of the last time offline_peer_number was seen to be active.
- */
- uint64_t last_active {
- get(uint32_t conference_number, uint32_t offline_peer_number)
- with error for peer_query;
- }
-
- }
-
- /**
- * Set maximum number of offline peers to store, overriding the default.
- */
- bool set_max_offline(uint32_t conference_number, uint32_t max_offline_peers) {
- /**
- * The conference number passed did not designate a valid conference.
- */
- CONFERENCE_NOT_FOUND,
- }
-
-
- /**
- * Invites a friend to a conference.
- *
- * @param friend_number The friend number of the friend we want to invite.
- * @param conference_number The conference number of the conference we want to invite the friend to.
- *
- * @return true on success.
- */
- bool invite(uint32_t friend_number, uint32_t conference_number) {
- /**
- * The conference number passed did not designate a valid conference.
- */
- CONFERENCE_NOT_FOUND,
- /**
- * The invite packet failed to send.
- */
- FAIL_SEND,
- /**
- * The client is not connected to the conference.
- */
- NO_CONNECTION,
- }
-
-
- /**
- * Joins a conference that the client has been invited to.
- *
- * After successfully joining the conference, the client will not be "connected"
- * to it until a handshaking procedure has been completed. A
- * `${event connected}` event will then occur for the conference. The client
- * will then remain connected to the conference until the conference is deleted,
- * even across core restarts. Many operations on a conference will fail with a
- * corresponding error if attempted on a conference to which the client is not
- * yet connected.
- *
- * @param friend_number The friend number of the friend who sent the invite.
- * @param cookie Received via the `${event invite}` event.
- * @param length The size of cookie.
- *
- * @return conference number on success, an unspecified value on failure.
- */
- uint32_t join(uint32_t friend_number, const uint8_t[length] cookie) {
- /**
- * The cookie passed has an invalid length.
- */
- INVALID_LENGTH,
- /**
- * The conference is not the expected type. This indicates an invalid cookie.
- */
- WRONG_TYPE,
- /**
- * The friend number passed does not designate a valid friend.
- */
- FRIEND_NOT_FOUND,
- /**
- * Client is already in this conference.
- */
- DUPLICATE,
- /**
- * Conference instance failed to initialize.
- */
- INIT_FAIL,
- /**
- * The join packet failed to send.
- */
- FAIL_SEND,
- }
-
-
- namespace send {
-
- /**
- * Send a text chat message to the conference.
- *
- * This function creates a conference message packet and pushes it into the send
- * queue.
- *
- * The message length may not exceed $MAX_MESSAGE_LENGTH. Larger messages
- * must be split by the client and sent as separate messages. Other clients can
- * then reassemble the fragments.
- *
- * @param conference_number The conference number of the conference the message is intended for.
- * @param type Message type (normal, action, ...).
- * @param message A non-NULL pointer to the first element of a byte array
- * containing the message text.
- * @param length Length of the message to be sent.
- *
- * @return true on success.
- */
- bool message(uint32_t conference_number, MESSAGE_TYPE type, const uint8_t[length] message) {
- /**
- * The conference number passed did not designate a valid conference.
- */
- CONFERENCE_NOT_FOUND,
- /**
- * The message is too long.
- */
- TOO_LONG,
- /**
- * The client is not connected to the conference.
- */
- NO_CONNECTION,
- /**
- * The message packet failed to send.
- */
- FAIL_SEND,
- }
- }
-
- error for title {
- /**
- * The conference number passed did not designate a valid conference.
- */
- CONFERENCE_NOT_FOUND,
- /**
- * The title is too long or empty.
- */
- INVALID_LENGTH,
- /**
- * The title packet failed to send.
- */
- FAIL_SEND,
- }
-
- uint8_t[length <= MAX_NAME_LENGTH] title {
-
- /**
- * Return the length of the conference title. Return value is unspecified on failure.
- *
- * The return value is equal to the `length` argument received by the last
- * `${event title}` callback.
- */
- size(uint32_t conference_number)
- with error for title;
-
- /**
- * Write the title designated by the given conference number to a byte array.
- *
- * Call $size to determine the allocation size for the `title` parameter.
- *
- * The data written to `title` is equal to the data received by the last
- * `${event title}` callback.
- *
- * @param title A valid memory region large enough to store the title.
- * If this parameter is NULL, this function has no effect.
- *
- * @return true on success.
- */
- get(uint32_t conference_number)
- with error for title;
-
- /**
- * Set the conference title and broadcast it to the rest of the conference.
- *
- * Title length cannot be longer than $MAX_NAME_LENGTH.
- *
- * @return true on success.
- */
- set(uint32_t conference_number)
- with error for title;
- }
-
-
- uint32_t[size] chatlist {
- /**
- * Return the number of conferences in the Tox instance.
- * This should be used to determine how much memory to allocate for `$get`.
- */
- size();
-
- /**
- * Copy a list of valid conference numbers into the array chatlist. Determine
- * how much space to allocate for the array with the `$size` function.
- *
- * Note that `${savedata.get}` saves all connected conferences;
- * when toxcore is created from savedata in which conferences were saved, those
- * conferences will be connected at startup, and will be listed by
- * `$get`.
- *
- * The conference number of a loaded conference may differ from the conference
- * number it had when it was saved.
- */
- get();
- }
-
-
- /**
- * Returns the type of conference ($TYPE) that conference_number is. Return value is
- * unspecified on failure.
- */
- TYPE type {
- get(uint32_t conference_number) {
- /**
- * The conference number passed did not designate a valid conference.
- */
- CONFERENCE_NOT_FOUND,
- }
- }
-
- /**
- * Get the conference unique ID.
- *
- * If id is NULL, this function has no effect.
- *
- * @param id A memory region large enough to store $CONFERENCE_ID_SIZE bytes.
- *
- * @return true on success.
- */
- const bool get_id(uint32_t conference_number, uint8_t[CONFERENCE_ID_SIZE] id);
-
- /**
- * Return the conference number associated with the specified id.
- *
- * @param id A byte array containing the conference id ($CONFERENCE_ID_SIZE).
- *
- * @return the conference number on success, an unspecified value on failure.
- */
- const uint32_t by_id(const uint8_t[CONFERENCE_ID_SIZE] id) {
- NULL,
- /**
- * No conference with the given id exists on the conference list.
- */
- NOT_FOUND,
- }
-
- /**
- * Get the conference unique ID.
- *
- * If uid is NULL, this function has no effect.
- *
- * @param uid A memory region large enough to store $CONFERENCE_UID_SIZE bytes.
- *
- * @return true on success.
- * @deprecated use $get_id instead (exactly the same function, just renamed).
- */
- const bool get_uid(uint32_t conference_number, uint8_t[CONFERENCE_UID_SIZE] uid);
-
- /**
- * Return the conference number associated with the specified uid.
- *
- * @param uid A byte array containing the conference id ($CONFERENCE_UID_SIZE).
- *
- * @return the conference number on success, an unspecified value on failure.
- * @deprecated use $by_id instead (exactly the same function, just renamed).
- */
- const uint32_t by_uid(const uint8_t[CONFERENCE_UID_SIZE] uid) {
- NULL,
- /**
- * No conference with the given uid exists on the conference list.
- */
- NOT_FOUND,
- }
-
-}
-
-
-/*******************************************************************************
- *
- * :: Low-level custom packet sending and receiving
- *
- ******************************************************************************/
-
-
-namespace friend {
-
- error for custom_packet {
- NULL,
- /**
- * The friend number did not designate a valid friend.
- */
- FRIEND_NOT_FOUND,
- /**
- * This client is currently not connected to the friend.
- */
- FRIEND_NOT_CONNECTED,
- /**
- * The first byte of data was not in the specified range for the packet type.
- * This range is 192-254 for lossy, and 69, 160-191 for lossless packets.
- */
- INVALID,
- /**
- * Attempted to send an empty packet.
- */
- EMPTY,
- /**
- * Packet data length exceeded $MAX_CUSTOM_PACKET_SIZE.
- */
- TOO_LONG,
- /**
- * Packet queue is full.
- */
- SENDQ,
- }
-
- namespace send {
-
- /**
- * Send a custom lossy packet to a friend.
- *
- * The first byte of data must be in the range 192-254. Maximum length of a
- * custom packet is $MAX_CUSTOM_PACKET_SIZE.
- *
- * Lossy packets behave like UDP packets, meaning they might never reach the
- * other side or might arrive more than once (if someone is messing with the
- * connection) or might arrive in the wrong order.
- *
- * Unless latency is an issue, it is recommended that you use lossless custom
- * packets instead.
- *
- * @param friend_number The friend number of the friend this lossy packet
- * should be sent to.
- * @param data A byte array containing the packet data.
- * @param length The length of the packet data byte array.
- *
- * @return true on success.
- */
- bool lossy_packet(uint32_t friend_number, const uint8_t[length <= MAX_CUSTOM_PACKET_SIZE] data)
- with error for custom_packet;
-
-
- /**
- * Send a custom lossless packet to a friend.
- *
- * The first byte of data must be in the range 69, 160-191. Maximum length of a
- * custom packet is $MAX_CUSTOM_PACKET_SIZE.
- *
- * Lossless packet behaviour is comparable to TCP (reliability, arrive in order)
- * but with packets instead of a stream.
- *
- * @param friend_number The friend number of the friend this lossless packet
- * should be sent to.
- * @param data A byte array containing the packet data.
- * @param length The length of the packet data byte array.
- *
- * @return true on success.
- */
- bool lossless_packet(uint32_t friend_number, const uint8_t[length <= MAX_CUSTOM_PACKET_SIZE] data)
- with error for custom_packet;
-
- }
-
-
- event lossy_packet const {
- /**
- * @param friend_number The friend number of the friend who sent a lossy packet.
- * @param data A byte array containing the received packet data.
- * @param length The length of the packet data byte array.
- */
- typedef void(uint32_t friend_number, const uint8_t[length <= MAX_CUSTOM_PACKET_SIZE] data);
- }
-
-
- event lossless_packet const {
- /**
- * @param friend_number The friend number of the friend who sent the packet.
- * @param data A byte array containing the received packet data.
- * @param length The length of the packet data byte array.
- */
- typedef void(uint32_t friend_number, const uint8_t[length <= MAX_CUSTOM_PACKET_SIZE] data);
- }
-
-}
-
-
-
-/*******************************************************************************
- *
- * :: Low-level network information
- *
- ******************************************************************************/
-
-
-error for get_port {
- /**
- * The instance was not bound to any port.
- */
- NOT_BOUND,
-}
-
-namespace self {
-
- uint8_t[PUBLIC_KEY_SIZE] dht_id {
- /**
- * Writes the temporary DHT public key of this instance to a byte array.
- *
- * This can be used in combination with an externally accessible IP address and
- * the bound port (from ${udp_port.get}) to run a temporary bootstrap node.
- *
- * Be aware that every time a new instance is created, the DHT public key
- * changes, meaning this cannot be used to run a permanent bootstrap node.
- *
- * @param dht_id A memory region of at least $PUBLIC_KEY_SIZE bytes. If this
- * parameter is NULL, this function has no effect.
- */
- get();
- }
-
-
-
- uint16_t udp_port {
- /**
- * Return the UDP port this Tox instance is bound to.
- */
- get() with error for get_port;
- }
-
-
- uint16_t tcp_port {
- /**
- * Return the TCP port this Tox instance is bound to. This is only relevant if
- * the instance is acting as a TCP relay.
- */
- get() with error for get_port;
- }
-
-}
-
-} // class tox
-
-%{
-#ifdef __cplusplus
-}
-#endif
-
-typedef TOX_ERR_OPTIONS_NEW Tox_Err_Options_New;
-typedef TOX_ERR_NEW Tox_Err_New;
-typedef TOX_ERR_BOOTSTRAP Tox_Err_Bootstrap;
-typedef TOX_ERR_SET_INFO Tox_Err_Set_Info;
-typedef TOX_ERR_FRIEND_ADD Tox_Err_Friend_Add;
-typedef TOX_ERR_FRIEND_DELETE Tox_Err_Friend_Delete;
-typedef TOX_ERR_FRIEND_BY_PUBLIC_KEY Tox_Err_Friend_By_Public_Key;
-typedef TOX_ERR_FRIEND_GET_PUBLIC_KEY Tox_Err_Friend_Get_Public_Key;
-typedef TOX_ERR_FRIEND_GET_LAST_ONLINE Tox_Err_Friend_Get_Last_Online;
-typedef TOX_ERR_FRIEND_QUERY Tox_Err_Friend_Query;
-typedef TOX_ERR_SET_TYPING Tox_Err_Set_Typing;
-typedef TOX_ERR_FRIEND_SEND_MESSAGE Tox_Err_Friend_Send_Message;
-typedef TOX_ERR_FILE_CONTROL Tox_Err_File_Control;
-typedef TOX_ERR_FILE_SEEK Tox_Err_File_Seek;
-typedef TOX_ERR_FILE_GET Tox_Err_File_Get;
-typedef TOX_ERR_FILE_SEND Tox_Err_File_Send;
-typedef TOX_ERR_FILE_SEND_CHUNK Tox_Err_File_Send_Chunk;
-typedef TOX_ERR_CONFERENCE_NEW Tox_Err_Conference_New;
-typedef TOX_ERR_CONFERENCE_DELETE Tox_Err_Conference_Delete;
-typedef TOX_ERR_CONFERENCE_PEER_QUERY Tox_Err_Conference_Peer_Query;
-typedef TOX_ERR_CONFERENCE_SET_MAX_OFFLINE Tox_Err_Conference_Set_Max_Offline;
-typedef TOX_ERR_CONFERENCE_BY_ID Tox_Err_Conference_By_Id;
-typedef TOX_ERR_CONFERENCE_BY_UID Tox_Err_Conference_By_Uid;
-typedef TOX_ERR_CONFERENCE_INVITE Tox_Err_Conference_Invite;
-typedef TOX_ERR_CONFERENCE_JOIN Tox_Err_Conference_Join;
-typedef TOX_ERR_CONFERENCE_SEND_MESSAGE Tox_Err_Conference_Send_Message;
-typedef TOX_ERR_CONFERENCE_TITLE Tox_Err_Conference_Title;
-typedef TOX_ERR_CONFERENCE_GET_TYPE Tox_Err_Conference_Get_Type;
-typedef TOX_ERR_FRIEND_CUSTOM_PACKET Tox_Err_Friend_Custom_Packet;
-typedef TOX_ERR_GET_PORT Tox_Err_Get_Port;
-typedef TOX_USER_STATUS Tox_User_Status;
-typedef TOX_MESSAGE_TYPE Tox_Message_Type;
-typedef TOX_PROXY_TYPE Tox_Proxy_Type;
-typedef TOX_SAVEDATA_TYPE Tox_Savedata_Type;
-typedef TOX_LOG_LEVEL Tox_Log_Level;
-typedef TOX_CONNECTION Tox_Connection;
-typedef TOX_FILE_CONTROL Tox_File_Control;
-typedef TOX_CONFERENCE_TYPE Tox_Conference_Type;
-
-//!TOKSTYLE+
-
-#endif // C_TOXCORE_TOXCORE_TOX_H
-%}
diff --git a/protocols/Tox/libtox/src/toxcore/tox.c b/protocols/Tox/libtox/src/toxcore/tox.c
index 780d913667..fce8347c5e 100644
--- a/protocols/Tox/libtox/src/toxcore/tox.c
+++ b/protocols/Tox/libtox/src/toxcore/tox.c
@@ -3,18 +3,12 @@
* Copyright © 2013 Tox project.
*/
-/*
+/**
* The Tox public API.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#ifndef __cplusplus
#ifndef _XOPEN_SOURCE
#define _XOPEN_SOURCE 600
#endif
-#endif
#include "tox.h"
#include "tox_private.h"
@@ -30,39 +24,29 @@
#include "../toxencryptsave/defines.h"
-#define SET_ERROR_PARAMETER(param, x) do { if (param) { *param = x; } } while (0)
-
-#if TOX_HASH_LENGTH != CRYPTO_SHA256_SIZE
-#error "TOX_HASH_LENGTH is assumed to be equal to CRYPTO_SHA256_SIZE"
-#endif
-
-#if FILE_ID_LENGTH != CRYPTO_SYMMETRIC_KEY_SIZE
-#error "FILE_ID_LENGTH is assumed to be equal to CRYPTO_SYMMETRIC_KEY_SIZE"
-#endif
-
-#if TOX_FILE_ID_LENGTH != CRYPTO_SYMMETRIC_KEY_SIZE
-#error "TOX_FILE_ID_LENGTH is assumed to be equal to CRYPTO_SYMMETRIC_KEY_SIZE"
-#endif
-
-#if TOX_FILE_ID_LENGTH != TOX_HASH_LENGTH
-#error "TOX_FILE_ID_LENGTH is assumed to be equal to TOX_HASH_LENGTH"
-#endif
-
-#if TOX_PUBLIC_KEY_SIZE != CRYPTO_PUBLIC_KEY_SIZE
-#error "TOX_PUBLIC_KEY_SIZE is assumed to be equal to CRYPTO_PUBLIC_KEY_SIZE"
-#endif
-
-#if TOX_SECRET_KEY_SIZE != CRYPTO_SECRET_KEY_SIZE
-#error "TOX_SECRET_KEY_SIZE is assumed to be equal to CRYPTO_SECRET_KEY_SIZE"
-#endif
-
-#if TOX_MAX_NAME_LENGTH != MAX_NAME_LENGTH
-#error "TOX_MAX_NAME_LENGTH is assumed to be equal to MAX_NAME_LENGTH"
-#endif
-
-#if TOX_MAX_STATUS_MESSAGE_LENGTH != MAX_STATUSMESSAGE_LENGTH
-#error "TOX_MAX_STATUS_MESSAGE_LENGTH is assumed to be equal to MAX_STATUSMESSAGE_LENGTH"
-#endif
+#define SET_ERROR_PARAMETER(param, x) \
+ do { \
+ if (param) { \
+ *param = x; \
+ } \
+ } while (0)
+
+static_assert(TOX_HASH_LENGTH == CRYPTO_SHA256_SIZE,
+ "TOX_HASH_LENGTH is assumed to be equal to CRYPTO_SHA256_SIZE");
+static_assert(FILE_ID_LENGTH == CRYPTO_SYMMETRIC_KEY_SIZE,
+ "FILE_ID_LENGTH is assumed to be equal to CRYPTO_SYMMETRIC_KEY_SIZE");
+static_assert(TOX_FILE_ID_LENGTH == CRYPTO_SYMMETRIC_KEY_SIZE,
+ "TOX_FILE_ID_LENGTH is assumed to be equal to CRYPTO_SYMMETRIC_KEY_SIZE");
+static_assert(TOX_FILE_ID_LENGTH == TOX_HASH_LENGTH,
+ "TOX_FILE_ID_LENGTH is assumed to be equal to TOX_HASH_LENGTH");
+static_assert(TOX_PUBLIC_KEY_SIZE == CRYPTO_PUBLIC_KEY_SIZE,
+ "TOX_PUBLIC_KEY_SIZE is assumed to be equal to CRYPTO_PUBLIC_KEY_SIZE");
+static_assert(TOX_SECRET_KEY_SIZE == CRYPTO_SECRET_KEY_SIZE,
+ "TOX_SECRET_KEY_SIZE is assumed to be equal to CRYPTO_SECRET_KEY_SIZE");
+static_assert(TOX_MAX_NAME_LENGTH == MAX_NAME_LENGTH,
+ "TOX_MAX_NAME_LENGTH is assumed to be equal to MAX_NAME_LENGTH");
+static_assert(TOX_MAX_STATUS_MESSAGE_LENGTH == MAX_STATUSMESSAGE_LENGTH,
+ "TOX_MAX_STATUS_MESSAGE_LENGTH is assumed to be equal to MAX_STATUSMESSAGE_LENGTH");
struct Tox {
// XXX: Messenger *must* be the first member, because toxav casts its
@@ -367,7 +351,7 @@ static State_Load_Status state_load_callback(void *outer, const uint8_t *data, u
return STATE_LOAD_STATUS_CONTINUE;
}
-/* Load tox from data of size length. */
+/** Load tox from data of size length. */
static int tox_load(Tox *tox, const uint8_t *data, uint32_t length)
{
uint32_t data32[2];
@@ -388,7 +372,6 @@ static int tox_load(Tox *tox, const uint8_t *data, uint32_t length)
length - cookie_len, STATE_COOKIE_TYPE);
}
-
Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error)
{
Tox *tox = (Tox *)calloc(1, sizeof(Tox));
@@ -410,13 +393,15 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error)
default_options = tox_options_new(&err);
switch (err) {
- case TOX_ERR_OPTIONS_NEW_OK:
+ case TOX_ERR_OPTIONS_NEW_OK: {
break;
+ }
- case TOX_ERR_OPTIONS_NEW_MALLOC:
+ case TOX_ERR_OPTIONS_NEW_MALLOC: {
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC);
free(tox);
return nullptr;
+ }
}
}
@@ -449,7 +434,7 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error)
return nullptr;
}
- if (crypto_memcmp(tox_options_get_savedata_data(opts), TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) == 0) {
+ if (memcmp(tox_options_get_savedata_data(opts), TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) == 0) {
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_LOAD_ENCRYPTED);
tox_options_free(default_options);
free(tox);
@@ -472,23 +457,27 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error)
m_options.log_user_data = tox_options_get_log_user_data(opts);
switch (tox_options_get_proxy_type(opts)) {
- case TOX_PROXY_TYPE_HTTP:
+ case TOX_PROXY_TYPE_HTTP: {
m_options.proxy_info.proxy_type = TCP_PROXY_HTTP;
break;
+ }
- case TOX_PROXY_TYPE_SOCKS5:
+ case TOX_PROXY_TYPE_SOCKS5: {
m_options.proxy_info.proxy_type = TCP_PROXY_SOCKS5;
break;
+ }
- case TOX_PROXY_TYPE_NONE:
+ case TOX_PROXY_TYPE_NONE: {
m_options.proxy_info.proxy_type = TCP_PROXY_NONE;
break;
+ }
- default:
+ default: {
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_PROXY_BAD_TYPE);
tox_options_free(default_options);
free(tox);
return nullptr;
+ }
}
if (m_options.proxy_info.proxy_type != TCP_PROXY_NONE) {
@@ -526,7 +515,7 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error)
}
if (tox_options_get_experimental_thread_safety(opts)) {
- tox->mutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
+ tox->mutex = (pthread_mutex_t *)calloc(1, sizeof(pthread_mutex_t));
if (tox->mutex == nullptr) {
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC);
@@ -703,20 +692,22 @@ bool tox_bootstrap(Tox *tox, const char *host, uint16_t port, const uint8_t *pub
const int32_t count = net_getipport(host, &root, TOX_SOCK_DGRAM);
if (count == -1) {
+ LOGGER_DEBUG(tox->m->log, "could not resolve bootstrap node '%s'", host);
net_freeipport(root);
SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_BAD_HOST);
return 0;
}
- unsigned int i;
-
lock(tox);
- for (i = 0; i < count; ++i) {
+ for (int32_t i = 0; i < count; ++i) {
root[i].port = net_htons(port);
- onion_add_bs_path_node(tox->m->onion_c, root[i], public_key);
- dht_bootstrap(tox->m->dht, root[i], public_key);
+ onion_add_bs_path_node(tox->m->onion_c, &root[i], public_key);
+
+ if (!tox->m->options.udp_disabled) {
+ dht_bootstrap(tox->m->dht, &root[i], public_key);
+ }
}
unlock(tox);
@@ -728,6 +719,7 @@ bool tox_bootstrap(Tox *tox, const char *host, uint16_t port, const uint8_t *pub
return 1;
}
+ LOGGER_DEBUG(tox->m->log, "bootstrap node '%s' resolved to 0 IP_Ports", host);
SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_BAD_HOST);
return 0;
}
@@ -749,7 +741,7 @@ bool tox_add_tcp_relay(Tox *tox, const char *host, uint16_t port, const uint8_t
IP_Port *root;
- int32_t count = net_getipport(host, &root, TOX_SOCK_STREAM);
+ const int32_t count = net_getipport(host, &root, TOX_SOCK_STREAM);
if (count == -1) {
net_freeipport(root);
@@ -757,14 +749,12 @@ bool tox_add_tcp_relay(Tox *tox, const char *host, uint16_t port, const uint8_t
return 0;
}
- unsigned int i;
-
lock(tox);
- for (i = 0; i < count; ++i) {
+ for (int32_t i = 0; i < count; ++i) {
root[i].port = net_htons(port);
- add_tcp_relay(tox->m->net_crypto, root[i], public_key);
+ add_tcp_relay(tox->m->net_crypto, &root[i], public_key);
}
unlock(tox);
@@ -984,38 +974,46 @@ Tox_User_Status tox_self_get_status(const Tox *tox)
static void set_friend_error(const Logger *log, int32_t ret, Tox_Err_Friend_Add *error)
{
switch (ret) {
- case FAERR_TOOLONG:
+ case FAERR_TOOLONG: {
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_ADD_TOO_LONG);
break;
+ }
- case FAERR_NOMESSAGE:
+ case FAERR_NOMESSAGE: {
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_ADD_NO_MESSAGE);
break;
+ }
- case FAERR_OWNKEY:
+ case FAERR_OWNKEY: {
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_ADD_OWN_KEY);
break;
+ }
- case FAERR_ALREADYSENT:
+ case FAERR_ALREADYSENT: {
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_ADD_ALREADY_SENT);
break;
+ }
- case FAERR_BADCHECKSUM:
+ case FAERR_BADCHECKSUM: {
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_ADD_BAD_CHECKSUM);
break;
+ }
- case FAERR_SETNEWNOSPAM:
+ case FAERR_SETNEWNOSPAM: {
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_ADD_SET_NEW_NOSPAM);
break;
+ }
- case FAERR_NOMEM:
+ case FAERR_NOMEM: {
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_ADD_MALLOC);
break;
+ }
- default:
+ default: {
/* can't happen */
- LOGGER_FATAL(log, "impossible: unknown friend-add error");
+ LOGGER_FATAL(log, "impossible return value: %d", ret);
break;
+ }
}
}
@@ -1351,34 +1349,41 @@ bool tox_self_set_typing(Tox *tox, uint32_t friend_number, bool typing, Tox_Err_
static void set_message_error(const Logger *log, int ret, Tox_Err_Friend_Send_Message *error)
{
switch (ret) {
- case 0:
+ case 0: {
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_SEND_MESSAGE_OK);
break;
+ }
- case -1:
+ case -1: {
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_SEND_MESSAGE_FRIEND_NOT_FOUND);
break;
+ }
- case -2:
+ case -2: {
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_SEND_MESSAGE_TOO_LONG);
break;
+ }
- case -3:
+ case -3: {
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_SEND_MESSAGE_FRIEND_NOT_CONNECTED);
break;
+ }
- case -4:
+ case -4: {
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_SEND_MESSAGE_SENDQ);
break;
+ }
- case -5:
+ case -5: {
LOGGER_FATAL(log, "impossible: Messenger and Tox disagree on message types");
break;
+ }
- default:
+ default: {
/* can't happen */
- LOGGER_FATAL(log, "impossible: unknown send-message error: %d", ret);
+ LOGGER_FATAL(log, "impossible return value: %d", ret);
break;
+ }
}
}
@@ -1447,40 +1452,51 @@ bool tox_file_control(Tox *tox, uint32_t friend_number, uint32_t file_number, To
}
switch (ret) {
- case -1:
+ case -1: {
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_CONTROL_FRIEND_NOT_FOUND);
return 0;
+ }
- case -2:
+ case -2: {
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_CONTROL_FRIEND_NOT_CONNECTED);
return 0;
+ }
- case -3:
+ case -3: {
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_CONTROL_NOT_FOUND);
return 0;
+ }
- case -4:
- /* can't happen */
+ case -4: {
+ /* can't happen (this code is returned if `control` is invalid type) */
+ LOGGER_FATAL(tox->m->log, "impossible return value: %d", ret);
return 0;
+ }
- case -5:
+ case -5: {
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_CONTROL_ALREADY_PAUSED);
return 0;
+ }
- case -6:
+ case -6: {
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_CONTROL_DENIED);
return 0;
+ }
- case -7:
+ case -7: {
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_CONTROL_NOT_PAUSED);
return 0;
+ }
- case -8:
+ case -8: {
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_CONTROL_SENDQ);
return 0;
+ }
}
/* can't happen */
+ LOGGER_FATAL(tox->m->log, "impossible return value: %d", ret);
+
return 0;
}
@@ -1498,33 +1514,41 @@ bool tox_file_seek(Tox *tox, uint32_t friend_number, uint32_t file_number, uint6
}
switch (ret) {
- case -1:
+ case -1: {
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_SEEK_FRIEND_NOT_FOUND);
return 0;
+ }
- case -2:
+ case -2: {
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_SEEK_FRIEND_NOT_CONNECTED);
return 0;
+ }
- case -3:
+ case -3: {
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_SEEK_NOT_FOUND);
return 0;
+ }
case -4: // fall-through
- case -5:
+ case -5: {
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_SEEK_DENIED);
return 0;
+ }
- case -6:
+ case -6: {
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_SEEK_INVALID_POSITION);
return 0;
+ }
- case -8:
+ case -8: {
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_SEEK_SENDQ);
return 0;
+ }
}
/* can't happen */
+ LOGGER_FATAL(tox->m->log, "impossible return value: %d", ret);
+
return 0;
}
@@ -1590,24 +1614,30 @@ uint32_t tox_file_send(Tox *tox, uint32_t friend_number, uint32_t kind, uint64_t
}
switch (file_num) {
- case -1:
+ case -1: {
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_SEND_FRIEND_NOT_FOUND);
return UINT32_MAX;
+ }
- case -2:
+ case -2: {
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_SEND_NAME_TOO_LONG);
return UINT32_MAX;
+ }
- case -3:
+ case -3: {
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_SEND_TOO_MANY);
return UINT32_MAX;
+ }
- case -4:
+ case -4: {
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_SEND_FRIEND_NOT_CONNECTED);
return UINT32_MAX;
+ }
}
/* can't happen */
+ LOGGER_FATAL(tox->m->log, "impossible return value: %ld", file_num);
+
return UINT32_MAX;
}
@@ -1625,36 +1655,45 @@ bool tox_file_send_chunk(Tox *tox, uint32_t friend_number, uint32_t file_number,
}
switch (ret) {
- case -1:
+ case -1: {
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_SEND_CHUNK_FRIEND_NOT_FOUND);
return 0;
+ }
- case -2:
+ case -2: {
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_SEND_CHUNK_FRIEND_NOT_CONNECTED);
return 0;
+ }
- case -3:
+ case -3: {
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_SEND_CHUNK_NOT_FOUND);
return 0;
+ }
- case -4:
+ case -4: {
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_SEND_CHUNK_NOT_TRANSFERRING);
return 0;
+ }
- case -5:
+ case -5: {
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_SEND_CHUNK_INVALID_LENGTH);
return 0;
+ }
- case -6:
+ case -6: {
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_SEND_CHUNK_SENDQ);
return 0;
+ }
- case -7:
+ case -7: {
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_SEND_CHUNK_WRONG_POSITION);
return 0;
+ }
}
/* can't happen */
+ LOGGER_FATAL(tox->m->log, "impossible return value: %d", ret);
+
return 0;
}
@@ -1769,13 +1808,15 @@ size_t tox_conference_peer_get_name_size(const Tox *tox, uint32_t conference_num
unlock(tox);
switch (ret) {
- case -1:
+ case -1: {
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_PEER_QUERY_CONFERENCE_NOT_FOUND);
return -1;
+ }
- case -2:
+ case -2: {
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_PEER_QUERY_PEER_NOT_FOUND);
return -1;
+ }
}
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_PEER_QUERY_OK);
@@ -1791,13 +1832,15 @@ bool tox_conference_peer_get_name(const Tox *tox, uint32_t conference_number, ui
unlock(tox);
switch (ret) {
- case -1:
+ case -1: {
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_PEER_QUERY_CONFERENCE_NOT_FOUND);
return false;
+ }
- case -2:
+ case -2: {
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_PEER_QUERY_PEER_NOT_FOUND);
return false;
+ }
}
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_PEER_QUERY_OK);
@@ -1813,13 +1856,15 @@ bool tox_conference_peer_get_public_key(const Tox *tox, uint32_t conference_numb
unlock(tox);
switch (ret) {
- case -1:
+ case -1: {
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_PEER_QUERY_CONFERENCE_NOT_FOUND);
return false;
+ }
- case -2:
+ case -2: {
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_PEER_QUERY_PEER_NOT_FOUND);
return false;
+ }
}
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_PEER_QUERY_OK);
@@ -1835,17 +1880,20 @@ bool tox_conference_peer_number_is_ours(const Tox *tox, uint32_t conference_numb
unlock(tox);
switch (ret) {
- case -1:
+ case -1: {
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_PEER_QUERY_CONFERENCE_NOT_FOUND);
return false;
+ }
- case -2:
+ case -2: {
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_PEER_QUERY_PEER_NOT_FOUND);
return false;
+ }
- case -3:
+ case -3: {
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_PEER_QUERY_NO_CONNECTION);
return false;
+ }
}
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_PEER_QUERY_OK);
@@ -1879,13 +1927,15 @@ size_t tox_conference_offline_peer_get_name_size(const Tox *tox, uint32_t confer
unlock(tox);
switch (ret) {
- case -1:
+ case -1: {
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_PEER_QUERY_CONFERENCE_NOT_FOUND);
return -1;
+ }
- case -2:
+ case -2: {
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_PEER_QUERY_PEER_NOT_FOUND);
return -1;
+ }
}
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_PEER_QUERY_OK);
@@ -1902,13 +1952,15 @@ bool tox_conference_offline_peer_get_name(const Tox *tox, uint32_t conference_nu
unlock(tox);
switch (ret) {
- case -1:
+ case -1: {
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_PEER_QUERY_CONFERENCE_NOT_FOUND);
return false;
+ }
- case -2:
+ case -2: {
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_PEER_QUERY_PEER_NOT_FOUND);
return false;
+ }
}
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_PEER_QUERY_OK);
@@ -1925,13 +1977,15 @@ bool tox_conference_offline_peer_get_public_key(const Tox *tox, uint32_t confere
unlock(tox);
switch (ret) {
- case -1:
+ case -1: {
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_PEER_QUERY_CONFERENCE_NOT_FOUND);
return false;
+ }
- case -2:
+ case -2: {
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_PEER_QUERY_PEER_NOT_FOUND);
return false;
+ }
}
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_PEER_QUERY_OK);
@@ -1950,13 +2004,15 @@ uint64_t tox_conference_offline_peer_get_last_active(const Tox *tox, uint32_t co
unlock(tox);
switch (ret) {
- case -1:
+ case -1: {
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_PEER_QUERY_CONFERENCE_NOT_FOUND);
return UINT64_MAX;
+ }
- case -2:
+ case -2: {
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_PEER_QUERY_PEER_NOT_FOUND);
return UINT64_MAX;
+ }
}
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_PEER_QUERY_OK);
@@ -1990,17 +2046,20 @@ bool tox_conference_invite(Tox *tox, uint32_t friend_number, uint32_t conference
unlock(tox);
switch (ret) {
- case -1:
+ case -1: {
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_INVITE_CONFERENCE_NOT_FOUND);
return false;
+ }
- case -2:
+ case -2: {
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_INVITE_FAIL_SEND);
return false;
+ }
- case -3:
+ case -3: {
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_INVITE_NO_CONNECTION);
return false;
+ }
}
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_INVITE_OK);
@@ -2016,29 +2075,35 @@ uint32_t tox_conference_join(Tox *tox, uint32_t friend_number, const uint8_t *co
unlock(tox);
switch (ret) {
- case -1:
+ case -1: {
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_JOIN_INVALID_LENGTH);
return UINT32_MAX;
+ }
- case -2:
+ case -2: {
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_JOIN_WRONG_TYPE);
return UINT32_MAX;
+ }
- case -3:
+ case -3: {
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_JOIN_FRIEND_NOT_FOUND);
return UINT32_MAX;
+ }
- case -4:
+ case -4: {
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_JOIN_DUPLICATE);
return UINT32_MAX;
+ }
- case -5:
+ case -5: {
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_JOIN_INIT_FAIL);
return UINT32_MAX;
+ }
- case -6:
+ case -6: {
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_JOIN_FAIL_SEND);
return UINT32_MAX;
+ }
}
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_JOIN_OK);
@@ -2061,21 +2126,25 @@ bool tox_conference_send_message(Tox *tox, uint32_t conference_number, Tox_Messa
unlock(tox);
switch (ret) {
- case -1:
+ case -1: {
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_SEND_MESSAGE_CONFERENCE_NOT_FOUND);
return false;
+ }
- case -2:
+ case -2: {
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_SEND_MESSAGE_TOO_LONG);
return false;
+ }
- case -3:
+ case -3: {
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_SEND_MESSAGE_NO_CONNECTION);
return false;
+ }
- case -4:
+ case -4: {
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_SEND_MESSAGE_FAIL_SEND);
return false;
+ }
}
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_SEND_MESSAGE_OK);
@@ -2090,13 +2159,15 @@ size_t tox_conference_get_title_size(const Tox *tox, uint32_t conference_number,
unlock(tox);
switch (ret) {
- case -1:
+ case -1: {
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_TITLE_CONFERENCE_NOT_FOUND);
return -1;
+ }
- case -2:
+ case -2: {
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_TITLE_INVALID_LENGTH);
return -1;
+ }
}
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_TITLE_OK);
@@ -2112,13 +2183,15 @@ bool tox_conference_get_title(const Tox *tox, uint32_t conference_number, uint8_
unlock(tox);
switch (ret) {
- case -1:
+ case -1: {
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_TITLE_CONFERENCE_NOT_FOUND);
return false;
+ }
- case -2:
+ case -2: {
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_TITLE_INVALID_LENGTH);
return false;
+ }
}
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_TITLE_OK);
@@ -2134,17 +2207,20 @@ bool tox_conference_set_title(Tox *tox, uint32_t conference_number, const uint8_
unlock(tox);
switch (ret) {
- case -1:
+ case -1: {
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_TITLE_CONFERENCE_NOT_FOUND);
return false;
+ }
- case -2:
+ case -2: {
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_TITLE_INVALID_LENGTH);
return false;
+ }
- case -3:
+ case -3: {
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_TITLE_FAIL_SEND);
return false;
+ }
}
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_TITLE_OK);
@@ -2186,7 +2262,6 @@ Tox_Conference_Type tox_conference_get_type(const Tox *tox, uint32_t conference_
return (Tox_Conference_Type)ret;
}
-/* id is TOX_CONFERENCE_ID_SIZE bytes */
bool tox_conference_get_id(const Tox *tox, uint32_t conference_number, uint8_t *id)
{
assert(tox != nullptr);
@@ -2197,7 +2272,6 @@ bool tox_conference_get_id(const Tox *tox, uint32_t conference_number, uint8_t *
}
// TODO(iphydf): Delete in 0.3.0.
-/* uid is TOX_CONFERENCE_ID_SIZE bytes */
bool tox_conference_get_uid(const Tox *tox, uint32_t conference_number, uint8_t *uid)
{
assert(tox != nullptr);
@@ -2234,17 +2308,20 @@ uint32_t tox_conference_by_uid(const Tox *tox, const uint8_t *uid, Tox_Err_Confe
const uint32_t res = tox_conference_by_id(tox, uid, &id_error);
switch (id_error) {
- case TOX_ERR_CONFERENCE_BY_ID_OK:
+ case TOX_ERR_CONFERENCE_BY_ID_OK: {
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_BY_UID_OK);
break;
+ }
- case TOX_ERR_CONFERENCE_BY_ID_NULL:
+ case TOX_ERR_CONFERENCE_BY_ID_NULL: {
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_BY_UID_NULL);
break;
+ }
- case TOX_ERR_CONFERENCE_BY_ID_NOT_FOUND:
+ case TOX_ERR_CONFERENCE_BY_ID_NOT_FOUND: {
SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_BY_UID_NOT_FOUND);
break;
+ }
}
return res;
@@ -2253,29 +2330,35 @@ uint32_t tox_conference_by_uid(const Tox *tox, const uint8_t *uid, Tox_Err_Confe
static void set_custom_packet_error(int ret, Tox_Err_Friend_Custom_Packet *error)
{
switch (ret) {
- case 0:
+ case 0: {
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_CUSTOM_PACKET_OK);
break;
+ }
- case -1:
+ case -1: {
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_CUSTOM_PACKET_FRIEND_NOT_FOUND);
break;
+ }
- case -2:
+ case -2: {
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_CUSTOM_PACKET_TOO_LONG);
break;
+ }
- case -3:
+ case -3: {
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_CUSTOM_PACKET_INVALID);
break;
+ }
- case -4:
+ case -4: {
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_CUSTOM_PACKET_FRIEND_NOT_CONNECTED);
break;
+ }
- case -5:
+ case -5: {
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_CUSTOM_PACKET_SENDQ);
break;
+ }
}
}
diff --git a/protocols/Tox/libtox/src/toxcore/tox.h b/protocols/Tox/libtox/src/toxcore/tox.h
index ab71986e9e..38ec9f4b5a 100644
--- a/protocols/Tox/libtox/src/toxcore/tox.h
+++ b/protocols/Tox/libtox/src/toxcore/tox.h
@@ -3,33 +3,8 @@
* Copyright © 2013 Tox project.
*/
-/*
- * The Tox public API.
- */
-#ifndef C_TOXCORE_TOXCORE_TOX_H
-#define C_TOXCORE_TOXCORE_TOX_H
-
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdint.h>
-
-//!TOKSTYLE-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/*******************************************************************************
- * `tox.h` SHOULD *NOT* BE EDITED MANUALLY – any changes should be made to *
- * `tox.api.h`, located in `toxcore/`. For instructions on how to *
- * generate `tox.h` from `tox.api.h` please refer to `docs/apidsl.md` *
- ******************************************************************************/
-
-
-
-/**
- * @page core Public core API for Tox clients.
+/** @file
+ * @brief Public core API for Tox clients.
*
* Every function that can fail takes a function-specific error code pointer
* that can be used to diagnose problems with the Tox state or the function
@@ -66,9 +41,8 @@ extern "C" {
*
* Integer constants and the memory layout of publicly exposed structs are not
* part of the ABI.
- */
-/**
- * @subsection events Events and callbacks
+ *
+ * @section events Events and callbacks
*
* Events are handled by callbacks. One callback can be registered per event.
* All events have a callback function type named `tox_{event}_cb` and a
@@ -89,9 +63,8 @@ extern "C" {
* Old style callbacks that are registered together with a user data pointer
* receive that pointer as argument when they are called. They can each have
* their own user data pointer of their own type.
- */
-/**
- * @subsection threading Threading implications
+ *
+ * @section threading Threading implications
*
* It is possible to run multiple concurrent threads with a Tox instance for
* each thread. It is also possible to run all Tox instances in the same thread.
@@ -124,30 +97,40 @@ extern "C" {
* memory, the length may have become invalid, and the call to
* tox_self_get_name may cause undefined behaviour.
*/
+#ifndef C_TOXCORE_TOXCORE_TOX_H
+#define C_TOXCORE_TOXCORE_TOX_H
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef TOX_DEFINED
+#define TOX_DEFINED
/**
- * The Tox instance type. All the state associated with a connection is held
+ * @brief The Tox instance type.
+ *
+ * All the state associated with a connection is held
* within the instance. Multiple instances can exist and operate concurrently.
* The maximum number of Tox instances that can exist on a single network
* device is limited. Note that this is not just a per-process limit, since the
* limiting factor is the number of usable ports on a device.
*/
-#ifndef TOX_DEFINED
-#define TOX_DEFINED
typedef struct Tox Tox;
#endif /* TOX_DEFINED */
-/*******************************************************************************
- *
- * :: API version
- *
- ******************************************************************************/
-
-
+/** @{
+ * @name API version
+ */
/**
- * The major version number. Incremented when the API or ABI changes in an
- * incompatible way.
+ * @brief The major version number.
+ *
+ * Incremented when the API or ABI changes in an incompatible way.
*
* The function variants of these constants return the version number of the
* library. They can be used to display the Tox library version or to check
@@ -158,27 +141,33 @@ typedef struct Tox Tox;
uint32_t tox_version_major(void);
/**
- * The minor version number. Incremented when functionality is added without
- * breaking the API or ABI. Set to 0 when the major version number is
- * incremented.
+ * @brief The minor version number.
+ *
+ * Incremented when functionality is added without breaking the API or ABI.
+ * Set to 0 when the major version number is incremented.
*/
#define TOX_VERSION_MINOR 2
uint32_t tox_version_minor(void);
/**
- * The patch or revision number. Incremented when bugfixes are applied without
- * changing any functionality or API or ABI.
+ * @brief The patch or revision number.
+ *
+ * Incremented when bugfixes are applied without changing any functionality or
+ * API or ABI.
*/
-#define TOX_VERSION_PATCH 13
+#define TOX_VERSION_PATCH 15
uint32_t tox_version_patch(void);
+//!TOKSTYLE-
/**
- * A macro to check at preprocessing time whether the client code is compatible
- * with the installed version of Tox. Leading zeros in the version number are
- * ignored. E.g. 0.1.5 is to 0.1.4 what 1.5 is to 1.4, that is: it can add new
- * features, but can't break the API.
+ * @brief A macro to check at preprocessing time whether the client code is
+ * compatible with the installed version of Tox.
+ *
+ * Leading zeros in the version number are ignored. E.g. 0.1.5 is to 0.1.4
+ * what 1.5 is to 1.4, that is: it can add new features, but can't break the
+ * API.
*/
#define TOX_VERSION_IS_API_COMPATIBLE(MAJOR, MINOR, PATCH) \
((TOX_VERSION_MAJOR > 0 && TOX_VERSION_MAJOR == MAJOR) && ( \
@@ -194,49 +183,48 @@ uint32_t tox_version_patch(void);
TOX_VERSION_PATCH == PATCH \
)) \
))
+//!TOKSTYLE+
/**
- * Return whether the compiled library version is compatible with the passed
- * version numbers.
+ * @brief Return whether the compiled library version is compatible with the
+ * passed version numbers.
*/
bool tox_version_is_compatible(uint32_t major, uint32_t minor, uint32_t patch);
/**
- * A convenience macro to call tox_version_is_compatible with the currently
- * compiling API version.
+ * @brief A convenience macro to call tox_version_is_compatible with the
+ * currently compiling API version.
*/
#define TOX_VERSION_IS_ABI_COMPATIBLE() \
tox_version_is_compatible(TOX_VERSION_MAJOR, TOX_VERSION_MINOR, TOX_VERSION_PATCH)
+/** @} */
-/*******************************************************************************
- *
- * :: Numeric constants
+
+/** @{
+ * @name Numeric constants
*
* The values of these are not part of the ABI. Prefer to use the function
* versions of them for code that should remain compatible with future versions
* of toxcore.
- *
- ******************************************************************************/
-
-
+ */
/**
- * The size of a Tox Public Key in bytes.
+ * @brief The size of a Tox Public Key in bytes.
*/
#define TOX_PUBLIC_KEY_SIZE 32
uint32_t tox_public_key_size(void);
/**
- * The size of a Tox Secret Key in bytes.
+ * @brief The size of a Tox Secret Key in bytes.
*/
#define TOX_SECRET_KEY_SIZE 32
uint32_t tox_secret_key_size(void);
/**
- * The size of a Tox Conference unique id in bytes.
+ * @brief The size of a Tox Conference unique id in bytes.
*
* @deprecated Use TOX_CONFERENCE_ID_SIZE instead.
*/
@@ -245,22 +233,24 @@ uint32_t tox_secret_key_size(void);
uint32_t tox_conference_uid_size(void);
/**
- * The size of a Tox Conference unique id in bytes.
+ * @brief The size of a Tox Conference unique id in bytes.
*/
#define TOX_CONFERENCE_ID_SIZE 32
uint32_t tox_conference_id_size(void);
/**
- * The size of the nospam in bytes when written in a Tox address.
+ * @brief The size of the nospam in bytes when written in a Tox address.
*/
#define TOX_NOSPAM_SIZE (sizeof(uint32_t))
uint32_t tox_nospam_size(void);
/**
- * The size of a Tox address in bytes. Tox addresses are in the format
- * [Public Key (TOX_PUBLIC_KEY_SIZE bytes)][nospam (4 bytes)][checksum (2 bytes)].
+ * @brief The size of a Tox address in bytes.
+ *
+ * Tox addresses are in the format
+ * `[Public Key (TOX_PUBLIC_KEY_SIZE bytes)][nospam (4 bytes)][checksum (2 bytes)]`.
*
* The checksum is computed over the Public Key and the nospam value. The first
* byte is an XOR of all the even bytes (0, 2, 4, ...), the second byte is an
@@ -271,7 +261,7 @@ uint32_t tox_nospam_size(void);
uint32_t tox_address_size(void);
/**
- * Maximum length of a nickname in bytes.
+ * @brief Maximum length of a nickname in bytes.
*
* @deprecated The macro will be removed in 0.3.0. Use the function instead.
*/
@@ -280,7 +270,7 @@ uint32_t tox_address_size(void);
uint32_t tox_max_name_length(void);
/**
- * Maximum length of a status message in bytes.
+ * @brief Maximum length of a status message in bytes.
*
* @deprecated The macro will be removed in 0.3.0. Use the function instead.
*/
@@ -289,7 +279,7 @@ uint32_t tox_max_name_length(void);
uint32_t tox_max_status_message_length(void);
/**
- * Maximum length of a friend request message in bytes.
+ * @brief Maximum length of a friend request message in bytes.
*
* @deprecated The macro will be removed in 0.3.0. Use the function instead.
*/
@@ -298,7 +288,7 @@ uint32_t tox_max_status_message_length(void);
uint32_t tox_max_friend_request_length(void);
/**
- * Maximum length of a single message after which it should be split.
+ * @brief Maximum length of a single message after which it should be split.
*
* @deprecated The macro will be removed in 0.3.0. Use the function instead.
*/
@@ -307,7 +297,7 @@ uint32_t tox_max_friend_request_length(void);
uint32_t tox_max_message_length(void);
/**
- * Maximum size of custom packets. TODO(iphydf): should be LENGTH?
+ * @brief Maximum size of custom packets. TODO(iphydf): should be LENGTH?
*
* @deprecated The macro will be removed in 0.3.0. Use the function instead.
*/
@@ -316,21 +306,21 @@ uint32_t tox_max_message_length(void);
uint32_t tox_max_custom_packet_size(void);
/**
- * The number of bytes in a hash generated by tox_hash.
+ * @brief The number of bytes in a hash generated by tox_hash.
*/
#define TOX_HASH_LENGTH 32
uint32_t tox_hash_length(void);
/**
- * The number of bytes in a file id.
+ * @brief The number of bytes in a file id.
*/
#define TOX_FILE_ID_LENGTH 32
uint32_t tox_file_id_length(void);
/**
- * Maximum file name length for file transfers.
+ * @brief Maximum file name length for file transfers.
*
* @deprecated The macro will be removed in 0.3.0. Use the function instead.
*/
@@ -339,7 +329,7 @@ uint32_t tox_file_id_length(void);
uint32_t tox_max_filename_length(void);
/**
- * Maximum length of a hostname, e.g. proxy or bootstrap node names.
+ * @brief Maximum length of a hostname, e.g. proxy or bootstrap node names.
*
* This length does not include the NUL byte. Hostnames are NUL-terminated C
* strings, so they are 255 characters plus one NUL byte.
@@ -350,22 +340,17 @@ uint32_t tox_max_filename_length(void);
uint32_t tox_max_hostname_length(void);
-
-/*******************************************************************************
- *
- * :: Global enumerations
- *
- ******************************************************************************/
+/** @} */
+/** @{
+ * @name Global enumerations
+ */
/**
- * Represents the possible statuses a client can have.
- *
- * @deprecated All UPPER_CASE enum type names are deprecated. Use the
- * Camel_Snake_Case versions, instead.
+ * @brief Represents the possible statuses a client can have.
*/
-typedef enum TOX_USER_STATUS {
+typedef enum Tox_User_Status {
/**
* User is online and available.
@@ -384,17 +369,14 @@ typedef enum TOX_USER_STATUS {
*/
TOX_USER_STATUS_BUSY,
-} TOX_USER_STATUS;
+} Tox_User_Status;
/**
- * Represents message types for tox_friend_send_message and conference
+ * @brief Represents message types for tox_friend_send_message and conference
* messages.
- *
- * @deprecated All UPPER_CASE enum type names are deprecated. Use the
- * Camel_Snake_Case versions, instead.
*/
-typedef enum TOX_MESSAGE_TYPE {
+typedef enum Tox_Message_Type {
/**
* Normal text message. Similar to PRIVMSG on IRC.
@@ -407,25 +389,19 @@ typedef enum TOX_MESSAGE_TYPE {
*/
TOX_MESSAGE_TYPE_ACTION,
-} TOX_MESSAGE_TYPE;
+} Tox_Message_Type;
+/** @} */
-/*******************************************************************************
- *
- * :: Startup options
- *
- ******************************************************************************/
-
-
+/** @{
+ * @name Startup options
+ */
/**
- * Type of proxy used to connect to TCP relays.
- *
- * @deprecated All UPPER_CASE enum type names are deprecated. Use the
- * Camel_Snake_Case versions, instead.
+ * @brief Type of proxy used to connect to TCP relays.
*/
-typedef enum TOX_PROXY_TYPE {
+typedef enum Tox_Proxy_Type {
/**
* Don't use a proxy.
@@ -442,16 +418,13 @@ typedef enum TOX_PROXY_TYPE {
*/
TOX_PROXY_TYPE_SOCKS5,
-} TOX_PROXY_TYPE;
+} Tox_Proxy_Type;
/**
- * Type of savedata to create the Tox instance from.
- *
- * @deprecated All UPPER_CASE enum type names are deprecated. Use the
- * Camel_Snake_Case versions, instead.
+ * @brief Type of savedata to create the Tox instance from.
*/
-typedef enum TOX_SAVEDATA_TYPE {
+typedef enum Tox_Savedata_Type {
/**
* No savedata.
@@ -468,16 +441,13 @@ typedef enum TOX_SAVEDATA_TYPE {
*/
TOX_SAVEDATA_TYPE_SECRET_KEY,
-} TOX_SAVEDATA_TYPE;
+} Tox_Savedata_Type;
/**
- * Severity level of log messages.
- *
- * @deprecated All UPPER_CASE enum type names are deprecated. Use the
- * Camel_Snake_Case versions, instead.
+ * @brief Severity level of log messages.
*/
-typedef enum TOX_LOG_LEVEL {
+typedef enum Tox_Log_Level {
/**
* Very detailed traces including all network activity.
@@ -504,11 +474,12 @@ typedef enum TOX_LOG_LEVEL {
*/
TOX_LOG_LEVEL_ERROR,
-} TOX_LOG_LEVEL;
+} Tox_Log_Level;
/**
- * This event is triggered when the toxcore library logs an internal message.
+ * @brief This event is triggered when the toxcore library logs an internal message.
+ *
* This is mostly useful for debugging. This callback can be called from any
* function, not just tox_iterate. This means the user data lifetime must at
* least extend between registering and unregistering it or tox_kill.
@@ -524,13 +495,14 @@ typedef enum TOX_LOG_LEVEL {
* @param message The log message.
* @param user_data The user data pointer passed to tox_new in options.
*/
-typedef void tox_log_cb(Tox *tox, TOX_LOG_LEVEL level, const char *file, uint32_t line, const char *func,
+typedef void tox_log_cb(Tox *tox, Tox_Log_Level level, const char *file, uint32_t line, const char *func,
const char *message, void *user_data);
/**
- * This struct contains all the startup options for Tox. You must tox_options_new to
- * allocate an object of this type.
+ * @brief This struct contains all the startup options for Tox.
+ *
+ * You must tox_options_new to allocate an object of this type.
*
* WARNING: Although this struct happens to be visible in the API, it is
* effectively private. Do not allocate this yourself or access members
@@ -577,7 +549,7 @@ struct Tox_Options {
/**
* Pass communications through a proxy.
*/
- TOX_PROXY_TYPE proxy_type;
+ Tox_Proxy_Type proxy_type;
/**
@@ -608,7 +580,7 @@ struct Tox_Options {
* The start port of the inclusive port range to attempt to use.
*
* If both start_port and end_port are 0, the default port range will be
- * used: [33445, 33545].
+ * used: `[33445, 33545]`.
*
* If either start_port or end_port is 0 while the other is non-zero, the
* non-zero port will be the only port in the range.
@@ -648,7 +620,7 @@ struct Tox_Options {
/**
* The type of savedata to load from.
*/
- TOX_SAVEDATA_TYPE savedata_type;
+ Tox_Savedata_Type savedata_type;
/**
@@ -706,9 +678,9 @@ bool tox_options_get_local_discovery_enabled(const struct Tox_Options *options);
void tox_options_set_local_discovery_enabled(struct Tox_Options *options, bool local_discovery_enabled);
-TOX_PROXY_TYPE tox_options_get_proxy_type(const struct Tox_Options *options);
+Tox_Proxy_Type tox_options_get_proxy_type(const struct Tox_Options *options);
-void tox_options_set_proxy_type(struct Tox_Options *options, TOX_PROXY_TYPE type);
+void tox_options_set_proxy_type(struct Tox_Options *options, Tox_Proxy_Type type);
const char *tox_options_get_proxy_host(const struct Tox_Options *options);
@@ -734,9 +706,9 @@ bool tox_options_get_hole_punching_enabled(const struct Tox_Options *options);
void tox_options_set_hole_punching_enabled(struct Tox_Options *options, bool hole_punching_enabled);
-TOX_SAVEDATA_TYPE tox_options_get_savedata_type(const struct Tox_Options *options);
+Tox_Savedata_Type tox_options_get_savedata_type(const struct Tox_Options *options);
-void tox_options_set_savedata_type(struct Tox_Options *options, TOX_SAVEDATA_TYPE type);
+void tox_options_set_savedata_type(struct Tox_Options *options, Tox_Savedata_Type type);
const uint8_t *tox_options_get_savedata_data(const struct Tox_Options *options);
@@ -759,7 +731,7 @@ bool tox_options_get_experimental_thread_safety(const struct Tox_Options *option
void tox_options_set_experimental_thread_safety(struct Tox_Options *options, bool thread_safety);
/**
- * Initialises a Tox_Options object with the default options.
+ * @brief Initialises a Tox_Options object with the default options.
*
* The result of this function is independent of the original options. All
* values will be overwritten, no values will be read (so it is permissible
@@ -771,7 +743,7 @@ void tox_options_set_experimental_thread_safety(struct Tox_Options *options, boo
*/
void tox_options_default(struct Tox_Options *options);
-typedef enum TOX_ERR_OPTIONS_NEW {
+typedef enum Tox_Err_Options_New {
/**
* The function returned successfully.
@@ -783,12 +755,14 @@ typedef enum TOX_ERR_OPTIONS_NEW {
*/
TOX_ERR_OPTIONS_NEW_MALLOC,
-} TOX_ERR_OPTIONS_NEW;
+} Tox_Err_Options_New;
/**
- * Allocates a new Tox_Options object and initialises it with the default
- * options. This function can be used to preserve long term ABI compatibility by
+ * @brief Allocates a new Tox_Options object and initialises it with the default
+ * options.
+ *
+ * This function can be used to preserve long term ABI compatibility by
* giving the responsibility of allocation and deallocation to the Tox library.
*
* Objects returned from this function must be freed using the tox_options_free
@@ -796,26 +770,24 @@ typedef enum TOX_ERR_OPTIONS_NEW {
*
* @return A new Tox_Options object with default options or NULL on failure.
*/
-struct Tox_Options *tox_options_new(TOX_ERR_OPTIONS_NEW *error);
+struct Tox_Options *tox_options_new(Tox_Err_Options_New *error);
/**
- * Releases all resources associated with an options objects.
+ * @brief Releases all resources associated with an options objects.
*
* Passing a pointer that was not returned by tox_options_new results in
* undefined behaviour.
*/
void tox_options_free(struct Tox_Options *options);
-
-/*******************************************************************************
- *
- * :: Creation and destruction
- *
- ******************************************************************************/
+/** @} */
+/** @{
+ * @name Creation and destruction
+ */
-typedef enum TOX_ERR_NEW {
+typedef enum Tox_Err_New {
/**
* The function returned successfully.
@@ -875,7 +847,7 @@ typedef enum TOX_ERR_NEW {
*/
TOX_ERR_NEW_LOAD_BAD_FORMAT,
-} TOX_ERR_NEW;
+} Tox_Err_New;
/**
@@ -894,11 +866,11 @@ typedef enum TOX_ERR_NEW {
*
* @return A new Tox instance pointer on success or NULL on failure.
*/
-Tox *tox_new(const struct Tox_Options *options, TOX_ERR_NEW *error);
+Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error);
/**
- * Releases all resources associated with the Tox instance and disconnects from
- * the network.
+ * @brief Releases all resources associated with the Tox instance and
+ * disconnects from the network.
*
* After calling this function, the Tox pointer becomes invalid. No other
* functions can be called, and the pointer value can no longer be read.
@@ -906,15 +878,17 @@ Tox *tox_new(const struct Tox_Options *options, TOX_ERR_NEW *error);
void tox_kill(Tox *tox);
/**
- * Calculates the number of bytes required to store the tox instance with
- * tox_get_savedata. This function cannot fail. The result is always greater than 0.
+ * @brief Calculates the number of bytes required to store the tox instance with
+ * tox_get_savedata.
+ *
+ * This function cannot fail. The result is always greater than 0.
*
* @see threading for concurrency implications.
*/
size_t tox_get_savedata_size(const Tox *tox);
/**
- * Store all information associated with the tox instance to a byte array.
+ * @brief Store all information associated with the tox instance to a byte array.
*
* @param savedata A memory region large enough to store the tox instance
* data. Call tox_get_savedata_size to find the number of bytes required. If this parameter
@@ -922,16 +896,14 @@ size_t tox_get_savedata_size(const Tox *tox);
*/
void tox_get_savedata(const Tox *tox, uint8_t *savedata);
-
-/*******************************************************************************
- *
- * :: Connection lifecycle and event loop
- *
- ******************************************************************************/
+/** @} */
+/** @{
+ * @name Connection lifecycle and event loop
+ */
-typedef enum TOX_ERR_BOOTSTRAP {
+typedef enum Tox_Err_Bootstrap {
/**
* The function returned successfully.
@@ -954,11 +926,11 @@ typedef enum TOX_ERR_BOOTSTRAP {
*/
TOX_ERR_BOOTSTRAP_BAD_PORT,
-} TOX_ERR_BOOTSTRAP;
+} Tox_Err_Bootstrap;
/**
- * Sends a "get nodes" request to the given bootstrap node with IP, port, and
+ * @brief Sends a "get nodes" request to the given bootstrap node with IP, port, and
* public key to setup connections.
*
* This function will attempt to connect to the node using UDP. You must use
@@ -972,10 +944,10 @@ typedef enum TOX_ERR_BOOTSTRAP {
* (TOX_PUBLIC_KEY_SIZE bytes).
* @return true on success.
*/
-bool tox_bootstrap(Tox *tox, const char *host, uint16_t port, const uint8_t *public_key, TOX_ERR_BOOTSTRAP *error);
+bool tox_bootstrap(Tox *tox, const char *host, uint16_t port, const uint8_t *public_key, Tox_Err_Bootstrap *error);
/**
- * Adds additional host:port pair as TCP relay.
+ * @brief Adds additional host:port pair as TCP relay.
*
* This function can be used to initiate TCP connections to different ports on
* the same bootstrap node, or to add TCP relays without using them as
@@ -988,15 +960,12 @@ bool tox_bootstrap(Tox *tox, const char *host, uint16_t port, const uint8_t *pub
* (TOX_PUBLIC_KEY_SIZE bytes).
* @return true on success.
*/
-bool tox_add_tcp_relay(Tox *tox, const char *host, uint16_t port, const uint8_t *public_key, TOX_ERR_BOOTSTRAP *error);
+bool tox_add_tcp_relay(Tox *tox, const char *host, uint16_t port, const uint8_t *public_key, Tox_Err_Bootstrap *error);
/**
- * Protocols that can be used to connect to the network or friends.
- *
- * @deprecated All UPPER_CASE enum type names are deprecated. Use the
- * Camel_Snake_Case versions, instead.
+ * @brief Protocols that can be used to connect to the network or friends.
*/
-typedef enum TOX_CONNECTION {
+typedef enum Tox_Connection {
/**
* There is no connection. This instance, or the friend the state change is
@@ -1019,26 +988,30 @@ typedef enum TOX_CONNECTION {
*/
TOX_CONNECTION_UDP,
-} TOX_CONNECTION;
+} Tox_Connection;
/**
- * Return whether we are connected to the DHT. The return value is equal to the
- * last value received through the `self_connection_status` callback.
+ * @brief Return whether we are connected to the DHT.
+ *
+ * The return value is equal to the last value received through the
+ * `self_connection_status` callback.
*
* @deprecated This getter is deprecated. Use the event and store the status
* in the client state.
*/
-TOX_CONNECTION tox_self_get_connection_status(const Tox *tox);
+Tox_Connection tox_self_get_connection_status(const Tox *tox);
/**
* @param connection_status Whether we are connected to the DHT.
*/
-typedef void tox_self_connection_status_cb(Tox *tox, TOX_CONNECTION connection_status, void *user_data);
+typedef void tox_self_connection_status_cb(Tox *tox, Tox_Connection connection_status, void *user_data);
/**
- * Set the callback for the `self_connection_status` event. Pass NULL to unset.
+ * @brief Set the callback for the `self_connection_status` event.
+ *
+ * Pass NULL to unset.
*
* This event is triggered whenever there is a change in the DHT connection
* state. When disconnected, a client may choose to call tox_bootstrap again, to
@@ -1051,30 +1024,29 @@ typedef void tox_self_connection_status_cb(Tox *tox, TOX_CONNECTION connection_s
void tox_callback_self_connection_status(Tox *tox, tox_self_connection_status_cb *callback);
/**
- * Return the time in milliseconds before tox_iterate() should be called again
+ * @brief Return the time in milliseconds before tox_iterate() should be called again
* for optimal performance.
*/
uint32_t tox_iteration_interval(const Tox *tox);
/**
- * The main loop that needs to be run in intervals of tox_iteration_interval()
+ * @brief The main loop that needs to be run in intervals of tox_iteration_interval()
* milliseconds.
*/
void tox_iterate(Tox *tox, void *user_data);
-
-/*******************************************************************************
- *
- * :: Internal client information (Tox address/id)
- *
- ******************************************************************************/
+/** @} */
+/** @{
+ * @name Internal client information (Tox address/id)
+ */
/**
- * Writes the Tox friend address of the client to a byte array. The address is
- * not in human-readable format. If a client wants to display the address,
- * formatting is required.
+ * @brief Writes the Tox friend address of the client to a byte array.
+ *
+ * The address is not in human-readable format. If a client wants to display
+ * the address, formatting is required.
*
* @param address A memory region of at least TOX_ADDRESS_SIZE bytes. If this
* parameter is NULL, this function has no effect.
@@ -1083,22 +1055,24 @@ void tox_iterate(Tox *tox, void *user_data);
void tox_self_get_address(const Tox *tox, uint8_t *address);
/**
- * Set the 4-byte nospam part of the address. This value is expected in host
- * byte order. I.e. 0x12345678 will form the bytes [12, 34, 56, 78] in the
- * nospam part of the Tox friend address.
+ * @brief Set the 4-byte nospam part of the address.
+ *
+ * This value is expected in host byte order. I.e. 0x12345678 will form the
+ * bytes `[12, 34, 56, 78]` in the nospam part of the Tox friend address.
*
* @param nospam Any 32 bit unsigned integer.
*/
void tox_self_set_nospam(Tox *tox, uint32_t nospam);
/**
- * Get the 4-byte nospam part of the address. This value is returned in host
- * byte order.
+ * @brief Get the 4-byte nospam part of the address.
+ *
+ * This value is returned in host byte order.
*/
uint32_t tox_self_get_nospam(const Tox *tox);
/**
- * Copy the Tox Public Key (long term) from the Tox object.
+ * @brief Copy the Tox Public Key (long term) from the Tox object.
*
* @param public_key A memory region of at least TOX_PUBLIC_KEY_SIZE bytes. If
* this parameter is NULL, this function has no effect.
@@ -1106,27 +1080,25 @@ uint32_t tox_self_get_nospam(const Tox *tox);
void tox_self_get_public_key(const Tox *tox, uint8_t *public_key);
/**
- * Copy the Tox Secret Key from the Tox object.
+ * @brief Copy the Tox Secret Key from the Tox object.
*
* @param secret_key A memory region of at least TOX_SECRET_KEY_SIZE bytes. If
* this parameter is NULL, this function has no effect.
*/
void tox_self_get_secret_key(const Tox *tox, uint8_t *secret_key);
-
-/*******************************************************************************
- *
- * :: User-visible client information (nickname/status)
- *
- ******************************************************************************/
+/** @} */
+/** @{
+ * @name User-visible client information (nickname/status)
+ */
/**
- * Common error codes for all functions that set a piece of user-visible
+ * @brief Common error codes for all functions that set a piece of user-visible
* client information.
*/
-typedef enum TOX_ERR_SET_INFO {
+typedef enum Tox_Err_Set_Info {
/**
* The function returned successfully.
@@ -1143,11 +1115,11 @@ typedef enum TOX_ERR_SET_INFO {
*/
TOX_ERR_SET_INFO_TOO_LONG,
-} TOX_ERR_SET_INFO;
+} Tox_Err_Set_Info;
/**
- * Set the nickname for the Tox client.
+ * @brief Set the nickname for the Tox client.
*
* Nickname length cannot exceed TOX_MAX_NAME_LENGTH. If length is 0, the name
* parameter is ignored (it can be NULL), and the nickname is set back to empty.
@@ -1157,10 +1129,10 @@ typedef enum TOX_ERR_SET_INFO {
*
* @return true on success.
*/
-bool tox_self_set_name(Tox *tox, const uint8_t *name, size_t length, TOX_ERR_SET_INFO *error);
+bool tox_self_set_name(Tox *tox, const uint8_t *name, size_t length, Tox_Err_Set_Info *error);
/**
- * Return the length of the current nickname as passed to tox_self_set_name.
+ * @brief Return the length of the current nickname as passed to tox_self_set_name.
*
* If no nickname was set before calling this function, the name is empty,
* and this function returns 0.
@@ -1170,7 +1142,7 @@ bool tox_self_set_name(Tox *tox, const uint8_t *name, size_t length, TOX_ERR_SET
size_t tox_self_get_name_size(const Tox *tox);
/**
- * Write the nickname set by tox_self_set_name to a byte array.
+ * @brief Write the nickname set by tox_self_set_name to a byte array.
*
* If no nickname was set before calling this function, the name is empty,
* and this function has no effect.
@@ -1184,16 +1156,16 @@ size_t tox_self_get_name_size(const Tox *tox);
void tox_self_get_name(const Tox *tox, uint8_t *name);
/**
- * Set the client's status message.
+ * @brief Set the client's status message.
*
* Status message length cannot exceed TOX_MAX_STATUS_MESSAGE_LENGTH. If
* length is 0, the status parameter is ignored (it can be NULL), and the
* user status is set back to empty.
*/
-bool tox_self_set_status_message(Tox *tox, const uint8_t *status_message, size_t length, TOX_ERR_SET_INFO *error);
+bool tox_self_set_status_message(Tox *tox, const uint8_t *status_message, size_t length, Tox_Err_Set_Info *error);
/**
- * Return the length of the current status message as passed to tox_self_set_status_message.
+ * @brief Return the length of the current status message as passed to tox_self_set_status_message.
*
* If no status message was set before calling this function, the status
* is empty, and this function returns 0.
@@ -1203,7 +1175,7 @@ bool tox_self_set_status_message(Tox *tox, const uint8_t *status_message, size_t
size_t tox_self_get_status_message_size(const Tox *tox);
/**
- * Write the status message set by tox_self_set_status_message to a byte array.
+ * @brief Write the status message set by tox_self_set_status_message to a byte array.
*
* If no status message was set before calling this function, the status is
* empty, and this function has no effect.
@@ -1217,27 +1189,25 @@ size_t tox_self_get_status_message_size(const Tox *tox);
void tox_self_get_status_message(const Tox *tox, uint8_t *status_message);
/**
- * Set the client's user status.
+ * @brief Set the client's user status.
*
* @param status One of the user statuses listed in the enumeration above.
*/
-void tox_self_set_status(Tox *tox, TOX_USER_STATUS status);
+void tox_self_set_status(Tox *tox, Tox_User_Status status);
/**
- * Returns the client's user status.
+ * @brief Returns the client's user status.
*/
-TOX_USER_STATUS tox_self_get_status(const Tox *tox);
-
+Tox_User_Status tox_self_get_status(const Tox *tox);
-/*******************************************************************************
- *
- * :: Friend list management
- *
- ******************************************************************************/
+/** @} */
+/** @{
+ * @name Friend list management
+ */
-typedef enum TOX_ERR_FRIEND_ADD {
+typedef enum Tox_Err_Friend_Add {
/**
* The function returned successfully.
@@ -1287,11 +1257,11 @@ typedef enum TOX_ERR_FRIEND_ADD {
*/
TOX_ERR_FRIEND_ADD_MALLOC,
-} TOX_ERR_FRIEND_ADD;
+} Tox_Err_Friend_Add;
/**
- * Add a friend to the friend list and send a friend request.
+ * @brief Add a friend to the friend list and send a friend request.
*
* A friend request message must be at least 1 byte long and at most
* TOX_MAX_FRIEND_REQUEST_LENGTH.
@@ -1314,10 +1284,10 @@ typedef enum TOX_ERR_FRIEND_ADD {
* @return the friend number on success, an unspecified value on failure.
*/
uint32_t tox_friend_add(Tox *tox, const uint8_t *address, const uint8_t *message, size_t length,
- TOX_ERR_FRIEND_ADD *error);
+ Tox_Err_Friend_Add *error);
/**
- * Add a friend without sending a friend request.
+ * @brief Add a friend without sending a friend request.
*
* This function is used to add a friend in response to a friend request. If the
* client receives a friend request, it can be reasonably sure that the other
@@ -1334,9 +1304,9 @@ uint32_t tox_friend_add(Tox *tox, const uint8_t *address, const uint8_t *message
* @return the friend number on success, an unspecified value on failure.
* @see tox_friend_add for a more detailed description of friend numbers.
*/
-uint32_t tox_friend_add_norequest(Tox *tox, const uint8_t *public_key, TOX_ERR_FRIEND_ADD *error);
+uint32_t tox_friend_add_norequest(Tox *tox, const uint8_t *public_key, Tox_Err_Friend_Add *error);
-typedef enum TOX_ERR_FRIEND_DELETE {
+typedef enum Tox_Err_Friend_Delete {
/**
* The function returned successfully.
@@ -1348,11 +1318,11 @@ typedef enum TOX_ERR_FRIEND_DELETE {
*/
TOX_ERR_FRIEND_DELETE_FRIEND_NOT_FOUND,
-} TOX_ERR_FRIEND_DELETE;
+} Tox_Err_Friend_Delete;
/**
- * Remove a friend from the friend list.
+ * @brief Remove a friend from the friend list.
*
* This does not notify the friend of their deletion. After calling this
* function, this client will appear offline to the friend and no communication
@@ -1362,18 +1332,16 @@ typedef enum TOX_ERR_FRIEND_DELETE {
*
* @return true on success.
*/
-bool tox_friend_delete(Tox *tox, uint32_t friend_number, TOX_ERR_FRIEND_DELETE *error);
+bool tox_friend_delete(Tox *tox, uint32_t friend_number, Tox_Err_Friend_Delete *error);
-
-/*******************************************************************************
- *
- * :: Friend list queries
- *
- ******************************************************************************/
+/** @} */
+/** @{
+ * @name Friend list queries
+ */
-typedef enum TOX_ERR_FRIEND_BY_PUBLIC_KEY {
+typedef enum Tox_Err_Friend_By_Public_Key {
/**
* The function returned successfully.
@@ -1390,25 +1358,25 @@ typedef enum TOX_ERR_FRIEND_BY_PUBLIC_KEY {
*/
TOX_ERR_FRIEND_BY_PUBLIC_KEY_NOT_FOUND,
-} TOX_ERR_FRIEND_BY_PUBLIC_KEY;
+} Tox_Err_Friend_By_Public_Key;
/**
- * Return the friend number associated with that Public Key.
+ * @brief Return the friend number associated with that Public Key.
*
* @return the friend number on success, an unspecified value on failure.
* @param public_key A byte array containing the Public Key.
*/
-uint32_t tox_friend_by_public_key(const Tox *tox, const uint8_t *public_key, TOX_ERR_FRIEND_BY_PUBLIC_KEY *error);
+uint32_t tox_friend_by_public_key(const Tox *tox, const uint8_t *public_key, Tox_Err_Friend_By_Public_Key *error);
/**
- * Checks if a friend with the given friend number exists and returns true if
+ * @brief Checks if a friend with the given friend number exists and returns true if
* it does.
*/
bool tox_friend_exists(const Tox *tox, uint32_t friend_number);
/**
- * Return the number of friends on the friend list.
+ * @brief Return the number of friends on the friend list.
*
* This function can be used to determine how much memory to allocate for
* tox_self_get_friend_list.
@@ -1416,7 +1384,7 @@ bool tox_friend_exists(const Tox *tox, uint32_t friend_number);
size_t tox_self_get_friend_list_size(const Tox *tox);
/**
- * Copy a list of valid friend numbers into an array.
+ * @brief Copy a list of valid friend numbers into an array.
*
* Call tox_self_get_friend_list_size to determine the number of elements to allocate.
*
@@ -1425,7 +1393,7 @@ size_t tox_self_get_friend_list_size(const Tox *tox);
*/
void tox_self_get_friend_list(const Tox *tox, uint32_t *friend_list);
-typedef enum TOX_ERR_FRIEND_GET_PUBLIC_KEY {
+typedef enum Tox_Err_Friend_Get_Public_Key {
/**
* The function returned successfully.
@@ -1437,11 +1405,11 @@ typedef enum TOX_ERR_FRIEND_GET_PUBLIC_KEY {
*/
TOX_ERR_FRIEND_GET_PUBLIC_KEY_FRIEND_NOT_FOUND,
-} TOX_ERR_FRIEND_GET_PUBLIC_KEY;
+} Tox_Err_Friend_Get_Public_Key;
/**
- * Copies the Public Key associated with a given friend number to a byte array.
+ * @brief Copies the Public Key associated with a given friend number to a byte array.
*
* @param friend_number The friend number you want the Public Key of.
* @param public_key A memory region of at least TOX_PUBLIC_KEY_SIZE bytes. If
@@ -1450,9 +1418,9 @@ typedef enum TOX_ERR_FRIEND_GET_PUBLIC_KEY {
* @return true on success.
*/
bool tox_friend_get_public_key(const Tox *tox, uint32_t friend_number, uint8_t *public_key,
- TOX_ERR_FRIEND_GET_PUBLIC_KEY *error);
+ Tox_Err_Friend_Get_Public_Key *error);
-typedef enum TOX_ERR_FRIEND_GET_LAST_ONLINE {
+typedef enum Tox_Err_Friend_Get_Last_Online {
/**
* The function returned successfully.
@@ -1464,30 +1432,30 @@ typedef enum TOX_ERR_FRIEND_GET_LAST_ONLINE {
*/
TOX_ERR_FRIEND_GET_LAST_ONLINE_FRIEND_NOT_FOUND,
-} TOX_ERR_FRIEND_GET_LAST_ONLINE;
+} Tox_Err_Friend_Get_Last_Online;
/**
- * Return a unix-time timestamp of the last time the friend associated with a given
- * friend number was seen online. This function will return UINT64_MAX on error.
+ * @brief Return a unix-time timestamp of the last time the friend associated with a given
+ * friend number was seen online.
+ *
+ * This function will return UINT64_MAX on error.
*
* @param friend_number The friend number you want to query.
*/
-uint64_t tox_friend_get_last_online(const Tox *tox, uint32_t friend_number, TOX_ERR_FRIEND_GET_LAST_ONLINE *error);
-
+uint64_t tox_friend_get_last_online(const Tox *tox, uint32_t friend_number, Tox_Err_Friend_Get_Last_Online *error);
-/*******************************************************************************
- *
- * :: Friend-specific state queries (can also be received through callbacks)
- *
- ******************************************************************************/
+/** @} */
+/** @{
+ * @name Friend-specific state queries (can also be received through callbacks)
+ */
/**
- * Common error codes for friend state query functions.
+ * @brief Common error codes for friend state query functions.
*/
-typedef enum TOX_ERR_FRIEND_QUERY {
+typedef enum Tox_Err_Friend_Query {
/**
* The function returned successfully.
@@ -1506,20 +1474,21 @@ typedef enum TOX_ERR_FRIEND_QUERY {
*/
TOX_ERR_FRIEND_QUERY_FRIEND_NOT_FOUND,
-} TOX_ERR_FRIEND_QUERY;
+} Tox_Err_Friend_Query;
/**
- * Return the length of the friend's name. If the friend number is invalid, the
- * return value is unspecified.
+ * @brief Return the length of the friend's name.
+ *
+ * If the friend number is invalid, the return value is unspecified.
*
* The return value is equal to the `length` argument received by the last
* `friend_name` callback.
*/
-size_t tox_friend_get_name_size(const Tox *tox, uint32_t friend_number, TOX_ERR_FRIEND_QUERY *error);
+size_t tox_friend_get_name_size(const Tox *tox, uint32_t friend_number, Tox_Err_Friend_Query *error);
/**
- * Write the name of the friend designated by the given friend number to a byte
+ * @brief Write the name of the friend designated by the given friend number to a byte
* array.
*
* Call tox_friend_get_name_size to determine the allocation size for the `name`
@@ -1532,7 +1501,7 @@ size_t tox_friend_get_name_size(const Tox *tox, uint32_t friend_number, TOX_ERR_
*
* @return true on success.
*/
-bool tox_friend_get_name(const Tox *tox, uint32_t friend_number, uint8_t *name, TOX_ERR_FRIEND_QUERY *error);
+bool tox_friend_get_name(const Tox *tox, uint32_t friend_number, uint8_t *name, Tox_Err_Friend_Query *error);
/**
* @param friend_number The friend number of the friend whose name changed.
@@ -1545,20 +1514,23 @@ typedef void tox_friend_name_cb(Tox *tox, uint32_t friend_number, const uint8_t
/**
- * Set the callback for the `friend_name` event. Pass NULL to unset.
+ * @brief Set the callback for the `friend_name` event.
+ *
+ * Pass NULL to unset.
*
* This event is triggered when a friend changes their name.
*/
void tox_callback_friend_name(Tox *tox, tox_friend_name_cb *callback);
/**
- * Return the length of the friend's status message. If the friend number is
- * invalid, the return value is SIZE_MAX.
+ * @brief Return the length of the friend's status message.
+ *
+ * If the friend number isinvalid, the return value is SIZE_MAX.
*/
-size_t tox_friend_get_status_message_size(const Tox *tox, uint32_t friend_number, TOX_ERR_FRIEND_QUERY *error);
+size_t tox_friend_get_status_message_size(const Tox *tox, uint32_t friend_number, Tox_Err_Friend_Query *error);
/**
- * Write the status message of the friend designated by the given friend number to a byte
+ * @brief Write the status message of the friend designated by the given friend number to a byte
* array.
*
* Call tox_friend_get_status_message_size to determine the allocation size for the `status_message`
@@ -1570,7 +1542,7 @@ size_t tox_friend_get_status_message_size(const Tox *tox, uint32_t friend_number
* @param status_message A valid memory region large enough to store the friend's status message.
*/
bool tox_friend_get_status_message(const Tox *tox, uint32_t friend_number, uint8_t *status_message,
- TOX_ERR_FRIEND_QUERY *error);
+ Tox_Err_Friend_Query *error);
/**
* @param friend_number The friend number of the friend whose status message
@@ -1585,15 +1557,18 @@ typedef void tox_friend_status_message_cb(Tox *tox, uint32_t friend_number, cons
/**
- * Set the callback for the `friend_status_message` event. Pass NULL to unset.
+ * @brief Set the callback for the `friend_status_message` event.
+ *
+ * Pass NULL to unset.
*
* This event is triggered when a friend changes their status message.
*/
void tox_callback_friend_status_message(Tox *tox, tox_friend_status_message_cb *callback);
/**
- * Return the friend's user status (away/busy/...). If the friend number is
- * invalid, the return value is unspecified.
+ * @brief Return the friend's user status (away/busy/...).
+ *
+ * If the friend number is invalid, the return value is unspecified.
*
* The status returned is equal to the last status received through the
* `friend_status` callback.
@@ -1601,25 +1576,27 @@ void tox_callback_friend_status_message(Tox *tox, tox_friend_status_message_cb *
* @deprecated This getter is deprecated. Use the event and store the status
* in the client state.
*/
-TOX_USER_STATUS tox_friend_get_status(const Tox *tox, uint32_t friend_number, TOX_ERR_FRIEND_QUERY *error);
+Tox_User_Status tox_friend_get_status(const Tox *tox, uint32_t friend_number, Tox_Err_Friend_Query *error);
/**
* @param friend_number The friend number of the friend whose user status
* changed.
* @param status The new user status.
*/
-typedef void tox_friend_status_cb(Tox *tox, uint32_t friend_number, TOX_USER_STATUS status, void *user_data);
+typedef void tox_friend_status_cb(Tox *tox, uint32_t friend_number, Tox_User_Status status, void *user_data);
/**
- * Set the callback for the `friend_status` event. Pass NULL to unset.
+ * @brief Set the callback for the `friend_status` event.
+ *
+ * Pass NULL to unset.
*
* This event is triggered when a friend changes their user status.
*/
void tox_callback_friend_status(Tox *tox, tox_friend_status_cb *callback);
/**
- * Check whether a friend is currently connected to this client.
+ * @brief Check whether a friend is currently connected to this client.
*
* The result of this function is equal to the last value received by the
* `friend_connection_status` callback.
@@ -1633,7 +1610,7 @@ void tox_callback_friend_status(Tox *tox, tox_friend_status_cb *callback);
* @deprecated This getter is deprecated. Use the event and store the status
* in the client state.
*/
-TOX_CONNECTION tox_friend_get_connection_status(const Tox *tox, uint32_t friend_number, TOX_ERR_FRIEND_QUERY *error);
+Tox_Connection tox_friend_get_connection_status(const Tox *tox, uint32_t friend_number, Tox_Err_Friend_Query *error);
/**
* @param friend_number The friend number of the friend whose connection status
@@ -1641,12 +1618,14 @@ TOX_CONNECTION tox_friend_get_connection_status(const Tox *tox, uint32_t friend_
* @param connection_status The result of calling
* tox_friend_get_connection_status on the passed friend_number.
*/
-typedef void tox_friend_connection_status_cb(Tox *tox, uint32_t friend_number, TOX_CONNECTION connection_status,
+typedef void tox_friend_connection_status_cb(Tox *tox, uint32_t friend_number, Tox_Connection connection_status,
void *user_data);
/**
- * Set the callback for the `friend_connection_status` event. Pass NULL to unset.
+ * @brief Set the callback for the `friend_connection_status` event.
+ *
+ * Pass NULL to unset.
*
* This event is triggered when a friend goes offline after having been online,
* or when a friend goes online.
@@ -1657,7 +1636,7 @@ typedef void tox_friend_connection_status_cb(Tox *tox, uint32_t friend_number, T
void tox_callback_friend_connection_status(Tox *tox, tox_friend_connection_status_cb *callback);
/**
- * Check whether a friend is currently typing a message.
+ * @brief Check whether a friend is currently typing a message.
*
* @param friend_number The friend number for which to query the typing status.
*
@@ -1668,7 +1647,7 @@ void tox_callback_friend_connection_status(Tox *tox, tox_friend_connection_statu
* @deprecated This getter is deprecated. Use the event and store the status
* in the client state.
*/
-bool tox_friend_get_typing(const Tox *tox, uint32_t friend_number, TOX_ERR_FRIEND_QUERY *error);
+bool tox_friend_get_typing(const Tox *tox, uint32_t friend_number, Tox_Err_Friend_Query *error);
/**
* @param friend_number The friend number of the friend who started or stopped
@@ -1680,22 +1659,22 @@ typedef void tox_friend_typing_cb(Tox *tox, uint32_t friend_number, bool is_typi
/**
- * Set the callback for the `friend_typing` event. Pass NULL to unset.
+ * @brief Set the callback for the `friend_typing` event.
+ *
+ * Pass NULL to unset.
*
* This event is triggered when a friend starts or stops typing.
*/
void tox_callback_friend_typing(Tox *tox, tox_friend_typing_cb *callback);
-
-/*******************************************************************************
- *
- * :: Sending private messages
- *
- ******************************************************************************/
+/** @} */
+/** @{
+ * @name Sending private messages
+ */
-typedef enum TOX_ERR_SET_TYPING {
+typedef enum Tox_Err_Set_Typing {
/**
* The function returned successfully.
@@ -1707,11 +1686,11 @@ typedef enum TOX_ERR_SET_TYPING {
*/
TOX_ERR_SET_TYPING_FRIEND_NOT_FOUND,
-} TOX_ERR_SET_TYPING;
+} Tox_Err_Set_Typing;
/**
- * Set the client's typing status for a friend.
+ * @brief Set the client's typing status for a friend.
*
* The client is responsible for turning it on or off.
*
@@ -1720,9 +1699,9 @@ typedef enum TOX_ERR_SET_TYPING {
*
* @return true on success.
*/
-bool tox_self_set_typing(Tox *tox, uint32_t friend_number, bool typing, TOX_ERR_SET_TYPING *error);
+bool tox_self_set_typing(Tox *tox, uint32_t friend_number, bool typing, Tox_Err_Set_Typing *error);
-typedef enum TOX_ERR_FRIEND_SEND_MESSAGE {
+typedef enum Tox_Err_Friend_Send_Message {
/**
* The function returned successfully.
@@ -1759,11 +1738,11 @@ typedef enum TOX_ERR_FRIEND_SEND_MESSAGE {
*/
TOX_ERR_FRIEND_SEND_MESSAGE_EMPTY,
-} TOX_ERR_FRIEND_SEND_MESSAGE;
+} Tox_Err_Friend_Send_Message;
/**
- * Send a text chat message to an online friend.
+ * @brief Send a text chat message to an online friend.
*
* This function creates a chat message packet and pushes it into the send
* queue.
@@ -1785,8 +1764,8 @@ typedef enum TOX_ERR_FRIEND_SEND_MESSAGE {
* containing the message text.
* @param length Length of the message to be sent.
*/
-uint32_t tox_friend_send_message(Tox *tox, uint32_t friend_number, TOX_MESSAGE_TYPE type, const uint8_t *message,
- size_t length, TOX_ERR_FRIEND_SEND_MESSAGE *error);
+uint32_t tox_friend_send_message(Tox *tox, uint32_t friend_number, Tox_Message_Type type, const uint8_t *message,
+ size_t length, Tox_Err_Friend_Send_Message *error);
/**
* @param friend_number The friend number of the friend who received the message.
@@ -1797,21 +1776,21 @@ typedef void tox_friend_read_receipt_cb(Tox *tox, uint32_t friend_number, uint32
/**
- * Set the callback for the `friend_read_receipt` event. Pass NULL to unset.
+ * @brief Set the callback for the `friend_read_receipt` event.
+ *
+ * Pass NULL to unset.
*
* This event is triggered when the friend receives the message sent with
* tox_friend_send_message with the corresponding message ID.
*/
void tox_callback_friend_read_receipt(Tox *tox, tox_friend_read_receipt_cb *callback);
-
-/*******************************************************************************
- *
- * :: Receiving private messages and friend requests
- *
- ******************************************************************************/
+/** @} */
+/** @{
+ * @name Receiving private messages and friend requests
+ */
/**
* @param public_key The Public Key of the user who sent the friend request.
@@ -1823,7 +1802,9 @@ typedef void tox_friend_request_cb(Tox *tox, const uint8_t *public_key, const ui
/**
- * Set the callback for the `friend_request` event. Pass NULL to unset.
+ * @brief Set the callback for the `friend_request` event.
+ *
+ * Pass NULL to unset.
*
* This event is triggered when a friend request is received.
*/
@@ -1834,28 +1815,28 @@ void tox_callback_friend_request(Tox *tox, tox_friend_request_cb *callback);
* @param message The message data they sent.
* @param length The size of the message byte array.
*/
-typedef void tox_friend_message_cb(Tox *tox, uint32_t friend_number, TOX_MESSAGE_TYPE type, const uint8_t *message,
+typedef void tox_friend_message_cb(Tox *tox, uint32_t friend_number, Tox_Message_Type type, const uint8_t *message,
size_t length, void *user_data);
/**
- * Set the callback for the `friend_message` event. Pass NULL to unset.
+ * @brief Set the callback for the `friend_message` event.
+ *
+ * Pass NULL to unset.
*
* This event is triggered when a message from a friend is received.
*/
void tox_callback_friend_message(Tox *tox, tox_friend_message_cb *callback);
-
-/*******************************************************************************
- *
- * :: File transmission: common between sending and receiving
- *
- ******************************************************************************/
+/** @} */
+/** @{
+ * @name File transmission: common between sending and receiving
+ */
/**
- * Generates a cryptographic hash of the given data.
+ * @brief Generates a cryptographic hash of the given data.
*
* This function may be used by clients for any purpose, but is provided
* primarily for validating cached avatars. This use is highly recommended to
@@ -1876,14 +1857,15 @@ void tox_callback_friend_message(Tox *tox, tox_friend_message_cb *callback);
bool tox_hash(uint8_t *hash, const uint8_t *data, size_t length);
/**
- * A list of pre-defined file kinds. Toxcore itself does not behave
- * differently for different file kinds. These are a hint to the client
- * telling it what use the sender intended for the file. The `kind` parameter
- * in the send function and recv callback are `uint32_t`, not TOX_FILE_KIND, because
- * clients can invent their own file kind. Unknown file kinds should be
- * treated as TOX_FILE_KIND_DATA.
+ * @brief A list of pre-defined file kinds.
+ *
+ * Toxcore itself does not behave differently for different file kinds. These
+ * are a hint to the client telling it what use the sender intended for the
+ * file. The `kind` parameter in the send function and recv callback are
+ * `uint32_t`, not Tox_File_Kind, because clients can invent their own file
+ * kind. Unknown file kinds should be treated as TOX_FILE_KIND_DATA.
*/
-enum TOX_FILE_KIND {
+enum Tox_File_Kind {
/**
* Arbitrary file data. Clients can choose to handle it based on the file name
@@ -1916,7 +1898,7 @@ enum TOX_FILE_KIND {
};
-typedef enum TOX_FILE_CONTROL {
+typedef enum Tox_File_Control {
/**
* Sent by the receiving side to accept a file send request. Also sent after a
@@ -1938,10 +1920,10 @@ typedef enum TOX_FILE_CONTROL {
*/
TOX_FILE_CONTROL_CANCEL,
-} TOX_FILE_CONTROL;
+} Tox_File_Control;
-typedef enum TOX_ERR_FILE_CONTROL {
+typedef enum Tox_Err_File_Control {
/**
* The function returned successfully.
@@ -1984,11 +1966,11 @@ typedef enum TOX_ERR_FILE_CONTROL {
*/
TOX_ERR_FILE_CONTROL_SENDQ,
-} TOX_ERR_FILE_CONTROL;
+} Tox_Err_File_Control;
/**
- * Sends a file control command to a friend for a given file transfer.
+ * @brief Sends a file control command to a friend for a given file transfer.
*
* @param friend_number The friend number of the friend the file is being
* transferred to or received from.
@@ -1997,11 +1979,11 @@ typedef enum TOX_ERR_FILE_CONTROL {
*
* @return true on success.
*/
-bool tox_file_control(Tox *tox, uint32_t friend_number, uint32_t file_number, TOX_FILE_CONTROL control,
- TOX_ERR_FILE_CONTROL *error);
+bool tox_file_control(Tox *tox, uint32_t friend_number, uint32_t file_number, Tox_File_Control control,
+ Tox_Err_File_Control *error);
/**
- * When receiving TOX_FILE_CONTROL_CANCEL, the client should release the
+ * @brief When receiving TOX_FILE_CONTROL_CANCEL, the client should release the
* resources associated with the file number and consider the transfer failed.
*
* @param friend_number The friend number of the friend who is sending the file.
@@ -2009,19 +1991,21 @@ bool tox_file_control(Tox *tox, uint32_t friend_number, uint32_t file_number, TO
* associated with.
* @param control The file control command received.
*/
-typedef void tox_file_recv_control_cb(Tox *tox, uint32_t friend_number, uint32_t file_number, TOX_FILE_CONTROL control,
+typedef void tox_file_recv_control_cb(Tox *tox, uint32_t friend_number, uint32_t file_number, Tox_File_Control control,
void *user_data);
/**
- * Set the callback for the `file_recv_control` event. Pass NULL to unset.
+ * @brief Set the callback for the `file_recv_control` event.
+ *
+ * Pass NULL to unset.
*
* This event is triggered when a file control command is received from a
* friend.
*/
void tox_callback_file_recv_control(Tox *tox, tox_file_recv_control_cb *callback);
-typedef enum TOX_ERR_FILE_SEEK {
+typedef enum Tox_Err_File_Seek {
/**
* The function returned successfully.
@@ -2058,11 +2042,11 @@ typedef enum TOX_ERR_FILE_SEEK {
*/
TOX_ERR_FILE_SEEK_SENDQ,
-} TOX_ERR_FILE_SEEK;
+} Tox_Err_File_Seek;
/**
- * Sends a file seek control command to a friend for a given file transfer.
+ * @brief Sends a file seek control command to a friend for a given file transfer.
*
* This function can only be called to resume a file transfer right before
* TOX_FILE_CONTROL_RESUME is sent.
@@ -2072,9 +2056,9 @@ typedef enum TOX_ERR_FILE_SEEK {
* @param file_number The friend-specific identifier for the file transfer.
* @param position The position that the file should be seeked to.
*/
-bool tox_file_seek(Tox *tox, uint32_t friend_number, uint32_t file_number, uint64_t position, TOX_ERR_FILE_SEEK *error);
+bool tox_file_seek(Tox *tox, uint32_t friend_number, uint32_t file_number, uint64_t position, Tox_Err_File_Seek *error);
-typedef enum TOX_ERR_FILE_GET {
+typedef enum Tox_Err_File_Get {
/**
* The function returned successfully.
@@ -2096,11 +2080,11 @@ typedef enum TOX_ERR_FILE_GET {
*/
TOX_ERR_FILE_GET_NOT_FOUND,
-} TOX_ERR_FILE_GET;
+} Tox_Err_File_Get;
/**
- * Copy the file id associated to the file transfer to a byte array.
+ * @brief Copy the file id associated to the file transfer to a byte array.
*
* @param friend_number The friend number of the friend the file is being
* transferred to or received from.
@@ -2111,18 +2095,16 @@ typedef enum TOX_ERR_FILE_GET {
* @return true on success.
*/
bool tox_file_get_file_id(const Tox *tox, uint32_t friend_number, uint32_t file_number, uint8_t *file_id,
- TOX_ERR_FILE_GET *error);
+ Tox_Err_File_Get *error);
-
-/*******************************************************************************
- *
- * :: File transmission: sending
- *
- ******************************************************************************/
+/** @} */
+/** @{
+ * @name File transmission: sending
+ */
-typedef enum TOX_ERR_FILE_SEND {
+typedef enum Tox_Err_File_Send {
/**
* The function returned successfully.
@@ -2155,11 +2137,11 @@ typedef enum TOX_ERR_FILE_SEND {
*/
TOX_ERR_FILE_SEND_TOO_MANY,
-} TOX_ERR_FILE_SEND;
+} Tox_Err_File_Send;
/**
- * Send a file transmission request.
+ * @brief Send a file transmission request.
*
* Maximum filename length is TOX_MAX_FILENAME_LENGTH bytes. The filename
* should generally just be a file name, not a path with directory names.
@@ -2218,9 +2200,9 @@ typedef enum TOX_ERR_FILE_SEND {
* should not be relied on.
*/
uint32_t tox_file_send(Tox *tox, uint32_t friend_number, uint32_t kind, uint64_t file_size, const uint8_t *file_id,
- const uint8_t *filename, size_t filename_length, TOX_ERR_FILE_SEND *error);
+ const uint8_t *filename, size_t filename_length, Tox_Err_File_Send *error);
-typedef enum TOX_ERR_FILE_SEND_CHUNK {
+typedef enum Tox_Err_File_Send_Chunk {
/**
* The function returned successfully.
@@ -2270,11 +2252,11 @@ typedef enum TOX_ERR_FILE_SEND_CHUNK {
*/
TOX_ERR_FILE_SEND_CHUNK_WRONG_POSITION,
-} TOX_ERR_FILE_SEND_CHUNK;
+} Tox_Err_File_Send_Chunk;
/**
- * Send a chunk of file data to a friend.
+ * @brief Send a chunk of file data to a friend.
*
* This function is called in response to the `file_chunk_request` callback. The
* length parameter should be equal to the one received though the callback.
@@ -2290,7 +2272,7 @@ typedef enum TOX_ERR_FILE_SEND_CHUNK {
* @return true on success.
*/
bool tox_file_send_chunk(Tox *tox, uint32_t friend_number, uint32_t file_number, uint64_t position, const uint8_t *data,
- size_t length, TOX_ERR_FILE_SEND_CHUNK *error);
+ size_t length, Tox_Err_File_Send_Chunk *error);
/**
* If the length parameter is 0, the file transfer is finished, and the client's
@@ -2319,20 +2301,20 @@ typedef void tox_file_chunk_request_cb(Tox *tox, uint32_t friend_number, uint32_
/**
- * Set the callback for the `file_chunk_request` event. Pass NULL to unset.
+ * @brief Set the callback for the `file_chunk_request` event.
+ *
+ * Pass NULL to unset.
*
* This event is triggered when Core is ready to send more file data.
*/
void tox_callback_file_chunk_request(Tox *tox, tox_file_chunk_request_cb *callback);
-
-/*******************************************************************************
- *
- * :: File transmission: receiving
- *
- ******************************************************************************/
+/** @} */
+/** @{
+ * @name File transmission: receiving
+ */
/**
* The client should acquire resources to be associated with the file transfer.
@@ -2357,7 +2339,9 @@ typedef void tox_file_recv_cb(Tox *tox, uint32_t friend_number, uint32_t file_nu
/**
- * Set the callback for the `file_recv` event. Pass NULL to unset.
+ * @brief Set the callback for the `file_recv` event.
+ *
+ * Pass NULL to unset.
*
* This event is triggered when a file transfer request is received.
*/
@@ -2384,29 +2368,26 @@ typedef void tox_file_recv_chunk_cb(Tox *tox, uint32_t friend_number, uint32_t f
/**
- * Set the callback for the `file_recv_chunk` event. Pass NULL to unset.
+ * @brief Set the callback for the `file_recv_chunk` event.
+ *
+ * Pass NULL to unset.
*
* This event is first triggered when a file transfer request is received, and
* subsequently when a chunk of file data for an accepted request was received.
*/
void tox_callback_file_recv_chunk(Tox *tox, tox_file_recv_chunk_cb *callback);
-
-/*******************************************************************************
- *
- * :: Conference management
- *
- ******************************************************************************/
+/** @} */
+/** @{
+ * @name Conference management
+ */
/**
- * Conference types for the conference_invite event.
- *
- * @deprecated All UPPER_CASE enum type names are deprecated. Use the
- * Camel_Snake_Case versions, instead.
+ * @brief Conference types for the conference_invite event.
*/
-typedef enum TOX_CONFERENCE_TYPE {
+typedef enum Tox_Conference_Type {
/**
* Text-only conferences that must be accepted with the tox_conference_join function.
@@ -2418,7 +2399,7 @@ typedef enum TOX_CONFERENCE_TYPE {
*/
TOX_CONFERENCE_TYPE_AV,
-} TOX_CONFERENCE_TYPE;
+} Tox_Conference_Type;
/**
@@ -2431,12 +2412,14 @@ typedef enum TOX_CONFERENCE_TYPE {
* conference.
* @param length The length of the cookie.
*/
-typedef void tox_conference_invite_cb(Tox *tox, uint32_t friend_number, TOX_CONFERENCE_TYPE type, const uint8_t *cookie,
+typedef void tox_conference_invite_cb(Tox *tox, uint32_t friend_number, Tox_Conference_Type type, const uint8_t *cookie,
size_t length, void *user_data);
/**
- * Set the callback for the `conference_invite` event. Pass NULL to unset.
+ * @brief Set the callback for the `conference_invite` event.
+ *
+ * Pass NULL to unset.
*
* This event is triggered when the client is invited to join a conference.
*/
@@ -2449,7 +2432,9 @@ typedef void tox_conference_connected_cb(Tox *tox, uint32_t conference_number, v
/**
- * Set the callback for the `conference_connected` event. Pass NULL to unset.
+ * @brief Set the callback for the `conference_connected` event.
+ *
+ * Pass NULL to unset.
*
* This event is triggered when the client successfully connects to a
* conference after joining it with the tox_conference_join function.
@@ -2464,11 +2449,13 @@ void tox_callback_conference_connected(Tox *tox, tox_conference_connected_cb *ca
* @param length The length of the message.
*/
typedef void tox_conference_message_cb(Tox *tox, uint32_t conference_number, uint32_t peer_number,
- TOX_MESSAGE_TYPE type, const uint8_t *message, size_t length, void *user_data);
+ Tox_Message_Type type, const uint8_t *message, size_t length, void *user_data);
/**
- * Set the callback for the `conference_message` event. Pass NULL to unset.
+ * @brief Set the callback for the `conference_message` event.
+ *
+ * Pass NULL to unset.
*
* This event is triggered when the client receives a conference message.
*/
@@ -2485,7 +2472,9 @@ typedef void tox_conference_title_cb(Tox *tox, uint32_t conference_number, uint3
/**
- * Set the callback for the `conference_title` event. Pass NULL to unset.
+ * @brief Set the callback for the `conference_title` event.
+ *
+ * Pass NULL to unset.
*
* This event is triggered when a peer changes the conference title.
*
@@ -2505,7 +2494,9 @@ typedef void tox_conference_peer_name_cb(Tox *tox, uint32_t conference_number, u
/**
- * Set the callback for the `conference_peer_name` event. Pass NULL to unset.
+ * @brief Set the callback for the `conference_peer_name` event.
+ *
+ * Pass NULL to unset.
*
* This event is triggered when a peer changes their name.
*/
@@ -2519,13 +2510,15 @@ typedef void tox_conference_peer_list_changed_cb(Tox *tox, uint32_t conference_n
/**
- * Set the callback for the `conference_peer_list_changed` event. Pass NULL to unset.
+ * @brief Set the callback for the `conference_peer_list_changed` event.
+ *
+ * Pass NULL to unset.
*
* This event is triggered when a peer joins or leaves the conference.
*/
void tox_callback_conference_peer_list_changed(Tox *tox, tox_conference_peer_list_changed_cb *callback);
-typedef enum TOX_ERR_CONFERENCE_NEW {
+typedef enum Tox_Err_Conference_New {
/**
* The function returned successfully.
@@ -2537,19 +2530,21 @@ typedef enum TOX_ERR_CONFERENCE_NEW {
*/
TOX_ERR_CONFERENCE_NEW_INIT,
-} TOX_ERR_CONFERENCE_NEW;
+} Tox_Err_Conference_New;
/**
- * Creates a new conference.
+ * @brief Creates a new conference.
*
* This function creates and connects to a new text conference.
*
- * @return conference number on success, or an unspecified value on failure.
+ * @return
+ * - conference number on success
+ * - an unspecified value on failure
*/
-uint32_t tox_conference_new(Tox *tox, TOX_ERR_CONFERENCE_NEW *error);
+uint32_t tox_conference_new(Tox *tox, Tox_Err_Conference_New *error);
-typedef enum TOX_ERR_CONFERENCE_DELETE {
+typedef enum Tox_Err_Conference_Delete {
/**
* The function returned successfully.
@@ -2561,22 +2556,22 @@ typedef enum TOX_ERR_CONFERENCE_DELETE {
*/
TOX_ERR_CONFERENCE_DELETE_CONFERENCE_NOT_FOUND,
-} TOX_ERR_CONFERENCE_DELETE;
+} Tox_Err_Conference_Delete;
/**
- * This function deletes a conference.
+ * @brief This function deletes a conference.
*
* @param conference_number The conference number of the conference to be deleted.
*
* @return true on success.
*/
-bool tox_conference_delete(Tox *tox, uint32_t conference_number, TOX_ERR_CONFERENCE_DELETE *error);
+bool tox_conference_delete(Tox *tox, uint32_t conference_number, Tox_Err_Conference_Delete *error);
/**
- * Error codes for peer info queries.
+ * @brief Error codes for peer info queries.
*/
-typedef enum TOX_ERR_CONFERENCE_PEER_QUERY {
+typedef enum Tox_Err_Conference_Peer_Query {
/**
* The function returned successfully.
@@ -2598,25 +2593,28 @@ typedef enum TOX_ERR_CONFERENCE_PEER_QUERY {
*/
TOX_ERR_CONFERENCE_PEER_QUERY_NO_CONNECTION,
-} TOX_ERR_CONFERENCE_PEER_QUERY;
+} Tox_Err_Conference_Peer_Query;
/**
- * Return the number of online peers in the conference. The unsigned
- * integers less than this number are the valid values of peer_number for
- * the functions querying these peers. Return value is unspecified on
- * failure.
+ * @brief Return the number of online peers in the conference.
+ *
+ * The unsigned integers less than this number are the valid values of
+ * peer_number for the functions querying these peers. Return value is
+ * unspecified on failure.
*/
-uint32_t tox_conference_peer_count(const Tox *tox, uint32_t conference_number, TOX_ERR_CONFERENCE_PEER_QUERY *error);
+uint32_t tox_conference_peer_count(const Tox *tox, uint32_t conference_number, Tox_Err_Conference_Peer_Query *error);
/**
- * Return the length of the peer's name. Return value is unspecified on failure.
+ * @brief Return the length of the peer's name.
+ *
+ * Return value is unspecified on failure.
*/
size_t tox_conference_peer_get_name_size(const Tox *tox, uint32_t conference_number, uint32_t peer_number,
- TOX_ERR_CONFERENCE_PEER_QUERY *error);
+ Tox_Err_Conference_Peer_Query *error);
/**
- * Copy the name of peer_number who is in conference_number to name.
+ * @brief Copy the name of peer_number who is in conference_number to name.
*
* Call tox_conference_peer_get_name_size to determine the allocation size for the `name` parameter.
*
@@ -2625,39 +2623,45 @@ size_t tox_conference_peer_get_name_size(const Tox *tox, uint32_t conference_num
* @return true on success.
*/
bool tox_conference_peer_get_name(const Tox *tox, uint32_t conference_number, uint32_t peer_number, uint8_t *name,
- TOX_ERR_CONFERENCE_PEER_QUERY *error);
+ Tox_Err_Conference_Peer_Query *error);
/**
- * Copy the public key of peer_number who is in conference_number to public_key.
+ * @brief Copy the public key of peer_number who is in conference_number to public_key.
+ *
* public_key must be TOX_PUBLIC_KEY_SIZE long.
*
* @return true on success.
*/
bool tox_conference_peer_get_public_key(const Tox *tox, uint32_t conference_number, uint32_t peer_number,
- uint8_t *public_key, TOX_ERR_CONFERENCE_PEER_QUERY *error);
+ uint8_t *public_key, Tox_Err_Conference_Peer_Query *error);
/**
- * Return true if passed peer_number corresponds to our own.
+ * @brief Return true if passed peer_number corresponds to our own.
*/
bool tox_conference_peer_number_is_ours(const Tox *tox, uint32_t conference_number, uint32_t peer_number,
- TOX_ERR_CONFERENCE_PEER_QUERY *error);
+ Tox_Err_Conference_Peer_Query *error);
/**
- * Return the number of offline peers in the conference. The unsigned
- * integers less than this number are the valid values of offline_peer_number for
- * the functions querying these peers. Return value is unspecified on failure.
+ * @brief Return the number of offline peers in the conference.
+ *
+ * The unsigned integers less than this number are the valid values of
+ * offline_peer_number for the functions querying these peers.
+ *
+ * Return value is unspecified on failure.
*/
uint32_t tox_conference_offline_peer_count(const Tox *tox, uint32_t conference_number,
- TOX_ERR_CONFERENCE_PEER_QUERY *error);
+ Tox_Err_Conference_Peer_Query *error);
/**
- * Return the length of the offline peer's name. Return value is unspecified on failure.
+ * @brief Return the length of the offline peer's name.
+ *
+ * Return value is unspecified on failure.
*/
size_t tox_conference_offline_peer_get_name_size(const Tox *tox, uint32_t conference_number,
- uint32_t offline_peer_number, TOX_ERR_CONFERENCE_PEER_QUERY *error);
+ uint32_t offline_peer_number, Tox_Err_Conference_Peer_Query *error);
/**
- * Copy the name of offline_peer_number who is in conference_number to name.
+ * @brief Copy the name of offline_peer_number who is in conference_number to name.
*
* Call tox_conference_offline_peer_get_name_size to determine the allocation size for the `name` parameter.
*
@@ -2666,24 +2670,25 @@ size_t tox_conference_offline_peer_get_name_size(const Tox *tox, uint32_t confer
* @return true on success.
*/
bool tox_conference_offline_peer_get_name(const Tox *tox, uint32_t conference_number, uint32_t offline_peer_number,
- uint8_t *name, TOX_ERR_CONFERENCE_PEER_QUERY *error);
+ uint8_t *name, Tox_Err_Conference_Peer_Query *error);
/**
- * Copy the public key of offline_peer_number who is in conference_number to public_key.
+ * @brief Copy the public key of offline_peer_number who is in conference_number to public_key.
+ *
* public_key must be TOX_PUBLIC_KEY_SIZE long.
*
* @return true on success.
*/
bool tox_conference_offline_peer_get_public_key(const Tox *tox, uint32_t conference_number,
- uint32_t offline_peer_number, uint8_t *public_key, TOX_ERR_CONFERENCE_PEER_QUERY *error);
+ uint32_t offline_peer_number, uint8_t *public_key, Tox_Err_Conference_Peer_Query *error);
/**
- * Return a unix-time timestamp of the last time offline_peer_number was seen to be active.
+ * @brief Return a unix-time timestamp of the last time offline_peer_number was seen to be active.
*/
uint64_t tox_conference_offline_peer_get_last_active(const Tox *tox, uint32_t conference_number,
- uint32_t offline_peer_number, TOX_ERR_CONFERENCE_PEER_QUERY *error);
+ uint32_t offline_peer_number, Tox_Err_Conference_Peer_Query *error);
-typedef enum TOX_ERR_CONFERENCE_SET_MAX_OFFLINE {
+typedef enum Tox_Err_Conference_Set_Max_Offline {
/**
* The function returned successfully.
@@ -2695,16 +2700,16 @@ typedef enum TOX_ERR_CONFERENCE_SET_MAX_OFFLINE {
*/
TOX_ERR_CONFERENCE_SET_MAX_OFFLINE_CONFERENCE_NOT_FOUND,
-} TOX_ERR_CONFERENCE_SET_MAX_OFFLINE;
+} Tox_Err_Conference_Set_Max_Offline;
/**
- * Set maximum number of offline peers to store, overriding the default.
+ * @brief Set maximum number of offline peers to store, overriding the default.
*/
bool tox_conference_set_max_offline(Tox *tox, uint32_t conference_number, uint32_t max_offline_peers,
- TOX_ERR_CONFERENCE_SET_MAX_OFFLINE *error);
+ Tox_Err_Conference_Set_Max_Offline *error);
-typedef enum TOX_ERR_CONFERENCE_INVITE {
+typedef enum Tox_Err_Conference_Invite {
/**
* The function returned successfully.
@@ -2726,11 +2731,11 @@ typedef enum TOX_ERR_CONFERENCE_INVITE {
*/
TOX_ERR_CONFERENCE_INVITE_NO_CONNECTION,
-} TOX_ERR_CONFERENCE_INVITE;
+} Tox_Err_Conference_Invite;
/**
- * Invites a friend to a conference.
+ * @brief Invites a friend to a conference.
*
* @param friend_number The friend number of the friend we want to invite.
* @param conference_number The conference number of the conference we want to invite the friend to.
@@ -2738,9 +2743,9 @@ typedef enum TOX_ERR_CONFERENCE_INVITE {
* @return true on success.
*/
bool tox_conference_invite(Tox *tox, uint32_t friend_number, uint32_t conference_number,
- TOX_ERR_CONFERENCE_INVITE *error);
+ Tox_Err_Conference_Invite *error);
-typedef enum TOX_ERR_CONFERENCE_JOIN {
+typedef enum Tox_Err_Conference_Join {
/**
* The function returned successfully.
@@ -2777,11 +2782,11 @@ typedef enum TOX_ERR_CONFERENCE_JOIN {
*/
TOX_ERR_CONFERENCE_JOIN_FAIL_SEND,
-} TOX_ERR_CONFERENCE_JOIN;
+} Tox_Err_Conference_Join;
/**
- * Joins a conference that the client has been invited to.
+ * @brief Joins a conference that the client has been invited to.
*
* After successfully joining the conference, the client will not be "connected"
* to it until a handshaking procedure has been completed. A
@@ -2798,9 +2803,9 @@ typedef enum TOX_ERR_CONFERENCE_JOIN {
* @return conference number on success, an unspecified value on failure.
*/
uint32_t tox_conference_join(Tox *tox, uint32_t friend_number, const uint8_t *cookie, size_t length,
- TOX_ERR_CONFERENCE_JOIN *error);
+ Tox_Err_Conference_Join *error);
-typedef enum TOX_ERR_CONFERENCE_SEND_MESSAGE {
+typedef enum Tox_Err_Conference_Send_Message {
/**
* The function returned successfully.
@@ -2827,11 +2832,11 @@ typedef enum TOX_ERR_CONFERENCE_SEND_MESSAGE {
*/
TOX_ERR_CONFERENCE_SEND_MESSAGE_FAIL_SEND,
-} TOX_ERR_CONFERENCE_SEND_MESSAGE;
+} Tox_Err_Conference_Send_Message;
/**
- * Send a text chat message to the conference.
+ * @brief Send a text chat message to the conference.
*
* This function creates a conference message packet and pushes it into the send
* queue.
@@ -2848,10 +2853,10 @@ typedef enum TOX_ERR_CONFERENCE_SEND_MESSAGE {
*
* @return true on success.
*/
-bool tox_conference_send_message(Tox *tox, uint32_t conference_number, TOX_MESSAGE_TYPE type, const uint8_t *message,
- size_t length, TOX_ERR_CONFERENCE_SEND_MESSAGE *error);
+bool tox_conference_send_message(Tox *tox, uint32_t conference_number, Tox_Message_Type type, const uint8_t *message,
+ size_t length, Tox_Err_Conference_Send_Message *error);
-typedef enum TOX_ERR_CONFERENCE_TITLE {
+typedef enum Tox_Err_Conference_Title {
/**
* The function returned successfully.
@@ -2873,19 +2878,21 @@ typedef enum TOX_ERR_CONFERENCE_TITLE {
*/
TOX_ERR_CONFERENCE_TITLE_FAIL_SEND,
-} TOX_ERR_CONFERENCE_TITLE;
+} Tox_Err_Conference_Title;
/**
- * Return the length of the conference title. Return value is unspecified on failure.
+ * @brief Return the length of the conference title.
+ *
+ * Return value is unspecified on failure.
*
* The return value is equal to the `length` argument received by the last
* `conference_title` callback.
*/
-size_t tox_conference_get_title_size(const Tox *tox, uint32_t conference_number, TOX_ERR_CONFERENCE_TITLE *error);
+size_t tox_conference_get_title_size(const Tox *tox, uint32_t conference_number, Tox_Err_Conference_Title *error);
/**
- * Write the title designated by the given conference number to a byte array.
+ * @brief Write the title designated by the given conference number to a byte array.
*
* Call tox_conference_get_title_size to determine the allocation size for the `title` parameter.
*
@@ -2898,27 +2905,30 @@ size_t tox_conference_get_title_size(const Tox *tox, uint32_t conference_number,
* @return true on success.
*/
bool tox_conference_get_title(const Tox *tox, uint32_t conference_number, uint8_t *title,
- TOX_ERR_CONFERENCE_TITLE *error);
+ Tox_Err_Conference_Title *error);
/**
- * Set the conference title and broadcast it to the rest of the conference.
+ * @brief Set the conference title and broadcast it to the rest of the conference.
*
* Title length cannot be longer than TOX_MAX_NAME_LENGTH.
*
* @return true on success.
*/
bool tox_conference_set_title(Tox *tox, uint32_t conference_number, const uint8_t *title, size_t length,
- TOX_ERR_CONFERENCE_TITLE *error);
+ Tox_Err_Conference_Title *error);
/**
- * Return the number of conferences in the Tox instance.
+ * @brief Return the number of conferences in the Tox instance.
+ *
* This should be used to determine how much memory to allocate for `tox_conference_get_chatlist`.
*/
size_t tox_conference_get_chatlist_size(const Tox *tox);
/**
- * Copy a list of valid conference numbers into the array chatlist. Determine
- * how much space to allocate for the array with the `tox_conference_get_chatlist_size` function.
+ * @brief Copy a list of valid conference numbers into the array chatlist.
+ *
+ * Determine how much space to allocate for the array with the
+ * `tox_conference_get_chatlist_size` function.
*
* Note that `tox_get_savedata` saves all connected conferences;
* when toxcore is created from savedata in which conferences were saved, those
@@ -2931,10 +2941,11 @@ size_t tox_conference_get_chatlist_size(const Tox *tox);
void tox_conference_get_chatlist(const Tox *tox, uint32_t *chatlist);
/**
- * Returns the type of conference (TOX_CONFERENCE_TYPE) that conference_number is. Return value is
- * unspecified on failure.
+ * @brief Returns the type of conference (Tox_Conference_Type) that conference_number is.
+ *
+ * Return value is unspecified on failure.
*/
-typedef enum TOX_ERR_CONFERENCE_GET_TYPE {
+typedef enum Tox_Err_Conference_Get_Type {
/**
* The function returned successfully.
@@ -2946,14 +2957,17 @@ typedef enum TOX_ERR_CONFERENCE_GET_TYPE {
*/
TOX_ERR_CONFERENCE_GET_TYPE_CONFERENCE_NOT_FOUND,
-} TOX_ERR_CONFERENCE_GET_TYPE;
+} Tox_Err_Conference_Get_Type;
-TOX_CONFERENCE_TYPE tox_conference_get_type(const Tox *tox, uint32_t conference_number,
- TOX_ERR_CONFERENCE_GET_TYPE *error);
+/**
+ * @brief Get the type (text or A/V) for the conference.
+ */
+Tox_Conference_Type tox_conference_get_type(const Tox *tox, uint32_t conference_number,
+ Tox_Err_Conference_Get_Type *error);
/**
- * Get the conference unique ID.
+ * @brief Get the conference unique ID.
*
* If id is NULL, this function has no effect.
*
@@ -2963,7 +2977,7 @@ TOX_CONFERENCE_TYPE tox_conference_get_type(const Tox *tox, uint32_t conference_
*/
bool tox_conference_get_id(const Tox *tox, uint32_t conference_number, uint8_t *id);
-typedef enum TOX_ERR_CONFERENCE_BY_ID {
+typedef enum Tox_Err_Conference_By_Id {
/**
* The function returned successfully.
@@ -2980,20 +2994,20 @@ typedef enum TOX_ERR_CONFERENCE_BY_ID {
*/
TOX_ERR_CONFERENCE_BY_ID_NOT_FOUND,
-} TOX_ERR_CONFERENCE_BY_ID;
+} Tox_Err_Conference_By_Id;
/**
- * Return the conference number associated with the specified id.
+ * @brief Return the conference number associated with the specified id.
*
* @param id A byte array containing the conference id (TOX_CONFERENCE_ID_SIZE).
*
* @return the conference number on success, an unspecified value on failure.
*/
-uint32_t tox_conference_by_id(const Tox *tox, const uint8_t *id, TOX_ERR_CONFERENCE_BY_ID *error);
+uint32_t tox_conference_by_id(const Tox *tox, const uint8_t *id, Tox_Err_Conference_By_Id *error);
/**
- * Get the conference unique ID.
+ * @brief Get the conference unique ID.
*
* If uid is NULL, this function has no effect.
*
@@ -3004,7 +3018,7 @@ uint32_t tox_conference_by_id(const Tox *tox, const uint8_t *id, TOX_ERR_CONFERE
*/
bool tox_conference_get_uid(const Tox *tox, uint32_t conference_number, uint8_t *uid);
-typedef enum TOX_ERR_CONFERENCE_BY_UID {
+typedef enum Tox_Err_Conference_By_Uid {
/**
* The function returned successfully.
@@ -3021,29 +3035,27 @@ typedef enum TOX_ERR_CONFERENCE_BY_UID {
*/
TOX_ERR_CONFERENCE_BY_UID_NOT_FOUND,
-} TOX_ERR_CONFERENCE_BY_UID;
+} Tox_Err_Conference_By_Uid;
/**
- * Return the conference number associated with the specified uid.
+ * @brief Return the conference number associated with the specified uid.
*
* @param uid A byte array containing the conference id (TOX_CONFERENCE_UID_SIZE).
*
* @return the conference number on success, an unspecified value on failure.
* @deprecated use tox_conference_by_id instead (exactly the same function, just renamed).
*/
-uint32_t tox_conference_by_uid(const Tox *tox, const uint8_t *uid, TOX_ERR_CONFERENCE_BY_UID *error);
+uint32_t tox_conference_by_uid(const Tox *tox, const uint8_t *uid, Tox_Err_Conference_By_Uid *error);
-
-/*******************************************************************************
- *
- * :: Low-level custom packet sending and receiving
- *
- ******************************************************************************/
+/** @} */
+/** @{
+ * @name Low-level custom packet sending and receiving
+ */
-typedef enum TOX_ERR_FRIEND_CUSTOM_PACKET {
+typedef enum Tox_Err_Friend_Custom_Packet {
/**
* The function returned successfully.
@@ -3086,11 +3098,11 @@ typedef enum TOX_ERR_FRIEND_CUSTOM_PACKET {
*/
TOX_ERR_FRIEND_CUSTOM_PACKET_SENDQ,
-} TOX_ERR_FRIEND_CUSTOM_PACKET;
+} Tox_Err_Friend_Custom_Packet;
/**
- * Send a custom lossy packet to a friend.
+ * @brief Send a custom lossy packet to a friend.
*
* The first byte of data must be in the range 192-254. Maximum length of a
* custom packet is TOX_MAX_CUSTOM_PACKET_SIZE.
@@ -3110,10 +3122,10 @@ typedef enum TOX_ERR_FRIEND_CUSTOM_PACKET {
* @return true on success.
*/
bool tox_friend_send_lossy_packet(Tox *tox, uint32_t friend_number, const uint8_t *data, size_t length,
- TOX_ERR_FRIEND_CUSTOM_PACKET *error);
+ Tox_Err_Friend_Custom_Packet *error);
/**
- * Send a custom lossless packet to a friend.
+ * @brief Send a custom lossless packet to a friend.
*
* The first byte of data must be in the range 69, 160-191. Maximum length of a
* custom packet is TOX_MAX_CUSTOM_PACKET_SIZE.
@@ -3129,7 +3141,7 @@ bool tox_friend_send_lossy_packet(Tox *tox, uint32_t friend_number, const uint8_
* @return true on success.
*/
bool tox_friend_send_lossless_packet(Tox *tox, uint32_t friend_number, const uint8_t *data, size_t length,
- TOX_ERR_FRIEND_CUSTOM_PACKET *error);
+ Tox_Err_Friend_Custom_Packet *error);
/**
* @param friend_number The friend number of the friend who sent a lossy packet.
@@ -3141,8 +3153,9 @@ typedef void tox_friend_lossy_packet_cb(Tox *tox, uint32_t friend_number, const
/**
- * Set the callback for the `friend_lossy_packet` event. Pass NULL to unset.
+ * @brief Set the callback for the `friend_lossy_packet` event.
*
+ * Pass NULL to unset.
*/
void tox_callback_friend_lossy_packet(Tox *tox, tox_friend_lossy_packet_cb *callback);
@@ -3156,21 +3169,20 @@ typedef void tox_friend_lossless_packet_cb(Tox *tox, uint32_t friend_number, con
/**
- * Set the callback for the `friend_lossless_packet` event. Pass NULL to unset.
+ * @brief Set the callback for the `friend_lossless_packet` event.
*
+ * Pass NULL to unset.
*/
void tox_callback_friend_lossless_packet(Tox *tox, tox_friend_lossless_packet_cb *callback);
-
-/*******************************************************************************
- *
- * :: Low-level network information
- *
- ******************************************************************************/
+/** @} */
+/** @{
+ * @name Low-level network information
+ */
-typedef enum TOX_ERR_GET_PORT {
+typedef enum Tox_Err_Get_Port {
/**
* The function returned successfully.
@@ -3182,11 +3194,11 @@ typedef enum TOX_ERR_GET_PORT {
*/
TOX_ERR_GET_PORT_NOT_BOUND,
-} TOX_ERR_GET_PORT;
+} Tox_Err_Get_Port;
/**
- * Writes the temporary DHT public key of this instance to a byte array.
+ * @brief Writes the temporary DHT public key of this instance to a byte array.
*
* This can be used in combination with an externally accessible IP address and
* the bound port (from tox_self_get_udp_port) to run a temporary bootstrap node.
@@ -3200,59 +3212,67 @@ typedef enum TOX_ERR_GET_PORT {
void tox_self_get_dht_id(const Tox *tox, uint8_t *dht_id);
/**
- * Return the UDP port this Tox instance is bound to.
+ * @brief Return the UDP port this Tox instance is bound to.
*/
-uint16_t tox_self_get_udp_port(const Tox *tox, TOX_ERR_GET_PORT *error);
+uint16_t tox_self_get_udp_port(const Tox *tox, Tox_Err_Get_Port *error);
/**
- * Return the TCP port this Tox instance is bound to. This is only relevant if
- * the instance is acting as a TCP relay.
+ * @brief Return the TCP port this Tox instance is bound to.
+ *
+ * This is only relevant if the instance is acting as a TCP relay.
*/
-uint16_t tox_self_get_tcp_port(const Tox *tox, TOX_ERR_GET_PORT *error);
+uint16_t tox_self_get_tcp_port(const Tox *tox, Tox_Err_Get_Port *error);
+
+/** @} */
#ifdef __cplusplus
}
#endif
-typedef TOX_ERR_OPTIONS_NEW Tox_Err_Options_New;
-typedef TOX_ERR_NEW Tox_Err_New;
-typedef TOX_ERR_BOOTSTRAP Tox_Err_Bootstrap;
-typedef TOX_ERR_SET_INFO Tox_Err_Set_Info;
-typedef TOX_ERR_FRIEND_ADD Tox_Err_Friend_Add;
-typedef TOX_ERR_FRIEND_DELETE Tox_Err_Friend_Delete;
-typedef TOX_ERR_FRIEND_BY_PUBLIC_KEY Tox_Err_Friend_By_Public_Key;
-typedef TOX_ERR_FRIEND_GET_PUBLIC_KEY Tox_Err_Friend_Get_Public_Key;
-typedef TOX_ERR_FRIEND_GET_LAST_ONLINE Tox_Err_Friend_Get_Last_Online;
-typedef TOX_ERR_FRIEND_QUERY Tox_Err_Friend_Query;
-typedef TOX_ERR_SET_TYPING Tox_Err_Set_Typing;
-typedef TOX_ERR_FRIEND_SEND_MESSAGE Tox_Err_Friend_Send_Message;
-typedef TOX_ERR_FILE_CONTROL Tox_Err_File_Control;
-typedef TOX_ERR_FILE_SEEK Tox_Err_File_Seek;
-typedef TOX_ERR_FILE_GET Tox_Err_File_Get;
-typedef TOX_ERR_FILE_SEND Tox_Err_File_Send;
-typedef TOX_ERR_FILE_SEND_CHUNK Tox_Err_File_Send_Chunk;
-typedef TOX_ERR_CONFERENCE_NEW Tox_Err_Conference_New;
-typedef TOX_ERR_CONFERENCE_DELETE Tox_Err_Conference_Delete;
-typedef TOX_ERR_CONFERENCE_PEER_QUERY Tox_Err_Conference_Peer_Query;
-typedef TOX_ERR_CONFERENCE_SET_MAX_OFFLINE Tox_Err_Conference_Set_Max_Offline;
-typedef TOX_ERR_CONFERENCE_BY_ID Tox_Err_Conference_By_Id;
-typedef TOX_ERR_CONFERENCE_BY_UID Tox_Err_Conference_By_Uid;
-typedef TOX_ERR_CONFERENCE_INVITE Tox_Err_Conference_Invite;
-typedef TOX_ERR_CONFERENCE_JOIN Tox_Err_Conference_Join;
-typedef TOX_ERR_CONFERENCE_SEND_MESSAGE Tox_Err_Conference_Send_Message;
-typedef TOX_ERR_CONFERENCE_TITLE Tox_Err_Conference_Title;
-typedef TOX_ERR_CONFERENCE_GET_TYPE Tox_Err_Conference_Get_Type;
-typedef TOX_ERR_FRIEND_CUSTOM_PACKET Tox_Err_Friend_Custom_Packet;
-typedef TOX_ERR_GET_PORT Tox_Err_Get_Port;
-typedef TOX_USER_STATUS Tox_User_Status;
-typedef TOX_MESSAGE_TYPE Tox_Message_Type;
-typedef TOX_PROXY_TYPE Tox_Proxy_Type;
-typedef TOX_SAVEDATA_TYPE Tox_Savedata_Type;
-typedef TOX_LOG_LEVEL Tox_Log_Level;
-typedef TOX_CONNECTION Tox_Connection;
-typedef TOX_FILE_CONTROL Tox_File_Control;
-typedef TOX_CONFERENCE_TYPE Tox_Conference_Type;
+//!TOKSTYLE-
+#ifndef DOXYGEN_IGNORE
+
+typedef Tox_Err_Options_New TOX_ERR_OPTIONS_NEW;
+typedef Tox_Err_New TOX_ERR_NEW;
+typedef Tox_Err_Bootstrap TOX_ERR_BOOTSTRAP;
+typedef Tox_Err_Set_Info TOX_ERR_SET_INFO;
+typedef Tox_Err_Friend_Add TOX_ERR_FRIEND_ADD;
+typedef Tox_Err_Friend_Delete TOX_ERR_FRIEND_DELETE;
+typedef Tox_Err_Friend_By_Public_Key TOX_ERR_FRIEND_BY_PUBLIC_KEY;
+typedef Tox_Err_Friend_Get_Public_Key TOX_ERR_FRIEND_GET_PUBLIC_KEY;
+typedef Tox_Err_Friend_Get_Last_Online TOX_ERR_FRIEND_GET_LAST_ONLINE;
+typedef Tox_Err_Friend_Query TOX_ERR_FRIEND_QUERY;
+typedef Tox_Err_Set_Typing TOX_ERR_SET_TYPING;
+typedef Tox_Err_Friend_Send_Message TOX_ERR_FRIEND_SEND_MESSAGE;
+typedef Tox_Err_File_Control TOX_ERR_FILE_CONTROL;
+typedef Tox_Err_File_Seek TOX_ERR_FILE_SEEK;
+typedef Tox_Err_File_Get TOX_ERR_FILE_GET;
+typedef Tox_Err_File_Send TOX_ERR_FILE_SEND;
+typedef Tox_Err_File_Send_Chunk TOX_ERR_FILE_SEND_CHUNK;
+typedef Tox_Err_Conference_New TOX_ERR_CONFERENCE_NEW;
+typedef Tox_Err_Conference_Delete TOX_ERR_CONFERENCE_DELETE;
+typedef Tox_Err_Conference_Peer_Query TOX_ERR_CONFERENCE_PEER_QUERY;
+typedef Tox_Err_Conference_Set_Max_Offline TOX_ERR_CONFERENCE_SET_MAX_OFFLINE;
+typedef Tox_Err_Conference_By_Id TOX_ERR_CONFERENCE_BY_ID;
+typedef Tox_Err_Conference_By_Uid TOX_ERR_CONFERENCE_BY_UID;
+typedef Tox_Err_Conference_Invite TOX_ERR_CONFERENCE_INVITE;
+typedef Tox_Err_Conference_Join TOX_ERR_CONFERENCE_JOIN;
+typedef Tox_Err_Conference_Send_Message TOX_ERR_CONFERENCE_SEND_MESSAGE;
+typedef Tox_Err_Conference_Title TOX_ERR_CONFERENCE_TITLE;
+typedef Tox_Err_Conference_Get_Type TOX_ERR_CONFERENCE_GET_TYPE;
+typedef Tox_Err_Friend_Custom_Packet TOX_ERR_FRIEND_CUSTOM_PACKET;
+typedef Tox_Err_Get_Port TOX_ERR_GET_PORT;
+typedef Tox_User_Status TOX_USER_STATUS;
+typedef Tox_Message_Type TOX_MESSAGE_TYPE;
+typedef Tox_Proxy_Type TOX_PROXY_TYPE;
+typedef Tox_Savedata_Type TOX_SAVEDATA_TYPE;
+typedef Tox_Log_Level TOX_LOG_LEVEL;
+typedef Tox_Connection TOX_CONNECTION;
+typedef Tox_File_Control TOX_FILE_CONTROL;
+typedef Tox_Conference_Type TOX_CONFERENCE_TYPE;
+typedef enum Tox_File_Kind TOX_FILE_KIND;
+#endif
//!TOKSTYLE+
#endif // C_TOXCORE_TOXCORE_TOX_H
diff --git a/protocols/Tox/libtox/src/toxcore/tox_api.c b/protocols/Tox/libtox/src/toxcore/tox_api.c
index 63b4bea335..89524ae4e2 100644
--- a/protocols/Tox/libtox/src/toxcore/tox_api.c
+++ b/protocols/Tox/libtox/src/toxcore/tox_api.c
@@ -1,11 +1,19 @@
+/* SPDX-License-Identifier: GPL-3.0-or-later
+ * Copyright © 2016-2021 The TokTok team.
+ */
#include "tox.h"
-#include "ccompat.h"
-
#include <stdlib.h>
#include <string.h>
-#define SET_ERROR_PARAMETER(param, x) do { if (param) { *param = x; } } while (0)
+#include "ccompat.h"
+
+#define SET_ERROR_PARAMETER(param, x) \
+ do { \
+ if (param) { \
+ *param = x; \
+ } \
+ } while (0)
//!TOKSTYLE-
@@ -90,7 +98,7 @@ void tox_options_default(struct Tox_Options *options)
struct Tox_Options *tox_options_new(Tox_Err_Options_New *error)
{
- struct Tox_Options *options = (struct Tox_Options *)malloc(sizeof(struct Tox_Options));
+ struct Tox_Options *options = (struct Tox_Options *)calloc(1, sizeof(struct Tox_Options));
if (options) {
tox_options_default(options);
diff --git a/protocols/Tox/libtox/src/toxcore/util.c b/protocols/Tox/libtox/src/toxcore/util.c
index 2f00adacb1..8174ef3fa2 100644
--- a/protocols/Tox/libtox/src/toxcore/util.c
+++ b/protocols/Tox/libtox/src/toxcore/util.c
@@ -4,13 +4,9 @@
* Copyright © 2013 plutooo
*/
-/*
+/**
* Utilities.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#ifndef _XOPEN_SOURCE
#define _XOPEN_SOURCE 600
#endif
@@ -24,7 +20,7 @@
#include "crypto_core.h" /* for CRYPTO_PUBLIC_KEY_SIZE */
-/* id functions */
+/** id functions */
bool id_equal(const uint8_t *dest, const uint8_t *src)
{
return public_key_cmp(dest, src) == 0;
diff --git a/protocols/Tox/libtox/src/toxcore/util.h b/protocols/Tox/libtox/src/toxcore/util.h
index 5483ff049e..bcae4f4a67 100644
--- a/protocols/Tox/libtox/src/toxcore/util.h
+++ b/protocols/Tox/libtox/src/toxcore/util.h
@@ -4,7 +4,7 @@
* Copyright © 2013 plutooo
*/
-/*
+/**
* Utilities.
*/
#ifndef C_TOXCORE_TOXCORE_UTIL_H
@@ -20,11 +20,11 @@
extern "C" {
#endif
-/* id functions */
+/** id functions */
bool id_equal(const uint8_t *dest, const uint8_t *src);
uint32_t id_copy(uint8_t *dest, const uint8_t *src); /* return value is CLIENT_ID_SIZE */
-/* Returns -1 if failed or 0 if success */
+/** Returns -1 if failed or 0 if success */
int create_recursive_mutex(pthread_mutex_t *mutex);
// Safe min/max functions with specific types. This forces the conversion to the
diff --git a/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/crypto_pwhash_scryptsalsa208sha256.h b/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/crypto_pwhash_scryptsalsa208sha256.h
deleted file mode 100644
index 8249fa1c97..0000000000
--- a/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/crypto_pwhash_scryptsalsa208sha256.h
+++ /dev/null
@@ -1,97 +0,0 @@
-#ifndef C_TOXCORE_TOXENCRYPTSAVE_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_H
-#define C_TOXCORE_TOXENCRYPTSAVE_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_H
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#ifdef VANILLA_NACL /* toxcore only uses this when libsodium is unavailable */
-
-#ifndef crypto_pwhash_scryptsalsa208sha256_H
-#define crypto_pwhash_scryptsalsa208sha256_H
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include "export.h"
-
-#ifdef __cplusplus
-# if __GNUC__
-# pragma GCC diagnostic ignored "-Wlong-long"
-# endif
-extern "C" {
-#endif
-
-#define crypto_pwhash_scryptsalsa208sha256_SALTBYTES 32U
-SODIUM_EXPORT
-size_t crypto_pwhash_scryptsalsa208sha256_saltbytes(void);
-
-#define crypto_pwhash_scryptsalsa208sha256_STRBYTES 102U
-SODIUM_EXPORT
-size_t crypto_pwhash_scryptsalsa208sha256_strbytes(void);
-
-#define crypto_pwhash_scryptsalsa208sha256_STRPREFIX "$7$"
-SODIUM_EXPORT
-const char *crypto_pwhash_scryptsalsa208sha256_strprefix(void);
-
-#define crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE 524288ULL
-SODIUM_EXPORT
-size_t crypto_pwhash_scryptsalsa208sha256_opslimit_interactive(void);
-
-#define crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE 16777216ULL
-SODIUM_EXPORT
-size_t crypto_pwhash_scryptsalsa208sha256_memlimit_interactive(void);
-
-#define crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_SENSITIVE 33554432ULL
-SODIUM_EXPORT
-size_t crypto_pwhash_scryptsalsa208sha256_opslimit_sensitive(void);
-
-#define crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_SENSITIVE 1073741824ULL
-SODIUM_EXPORT
-size_t crypto_pwhash_scryptsalsa208sha256_memlimit_sensitive(void);
-
-SODIUM_EXPORT
-int crypto_pwhash_scryptsalsa208sha256(unsigned char * const out,
- unsigned long long outlen,
- const char * const passwd,
- unsigned long long passwdlen,
- const unsigned char * const salt,
- unsigned long long opslimit,
- size_t memlimit);
-
-SODIUM_EXPORT
-int crypto_pwhash_scryptsalsa208sha256_str(char out[crypto_pwhash_scryptsalsa208sha256_STRBYTES],
- const char * const passwd,
- unsigned long long passwdlen,
- unsigned long long opslimit,
- size_t memlimit);
-
-SODIUM_EXPORT
-int crypto_pwhash_scryptsalsa208sha256_str_verify(const char str[crypto_pwhash_scryptsalsa208sha256_STRBYTES],
- const char * const passwd,
- unsigned long long passwdlen);
-
-SODIUM_EXPORT
-int crypto_pwhash_scryptsalsa208sha256_ll(const uint8_t * passwd, size_t passwdlen,
- const uint8_t * salt, size_t saltlen,
- uint64_t N, uint32_t r, uint32_t p,
- uint8_t * buf, size_t buflen);
-
-#ifdef __cplusplus
-}
-#endif
-
-/* Backward compatibility with version 0.5.0 */
-
-#define crypto_pwhash_scryptxsalsa208sha256_SALTBYTES crypto_pwhash_scryptsalsa208sha256_SALTBYTES
-#define crypto_pwhash_scryptxsalsa208sha256_saltbytes crypto_pwhash_scryptsalsa208sha256_saltbytes
-#define crypto_pwhash_scryptxsalsa208sha256_STRBYTES crypto_pwhash_scryptsalsa208sha256_STRBYTES
-#define crypto_pwhash_scryptxsalsa208sha256_strbytes crypto_pwhash_scryptsalsa208sha256_strbytes
-#define crypto_pwhash_scryptxsalsa208sha256 crypto_pwhash_scryptsalsa208sha256
-#define crypto_pwhash_scryptxsalsa208sha256_str crypto_pwhash_scryptsalsa208sha256_str
-#define crypto_pwhash_scryptxsalsa208sha256_str_verify crypto_pwhash_scryptsalsa208sha256_str_verify
-
-#endif
-
-#endif
-
-#endif
diff --git a/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/crypto_scrypt-common.c b/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/crypto_scrypt-common.c
deleted file mode 100644
index d3e420e068..0000000000
--- a/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/crypto_scrypt-common.c
+++ /dev/null
@@ -1,257 +0,0 @@
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#ifdef VANILLA_NACL /* toxcore only uses this when libsodium is unavailable */
-
-/*-
- * Copyright 2013 Alexander Peslyak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <stdint.h>
-#include <string.h>
-
-#include "crypto_pwhash_scryptsalsa208sha256.h"
-#include "crypto_scrypt.h"
-#include "runtime.h"
-#include "../../toxcore/crypto_core.h"
-
-static const char * const itoa64 =
- "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
-
-static uint8_t *
-encode64_uint32(uint8_t * dst, size_t dstlen, uint32_t src, uint32_t srcbits)
-{
- uint32_t bit;
-
- for (bit = 0; bit < srcbits; bit += 6) {
- if (dstlen < 1) {
- return NULL;
- }
- *dst++ = itoa64[src & 0x3f];
- dstlen--;
- src >>= 6;
- }
-
- return dst;
-}
-
-static uint8_t *
-encode64(uint8_t * dst, size_t dstlen, const uint8_t * src, size_t srclen)
-{
- size_t i;
-
- for (i = 0; i < srclen; ) {
- uint8_t * dnext;
- uint32_t value = 0, bits = 0;
- do {
- value |= (uint32_t)src[i++] << bits;
- bits += 8;
- } while (bits < 24 && i < srclen);
- dnext = encode64_uint32(dst, dstlen, value, bits);
- if (!dnext) {
- return NULL;
- }
- dstlen -= dnext - dst;
- dst = dnext;
- }
-
- return dst;
-}
-
-static int
-decode64_one(uint32_t * dst, uint8_t src)
-{
- const char *ptr = strchr(itoa64, src);
-
- if (ptr) {
- *dst = ptr - itoa64;
- return 0;
- }
- *dst = 0;
- return -1;
-}
-
-static const uint8_t *
-decode64_uint32(uint32_t * dst, uint32_t dstbits, const uint8_t * src)
-{
- uint32_t bit;
- uint32_t value;
-
- value = 0;
- for (bit = 0; bit < dstbits; bit += 6) {
- uint32_t one;
- if (decode64_one(&one, *src)) {
- *dst = 0;
- return NULL;
- }
- src++;
- value |= one << bit;
- }
-
- *dst = value;
- return src;
-}
-
-uint8_t *
-escrypt_r(escrypt_local_t * local, const uint8_t * passwd, size_t passwdlen,
- const uint8_t * setting, uint8_t * buf, size_t buflen)
-{
- uint8_t hash[crypto_pwhash_scryptsalsa208sha256_STRHASHBYTES];
- escrypt_kdf_t escrypt_kdf;
- const uint8_t *src;
- const uint8_t *salt;
- uint8_t *dst;
- size_t prefixlen;
- size_t saltlen;
- size_t need;
- uint64_t N;
- uint32_t N_log2;
- uint32_t r;
- uint32_t p;
-
- if (setting[0] != '$' || setting[1] != '7' || setting[2] != '$') {
- return NULL;
- }
- src = setting + 3;
-
- if (decode64_one(&N_log2, *src)) {
- return NULL;
- }
- src++;
- N = (uint64_t)1 << N_log2;
-
- src = decode64_uint32(&r, 30, src);
- if (!src) {
- return NULL;
- }
- src = decode64_uint32(&p, 30, src);
- if (!src) {
- return NULL;
- }
- prefixlen = src - setting;
-
- salt = src;
- src = (uint8_t *) strrchr((const char *)salt, '$');
- if (src) {
- saltlen = src - salt;
- } else {
- saltlen = strlen((const char *)salt);
- }
- need = prefixlen + saltlen + 1 +
- crypto_pwhash_scryptsalsa208sha256_STRHASHBYTES_ENCODED + 1;
- if (need > buflen || need < saltlen) {
- return NULL;
- }
-#if defined(HAVE_EMMINTRIN_H) || defined(_MSC_VER)
- escrypt_kdf =
- sodium_runtime_has_sse2() ? escrypt_kdf_sse : escrypt_kdf_nosse;
-#else
- escrypt_kdf = escrypt_kdf_nosse;
-#endif
- if (escrypt_kdf(local, passwd, passwdlen, salt, saltlen,
- N, r, p, hash, sizeof(hash))) {
- return NULL;
- }
-
- dst = buf;
- memcpy(dst, setting, prefixlen + saltlen);
- dst += prefixlen + saltlen;
- *dst++ = '$';
-
- dst = encode64(dst, buflen - (dst - buf), hash, sizeof(hash));
- crypto_memzero(hash, sizeof hash);
- if (!dst || dst >= buf + buflen) { /* Can't happen */
- return NULL;
- }
- *dst = 0; /* NUL termination */
-
- return buf;
-}
-
-uint8_t *
-escrypt_gensalt_r(uint32_t N_log2, uint32_t r, uint32_t p,
- const uint8_t * src, size_t srclen,
- uint8_t * buf, size_t buflen)
-{
- uint8_t *dst;
- size_t prefixlen =
- (sizeof "$7$" - 1U) + (1U /* N_log2 */) + (5U /* r */) + (5U /* p */);
- size_t saltlen = BYTES2CHARS(srclen);
- size_t need;
-
- need = prefixlen + saltlen + 1;
- if (need > buflen || need < saltlen || saltlen < srclen) {
- return NULL;
- }
- if (N_log2 > 63 || ((uint64_t)r * (uint64_t)p >= (1U << 30))) {
- return NULL;
- }
- dst = buf;
- *dst++ = '$';
- *dst++ = '7';
- *dst++ = '$';
-
- *dst++ = itoa64[N_log2];
-
- dst = encode64_uint32(dst, buflen - (dst - buf), r, 30);
- if (!dst) { /* Can't happen */
- return NULL;
- }
- dst = encode64_uint32(dst, buflen - (dst - buf), p, 30);
- if (!dst) { /* Can't happen */
- return NULL;
- }
- dst = encode64(dst, buflen - (dst - buf), src, srclen);
- if (!dst || dst >= buf + buflen) { /* Can't happen */
- return NULL;
- }
- *dst = 0; /* NUL termination */
-
- return buf;
-}
-
-int
-crypto_pwhash_scryptsalsa208sha256_ll(const uint8_t * passwd, size_t passwdlen,
- const uint8_t * salt, size_t saltlen,
- uint64_t N, uint32_t r, uint32_t p,
- uint8_t * buf, size_t buflen)
-{
- escrypt_kdf_t escrypt_kdf;
- escrypt_local_t local;
- int retval;
-
- if (escrypt_init_local(&local)) {
- return -1;
- }
-#if defined(HAVE_EMMINTRIN_H) || defined(_MSC_VER)
- escrypt_kdf =
- sodium_runtime_has_sse2() ? escrypt_kdf_sse : escrypt_kdf_nosse;
-#else
- escrypt_kdf = escrypt_kdf_nosse;
-#endif
- retval = escrypt_kdf(&local,
- passwd, passwdlen, salt, saltlen,
- N, r, p, buf, buflen);
- if (escrypt_free_local(&local)) {
- return -1;
- }
- return retval;
-}
-
-#endif
diff --git a/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/crypto_scrypt.h b/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/crypto_scrypt.h
deleted file mode 100644
index 978ac918d0..0000000000
--- a/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/crypto_scrypt.h
+++ /dev/null
@@ -1,98 +0,0 @@
-#ifndef C_TOXCORE_TOXENCRYPTSAVE_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_CRYPTO_SCRYPT_H
-#define C_TOXCORE_TOXENCRYPTSAVE_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_CRYPTO_SCRYPT_H
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#ifdef VANILLA_NACL /* toxcore only uses this when libsodium is unavailable */
-
-/*-
- * Copyright 2009 Colin Percival
- * Copyright 2013 Alexander Peslyak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This file was originally written by Colin Percival as part of the Tarsnap
- * online backup system.
- */
-#ifndef _CRYPTO_SCRYPT_H_
-#define _CRYPTO_SCRYPT_H_
-
-#include <stdint.h>
-
-#define crypto_pwhash_scryptsalsa208sha256_STRPREFIXBYTES 14
-#define crypto_pwhash_scryptsalsa208sha256_STRSETTINGBYTES 57
-#define crypto_pwhash_scryptsalsa208sha256_STRSALTBYTES 32
-#define crypto_pwhash_scryptsalsa208sha256_STRSALTBYTES_ENCODED 43
-#define crypto_pwhash_scryptsalsa208sha256_STRHASHBYTES 32
-#define crypto_pwhash_scryptsalsa208sha256_STRHASHBYTES_ENCODED 43
-
-#define BYTES2CHARS(bytes) ((((bytes) * 8) + 5) / 6)
-
-typedef struct {
- void * base, * aligned;
- size_t size;
-} escrypt_region_t;
-
-typedef escrypt_region_t escrypt_local_t;
-
-extern int escrypt_init_local(escrypt_local_t * __local);
-
-extern int escrypt_free_local(escrypt_local_t * __local);
-
-extern void *alloc_region(escrypt_region_t * region, size_t size);
-extern int free_region(escrypt_region_t * region);
-
-typedef int (*escrypt_kdf_t)(escrypt_local_t * __local,
- const uint8_t * __passwd, size_t __passwdlen,
- const uint8_t * __salt, size_t __saltlen,
- uint64_t __N, uint32_t __r, uint32_t __p,
- uint8_t * __buf, size_t __buflen);
-
-extern int escrypt_kdf_nosse(escrypt_local_t * __local,
- const uint8_t * __passwd, size_t __passwdlen,
- const uint8_t * __salt, size_t __saltlen,
- uint64_t __N, uint32_t __r, uint32_t __p,
- uint8_t * __buf, size_t __buflen);
-
-extern int escrypt_kdf_sse(escrypt_local_t * __local,
- const uint8_t * __passwd, size_t __passwdlen,
- const uint8_t * __salt, size_t __saltlen,
- uint64_t __N, uint32_t __r, uint32_t __p,
- uint8_t * __buf, size_t __buflen);
-
-extern uint8_t * escrypt_r(escrypt_local_t * __local,
- const uint8_t * __passwd, size_t __passwdlen,
- const uint8_t * __setting,
- uint8_t * __buf, size_t __buflen);
-
-extern uint8_t * escrypt_gensalt_r(
- uint32_t __N_log2, uint32_t __r, uint32_t __p,
- const uint8_t * __src, size_t __srclen,
- uint8_t * __buf, size_t __buflen);
-
-#endif /* !_CRYPTO_SCRYPT_H_ */
-
-#endif
-
-#endif
diff --git a/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/export.h b/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/export.h
deleted file mode 100644
index ebf8d9dfb9..0000000000
--- a/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/export.h
+++ /dev/null
@@ -1,43 +0,0 @@
-#ifndef C_TOXCORE_TOXENCRYPTSAVE_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_EXPORT_H
-#define C_TOXCORE_TOXENCRYPTSAVE_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_EXPORT_H
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#ifdef VANILLA_NACL /* toxcore only uses this when libsodium is unavailable */
-
-#ifndef __SODIUM_EXPORT_H__
-#define __SODIUM_EXPORT_H__
-
-#ifndef __GNUC__
-# ifdef __attribute__
-# undef __attribute__
-# endif
-# define __attribute__(a)
-#endif
-
-#ifdef SODIUM_STATIC
-# define SODIUM_EXPORT
-#else
-# if defined(_MSC_VER)
-# ifdef DLL_EXPORT
-# define SODIUM_EXPORT __declspec(dllexport)
-# else
-# define SODIUM_EXPORT __declspec(dllimport)
-# endif
-# else
-# if defined(__SUNPRO_C)
-# define SODIUM_EXPORT __attribute__ __global
-# elif defined(_MSG_VER)
-# define SODIUM_EXPORT extern __declspec(dllexport)
-# else
-# define SODIUM_EXPORT __attribute__ ((visibility ("default")))
-# endif
-# endif
-#endif
-
-#endif
-
-#endif
-
-#endif
diff --git a/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/nosse/pwhash_scryptsalsa208sha256_nosse.c b/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/nosse/pwhash_scryptsalsa208sha256_nosse.c
deleted file mode 100644
index 97d9ba6878..0000000000
--- a/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/nosse/pwhash_scryptsalsa208sha256_nosse.c
+++ /dev/null
@@ -1,309 +0,0 @@
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#ifdef VANILLA_NACL /* toxcore only uses this when libsodium is unavailable */
-
-/*-
- * Copyright 2009 Colin Percival
- * Copyright 2013 Alexander Peslyak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This file was originally written by Colin Percival as part of the Tarsnap
- * online backup system.
- */
-
-#include <errno.h>
-#include <limits.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "../pbkdf2-sha256.h"
-#include "../sysendian.h"
-#include "../crypto_scrypt.h"
-
-static inline void
-blkcpy(void * dest, const void * src, size_t len)
-{
- size_t * D = (size_t *) dest;
- const size_t * S = (const size_t *) src;
- size_t L = len / sizeof(size_t);
- size_t i;
-
- for (i = 0; i < L; i++)
- D[i] = S[i];
-}
-
-static inline void
-blkxor(void * dest, const void * src, size_t len)
-{
- size_t * D = (size_t *) dest;
- const size_t * S = (const size_t *) src;
- size_t L = len / sizeof(size_t);
- size_t i;
-
- for (i = 0; i < L; i++)
- D[i] ^= S[i];
-}
-
-/**
- * salsa20_8(B):
- * Apply the salsa20/8 core to the provided block.
- */
-static void
-salsa20_8(uint32_t B[16])
-{
- uint32_t x[16];
- size_t i;
-
- blkcpy(x, B, 64);
- for (i = 0; i < 8; i += 2) {
-#define R(a,b) (((a) << (b)) | ((a) >> (32 - (b))))
- /* Operate on columns. */
- x[ 4] ^= R(x[ 0]+x[12], 7); x[ 8] ^= R(x[ 4]+x[ 0], 9);
- x[12] ^= R(x[ 8]+x[ 4],13); x[ 0] ^= R(x[12]+x[ 8],18);
-
- x[ 9] ^= R(x[ 5]+x[ 1], 7); x[13] ^= R(x[ 9]+x[ 5], 9);
- x[ 1] ^= R(x[13]+x[ 9],13); x[ 5] ^= R(x[ 1]+x[13],18);
-
- x[14] ^= R(x[10]+x[ 6], 7); x[ 2] ^= R(x[14]+x[10], 9);
- x[ 6] ^= R(x[ 2]+x[14],13); x[10] ^= R(x[ 6]+x[ 2],18);
-
- x[ 3] ^= R(x[15]+x[11], 7); x[ 7] ^= R(x[ 3]+x[15], 9);
- x[11] ^= R(x[ 7]+x[ 3],13); x[15] ^= R(x[11]+x[ 7],18);
-
- /* Operate on rows. */
- x[ 1] ^= R(x[ 0]+x[ 3], 7); x[ 2] ^= R(x[ 1]+x[ 0], 9);
- x[ 3] ^= R(x[ 2]+x[ 1],13); x[ 0] ^= R(x[ 3]+x[ 2],18);
-
- x[ 6] ^= R(x[ 5]+x[ 4], 7); x[ 7] ^= R(x[ 6]+x[ 5], 9);
- x[ 4] ^= R(x[ 7]+x[ 6],13); x[ 5] ^= R(x[ 4]+x[ 7],18);
-
- x[11] ^= R(x[10]+x[ 9], 7); x[ 8] ^= R(x[11]+x[10], 9);
- x[ 9] ^= R(x[ 8]+x[11],13); x[10] ^= R(x[ 9]+x[ 8],18);
-
- x[12] ^= R(x[15]+x[14], 7); x[13] ^= R(x[12]+x[15], 9);
- x[14] ^= R(x[13]+x[12],13); x[15] ^= R(x[14]+x[13],18);
-#undef R
- }
- for (i = 0; i < 16; i++)
- B[i] += x[i];
-}
-
-/**
- * blockmix_salsa8(Bin, Bout, X, r):
- * Compute Bout = BlockMix_{salsa20/8, r}(Bin). The input Bin must be 128r
- * bytes in length; the output Bout must also be the same size. The
- * temporary space X must be 64 bytes.
- */
-static void
-blockmix_salsa8(const uint32_t * Bin, uint32_t * Bout, uint32_t * X, size_t r)
-{
- size_t i;
-
- /* 1: X <-- B_{2r - 1} */
- blkcpy(X, &Bin[(2 * r - 1) * 16], 64);
-
- /* 2: for i = 0 to 2r - 1 do */
- for (i = 0; i < 2 * r; i += 2) {
- /* 3: X <-- H(X \xor B_i) */
- blkxor(X, &Bin[i * 16], 64);
- salsa20_8(X);
-
- /* 4: Y_i <-- X */
- /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
- blkcpy(&Bout[i * 8], X, 64);
-
- /* 3: X <-- H(X \xor B_i) */
- blkxor(X, &Bin[i * 16 + 16], 64);
- salsa20_8(X);
-
- /* 4: Y_i <-- X */
- /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
- blkcpy(&Bout[i * 8 + r * 16], X, 64);
- }
-}
-
-/**
- * integerify(B, r):
- * Return the result of parsing B_{2r-1} as a little-endian integer.
- */
-static inline uint64_t
-integerify(const void * B, size_t r)
-{
- const uint32_t * X = (const uint32_t *)((uintptr_t)(B) + (2 * r - 1) * 64);
-
- return (((uint64_t)(X[1]) << 32) + X[0]);
-}
-
-/**
- * smix(B, r, N, V, XY):
- * Compute B = SMix_r(B, N). The input B must be 128r bytes in length;
- * the temporary storage V must be 128rN bytes in length; the temporary
- * storage XY must be 256r + 64 bytes in length. The value N must be a
- * power of 2 greater than 1. The arrays B, V, and XY must be aligned to a
- * multiple of 64 bytes.
- */
-static void
-smix(uint8_t * B, size_t r, uint64_t N, uint32_t * V, uint32_t * XY)
-{
- uint32_t * X = XY;
- uint32_t * Y = &XY[32 * r];
- uint32_t * Z = &XY[64 * r];
- uint64_t i;
- uint64_t j;
- size_t k;
-
- /* 1: X <-- B */
- for (k = 0; k < 32 * r; k++)
- X[k] = le32dec(&B[4 * k]);
-
- /* 2: for i = 0 to N - 1 do */
- for (i = 0; i < N; i += 2) {
- /* 3: V_i <-- X */
- blkcpy(&V[i * (32 * r)], X, 128 * r);
-
- /* 4: X <-- H(X) */
- blockmix_salsa8(X, Y, Z, r);
-
- /* 3: V_i <-- X */
- blkcpy(&V[(i + 1) * (32 * r)], Y, 128 * r);
-
- /* 4: X <-- H(X) */
- blockmix_salsa8(Y, X, Z, r);
- }
-
- /* 6: for i = 0 to N - 1 do */
- for (i = 0; i < N; i += 2) {
- /* 7: j <-- Integerify(X) mod N */
- j = integerify(X, r) & (N - 1);
-
- /* 8: X <-- H(X \xor V_j) */
- blkxor(X, &V[j * (32 * r)], 128 * r);
- blockmix_salsa8(X, Y, Z, r);
-
- /* 7: j <-- Integerify(X) mod N */
- j = integerify(Y, r) & (N - 1);
-
- /* 8: X <-- H(X \xor V_j) */
- blkxor(Y, &V[j * (32 * r)], 128 * r);
- blockmix_salsa8(Y, X, Z, r);
- }
- /* 10: B' <-- X */
- for (k = 0; k < 32 * r; k++)
- le32enc(&B[4 * k], X[k]);
-}
-
-/**
- * escrypt_kdf(local, passwd, passwdlen, salt, saltlen,
- * N, r, p, buf, buflen):
- * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r,
- * p, buflen) and write the result into buf. The parameters r, p, and buflen
- * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32. The parameter N
- * must be a power of 2 greater than 1.
- *
- * Return 0 on success; or -1 on error.
- */
-int
-escrypt_kdf_nosse(escrypt_local_t * local,
- const uint8_t * passwd, size_t passwdlen,
- const uint8_t * salt, size_t saltlen,
- uint64_t N, uint32_t _r, uint32_t _p,
- uint8_t * buf, size_t buflen)
-{
- size_t B_size, V_size, XY_size, need;
- uint8_t * B;
- uint32_t * V, * XY;
- size_t r = _r, p = _p;
- uint32_t i;
-
- /* Sanity-check parameters. */
-#if SIZE_MAX > UINT32_MAX
- if (buflen > (((uint64_t)(1) << 32) - 1) * 32) {
- errno = EFBIG;
- return -1;
- }
-#endif
- if ((uint64_t)(r) * (uint64_t)(p) >= (1 << 30)) {
- errno = EFBIG;
- return -1;
- }
- if (((N & (N - 1)) != 0) || (N < 2)) {
- errno = EINVAL;
- return -1;
- }
- if (r == 0 || p == 0) {
- errno = EINVAL;
- return -1;
- }
- if ((r > SIZE_MAX / 128 / p) ||
-#if SIZE_MAX / 256 <= UINT32_MAX
- (r > SIZE_MAX / 256) ||
-#endif
- (N > SIZE_MAX / 128 / r)) {
- errno = ENOMEM;
- return -1;
- }
-
- /* Allocate memory. */
- B_size = (size_t)128 * r * p;
- V_size = (size_t)128 * r * N;
- need = B_size + V_size;
- if (need < V_size) {
- errno = ENOMEM;
- return -1;
- }
- XY_size = (size_t)256 * r + 64;
- need += XY_size;
- if (need < XY_size) {
- errno = ENOMEM;
- return -1;
- }
- if (local->size < need) {
- if (free_region(local))
- return -1;
- if (!alloc_region(local, need))
- return -1;
- }
- B = (uint8_t *)local->aligned;
- V = (uint32_t *)((uint8_t *)B + B_size);
- XY = (uint32_t *)((uint8_t *)V + V_size);
-
- /* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */
- PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, 1, B, B_size);
-
- /* 2: for i = 0 to p - 1 do */
- for (i = 0; i < p; i++) {
- /* 3: B_i <-- MF(B_i, N) */
- smix(&B[(size_t)128 * i * r], r, N, V, XY);
- }
-
- /* 5: DK <-- PBKDF2(P, B, 1, dkLen) */
- PBKDF2_SHA256(passwd, passwdlen, B, B_size, 1, buf, buflen);
-
- /* Success! */
- return 0;
-}
-
-#endif
diff --git a/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/note_to_maintainers.txt b/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/note_to_maintainers.txt
deleted file mode 100644
index 66bbfe2db9..0000000000
--- a/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/note_to_maintainers.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-This folder is only meant for use with nacl, i.e. when sodium is unavailable.
-
-
-The files in this folder were mostly copied from
-https://github.com/jedisct1/libsodium/tree/0.7.0/src/libsodium/crypto_pwhash/scryptsalsa208sha256,
-with #ifdef VANILLA_NACL added around each of them as required for this module.
-
-export.h, utils.h, and runtime.h were copied from
-https://github.com/jedisct1/libsodium/tree/0.7.0/src/libsodium/include/sodium.
-utils.h was significantly truncated.
-
-utils.c and runtime.c were copied from
-https://github.com/jedisct1/libsodium/blob/0.7.0/src/libsodium/sodium.
-utils.c was also significantly truncated.
diff --git a/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/pbkdf2-sha256.c b/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/pbkdf2-sha256.c
deleted file mode 100644
index c69d7c22e7..0000000000
--- a/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/pbkdf2-sha256.c
+++ /dev/null
@@ -1,97 +0,0 @@
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#ifdef VANILLA_NACL /* toxcore only uses this when libsodium is unavailable */
-
-/*-
- * Copyright 2005,2007,2009 Colin Percival
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/types.h>
-
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <crypto_hash_sha256.h>
-#include <crypto_auth_hmacsha256.h>
-
-#include "pbkdf2-sha256.h"
-#include "sysendian.h"
-#include "../../toxcore/crypto_core.h"
-
-/**
- * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen):
- * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and
- * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1).
- */
-void
-PBKDF2_SHA256(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt,
- size_t saltlen, uint64_t c, uint8_t * buf, size_t dkLen)
-{
- uint8_t key[32] = {0};
- size_t i;
- uint8_t salt_and_ivec[saltlen + 4];
- uint8_t U[32];
- uint8_t T[32];
- uint64_t j;
- int k;
- size_t clen;
-
- if (passwdlen > 32) {
- /* For some reason libsodium allows 64byte keys meaning keys
- * between 32byte and 64bytes are not compatible with libsodium.
- toxencryptsave should only give 32byte passwds so this isn't an issue here.*/
- crypto_hash_sha256(key, passwd, passwdlen);
- } else {
- memcpy(key, passwd, passwdlen);
- }
-
- memcpy(salt_and_ivec, salt, saltlen);
-
- for (i = 0; i * 32 < dkLen; i++) {
- be32enc(salt_and_ivec + saltlen, (uint32_t)(i + 1));
- crypto_auth_hmacsha256(U, salt_and_ivec, sizeof(salt_and_ivec), key);
-
- memcpy(T, U, 32);
-
- for (j = 2; j <= c; j++) {
- crypto_auth_hmacsha256(U, U, 32, key);
-
- for (k = 0; k < 32; k++) {
- T[k] ^= U[k];
- }
- }
-
- clen = dkLen - i * 32;
- if (clen > 32) {
- clen = 32;
- }
- memcpy(&buf[i * 32], T, clen);
- }
- crypto_memzero((void *) key, sizeof(key));
-}
-
-#endif
diff --git a/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/pbkdf2-sha256.h b/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/pbkdf2-sha256.h
deleted file mode 100644
index 17cd211258..0000000000
--- a/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/pbkdf2-sha256.h
+++ /dev/null
@@ -1,57 +0,0 @@
-#ifndef C_TOXCORE_TOXENCRYPTSAVE_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_PBKDF2_SHA256_H
-#define C_TOXCORE_TOXENCRYPTSAVE_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_PBKDF2_SHA256_H
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#ifdef VANILLA_NACL /* toxcore only uses this when libsodium is unavailable */
-
-/*-
- * Copyright 2005,2007,2009 Colin Percival
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- */
-
-#ifndef _SHA256_H_
-#define _SHA256_H_
-
-#include <sys/types.h>
-
-#include <stdint.h>
-
-#include "crypto_auth_hmacsha256.h"
-
-/**
- * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen):
- * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and
- * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1).
- */
-void PBKDF2_SHA256(const uint8_t *, size_t, const uint8_t *, size_t,
- uint64_t, uint8_t *, size_t);
-
-#endif /* !_SHA256_H_ */
-
-#endif
-
-#endif
diff --git a/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/pwhash_scryptsalsa208sha256.c b/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/pwhash_scryptsalsa208sha256.c
deleted file mode 100644
index 3aab156f9d..0000000000
--- a/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/pwhash_scryptsalsa208sha256.c
+++ /dev/null
@@ -1,210 +0,0 @@
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#ifdef VANILLA_NACL /* toxcore only uses this when libsodium is unavailable */
-
-#include <errno.h>
-#include <limits.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <string.h>
-//#include <stdio.h>
-
-#include "crypto_pwhash_scryptsalsa208sha256.h"
-#include "crypto_scrypt.h"
-#include "../../toxcore/crypto_core.h"
-
-#define SETTING_SIZE(saltbytes) \
- (sizeof "$7$" - 1U) + \
- (1U /* N_log2 */) + (5U /* r */) + (5U /* p */) + BYTES2CHARS(saltbytes)
-
-static int
-pickparams(unsigned long long opslimit, const size_t memlimit,
- uint32_t * const N_log2, uint32_t * const p, uint32_t * const r)
-{
- unsigned long long maxN;
- unsigned long long maxrp;
-
- if (opslimit < 32768) {
- opslimit = 32768;
- }
- *r = 8;
- if (opslimit < memlimit / 32) {
- *p = 1;
- maxN = opslimit / (*r * 4);
- for (*N_log2 = 1; *N_log2 < 63; *N_log2 += 1) {
- if ((uint64_t)(1) << *N_log2 > maxN / 2) {
- break;
- }
- }
- } else {
- maxN = memlimit / (*r * 128);
- for (*N_log2 = 1; *N_log2 < 63; *N_log2 += 1) {
- if ((uint64_t) (1) << *N_log2 > maxN / 2) {
- break;
- }
- }
- maxrp = (opslimit / 4) / ((uint64_t) (1) << *N_log2);
- if (maxrp > 0x3fffffff) {
- maxrp = 0x3fffffff;
- }
- *p = (uint32_t) (maxrp) / *r;
- }
- return 0;
-}
-
-size_t
-crypto_pwhash_scryptsalsa208sha256_saltbytes(void)
-{
- return crypto_pwhash_scryptsalsa208sha256_SALTBYTES;
-}
-
-size_t
-crypto_pwhash_scryptsalsa208sha256_strbytes(void)
-{
- return crypto_pwhash_scryptsalsa208sha256_STRBYTES;
-}
-
-const char *
-crypto_pwhash_scryptsalsa208sha256_strprefix(void)
-{
- return crypto_pwhash_scryptsalsa208sha256_STRPREFIX;
-}
-
-size_t
-crypto_pwhash_scryptsalsa208sha256_opslimit_interactive(void)
-{
- return crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE;
-}
-
-size_t
-crypto_pwhash_scryptsalsa208sha256_memlimit_interactive(void)
-{
- return crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE;
-}
-
-size_t
-crypto_pwhash_scryptsalsa208sha256_opslimit_sensitive(void)
-{
- return crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_SENSITIVE;
-}
-
-size_t
-crypto_pwhash_scryptsalsa208sha256_memlimit_sensitive(void)
-{
- return crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_SENSITIVE;
-}
-
-int
-crypto_pwhash_scryptsalsa208sha256(unsigned char * const out,
- unsigned long long outlen,
- const char * const passwd,
- unsigned long long passwdlen,
- const unsigned char * const salt,
- unsigned long long opslimit,
- size_t memlimit)
-{
- //fprintf(stderr, "Doing that dirty thang!!!!\n");
- uint32_t N_log2;
- uint32_t p;
- uint32_t r;
-
- memset(out, 0, outlen);
- if (passwdlen > SIZE_MAX || outlen > SIZE_MAX) {
- errno = EFBIG;
- return -1;
- }
- if (pickparams(opslimit, memlimit, &N_log2, &p, &r) != 0) {
- errno = EINVAL;
- return -1;
- }
- return crypto_pwhash_scryptsalsa208sha256_ll((const uint8_t *) passwd,
- (size_t) passwdlen,
- (const uint8_t *) salt,
- crypto_pwhash_scryptsalsa208sha256_SALTBYTES,
- (uint64_t) (1) << N_log2, r, p,
- out, (size_t) outlen);
-}
-
-int
-crypto_pwhash_scryptsalsa208sha256_str(char out[crypto_pwhash_scryptsalsa208sha256_STRBYTES],
- const char * const passwd,
- unsigned long long passwdlen,
- unsigned long long opslimit,
- size_t memlimit)
-{
- uint8_t salt[crypto_pwhash_scryptsalsa208sha256_STRSALTBYTES];
- char setting[crypto_pwhash_scryptsalsa208sha256_STRSETTINGBYTES + 1U];
- escrypt_local_t escrypt_local;
- uint32_t N_log2;
- uint32_t p;
- uint32_t r;
-
- memset(out, 0, crypto_pwhash_scryptsalsa208sha256_STRBYTES);
- if (passwdlen > SIZE_MAX) {
- errno = EFBIG;
- return -1;
- }
- if (pickparams(opslimit, memlimit, &N_log2, &p, &r) != 0) {
- errno = EINVAL;
- return -1;
- }
- random_bytes(salt, sizeof salt);
- if (escrypt_gensalt_r(N_log2, r, p, salt, sizeof salt,
- (uint8_t *) setting, sizeof setting) == NULL) {
- errno = EINVAL;
- return -1;
- }
- if (escrypt_init_local(&escrypt_local) != 0) {
- return -1;
- }
- if (escrypt_r(&escrypt_local, (const uint8_t *) passwd, (size_t) passwdlen,
- (const uint8_t *) setting, (uint8_t *) out,
- crypto_pwhash_scryptsalsa208sha256_STRBYTES) == NULL) {
- escrypt_free_local(&escrypt_local);
- errno = EINVAL;
- return -1;
- }
- escrypt_free_local(&escrypt_local);
-
- (void) sizeof
- (int[SETTING_SIZE(crypto_pwhash_scryptsalsa208sha256_STRSALTBYTES)
- == crypto_pwhash_scryptsalsa208sha256_STRSETTINGBYTES ? 1 : -1]);
- (void) sizeof
- (int[crypto_pwhash_scryptsalsa208sha256_STRSETTINGBYTES + 1U +
- crypto_pwhash_scryptsalsa208sha256_STRHASHBYTES_ENCODED + 1U
- == crypto_pwhash_scryptsalsa208sha256_STRBYTES ? 1 : -1]);
-
- return 0;
-}
-
-int
-crypto_pwhash_scryptsalsa208sha256_str_verify(const char str[crypto_pwhash_scryptsalsa208sha256_STRBYTES],
- const char * const passwd,
- unsigned long long passwdlen)
-{
- char wanted[crypto_pwhash_scryptsalsa208sha256_STRBYTES];
- escrypt_local_t escrypt_local;
- int ret = -1;
-
- if (memchr(str, 0, crypto_pwhash_scryptsalsa208sha256_STRBYTES) !=
- &str[crypto_pwhash_scryptsalsa208sha256_STRBYTES - 1U]) {
- return -1;
- }
- if (escrypt_init_local(&escrypt_local) != 0) {
- return -1;
- }
- if (escrypt_r(&escrypt_local, (const uint8_t *) passwd, (size_t) passwdlen,
- (const uint8_t *) str, (uint8_t *) wanted,
- sizeof wanted) == NULL) {
- escrypt_free_local(&escrypt_local);
- return -1;
- }
- escrypt_free_local(&escrypt_local);
- ret = crypto_memcmp((const uint8_t *) wanted, (const uint8_t *) str, sizeof wanted);
- crypto_memzero(wanted, sizeof wanted);
-
- return ret;
-}
-
-#endif
diff --git a/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/runtime.c b/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/runtime.c
deleted file mode 100644
index a813b50609..0000000000
--- a/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/runtime.c
+++ /dev/null
@@ -1,144 +0,0 @@
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#ifdef VANILLA_NACL /* toxcore only uses this when libsodium is unavailable */
-
-#ifdef HAVE_ANDROID_GETCPUFEATURES
-# include <cpu-features.h>
-#endif
-
-#include "runtime.h"
-
-typedef struct CPUFeatures_ {
- int initialized;
- int has_neon;
- int has_sse2;
- int has_sse3;
-} CPUFeatures;
-
-static CPUFeatures _cpu_features;
-
-#ifdef HAVE_EMMINTRIN_H
-#define CPUID_SSE2 0x04000000
-#endif
-#ifdef HAVE_PMMINTRIN_H
-#define CPUIDECX_SSE3 0x00000001
-#endif
-
-static int
-_sodium_runtime_arm_cpu_features(CPUFeatures * const cpu_features)
-{
-#ifndef __arm__
- cpu_features->has_neon = 0;
- return -1;
-#else
-# ifdef __APPLE__
-# ifdef __ARM_NEON__
- cpu_features->has_neon = 1;
-# else
- cpu_features->has_neon = 0;
-# endif
-# elif defined(HAVE_ANDROID_GETCPUFEATURES) && defined(ANDROID_CPU_ARM_FEATURE_NEON)
- cpu_features->has_neon =
- (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0x0;
-# else
- cpu_features->has_neon = 0;
-# endif
- return 0;
-#endif
-}
-
-static void
-_cpuid(unsigned int cpu_info[4U], const unsigned int cpu_info_type)
-{
-#ifdef _MSC_VER
- __cpuidex((int *) cpu_info, cpu_info_type, 0);
-#elif defined(HAVE_CPUID)
- cpu_info[0] = cpu_info[1] = cpu_info[2] = cpu_info[3] = 0;
-# ifdef __i386__
- __asm__ __volatile__ ("pushfl; pushfl; "
- "popl %0; "
- "movl %0, %1; xorl %2, %0; "
- "pushl %0; "
- "popfl; pushfl; popl %0; popfl" :
- "=&r" (cpu_info[0]), "=&r" (cpu_info[1]) :
- "i" (0x200000));
- if (((cpu_info[0] ^ cpu_info[1]) & 0x200000) == 0x0) {
- return;
- }
-# endif
-# ifdef __i386__
- __asm__ __volatile__ ("xchgl %%ebx, %k1; cpuid; xchgl %%ebx, %k1" :
- "=a" (cpu_info[0]), "=&r" (cpu_info[1]),
- "=c" (cpu_info[2]), "=d" (cpu_info[3]) :
- "0" (cpu_info_type), "2" (0U));
-# elif defined(__x86_64__)
- __asm__ __volatile__ ("xchgq %%rbx, %q1; cpuid; xchgq %%rbx, %q1" :
- "=a" (cpu_info[0]), "=&r" (cpu_info[1]),
- "=c" (cpu_info[2]), "=d" (cpu_info[3]) :
- "0" (cpu_info_type), "2" (0U));
-# else
- __asm__ __volatile__ ("cpuid" :
- "=a" (cpu_info[0]), "=b" (cpu_info[1]),
- "=c" (cpu_info[2]), "=d" (cpu_info[3]) :
- "0" (cpu_info_type), "2" (0U));
-# endif
-#else
- cpu_info[0] = cpu_info[1] = cpu_info[2] = cpu_info[3] = 0;
-#endif
-}
-
-static int
-_sodium_runtime_intel_cpu_features(CPUFeatures * const cpu_features)
-{
- unsigned int cpu_info[4];
- unsigned int id;
-
- _cpuid(cpu_info, 0x0);
- if ((id = cpu_info[0]) == 0U) {
- return -1;
- }
- _cpuid(cpu_info, 0x00000001);
-#ifndef HAVE_EMMINTRIN_H
- cpu_features->has_sse2 = 0;
-#else
- cpu_features->has_sse2 = ((cpu_info[3] & CPUID_SSE2) != 0x0);
-#endif
-
-#ifndef HAVE_PMMINTRIN_H
- cpu_features->has_sse3 = 0;
-#else
- cpu_features->has_sse3 = ((cpu_info[2] & CPUIDECX_SSE3) != 0x0);
-#endif
-
- return 0;
-}
-
-int
-sodium_runtime_get_cpu_features(void)
-{
- int ret = -1;
-
- ret &= _sodium_runtime_arm_cpu_features(&_cpu_features);
- ret &= _sodium_runtime_intel_cpu_features(&_cpu_features);
- _cpu_features.initialized = 1;
-
- return ret;
-}
-
-int
-sodium_runtime_has_neon(void) {
- return _cpu_features.has_neon;
-}
-
-int
-sodium_runtime_has_sse2(void) {
- return _cpu_features.has_sse2;
-}
-
-int
-sodium_runtime_has_sse3(void) {
- return _cpu_features.has_sse3;
-}
-
-#endif
diff --git a/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/runtime.h b/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/runtime.h
deleted file mode 100644
index 260a4550a9..0000000000
--- a/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/runtime.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#ifndef C_TOXCORE_TOXENCRYPTSAVE_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_RUNTIME_H
-#define C_TOXCORE_TOXENCRYPTSAVE_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_RUNTIME_H
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#ifdef VANILLA_NACL /* toxcore only uses this when libsodium is unavailable */
-
-#ifndef __SODIUM_RUNTIME_H__
-#define __SODIUM_RUNTIME_H__ 1
-
-#include "export.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-SODIUM_EXPORT
-int sodium_runtime_get_cpu_features(void);
-
-SODIUM_EXPORT
-int sodium_runtime_has_neon(void);
-
-SODIUM_EXPORT
-int sodium_runtime_has_sse2(void);
-
-SODIUM_EXPORT
-int sodium_runtime_has_sse3(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
-#endif
-
-#endif
diff --git a/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/scrypt_platform.c b/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/scrypt_platform.c
deleted file mode 100644
index 5819651454..0000000000
--- a/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/scrypt_platform.c
+++ /dev/null
@@ -1,107 +0,0 @@
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#ifdef VANILLA_NACL /* toxcore only uses this when libsodium is unavailable */
-
-/*-
- * Copyright 2013 Alexander Peslyak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifdef HAVE_SYS_MMAN_H
-# include <sys/mman.h>
-#endif
-#include <errno.h>
-#include <stdlib.h>
-
-#include "crypto_scrypt.h"
-#include "runtime.h"
-
-#if !defined(MAP_ANON) && defined(MAP_ANONYMOUS)
-# define MAP_ANON MAP_ANONYMOUS
-#endif
-
-void *
-alloc_region(escrypt_region_t * region, size_t size)
-{
- uint8_t * base, * aligned;
-#ifdef MAP_ANON
- if ((base = (uint8_t *) mmap(NULL, size, PROT_READ | PROT_WRITE,
-#ifdef MAP_NOCORE
- MAP_ANON | MAP_PRIVATE | MAP_NOCORE,
-#else
- MAP_ANON | MAP_PRIVATE,
-#endif
- -1, 0)) == MAP_FAILED)
- base = NULL;
- aligned = base;
-#elif defined(HAVE_POSIX_MEMALIGN)
- if ((errno = posix_memalign((void **) &base, 64, size)) != 0)
- base = NULL;
- aligned = base;
-#else
- base = aligned = NULL;
- if (size + 63 < size)
- errno = ENOMEM;
- else if ((base = (uint8_t *) malloc(size + 63)) != NULL) {
- aligned = base + 63;
- aligned -= (uintptr_t)aligned & 63;
- }
-#endif
- region->base = base;
- region->aligned = aligned;
- region->size = base ? size : 0;
- return aligned;
-}
-
-static inline void
-init_region(escrypt_region_t * region)
-{
- region->base = region->aligned = NULL;
- region->size = 0;
-}
-
-int
-free_region(escrypt_region_t * region)
-{
- if (region->base) {
-#ifdef MAP_ANON
- if (munmap(region->base, region->size))
- return -1;
-#else
- free(region->base);
-#endif
- }
- init_region(region);
- return 0;
-}
-
-int
-escrypt_init_local(escrypt_local_t * local)
-{
- init_region(local);
- return 0;
-}
-
-int
-escrypt_free_local(escrypt_local_t * local)
-{
- return free_region(local);
-}
-
-#endif
diff --git a/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/sse/pwhash_scryptsalsa208sha256_sse.c b/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/sse/pwhash_scryptsalsa208sha256_sse.c
deleted file mode 100644
index 38a536a61a..0000000000
--- a/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/sse/pwhash_scryptsalsa208sha256_sse.c
+++ /dev/null
@@ -1,401 +0,0 @@
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#ifdef VANILLA_NACL /* toxcore only uses this when libsodium is unavailable */
-
-/*-
- * Copyright 2009 Colin Percival
- * Copyright 2012,2013 Alexander Peslyak
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This file was originally written by Colin Percival as part of the Tarsnap
- * online backup system.
- */
-
-#if defined(HAVE_EMMINTRIN_H) || defined(_MSC_VER)
-#if __GNUC__
-# pragma GCC target("sse2")
-#endif
-#include <emmintrin.h>
-#if defined(__XOP__) && defined(DISABLED)
-# include <x86intrin.h>
-#endif
-
-#include <errno.h>
-#include <limits.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "../pbkdf2-sha256.h"
-#include "../sysendian.h"
-#include "../crypto_scrypt.h"
-
-#if defined(__XOP__) && defined(DISABLED)
-#define ARX(out, in1, in2, s) \
- out = _mm_xor_si128(out, _mm_roti_epi32(_mm_add_epi32(in1, in2), s));
-#else
-#define ARX(out, in1, in2, s) \
- { \
- __m128i T = _mm_add_epi32(in1, in2); \
- out = _mm_xor_si128(out, _mm_slli_epi32(T, s)); \
- out = _mm_xor_si128(out, _mm_srli_epi32(T, 32-s)); \
- }
-#endif
-
-#define SALSA20_2ROUNDS \
- /* Operate on "columns". */ \
- ARX(X1, X0, X3, 7) \
- ARX(X2, X1, X0, 9) \
- ARX(X3, X2, X1, 13) \
- ARX(X0, X3, X2, 18) \
-\
- /* Rearrange data. */ \
- X1 = _mm_shuffle_epi32(X1, 0x93); \
- X2 = _mm_shuffle_epi32(X2, 0x4E); \
- X3 = _mm_shuffle_epi32(X3, 0x39); \
-\
- /* Operate on "rows". */ \
- ARX(X3, X0, X1, 7) \
- ARX(X2, X3, X0, 9) \
- ARX(X1, X2, X3, 13) \
- ARX(X0, X1, X2, 18) \
-\
- /* Rearrange data. */ \
- X1 = _mm_shuffle_epi32(X1, 0x39); \
- X2 = _mm_shuffle_epi32(X2, 0x4E); \
- X3 = _mm_shuffle_epi32(X3, 0x93);
-
-/**
- * Apply the salsa20/8 core to the block provided in (X0 ... X3) ^ (Z0 ... Z3).
- */
-#define SALSA20_8_XOR(in, out) \
- { \
- __m128i Y0 = X0 = _mm_xor_si128(X0, (in)[0]); \
- __m128i Y1 = X1 = _mm_xor_si128(X1, (in)[1]); \
- __m128i Y2 = X2 = _mm_xor_si128(X2, (in)[2]); \
- __m128i Y3 = X3 = _mm_xor_si128(X3, (in)[3]); \
- SALSA20_2ROUNDS \
- SALSA20_2ROUNDS \
- SALSA20_2ROUNDS \
- SALSA20_2ROUNDS \
- (out)[0] = X0 = _mm_add_epi32(X0, Y0); \
- (out)[1] = X1 = _mm_add_epi32(X1, Y1); \
- (out)[2] = X2 = _mm_add_epi32(X2, Y2); \
- (out)[3] = X3 = _mm_add_epi32(X3, Y3); \
- }
-
-/**
- * blockmix_salsa8(Bin, Bout, r):
- * Compute Bout = BlockMix_{salsa20/8, r}(Bin). The input Bin must be 128r
- * bytes in length; the output Bout must also be the same size.
- */
-static inline void
-blockmix_salsa8(const __m128i * Bin, __m128i * Bout, size_t r)
-{
- __m128i X0, X1, X2, X3;
- size_t i;
-
- /* 1: X <-- B_{2r - 1} */
- X0 = Bin[8 * r - 4];
- X1 = Bin[8 * r - 3];
- X2 = Bin[8 * r - 2];
- X3 = Bin[8 * r - 1];
-
- /* 3: X <-- H(X \xor B_i) */
- /* 4: Y_i <-- X */
- /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
- SALSA20_8_XOR(Bin, Bout)
-
- /* 2: for i = 0 to 2r - 1 do */
- r--;
- for (i = 0; i < r;) {
- /* 3: X <-- H(X \xor B_i) */
- /* 4: Y_i <-- X */
- /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
- SALSA20_8_XOR(&Bin[i * 8 + 4], &Bout[(r + i) * 4 + 4])
-
- i++;
-
- /* 3: X <-- H(X \xor B_i) */
- /* 4: Y_i <-- X */
- /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
- SALSA20_8_XOR(&Bin[i * 8], &Bout[i * 4])
- }
-
- /* 3: X <-- H(X \xor B_i) */
- /* 4: Y_i <-- X */
- /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
- SALSA20_8_XOR(&Bin[i * 8 + 4], &Bout[(r + i) * 4 + 4])
-}
-
-#define XOR4(in) \
- X0 = _mm_xor_si128(X0, (in)[0]); \
- X1 = _mm_xor_si128(X1, (in)[1]); \
- X2 = _mm_xor_si128(X2, (in)[2]); \
- X3 = _mm_xor_si128(X3, (in)[3]);
-
-#define XOR4_2(in1, in2) \
- X0 = _mm_xor_si128((in1)[0], (in2)[0]); \
- X1 = _mm_xor_si128((in1)[1], (in2)[1]); \
- X2 = _mm_xor_si128((in1)[2], (in2)[2]); \
- X3 = _mm_xor_si128((in1)[3], (in2)[3]);
-
-static inline uint32_t
-blockmix_salsa8_xor(const __m128i * Bin1, const __m128i * Bin2, __m128i * Bout,
- size_t r)
-{
- __m128i X0, X1, X2, X3;
- size_t i;
-
- /* 1: X <-- B_{2r - 1} */
- XOR4_2(&Bin1[8 * r - 4], &Bin2[8 * r - 4])
-
- /* 3: X <-- H(X \xor B_i) */
- /* 4: Y_i <-- X */
- /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
- XOR4(Bin1)
- SALSA20_8_XOR(Bin2, Bout)
-
- /* 2: for i = 0 to 2r - 1 do */
- r--;
- for (i = 0; i < r;) {
- /* 3: X <-- H(X \xor B_i) */
- /* 4: Y_i <-- X */
- /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
- XOR4(&Bin1[i * 8 + 4])
- SALSA20_8_XOR(&Bin2[i * 8 + 4], &Bout[(r + i) * 4 + 4])
-
- i++;
-
- /* 3: X <-- H(X \xor B_i) */
- /* 4: Y_i <-- X */
- /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
- XOR4(&Bin1[i * 8])
- SALSA20_8_XOR(&Bin2[i * 8], &Bout[i * 4])
- }
-
- /* 3: X <-- H(X \xor B_i) */
- /* 4: Y_i <-- X */
- /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
- XOR4(&Bin1[i * 8 + 4])
- SALSA20_8_XOR(&Bin2[i * 8 + 4], &Bout[(r + i) * 4 + 4])
-
- return _mm_cvtsi128_si32(X0);
-}
-
-#undef ARX
-#undef SALSA20_2ROUNDS
-#undef SALSA20_8_XOR
-#undef XOR4
-#undef XOR4_2
-
-/**
- * integerify(B, r):
- * Return the result of parsing B_{2r-1} as a little-endian integer.
- */
-static inline uint32_t
-integerify(const void * B, size_t r)
-{
- return *(const uint32_t *)((uintptr_t)(B) + (2 * r - 1) * 64);
-}
-
-/**
- * smix(B, r, N, V, XY):
- * Compute B = SMix_r(B, N). The input B must be 128r bytes in length;
- * the temporary storage V must be 128rN bytes in length; the temporary
- * storage XY must be 256r + 64 bytes in length. The value N must be a
- * power of 2 greater than 1. The arrays B, V, and XY must be aligned to a
- * multiple of 64 bytes.
- */
-static void
-smix(uint8_t * B, size_t r, uint32_t N, void * V, void * XY)
-{
- size_t s = 128 * r;
- __m128i * X = (__m128i *) V, * Y;
- uint32_t * X32 = (uint32_t *) V;
- uint32_t i, j;
- size_t k;
-
- /* 1: X <-- B */
- /* 3: V_i <-- X */
- for (k = 0; k < 2 * r; k++) {
- for (i = 0; i < 16; i++) {
- X32[k * 16 + i] =
- le32dec(&B[(k * 16 + (i * 5 % 16)) * 4]);
- }
- }
-
- /* 2: for i = 0 to N - 1 do */
- for (i = 1; i < N - 1; i += 2) {
- /* 4: X <-- H(X) */
- /* 3: V_i <-- X */
- Y = (__m128i *)((uintptr_t)(V) + i * s);
- blockmix_salsa8(X, Y, r);
-
- /* 4: X <-- H(X) */
- /* 3: V_i <-- X */
- X = (__m128i *)((uintptr_t)(V) + (i + 1) * s);
- blockmix_salsa8(Y, X, r);
- }
-
- /* 4: X <-- H(X) */
- /* 3: V_i <-- X */
- Y = (__m128i *)((uintptr_t)(V) + i * s);
- blockmix_salsa8(X, Y, r);
-
- /* 4: X <-- H(X) */
- /* 3: V_i <-- X */
- X = (__m128i *) XY;
- blockmix_salsa8(Y, X, r);
-
- X32 = (uint32_t *) XY;
- Y = (__m128i *)((uintptr_t)(XY) + s);
-
- /* 7: j <-- Integerify(X) mod N */
- j = integerify(X, r) & (N - 1);
-
- /* 6: for i = 0 to N - 1 do */
- for (i = 0; i < N; i += 2) {
- __m128i * V_j = (__m128i *)((uintptr_t)(V) + j * s);
-
- /* 8: X <-- H(X \xor V_j) */
- /* 7: j <-- Integerify(X) mod N */
- j = blockmix_salsa8_xor(X, V_j, Y, r) & (N - 1);
- V_j = (__m128i *)((uintptr_t)(V) + j * s);
-
- /* 8: X <-- H(X \xor V_j) */
- /* 7: j <-- Integerify(X) mod N */
- j = blockmix_salsa8_xor(Y, V_j, X, r) & (N - 1);
- }
-
- /* 10: B' <-- X */
- for (k = 0; k < 2 * r; k++) {
- for (i = 0; i < 16; i++) {
- le32enc(&B[(k * 16 + (i * 5 % 16)) * 4],
- X32[k * 16 + i]);
- }
- }
-}
-
-/**
- * escrypt_kdf(local, passwd, passwdlen, salt, saltlen,
- * N, r, p, buf, buflen):
- * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r,
- * p, buflen) and write the result into buf. The parameters r, p, and buflen
- * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32. The parameter N
- * must be a power of 2 greater than 1.
- *
- * Return 0 on success; or -1 on error.
- */
-int
-escrypt_kdf_sse(escrypt_local_t * local,
- const uint8_t * passwd, size_t passwdlen,
- const uint8_t * salt, size_t saltlen,
- uint64_t N, uint32_t _r, uint32_t _p,
- uint8_t * buf, size_t buflen)
-{
- size_t B_size, V_size, XY_size, need;
- uint8_t * B;
- uint32_t * V, * XY;
- size_t r = _r, p = _p;
- uint32_t i;
-
- /* Sanity-check parameters. */
-#if SIZE_MAX > UINT32_MAX
- if (buflen > (((uint64_t)(1) << 32) - 1) * 32) {
- errno = EFBIG;
- return -1;
- }
-#endif
- if ((uint64_t)(r) * (uint64_t)(p) >= (1 << 30)) {
- errno = EFBIG;
- return -1;
- }
- if (N > UINT32_MAX) {
- errno = EFBIG;
- return -1;
- }
- if (((N & (N - 1)) != 0) || (N < 2)) {
- errno = EINVAL;
- return -1;
- }
- if (r == 0 || p == 0) {
- errno = EINVAL;
- return -1;
- }
- if ((r > SIZE_MAX / 128 / p) ||
-#if SIZE_MAX / 256 <= UINT32_MAX
- (r > SIZE_MAX / 256) ||
-#endif
- (N > SIZE_MAX / 128 / r)) {
- errno = ENOMEM;
- return -1;
- }
-
- /* Allocate memory. */
- B_size = (size_t)128 * r * p;
- V_size = (size_t)128 * r * N;
- need = B_size + V_size;
- if (need < V_size) {
- errno = ENOMEM;
- return -1;
- }
- XY_size = (size_t)256 * r + 64;
- need += XY_size;
- if (need < XY_size) {
- errno = ENOMEM;
- return -1;
- }
- if (local->size < need) {
- if (free_region(local))
- return -1;
- if (!alloc_region(local, need))
- return -1;
- }
- B = (uint8_t *)local->aligned;
- V = (uint32_t *)((uint8_t *)B + B_size);
- XY = (uint32_t *)((uint8_t *)V + V_size);
-
- /* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */
- PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, 1, B, B_size);
-
- /* 2: for i = 0 to p - 1 do */
- for (i = 0; i < p; i++) {
- /* 3: B_i <-- MF(B_i, N) */
- smix(&B[(size_t)128 * i * r], r, N, V, XY);
- }
-
- /* 5: DK <-- PBKDF2(P, B, 1, dkLen) */
- PBKDF2_SHA256(passwd, passwdlen, B, B_size, 1, buf, buflen);
-
- /* Success! */
- return 0;
-}
-#endif
-
-#endif
-
-/* ISO C requires a translation unit to contain at least one declaration */
-typedef int non_empty_tu_decl;
diff --git a/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/sysendian.h b/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/sysendian.h
deleted file mode 100644
index 4deca4c645..0000000000
--- a/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/sysendian.h
+++ /dev/null
@@ -1,158 +0,0 @@
-#ifndef C_TOXCORE_TOXENCRYPTSAVE_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_SYSENDIAN_H
-#define C_TOXCORE_TOXENCRYPTSAVE_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_SYSENDIAN_H
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#ifdef VANILLA_NACL /* toxcore only uses this when libsodium is unavailable */
-
-#ifndef _SYSENDIAN_H_
-#define _SYSENDIAN_H_
-
-#include <stdint.h>
-
-/* Avoid namespace collisions with BSD <sys/endian.h>. */
-#define be16dec scrypt_be16dec
-#define be16enc scrypt_be16enc
-#define be32dec scrypt_be32dec
-#define be32enc scrypt_be32enc
-#define be64dec scrypt_be64dec
-#define be64enc scrypt_be64enc
-#define le16dec scrypt_le16dec
-#define le16enc scrypt_le16enc
-#define le32dec scrypt_le32dec
-#define le32enc scrypt_le32enc
-#define le64dec scrypt_le64dec
-#define le64enc scrypt_le64enc
-
-static inline uint16_t
-be16dec(const void *pp)
-{
- const uint8_t *p = (uint8_t const *)pp;
-
- return ((uint16_t)(p[1]) + ((uint16_t)(p[0]) << 8));
-}
-
-static inline void
-be16enc(void *pp, uint16_t x)
-{
- uint8_t * p = (uint8_t *)pp;
-
- p[1] = x & 0xff;
- p[0] = (x >> 8) & 0xff;
-}
-
-static inline uint32_t
-be32dec(const void *pp)
-{
- const uint8_t *p = (uint8_t const *)pp;
-
- return ((uint32_t)(p[3]) + ((uint32_t)(p[2]) << 8) +
- ((uint32_t)(p[1]) << 16) + ((uint32_t)(p[0]) << 24));
-}
-
-static inline void
-be32enc(void *pp, uint32_t x)
-{
- uint8_t * p = (uint8_t *)pp;
-
- p[3] = x & 0xff;
- p[2] = (x >> 8) & 0xff;
- p[1] = (x >> 16) & 0xff;
- p[0] = (x >> 24) & 0xff;
-}
-
-static inline uint64_t
-be64dec(const void *pp)
-{
- const uint8_t *p = (uint8_t const *)pp;
-
- return ((uint64_t)(p[7]) + ((uint64_t)(p[6]) << 8) +
- ((uint64_t)(p[5]) << 16) + ((uint64_t)(p[4]) << 24) +
- ((uint64_t)(p[3]) << 32) + ((uint64_t)(p[2]) << 40) +
- ((uint64_t)(p[1]) << 48) + ((uint64_t)(p[0]) << 56));
-}
-
-static inline void
-be64enc(void *pp, uint64_t x)
-{
- uint8_t * p = (uint8_t *)pp;
-
- p[7] = x & 0xff;
- p[6] = (x >> 8) & 0xff;
- p[5] = (x >> 16) & 0xff;
- p[4] = (x >> 24) & 0xff;
- p[3] = (x >> 32) & 0xff;
- p[2] = (x >> 40) & 0xff;
- p[1] = (x >> 48) & 0xff;
- p[0] = (x >> 56) & 0xff;
-}
-
-static inline uint16_t
-le16dec(const void *pp)
-{
- const uint8_t *p = (uint8_t const *)pp;
-
- return ((uint16_t)(p[0]) + ((uint16_t)(p[1]) << 8));
-}
-
-static inline void
-le16enc(void *pp, uint16_t x)
-{
- uint8_t * p = (uint8_t *)pp;
-
- p[0] = x & 0xff;
- p[1] = (x >> 8) & 0xff;
-}
-
-static inline uint32_t
-le32dec(const void *pp)
-{
- const uint8_t *p = (uint8_t const *)pp;
-
- return ((uint32_t)(p[0]) + ((uint32_t)(p[1]) << 8) +
- ((uint32_t)(p[2]) << 16) + ((uint32_t)(p[3]) << 24));
-}
-
-static inline void
-le32enc(void *pp, uint32_t x)
-{
- uint8_t * p = (uint8_t *)pp;
-
- p[0] = x & 0xff;
- p[1] = (x >> 8) & 0xff;
- p[2] = (x >> 16) & 0xff;
- p[3] = (x >> 24) & 0xff;
-}
-
-static inline uint64_t
-le64dec(const void *pp)
-{
- const uint8_t *p = (uint8_t const *)pp;
-
- return ((uint64_t)(p[0]) + ((uint64_t)(p[1]) << 8) +
- ((uint64_t)(p[2]) << 16) + ((uint64_t)(p[3]) << 24) +
- ((uint64_t)(p[4]) << 32) + ((uint64_t)(p[5]) << 40) +
- ((uint64_t)(p[6]) << 48) + ((uint64_t)(p[7]) << 56));
-}
-
-static inline void
-le64enc(void *pp, uint64_t x)
-{
- uint8_t * p = (uint8_t *)pp;
-
- p[0] = x & 0xff;
- p[1] = (x >> 8) & 0xff;
- p[2] = (x >> 16) & 0xff;
- p[3] = (x >> 24) & 0xff;
- p[4] = (x >> 32) & 0xff;
- p[5] = (x >> 40) & 0xff;
- p[6] = (x >> 48) & 0xff;
- p[7] = (x >> 56) & 0xff;
-}
-
-#endif /* !_SYSENDIAN_H_ */
-
-#endif
-
-#endif
diff --git a/protocols/Tox/libtox/src/toxencryptsave/defines.h b/protocols/Tox/libtox/src/toxencryptsave/defines.h
index 8a490344a7..71c0f105a5 100644
--- a/protocols/Tox/libtox/src/toxencryptsave/defines.h
+++ b/protocols/Tox/libtox/src/toxencryptsave/defines.h
@@ -1,3 +1,8 @@
+/* SPDX-License-Identifier: GPL-3.0-or-later
+ * Copyright © 2016-2021 The TokTok team.
+ * Copyright © 2013 Tox project.
+ */
+
#ifndef C_TOXCORE_TOXENCRYPTSAVE_DEFINES_H
#define C_TOXCORE_TOXENCRYPTSAVE_DEFINES_H
diff --git a/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.api.h b/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.api.h
deleted file mode 100644
index df5d1136f3..0000000000
--- a/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.api.h
+++ /dev/null
@@ -1,311 +0,0 @@
-%{
-/* SPDX-License-Identifier: GPL-3.0-or-later
- * Copyright © 2016-2018 The TokTok team.
- * Copyright © 2013-2016 Tox Developers.
- */
-
-/*
- * Batch encryption functions.
- */
-#ifndef C_TOXCORE_TOXENCRYPTSAVE_TOXENCRYPTSAVE_H
-#define C_TOXCORE_TOXENCRYPTSAVE_TOXENCRYPTSAVE_H
-
-//!TOKSTYLE-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdint.h>
-%}
-
-/*******************************************************************************
- *
- * This module is organized into two parts.
- *
- * 1. A simple API operating on plain text/cipher text data and a password to
- * encrypt or decrypt it.
- * 2. A more advanced API that splits key derivation and encryption into two
- * separate function calls.
- *
- * The first part is implemented in terms of the second part and simply calls
- * the separate functions in sequence. Since key derivation is very expensive
- * compared to the actual encryption, clients that do a lot of crypto should
- * prefer the advanced API and reuse pass-key objects.
- *
- * To use the second part, first derive an encryption key from a password with
- * ${tox.pass_Key.derive}, then use the derived key to encrypt the data.
- *
- * The encrypted data is prepended with a magic number, to aid validity
- * checking (no guarantees are made of course). Any data to be decrypted must
- * start with the magic number.
- *
- * Clients should consider alerting their users that, unlike plain data, if
- * even one bit becomes corrupted, the data will be entirely unrecoverable.
- * Ditto if they forget their password, there is no way to recover the data.
- *
- *******************************************************************************/
-
-class tox {
-
-/**
- * The size of the salt part of a pass-key.
- */
-const PASS_SALT_LENGTH = 32;
-/**
- * The size of the key part of a pass-key.
- */
-const PASS_KEY_LENGTH = 32;
-/**
- * The amount of additional data required to store any encrypted byte array.
- * Encrypting an array of N bytes requires N + $PASS_ENCRYPTION_EXTRA_LENGTH
- * bytes in the encrypted byte array.
- */
-const PASS_ENCRYPTION_EXTRA_LENGTH = 80;
-
-error for key_derivation {
- NULL,
- /**
- * The crypto lib was unable to derive a key from the given passphrase,
- * which is usually a lack of memory issue.
- */
- FAILED,
-}
-
-error for encryption {
- NULL,
- /**
- * The crypto lib was unable to derive a key from the given passphrase,
- * which is usually a lack of memory issue. The functions accepting keys
- * do not produce this error.
- */
- KEY_DERIVATION_FAILED,
- /**
- * The encryption itself failed.
- */
- FAILED,
-}
-
-error for decryption {
- NULL,
- /**
- * The input data was shorter than $PASS_ENCRYPTION_EXTRA_LENGTH bytes
- */
- INVALID_LENGTH,
- /**
- * The input data is missing the magic number (i.e. wasn't created by this
- * module, or is corrupted).
- */
- BAD_FORMAT,
- /**
- * The crypto lib was unable to derive a key from the given passphrase,
- * which is usually a lack of memory issue. The functions accepting keys
- * do not produce this error.
- */
- KEY_DERIVATION_FAILED,
- /**
- * The encrypted byte array could not be decrypted. Either the data was
- * corrupted or the password/key was incorrect.
- */
- FAILED,
-}
-
-
-/*******************************************************************************
- *
- * BEGIN PART 1
- *
- * The simple API is presented first. If your code spends too much time using
- * these functions, consider using the advanced functions instead and caching
- * the generated pass-key.
- *
- *******************************************************************************/
-
-/**
- * Encrypts the given data with the given passphrase.
- *
- * The output array must be at least `plaintext_len + $PASS_ENCRYPTION_EXTRA_LENGTH`
- * bytes long. This delegates to ${pass_Key.derive} and
- * ${pass_Key.encrypt}.
- *
- * @param plaintext A byte array of length `plaintext_len`.
- * @param plaintext_len The length of the plain text array. Bigger than 0.
- * @param passphrase The user-provided password. Can be empty.
- * @param passphrase_len The length of the password.
- * @param ciphertext The cipher text array to write the encrypted data to.
- *
- * @return true on success.
- */
-static bool pass_encrypt(const uint8_t[plaintext_len] plaintext, const uint8_t[passphrase_len] passphrase, uint8_t *ciphertext)
- with error for encryption;
-
-
-/**
- * Decrypts the given data with the given passphrase.
- *
- * The output array must be at least `ciphertext_len - $PASS_ENCRYPTION_EXTRA_LENGTH`
- * bytes long. This delegates to ${pass_Key.decrypt}.
- *
- * @param ciphertext A byte array of length `ciphertext_len`.
- * @param ciphertext_len The length of the cipher text array. At least $PASS_ENCRYPTION_EXTRA_LENGTH.
- * @param passphrase The user-provided password. Can be empty.
- * @param passphrase_len The length of the password.
- * @param plaintext The plain text array to write the decrypted data to.
- *
- * @return true on success.
- */
-static bool pass_decrypt(const uint8_t[ciphertext_len] ciphertext, const uint8_t[passphrase_len] passphrase, uint8_t *plaintext)
- with error for decryption;
-
-
-/*******************************************************************************
- *
- * BEGIN PART 2
- *
- * And now part 2, which does the actual encryption, and can be used to write
- * less CPU intensive client code than part one.
- *
- *******************************************************************************/
-
-class pass_Key {
- /**
- * This type represents a pass-key.
- *
- * A pass-key and a password are two different concepts: a password is given
- * by the user in plain text. A pass-key is the generated symmetric key used
- * for encryption and decryption. It is derived from a salt and the user-
- * provided password.
- *
- * The $this structure is hidden in the implementation. It can be created
- * using $derive or $derive_with_salt and must be deallocated using $free.
- */
- struct this;
-
- /**
- * Deallocate a $this. This function behaves like free(), so NULL is an
- * acceptable argument value.
- */
- void free();
-
- /**
- * Generates a secret symmetric key from the given passphrase.
- *
- * Be sure to not compromise the key! Only keep it in memory, do not write
- * it to disk.
- *
- * Note that this function is not deterministic; to derive the same key from
- * a password, you also must know the random salt that was used. A
- * deterministic version of this function is $derive_with_salt.
- *
- * @param passphrase The user-provided password. Can be empty.
- * @param passphrase_len The length of the password.
- *
- * @return true on success.
- */
- static this derive(const uint8_t[passphrase_len] passphrase)
- with error for key_derivation;
-
- /**
- * Same as above, except use the given salt for deterministic key derivation.
- *
- * @param passphrase The user-provided password. Can be empty.
- * @param passphrase_len The length of the password.
- * @param salt An array of at least $PASS_SALT_LENGTH bytes.
- *
- * @return true on success.
- */
- static this derive_with_salt(const uint8_t[passphrase_len] passphrase, const uint8_t[PASS_SALT_LENGTH] salt)
- with error for key_derivation;
-
- /**
- * Encrypt a plain text with a key produced by $derive or $derive_with_salt.
- *
- * The output array must be at least `plaintext_len + $PASS_ENCRYPTION_EXTRA_LENGTH`
- * bytes long.
- *
- * @param plaintext A byte array of length `plaintext_len`.
- * @param plaintext_len The length of the plain text array. Bigger than 0.
- * @param ciphertext The cipher text array to write the encrypted data to.
- *
- * @return true on success.
- */
- const bool encrypt(const uint8_t[plaintext_len] plaintext, uint8_t *ciphertext)
- with error for encryption;
-
- /**
- * This is the inverse of $encrypt, also using only keys produced by
- * $derive or $derive_with_salt.
- *
- * @param ciphertext A byte array of length `ciphertext_len`.
- * @param ciphertext_len The length of the cipher text array. At least $PASS_ENCRYPTION_EXTRA_LENGTH.
- * @param plaintext The plain text array to write the decrypted data to.
- *
- * @return true on success.
- */
- const bool decrypt(const uint8_t[ciphertext_len] ciphertext, uint8_t *plaintext)
- with error for decryption;
-}
-
-/**
- * Retrieves the salt used to encrypt the given data.
- *
- * The retrieved salt can then be passed to ${pass_Key.derive_with_salt} to
- * produce the same key as was previously used. Any data encrypted with this
- * module can be used as input.
- *
- * The cipher text must be at least $PASS_ENCRYPTION_EXTRA_LENGTH bytes in length.
- * The salt must be $PASS_SALT_LENGTH bytes in length.
- * If the passed byte arrays are smaller than required, the behaviour is
- * undefined.
- *
- * If the cipher text pointer or the salt is NULL, this function returns false.
- *
- * Success does not say anything about the validity of the data, only that
- * data of the appropriate size was copied.
- *
- * @return true on success.
- */
-static bool get_salt(const uint8_t *ciphertext, uint8_t[PASS_SALT_LENGTH] salt) {
- NULL,
- /**
- * The input data is missing the magic number (i.e. wasn't created by this
- * module, or is corrupted).
- */
- BAD_FORMAT,
-}
-
-/**
- * Determines whether or not the given data is encrypted by this module.
- *
- * It does this check by verifying that the magic number is the one put in
- * place by the encryption functions.
- *
- * The data must be at least $PASS_ENCRYPTION_EXTRA_LENGTH bytes in length.
- * If the passed byte array is smaller than required, the behaviour is
- * undefined.
- *
- * If the data pointer is NULL, the behaviour is undefined
- *
- * @return true if the data is encrypted by this module.
- */
-static bool is_data_encrypted(const uint8_t *data);
-
-}
-
-%{
-
-#ifdef __cplusplus
-}
-#endif
-
-typedef TOX_ERR_KEY_DERIVATION Tox_Err_Key_Derivation;
-typedef TOX_ERR_ENCRYPTION Tox_Err_Encryption;
-typedef TOX_ERR_DECRYPTION Tox_Err_Decryption;
-typedef TOX_ERR_GET_SALT Tox_Err_Get_Salt;
-
-//!TOKSTYLE+
-
-#endif // C_TOXCORE_TOXENCRYPTSAVE_TOXENCRYPTSAVE_H
-%}
diff --git a/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.c b/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.c
index be4bcaf26c..1d464534d0 100644
--- a/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.c
+++ b/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.c
@@ -3,32 +3,20 @@
* Copyright © 2013 Tox project.
*/
-/*
+/**
* Batch encryption functions.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "../toxcore/ccompat.h"
-#include "../toxcore/crypto_core.h"
-#include "defines.h"
#include "toxencryptsave.h"
-#define SET_ERROR_PARAMETER(param, x) do { if (param) { *param = x; } } while (0)
-
-#ifdef VANILLA_NACL
-#include <crypto_box.h>
-#include <crypto_hash_sha256.h>
-#include "crypto_pwhash_scryptsalsa208sha256/crypto_pwhash_scryptsalsa208sha256.h"
-#define crypto_box_MACBYTES (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES)
-#else
+
#include <sodium.h>
-#endif
#include <stdlib.h>
#include <string.h>
-//!TOKSTYLE-
+#include "../toxcore/ccompat.h"
+#include "../toxcore/crypto_core.h"
+#include "defines.h"
+
static_assert(TOX_PASS_SALT_LENGTH == crypto_pwhash_scryptsalsa208sha256_SALTBYTES,
"TOX_PASS_SALT_LENGTH is assumed to be equal to crypto_pwhash_scryptsalsa208sha256_SALTBYTES");
static_assert(TOX_PASS_KEY_LENGTH == CRYPTO_SHARED_KEY_SIZE,
@@ -36,7 +24,13 @@ static_assert(TOX_PASS_KEY_LENGTH == CRYPTO_SHARED_KEY_SIZE,
static_assert(TOX_PASS_ENCRYPTION_EXTRA_LENGTH == (crypto_box_MACBYTES + crypto_box_NONCEBYTES +
crypto_pwhash_scryptsalsa208sha256_SALTBYTES + TOX_ENC_SAVE_MAGIC_LENGTH),
"TOX_PASS_ENCRYPTION_EXTRA_LENGTH is assumed to be equal to (crypto_box_MACBYTES + crypto_box_NONCEBYTES + crypto_pwhash_scryptsalsa208sha256_SALTBYTES + TOX_ENC_SAVE_MAGIC_LENGTH)");
-//!TOKSTYLE+
+
+#define SET_ERROR_PARAMETER(param, x) \
+ do { \
+ if (param) { \
+ *param = x; \
+ } \
+ } while (0)
uint32_t tox_pass_salt_length(void)
{
@@ -142,7 +136,7 @@ Tox_Pass_Key *tox_pass_key_derive_with_salt(const uint8_t *passphrase, size_t pp
crypto_memzero(passkey, crypto_hash_sha256_BYTES); /* wipe plaintext pw */
- Tox_Pass_Key *out_key = (Tox_Pass_Key *)malloc(sizeof(Tox_Pass_Key));
+ Tox_Pass_Key *out_key = (Tox_Pass_Key *)calloc(1, sizeof(Tox_Pass_Key));
if (!out_key) {
SET_ERROR_PARAMETER(error, TOX_ERR_KEY_DERIVATION_FAILED);
@@ -156,18 +150,21 @@ Tox_Pass_Key *tox_pass_key_derive_with_salt(const uint8_t *passphrase, size_t pp
}
/**
- * Encrypt arbitrary with a key produced by `tox_derive_key_*`. The output
- * array must be at least data_len + TOX_PASS_ENCRYPTION_EXTRA_LENGTH bytes long.
- * key must be TOX_PASS_KEY_LENGTH bytes.
- * If you already have a symmetric key from somewhere besides this module, simply
- * call encrypt_data_symmetric in toxcore/crypto_core directly.
+ * Encrypt a plain text with a key produced by tox_pass_key_derive or tox_pass_key_derive_with_salt.
*
- * returns true on success
+ * The output array must be at least `plaintext_len + TOX_PASS_ENCRYPTION_EXTRA_LENGTH`
+ * bytes long.
+ *
+ * @param plaintext A byte array of length `plaintext_len`.
+ * @param plaintext_len The length of the plain text array. Bigger than 0.
+ * @param ciphertext The cipher text array to write the encrypted data to.
+ *
+ * @return true on success.
*/
-bool tox_pass_key_encrypt(const Tox_Pass_Key *key, const uint8_t *data, size_t data_len, uint8_t *out,
- Tox_Err_Encryption *error)
+bool tox_pass_key_encrypt(const Tox_Pass_Key *key, const uint8_t *plaintext, size_t plaintext_len,
+ uint8_t *ciphertext, Tox_Err_Encryption *error)
{
- if (data_len == 0 || !data || !key || !out) {
+ if (plaintext_len == 0 || !plaintext || !key || !ciphertext) {
SET_ERROR_PARAMETER(error, TOX_ERR_ENCRYPTION_NULL);
return 0;
}
@@ -180,21 +177,21 @@ bool tox_pass_key_encrypt(const Tox_Pass_Key *key, const uint8_t *data, size_t d
// need them to decrypt the data
/* first add the magic number */
- memcpy(out, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH);
- out += TOX_ENC_SAVE_MAGIC_LENGTH;
+ memcpy(ciphertext, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH);
+ ciphertext += TOX_ENC_SAVE_MAGIC_LENGTH;
/* then add the rest prefix */
- memcpy(out, key->salt, crypto_pwhash_scryptsalsa208sha256_SALTBYTES);
- out += crypto_pwhash_scryptsalsa208sha256_SALTBYTES;
+ memcpy(ciphertext, key->salt, crypto_pwhash_scryptsalsa208sha256_SALTBYTES);
+ ciphertext += crypto_pwhash_scryptsalsa208sha256_SALTBYTES;
uint8_t nonce[crypto_box_NONCEBYTES];
random_nonce(nonce);
- memcpy(out, nonce, crypto_box_NONCEBYTES);
- out += crypto_box_NONCEBYTES;
+ memcpy(ciphertext, nonce, crypto_box_NONCEBYTES);
+ ciphertext += crypto_box_NONCEBYTES;
/* now encrypt */
- if (encrypt_data_symmetric(key->key, nonce, data, data_len, out)
- != data_len + crypto_box_MACBYTES) {
+ if (encrypt_data_symmetric(key->key, nonce, plaintext, plaintext_len, ciphertext)
+ != plaintext_len + crypto_box_MACBYTES) {
SET_ERROR_PARAMETER(error, TOX_ERR_ENCRYPTION_FAILED);
return 0;
}
diff --git a/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.h b/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.h
index 4b58165e7d..3f22b75884 100644
--- a/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.h
+++ b/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.h
@@ -3,23 +3,22 @@
* Copyright © 2013-2016 Tox Developers.
*/
-/*
+/**
* Batch encryption functions.
*/
+
#ifndef C_TOXCORE_TOXENCRYPTSAVE_TOXENCRYPTSAVE_H
#define C_TOXCORE_TOXENCRYPTSAVE_TOXENCRYPTSAVE_H
-//!TOKSTYLE-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/*******************************************************************************
*
* This module is organized into two parts.
@@ -72,7 +71,7 @@ uint32_t tox_pass_key_length(void);
uint32_t tox_pass_encryption_extra_length(void);
-typedef enum TOX_ERR_KEY_DERIVATION {
+typedef enum Tox_Err_Key_Derivation {
/**
* The function returned successfully.
@@ -90,10 +89,10 @@ typedef enum TOX_ERR_KEY_DERIVATION {
*/
TOX_ERR_KEY_DERIVATION_FAILED,
-} TOX_ERR_KEY_DERIVATION;
+} Tox_Err_Key_Derivation;
-typedef enum TOX_ERR_ENCRYPTION {
+typedef enum Tox_Err_Encryption {
/**
* The function returned successfully.
@@ -117,10 +116,10 @@ typedef enum TOX_ERR_ENCRYPTION {
*/
TOX_ERR_ENCRYPTION_FAILED,
-} TOX_ERR_ENCRYPTION;
+} Tox_Err_Encryption;
-typedef enum TOX_ERR_DECRYPTION {
+typedef enum Tox_Err_Decryption {
/**
* The function returned successfully.
@@ -156,7 +155,7 @@ typedef enum TOX_ERR_DECRYPTION {
*/
TOX_ERR_DECRYPTION_FAILED,
-} TOX_ERR_DECRYPTION;
+} Tox_Err_Decryption;
@@ -188,7 +187,7 @@ typedef enum TOX_ERR_DECRYPTION {
* @return true on success.
*/
bool tox_pass_encrypt(const uint8_t *plaintext, size_t plaintext_len, const uint8_t *passphrase, size_t passphrase_len,
- uint8_t *ciphertext, TOX_ERR_ENCRYPTION *error);
+ uint8_t *ciphertext, Tox_Err_Encryption *error);
/**
* Decrypts the given data with the given passphrase.
@@ -205,7 +204,7 @@ bool tox_pass_encrypt(const uint8_t *plaintext, size_t plaintext_len, const uint
* @return true on success.
*/
bool tox_pass_decrypt(const uint8_t *ciphertext, size_t ciphertext_len, const uint8_t *passphrase,
- size_t passphrase_len, uint8_t *plaintext, TOX_ERR_DECRYPTION *error);
+ size_t passphrase_len, uint8_t *plaintext, Tox_Err_Decryption *error);
/*******************************************************************************
@@ -239,7 +238,7 @@ typedef struct Tox_Pass_Key Tox_Pass_Key;
* Deallocate a Tox_Pass_Key. This function behaves like free(), so NULL is an
* acceptable argument value.
*/
-void tox_pass_key_free(struct Tox_Pass_Key *_key);
+void tox_pass_key_free(struct Tox_Pass_Key *key);
/**
* Generates a secret symmetric key from the given passphrase.
@@ -249,7 +248,7 @@ void tox_pass_key_free(struct Tox_Pass_Key *_key);
*
* Note that this function is not deterministic; to derive the same key from
* a password, you also must know the random salt that was used. A
- * deterministic version of this function is tox_pass_key_derive_with_salt.
+ * deterministic version of this function is `tox_pass_key_derive_with_salt`.
*
* @param passphrase The user-provided password. Can be empty.
* @param passphrase_len The length of the password.
@@ -257,7 +256,7 @@ void tox_pass_key_free(struct Tox_Pass_Key *_key);
* @return true on success.
*/
struct Tox_Pass_Key *tox_pass_key_derive(const uint8_t *passphrase, size_t passphrase_len,
- TOX_ERR_KEY_DERIVATION *error);
+ Tox_Err_Key_Derivation *error);
/**
* Same as above, except use the given salt for deterministic key derivation.
@@ -269,7 +268,7 @@ struct Tox_Pass_Key *tox_pass_key_derive(const uint8_t *passphrase, size_t passp
* @return true on success.
*/
struct Tox_Pass_Key *tox_pass_key_derive_with_salt(const uint8_t *passphrase, size_t passphrase_len,
- const uint8_t *salt, TOX_ERR_KEY_DERIVATION *error);
+ const uint8_t *salt, Tox_Err_Key_Derivation *error);
/**
* Encrypt a plain text with a key produced by tox_pass_key_derive or tox_pass_key_derive_with_salt.
@@ -283,8 +282,8 @@ struct Tox_Pass_Key *tox_pass_key_derive_with_salt(const uint8_t *passphrase, si
*
* @return true on success.
*/
-bool tox_pass_key_encrypt(const struct Tox_Pass_Key *_key, const uint8_t *plaintext, size_t plaintext_len,
- uint8_t *ciphertext, TOX_ERR_ENCRYPTION *error);
+bool tox_pass_key_encrypt(const struct Tox_Pass_Key *key, const uint8_t *plaintext, size_t plaintext_len,
+ uint8_t *ciphertext, Tox_Err_Encryption *error);
/**
* This is the inverse of tox_pass_key_encrypt, also using only keys produced by
@@ -296,10 +295,10 @@ bool tox_pass_key_encrypt(const struct Tox_Pass_Key *_key, const uint8_t *plaint
*
* @return true on success.
*/
-bool tox_pass_key_decrypt(const struct Tox_Pass_Key *_key, const uint8_t *ciphertext, size_t ciphertext_len,
- uint8_t *plaintext, TOX_ERR_DECRYPTION *error);
+bool tox_pass_key_decrypt(const struct Tox_Pass_Key *key, const uint8_t *ciphertext, size_t ciphertext_len,
+ uint8_t *plaintext, Tox_Err_Decryption *error);
-typedef enum TOX_ERR_GET_SALT {
+typedef enum Tox_Err_Get_Salt {
/**
* The function returned successfully.
@@ -317,7 +316,7 @@ typedef enum TOX_ERR_GET_SALT {
*/
TOX_ERR_GET_SALT_BAD_FORMAT,
-} TOX_ERR_GET_SALT;
+} Tox_Err_Get_Salt;
/**
@@ -339,7 +338,7 @@ typedef enum TOX_ERR_GET_SALT {
*
* @return true on success.
*/
-bool tox_get_salt(const uint8_t *ciphertext, uint8_t *salt, TOX_ERR_GET_SALT *error);
+bool tox_get_salt(const uint8_t *ciphertext, uint8_t *salt, Tox_Err_Get_Salt *error);
/**
* Determines whether or not the given data is encrypted by this module.
@@ -362,10 +361,12 @@ bool tox_is_data_encrypted(const uint8_t *data);
}
#endif
-typedef TOX_ERR_KEY_DERIVATION Tox_Err_Key_Derivation;
-typedef TOX_ERR_ENCRYPTION Tox_Err_Encryption;
-typedef TOX_ERR_DECRYPTION Tox_Err_Decryption;
-typedef TOX_ERR_GET_SALT Tox_Err_Get_Salt;
+//!TOKSTYLE-
+
+typedef Tox_Err_Key_Derivation TOX_ERR_KEY_DERIVATION;
+typedef Tox_Err_Encryption TOX_ERR_ENCRYPTION;
+typedef Tox_Err_Decryption TOX_ERR_DECRYPTION;
+typedef Tox_Err_Get_Salt TOX_ERR_GET_SALT;
//!TOKSTYLE+