summaryrefslogtreecommitdiff
path: root/protocols/Tox/libtox/src
diff options
context:
space:
mode:
authoraunsane <aunsane@gmail.com>2018-10-08 20:45:34 +0300
committeraunsane <aunsane@gmail.com>2018-10-08 20:45:34 +0300
commitb8ad6c3cc2edef99dc2a416667c3933c1061994c (patch)
tree040c82bc03349628c9937215562ee93935672366 /protocols/Tox/libtox/src
parent0c470817d4d49a872bd068e717c6439f2b6cd5c0 (diff)
Tox: toxcore updated to v0.2.8
Diffstat (limited to 'protocols/Tox/libtox/src')
-rw-r--r--protocols/Tox/libtox/src/toxcore/DHT.c275
-rw-r--r--protocols/Tox/libtox/src/toxcore/DHT.h30
-rw-r--r--protocols/Tox/libtox/src/toxcore/LAN_discovery.api.h15
-rw-r--r--protocols/Tox/libtox/src/toxcore/LAN_discovery.c116
-rw-r--r--protocols/Tox/libtox/src/toxcore/LAN_discovery.h13
-rw-r--r--protocols/Tox/libtox/src/toxcore/Messenger.c569
-rw-r--r--protocols/Tox/libtox/src/toxcore/Messenger.h55
-rw-r--r--protocols/Tox/libtox/src/toxcore/TCP_client.c37
-rw-r--r--protocols/Tox/libtox/src/toxcore/TCP_client.h12
-rw-r--r--protocols/Tox/libtox/src/toxcore/TCP_connection.c28
-rw-r--r--protocols/Tox/libtox/src/toxcore/TCP_connection.h8
-rw-r--r--protocols/Tox/libtox/src/toxcore/TCP_server.c156
-rw-r--r--protocols/Tox/libtox/src/toxcore/TCP_server.h10
-rw-r--r--protocols/Tox/libtox/src/toxcore/ccompat.h6
-rw-r--r--protocols/Tox/libtox/src/toxcore/crypto_core.api.h10
-rw-r--r--protocols/Tox/libtox/src/toxcore/crypto_core.c51
-rw-r--r--protocols/Tox/libtox/src/toxcore/crypto_core.h10
-rw-r--r--protocols/Tox/libtox/src/toxcore/friend_connection.c29
-rw-r--r--protocols/Tox/libtox/src/toxcore/friend_connection.h9
-rw-r--r--protocols/Tox/libtox/src/toxcore/friend_requests.c2
-rw-r--r--protocols/Tox/libtox/src/toxcore/friend_requests.h6
-rw-r--r--protocols/Tox/libtox/src/toxcore/group.c632
-rw-r--r--protocols/Tox/libtox/src/toxcore/group.h36
-rw-r--r--protocols/Tox/libtox/src/toxcore/list.c2
-rw-r--r--protocols/Tox/libtox/src/toxcore/list.h6
-rw-r--r--protocols/Tox/libtox/src/toxcore/logger.c2
-rw-r--r--protocols/Tox/libtox/src/toxcore/logger.h9
-rw-r--r--protocols/Tox/libtox/src/toxcore/mono_time.c156
-rw-r--r--protocols/Tox/libtox/src/toxcore/mono_time.h59
-rw-r--r--protocols/Tox/libtox/src/toxcore/net_crypto.c89
-rw-r--r--protocols/Tox/libtox/src/toxcore/net_crypto.h24
-rw-r--r--protocols/Tox/libtox/src/toxcore/network.c162
-rw-r--r--protocols/Tox/libtox/src/toxcore/network.h151
-rw-r--r--protocols/Tox/libtox/src/toxcore/onion.c20
-rw-r--r--protocols/Tox/libtox/src/toxcore/onion.h14
-rw-r--r--protocols/Tox/libtox/src/toxcore/onion_announce.c35
-rw-r--r--protocols/Tox/libtox/src/toxcore/onion_announce.h8
-rw-r--r--protocols/Tox/libtox/src/toxcore/onion_client.c166
-rw-r--r--protocols/Tox/libtox/src/toxcore/onion_client.h8
-rw-r--r--protocols/Tox/libtox/src/toxcore/ping.api.h11
-rw-r--r--protocols/Tox/libtox/src/toxcore/ping.c21
-rw-r--r--protocols/Tox/libtox/src/toxcore/ping.h15
-rw-r--r--protocols/Tox/libtox/src/toxcore/ping_array.api.h37
-rw-r--r--protocols/Tox/libtox/src/toxcore/ping_array.c71
-rw-r--r--protocols/Tox/libtox/src/toxcore/ping_array.h42
-rw-r--r--protocols/Tox/libtox/src/toxcore/state.c15
-rw-r--r--protocols/Tox/libtox/src/toxcore/state.h4
-rw-r--r--protocols/Tox/libtox/src/toxcore/tox.api.h10
-rw-r--r--protocols/Tox/libtox/src/toxcore/tox.c29
-rw-r--r--protocols/Tox/libtox/src/toxcore/tox.h10
-rw-r--r--protocols/Tox/libtox/src/toxcore/util.c2
-rw-r--r--protocols/Tox/libtox/src/toxcore/util.h8
-rw-r--r--protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/crypto_pwhash_scryptsalsa208sha256.h5
-rw-r--r--protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/crypto_scrypt.h5
-rw-r--r--protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/export.h5
-rw-r--r--protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/pbkdf2-sha256.h5
-rw-r--r--protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/runtime.h5
-rw-r--r--protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/sysendian.h5
-rw-r--r--protocols/Tox/libtox/src/toxencryptsave/defines.h5
-rw-r--r--protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.api.h8
-rw-r--r--protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.c2
-rw-r--r--protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.h8
62 files changed, 1985 insertions, 1369 deletions
diff --git a/protocols/Tox/libtox/src/toxcore/DHT.c b/protocols/Tox/libtox/src/toxcore/DHT.c
index 37dd9385a0..1eebb0c736 100644
--- a/protocols/Tox/libtox/src/toxcore/DHT.c
+++ b/protocols/Tox/libtox/src/toxcore/DHT.c
@@ -76,7 +76,7 @@ struct DHT_Friend {
/* number of times get_node packets were sent. */
uint32_t bootstrap_times;
- /* Symetric NAT hole punching stuff. */
+ /* Symmetric NAT hole punching stuff. */
NAT nat;
uint16_t lock_count;
@@ -93,6 +93,7 @@ typedef struct Cryptopacket_Handler {
struct DHT {
const Logger *log;
+ Mono_Time *mono_time;
Networking_Core *net;
bool hole_punching_enabled;
@@ -237,13 +238,14 @@ 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 therefor smart to store commonly used
+/* 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.
*
* 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
*/
-void get_shared_key(Shared_Keys *shared_keys, uint8_t *shared_key, const uint8_t *secret_key, const uint8_t *public_key)
+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)
{
uint32_t num = ~0;
uint32_t curr = 0;
@@ -256,12 +258,12 @@ void get_shared_key(Shared_Keys *shared_keys, uint8_t *shared_key, const uint8_t
if (id_equal(public_key, key->public_key)) {
memcpy(shared_key, key->shared_key, CRYPTO_SHARED_KEY_SIZE);
++key->times_requested;
- key->time_last_requested = unix_time();
+ key->time_last_requested = mono_time_get(mono_time);
return;
}
if (num != 0) {
- if (is_timeout(key->time_last_requested, KEYS_TIMEOUT)) {
+ if (mono_time_is_timeout(mono_time, key->time_last_requested, KEYS_TIMEOUT)) {
num = 0;
curr = index;
} else if (num > key->times_requested) {
@@ -279,11 +281,11 @@ void get_shared_key(Shared_Keys *shared_keys, uint8_t *shared_key, const uint8_t
if (num != UINT32_MAX) {
Shared_Key *const key = &shared_keys->keys[curr];
- key->stored = 1;
+ key->stored = true;
key->times_requested = 1;
memcpy(key->public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE);
memcpy(key->shared_key, shared_key, CRYPTO_SHARED_KEY_SIZE);
- key->time_last_requested = unix_time();
+ key->time_last_requested = mono_time_get(mono_time);
}
}
@@ -292,7 +294,7 @@ void get_shared_key(Shared_Keys *shared_keys, uint8_t *shared_key, const uint8_t
*/
void dht_get_shared_key_recv(DHT *dht, uint8_t *shared_key, const uint8_t *public_key)
{
- get_shared_key(&dht->shared_keys_recv, shared_key, dht->self_secret_key, public_key);
+ 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
@@ -300,7 +302,7 @@ void dht_get_shared_key_recv(DHT *dht, uint8_t *shared_key, const uint8_t *publi
*/
void dht_get_shared_key_sent(DHT *dht, uint8_t *shared_key, const uint8_t *public_key)
{
- get_shared_key(&dht->shared_keys_sent, shared_key, dht->self_secret_key, public_key);
+ get_shared_key(dht->mono_time, &dht->shared_keys_sent, shared_key, dht->self_secret_key, public_key);
}
#define CRYPTO_SIZE 1 + CRYPTO_PUBLIC_KEY_SIZE * 2 + CRYPTO_NONCE_SIZE
@@ -489,7 +491,7 @@ static int dht_create_packet(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
* 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, uint8_t tcp_enabled)
+int unpack_ip_port(IP_Port *ip_port, const uint8_t *data, uint16_t length, bool tcp_enabled)
{
if (data == nullptr) {
return -1;
@@ -572,7 +574,9 @@ int pack_nodes(uint8_t *data, uint16_t length, const Node_format *nodes, uint16_
memcpy(data + packed_length, nodes[i].public_key, CRYPTO_PUBLIC_KEY_SIZE);
packed_length += CRYPTO_PUBLIC_KEY_SIZE;
+#ifndef NDEBUG
const uint32_t increment = ipp_size + CRYPTO_PUBLIC_KEY_SIZE;
+#endif
assert(increment == PACKED_NODE_SIZE_IP4 || increment == PACKED_NODE_SIZE_IP6);
}
@@ -587,7 +591,7 @@ int pack_nodes(uint8_t *data, uint16_t length, const Node_format *nodes, uint16_
* return -1 on failure.
*/
int unpack_nodes(Node_format *nodes, uint16_t max_num_nodes, uint16_t *processed_data_len, const uint8_t *data,
- uint16_t length, uint8_t tcp_enabled)
+ uint16_t length, bool tcp_enabled)
{
uint32_t num = 0, len_processed = 0;
@@ -608,7 +612,9 @@ int unpack_nodes(Node_format *nodes, uint16_t max_num_nodes, uint16_t *processed
len_processed += CRYPTO_PUBLIC_KEY_SIZE;
++num;
+#ifndef NDEBUG
const uint32_t increment = ipp_size + CRYPTO_PUBLIC_KEY_SIZE;
+#endif
assert(increment == PACKED_NODE_SIZE_IP4 || increment == PACKED_NODE_SIZE_IP6);
}
@@ -667,7 +673,8 @@ static uint32_t index_of_client_ip_port(const Client_data *array, uint32_t size,
/* Update ip_port of client if it's needed.
*/
-static void update_client(const Logger *log, int index, Client_data *client, IP_Port ip_port)
+static void update_client(const Logger *log, const Mono_Time *mono_time, int index, Client_data *client,
+ IP_Port ip_port)
{
IPPTsPng *assoc;
int ip_version;
@@ -692,12 +699,12 @@ static void update_client(const Logger *log, int index, Client_data *client, IP_
net_ntohs(ip_port.port));
}
- if (ip_is_lan(assoc->ip_port.ip) != 0 && ip_is_lan(ip_port.ip) == 0) {
+ if (!ip_is_lan(assoc->ip_port.ip) && ip_is_lan(ip_port.ip)) {
return;
}
assoc->ip_port = ip_port;
- assoc->timestamp = unix_time();
+ assoc->timestamp = mono_time_get(mono_time);
}
/* Check if client with public_key is already in list of length length.
@@ -707,15 +714,15 @@ static void update_client(const Logger *log, int index, Client_data *client, IP_
*
* return True(1) or False(0)
*/
-static int client_or_ip_port_in_list(const Logger *log, Client_data *list, uint16_t length, const uint8_t *public_key,
- IP_Port ip_port)
+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 uint64_t temp_time = unix_time();
+ const uint64_t temp_time = mono_time_get(mono_time);
uint32_t index = index_of_client_pk(list, length, public_key);
/* if public_key is in list, find it and maybe overwrite ip_port */
if (index != UINT32_MAX) {
- update_client(log, index, &list[index], ip_port);
+ update_client(log, mono_time, index, &list[index], ip_port);
return 1;
}
@@ -752,30 +759,26 @@ static int client_or_ip_port_in_list(const Logger *log, Client_data *list, uint1
return 1;
}
-/* Add node to the node list making sure only the nodes closest to cmp_pk are in the list.
- */
-bool add_to_list(Node_format *nodes_list, unsigned int length, const uint8_t *pk, IP_Port ip_port,
+bool add_to_list(Node_format *nodes_list, uint32_t length, const uint8_t *pk, IP_Port ip_port,
const uint8_t *cmp_pk)
{
- uint8_t pk_bak[CRYPTO_PUBLIC_KEY_SIZE];
- IP_Port ip_port_bak;
-
- for (size_t i = 0; i < length; ++i) {
+ for (uint32_t i = 0; i < length; ++i) {
if (id_closest(cmp_pk, nodes_list[i].public_key, pk) == 2) {
+ uint8_t pk_bak[CRYPTO_PUBLIC_KEY_SIZE];
memcpy(pk_bak, nodes_list[i].public_key, CRYPTO_PUBLIC_KEY_SIZE);
- ip_port_bak = nodes_list[i].ip_port;
+ 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;
- if (i != (length - 1)) {
+ if (i != length - 1) {
add_to_list(nodes_list, length, pk_bak, ip_port_bak, cmp_pk);
}
- return 1;
+ return true;
}
}
- return 0;
+ return false;
}
/* TODO(irungentoo): change this to 7 when done*/
@@ -793,9 +796,9 @@ static uint8_t hardening_correct(const Hardening *h)
/*
* helper for get_close_nodes(). argument list is a monster :D
*/
-static void get_close_nodes_inner(const uint8_t *public_key, Node_format *nodes_list,
+static void get_close_nodes_inner(const Mono_Time *mono_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, uint8_t is_LAN, uint8_t want_good)
+ uint32_t *num_nodes_ptr, bool is_LAN, uint8_t want_good)
{
if (!net_family_is_ipv4(sa_family) && !net_family_is_ipv6(sa_family) && !net_family_is_unspec(sa_family)) {
return;
@@ -824,16 +827,16 @@ static void get_close_nodes_inner(const uint8_t *public_key, Node_format *nodes_
}
/* node not in a good condition? */
- if (is_timeout(ipptp->timestamp, BAD_NODE_TIMEOUT)) {
+ if (mono_time_is_timeout(mono_time, ipptp->timestamp, BAD_NODE_TIMEOUT)) {
continue;
}
/* don't send LAN ips to non LAN peers */
- if (ip_is_lan(ipptp->ip_port.ip) == 0 && !is_LAN) {
+ if (ip_is_lan(ipptp->ip_port.ip) && !is_LAN) {
continue;
}
- if (ip_is_lan(ipptp->ip_port.ip) != 0 && want_good && hardening_correct(&ipptp->hardening) != HARDENING_ALL_OK
+ if (!ip_is_lan(ipptp->ip_port.ip) && want_good && hardening_correct(&ipptp->hardening) != HARDENING_ALL_OK
&& !id_equal(public_key, client->public_key)) {
continue;
}
@@ -859,17 +862,17 @@ static void get_close_nodes_inner(const uint8_t *public_key, Node_format *nodes_
* 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, uint8_t is_LAN, uint8_t want_good)
+ Family sa_family, bool is_LAN, uint8_t want_good)
{
uint32_t num_nodes = 0;
- get_close_nodes_inner(public_key, nodes_list, sa_family,
+ get_close_nodes_inner(dht->mono_time, 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
for (uint32_t i = 0; i < dht->num_friends; ++i) {
- get_close_nodes_inner(dht, public_key, nodes_list, sa_family,
+ get_close_nodes_inner(dht->mono_time, public_key, nodes_list, sa_family,
dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS,
&num_nodes, is_LAN, want_good);
}
@@ -877,7 +880,7 @@ static int get_somewhat_close_nodes(const DHT *dht, const uint8_t *public_key, N
#endif
for (uint32_t i = 0; i < dht->num_friends; ++i) {
- get_close_nodes_inner(public_key, nodes_list, sa_family,
+ get_close_nodes_inner(dht->mono_time, public_key, nodes_list, sa_family,
dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS,
&num_nodes, is_LAN, 0);
}
@@ -886,20 +889,21 @@ static int get_somewhat_close_nodes(const DHT *dht, const uint8_t *public_key, N
}
int get_close_nodes(const DHT *dht, const uint8_t *public_key, Node_format *nodes_list, Family sa_family,
- uint8_t is_LAN, uint8_t want_good)
+ bool is_LAN, uint8_t want_good)
{
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);
}
typedef struct DHT_Cmp_data {
+ const Mono_Time *mono_time;
const uint8_t *base_public_key;
Client_data entry;
} DHT_Cmp_data;
-static bool assoc_timeout(const IPPTsPng *assoc)
+static bool assoc_timeout(const Mono_Time *mono_time, const IPPTsPng *assoc)
{
- return is_timeout(assoc->timestamp, BAD_NODE_TIMEOUT);
+ return mono_time_is_timeout(mono_time, assoc->timestamp, BAD_NODE_TIMEOUT);
}
static bool incorrect_hardening(const IPPTsPng *assoc)
@@ -916,8 +920,8 @@ static int cmp_dht_entry(const void *a, const void *b)
const Client_data entry2 = cmp2.entry;
const uint8_t *cmp_public_key = cmp1.base_public_key;
- bool t1 = assoc_timeout(&entry1.assoc4) && assoc_timeout(&entry1.assoc6);
- bool t2 = assoc_timeout(&entry2.assoc4) && assoc_timeout(&entry2.assoc6);
+ bool t1 = assoc_timeout(cmp1.mono_time, &entry1.assoc4) && assoc_timeout(cmp1.mono_time, &entry1.assoc6);
+ bool t2 = assoc_timeout(cmp2.mono_time, &entry2.assoc4) && assoc_timeout(cmp2.mono_time, &entry2.assoc6);
if (t1 && t2) {
return 0;
@@ -960,20 +964,23 @@ static int cmp_dht_entry(const void *a, const void *b)
* return 0 if node can't be stored.
* return 1 if it can.
*/
-static unsigned int store_node_ok(const Client_data *client, const uint8_t *public_key, const uint8_t *comp_public_key)
+static unsigned int store_node_ok(const Client_data *client, const Mono_Time *mono_time, const uint8_t *public_key,
+ const uint8_t *comp_public_key)
{
- return (is_timeout(client->assoc4.timestamp, BAD_NODE_TIMEOUT)
- && is_timeout(client->assoc6.timestamp, BAD_NODE_TIMEOUT))
+ return (mono_time_is_timeout(mono_time, client->assoc4.timestamp, BAD_NODE_TIMEOUT)
+ && mono_time_is_timeout(mono_time, client->assoc6.timestamp, BAD_NODE_TIMEOUT))
|| id_closest(comp_public_key, client->public_key, public_key) == 2;
}
-static void sort_client_list(Client_data *list, unsigned int length, const uint8_t *comp_public_key)
+static void sort_client_list(Client_data *list, const Mono_Time *mono_time, unsigned int length,
+ const uint8_t *comp_public_key)
{
// 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);
for (uint32_t i = 0; i < length; ++i) {
+ cmp_list[i].mono_time = mono_time;
cmp_list[i].base_public_key = comp_public_key;
cmp_list[i].entry = list[i];
}
@@ -985,7 +992,7 @@ static void sort_client_list(Client_data *list, unsigned int length, const uint8
}
}
-static void update_client_with_reset(Client_data *client, const IP_Port *ip_port)
+static void update_client_with_reset(const Mono_Time *mono_time, Client_data *client, const IP_Port *ip_port)
{
IPPTsPng *ipptp_write = nullptr;
IPPTsPng *ipptp_clear = nullptr;
@@ -999,7 +1006,7 @@ static void update_client_with_reset(Client_data *client, const IP_Port *ip_port
}
ipptp_write->ip_port = *ip_port;
- ipptp_write->timestamp = unix_time();
+ ipptp_write->timestamp = mono_time_get(mono_time);
ip_reset(&ipptp_write->ret_ip_port.ip);
ipptp_write->ret_ip_port.port = 0;
@@ -1022,7 +1029,8 @@ static void update_client_with_reset(Client_data *client, const IP_Port *ip_port
* than public_key.
*
* returns true when the item was stored, false otherwise */
-static bool replace_all(Client_data *list,
+static bool replace_all(const Mono_Time *mono_time,
+ Client_data *list,
uint16_t length,
const uint8_t *public_key,
IP_Port ip_port,
@@ -1032,17 +1040,17 @@ static bool replace_all(Client_data *list,
return false;
}
- if (!store_node_ok(&list[1], public_key, comp_public_key) &&
- !store_node_ok(&list[0], public_key, comp_public_key)) {
+ if (!store_node_ok(&list[1], mono_time, public_key, comp_public_key) &&
+ !store_node_ok(&list[0], mono_time, public_key, comp_public_key)) {
return false;
}
- sort_client_list(list, length, comp_public_key);
+ sort_client_list(list, mono_time, length, comp_public_key);
Client_data *const client = &list[0];
id_copy(client->public_key, public_key);
- update_client_with_reset(client, &ip_port);
+ update_client_with_reset(mono_time, client, &ip_port);
return true;
}
@@ -1066,8 +1074,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 (!is_timeout(client->assoc4.timestamp, BAD_NODE_TIMEOUT) ||
- !is_timeout(client->assoc6.timestamp, BAD_NODE_TIMEOUT)) {
+ if (!mono_time_is_timeout(dht->mono_time, client->assoc4.timestamp, BAD_NODE_TIMEOUT) ||
+ !mono_time_is_timeout(dht->mono_time, client->assoc6.timestamp, BAD_NODE_TIMEOUT)) {
continue;
}
@@ -1076,7 +1084,7 @@ 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(client, &ip_port);
+ update_client_with_reset(dht->mono_time, client, &ip_port);
return 0;
}
@@ -1090,8 +1098,8 @@ bool node_addable_to_close_list(DHT *dht, const uint8_t *public_key, IP_Port ip_
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, const uint8_t *public_key,
- IP_Port ip_port)
+static bool is_pk_in_client_list(const Client_data *list, unsigned int client_list_length, const Mono_Time *mono_time,
+ const uint8_t *public_key, IP_Port ip_port)
{
const uint32_t index = index_of_client_pk(list, client_list_length, public_key);
@@ -1103,7 +1111,7 @@ static bool is_pk_in_client_list(const Client_data *list, unsigned int client_li
? &list[index].assoc4
: &list[index].assoc6;
- return !is_timeout(assoc->timestamp, BAD_NODE_TIMEOUT);
+ return !mono_time_is_timeout(mono_time, assoc->timestamp, BAD_NODE_TIMEOUT);
}
static bool is_pk_in_close_list(DHT *dht, const uint8_t *public_key, IP_Port ip_port)
@@ -1114,7 +1122,8 @@ 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, public_key, ip_port);
+ return is_pk_in_client_list(dht->close_clientlist + index * LCLIENT_NODES, LCLIENT_NODES, dht->mono_time, public_key,
+ ip_port);
}
/* Check if the node obtained with a get_nodes with public_key should be pinged.
@@ -1153,17 +1162,18 @@ 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], public_key, dht_friend->public_key)) {
+ if (store_node_ok(&dht_friend->client_list[1], dht->mono_time, public_key, dht_friend->public_key)) {
store_ok = true;
}
- if (store_node_ok(&dht_friend->client_list[0], public_key, dht_friend->public_key)) {
+ if (store_node_ok(&dht_friend->client_list[0], dht->mono_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, public_key, ip_port);
+ const bool pk_in_list = is_pk_in_client_list(dht_friend->client_list, MAX_FRIEND_CLIENTS, dht->mono_time, public_key,
+ ip_port);
if (store_ok && index == UINT32_MAX && !pk_in_list) {
if (*friend_num < MAX_SENT_NODES) {
@@ -1200,8 +1210,8 @@ uint32_t addto_lists(DHT *dht, IP_Port ip_port, const uint8_t *public_key)
/* 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->close_clientlist,
- LCLIENT_LIST, public_key, ip_port);
+ 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);
/* 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)) {
@@ -1211,12 +1221,13 @@ uint32_t addto_lists(DHT *dht, IP_Port ip_port, const uint8_t *public_key)
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->friends_list[i].client_list,
+ 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);
/* replace_all should be called only if !in_list (don't extract to variable) */
- if (in_list || replace_all(dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS, public_key,
- ip_port, dht->friends_list[i].public_key)) {
+ if (in_list
+ || replace_all(dht->mono_time, dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS, public_key, ip_port,
+ dht->friends_list[i].public_key)) {
DHT_Friend *dht_friend = &dht->friends_list[i];
if (id_equal(public_key, dht_friend->public_key)) {
@@ -1241,9 +1252,10 @@ uint32_t addto_lists(DHT *dht, IP_Port ip_port, const uint8_t *public_key)
return used;
}
-static bool update_client_data(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, IP_Port ip_port,
+ const uint8_t *pk)
{
- const uint64_t temp_time = unix_time();
+ const uint64_t temp_time = mono_time_get(mono_time);
const uint32_t index = index_of_client_pk(array, size, pk);
if (index == UINT32_MAX) {
@@ -1278,7 +1290,7 @@ static void returnedip_ports(DHT *dht, IP_Port ip_port, const uint8_t *public_ke
}
if (id_equal(public_key, dht->self_public_key)) {
- update_client_data(dht->close_clientlist, LCLIENT_LIST, ip_port, nodepublic_key);
+ update_client_data(dht->mono_time, dht->close_clientlist, LCLIENT_LIST, ip_port, nodepublic_key);
return;
}
@@ -1286,7 +1298,7 @@ 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(client_list, MAX_FRIEND_CLIENTS, ip_port, nodepublic_key)) {
+ if (update_client_data(dht->mono_time, client_list, MAX_FRIEND_CLIENTS, ip_port, nodepublic_key)) {
return;
}
}
@@ -1314,9 +1326,9 @@ static int getnodes(DHT *dht, IP_Port ip_port, const uint8_t *public_key, const
if (sendback_node != nullptr) {
memcpy(plain_message + sizeof(receiver), sendback_node, sizeof(Node_format));
- ping_id = ping_array_add(dht->dht_harden_ping_array, plain_message, sizeof(plain_message));
+ 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, plain_message, sizeof(receiver));
+ ping_id = ping_array_add(dht->dht_ping_array, dht->mono_time, plain_message, sizeof(receiver));
}
if (ping_id == 0) {
@@ -1358,8 +1370,8 @@ static int sendnodes_ipv6(const DHT *dht, IP_Port ip_port, const uint8_t *public
const size_t node_format_size = sizeof(Node_format);
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) == 0,
- 1);
+ const uint32_t num_nodes =
+ get_close_nodes(dht, client_id, nodes_list, net_family_unspec, ip_is_lan(ip_port.ip), 1);
VLA(uint8_t, plain, 1 + node_format_size * MAX_SENT_NODES + length);
@@ -1433,9 +1445,9 @@ static bool sent_getnode_to_node(DHT *dht, const uint8_t *public_key, IP_Port no
{
uint8_t data[sizeof(Node_format) * 2];
- if (ping_array_check(dht->dht_ping_array, data, sizeof(data), ping_id) == sizeof(Node_format)) {
+ 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, data, sizeof(data), ping_id) == sizeof(data)) {
+ } 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 {
return false;
@@ -1678,7 +1690,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 (!is_timeout(assoc->timestamp, BAD_NODE_TIMEOUT)) {
+ if (!mono_time_is_timeout(dht->mono_time, assoc->timestamp, BAD_NODE_TIMEOUT)) {
*ip_port = assoc->ip_port;
return 1;
}
@@ -1692,7 +1704,7 @@ static uint8_t do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, co
Client_data *list, uint32_t list_count, uint32_t *bootstrap_times, bool sortable)
{
uint8_t not_kill = 0;
- const uint64_t temp_time = unix_time();
+ const uint64_t temp_time = mono_time_get(dht->mono_time);
uint32_t num_nodes = 0;
VLA(Client_data *, client_list, list_count * 2);
@@ -1709,17 +1721,17 @@ static uint8_t do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, co
for (uint32_t j = 0; j < sizeof(assocs) / sizeof(assocs[0]); ++j) {
IPPTsPng *const assoc = assocs[j];
- if (!is_timeout(assoc->timestamp, KILL_NODE_TIMEOUT)) {
+ if (!mono_time_is_timeout(dht->mono_time, assoc->timestamp, KILL_NODE_TIMEOUT)) {
sort = 0;
++not_kill;
- if (is_timeout(assoc->last_pinged, PING_INTERVAL)) {
+ if (mono_time_is_timeout(dht->mono_time, assoc->last_pinged, PING_INTERVAL)) {
getnodes(dht, assoc->ip_port, client->public_key, public_key, nullptr);
assoc->last_pinged = temp_time;
}
/* If node is good. */
- if (!is_timeout(assoc->timestamp, BAD_NODE_TIMEOUT)) {
+ if (!mono_time_is_timeout(dht->mono_time, assoc->timestamp, BAD_NODE_TIMEOUT)) {
client_list[num_nodes] = client;
assoc_list[num_nodes] = assoc;
++num_nodes;
@@ -1736,10 +1748,11 @@ static uint8_t do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, co
}
if (sortable && sort_ok) {
- sort_client_list(list, list_count, public_key);
+ sort_client_list(list, dht->mono_time, list_count, public_key);
}
- if ((num_nodes != 0) && (is_timeout(*lastgetnode, GET_NODE_INTERVAL) || *bootstrap_times < MAX_BOOTSTRAP_TIMES)) {
+ 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;
if ((num_nodes - 1) != rand_node) {
@@ -1801,7 +1814,7 @@ static void do_Close(DHT *dht)
*
* so: reset all nodes to be BAD_NODE_TIMEOUT, but not
* KILL_NODE_TIMEOUT, so we at least keep trying pings */
- const uint64_t badonly = unix_time() - BAD_NODE_TIMEOUT;
+ const uint64_t badonly = mono_time_get(dht->mono_time) - BAD_NODE_TIMEOUT;
for (size_t i = 0; i < LCLIENT_LIST; ++i) {
Client_data *const client = &dht->close_clientlist[i];
@@ -1906,19 +1919,21 @@ static int friend_iplist(const DHT *dht, IP_Port *ip_portlist, uint16_t friend_n
const Client_data *const client = &dht_friend->client_list[i];
/* If ip is not zero and node is good. */
- if (ip_isset(&client->assoc4.ret_ip_port.ip) && !is_timeout(client->assoc4.ret_timestamp, BAD_NODE_TIMEOUT)) {
+ if (ip_isset(&client->assoc4.ret_ip_port.ip)
+ && !mono_time_is_timeout(dht->mono_time, client->assoc4.ret_timestamp, BAD_NODE_TIMEOUT)) {
ipv4s[num_ipv4s] = client->assoc4.ret_ip_port;
++num_ipv4s;
}
- if (ip_isset(&client->assoc6.ret_ip_port.ip) && !is_timeout(client->assoc6.ret_timestamp, BAD_NODE_TIMEOUT)) {
+ if (ip_isset(&client->assoc6.ret_ip_port.ip)
+ && !mono_time_is_timeout(dht->mono_time, client->assoc6.ret_timestamp, BAD_NODE_TIMEOUT)) {
ipv6s[num_ipv6s] = client->assoc6.ret_ip_port;
++num_ipv6s;
}
if (id_equal(client->public_key, dht_friend->public_key)) {
- if (!is_timeout(client->assoc6.timestamp, BAD_NODE_TIMEOUT)
- || !is_timeout(client->assoc4.timestamp, BAD_NODE_TIMEOUT)) {
+ if (!mono_time_is_timeout(dht->mono_time, client->assoc6.timestamp, BAD_NODE_TIMEOUT)
+ || !mono_time_is_timeout(dht->mono_time, client->assoc4.timestamp, BAD_NODE_TIMEOUT)) {
return 0; /* direct connectivity */
}
}
@@ -1997,7 +2012,7 @@ int route_tofriend(const DHT *dht, const uint8_t *friend_id, const uint8_t *pack
const IPPTsPng *const assoc = *it;
/* If ip is not zero and node is good. */
- if (ip_isset(&assoc->ret_ip_port.ip) && !is_timeout(assoc->ret_timestamp, BAD_NODE_TIMEOUT)) {
+ 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) {
@@ -2039,7 +2054,7 @@ static int routeone_tofriend(DHT *dht, const uint8_t *friend_id, const uint8_t *
const IPPTsPng *const assoc = *it;
/* If ip is not zero and node is good. */
- if (ip_isset(&assoc->ret_ip_port.ip) && !is_timeout(assoc->ret_timestamp, BAD_NODE_TIMEOUT)) {
+ 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;
}
@@ -2116,7 +2131,7 @@ static int handle_NATping(void *object, IP_Port source, const uint8_t *source_pu
if (packet[0] == NAT_PING_REQUEST) {
/* 1 is reply */
send_NATping(dht, source_pubkey, ping_id, NAT_PING_RESPONSE);
- dht_friend->nat.recv_nat_ping_timestamp = unix_time();
+ dht_friend->nat.recv_nat_ping_timestamp = mono_time_get(dht->mono_time);
return 0;
}
@@ -2243,7 +2258,7 @@ static void punch_holes(DHT *dht, IP ip, uint16_t *port_list, uint16_t numports,
static void do_NAT(DHT *dht)
{
- const uint64_t temp_time = unix_time();
+ const uint64_t temp_time = mono_time_get(dht->mono_time);
for (uint32_t i = 0; i < dht->num_friends; ++i) {
IP_Port ip_list[MAX_FRIEND_CLIENTS];
@@ -2393,7 +2408,7 @@ static uint32_t have_nodes_closelist(DHT *dht, Node_format *nodes, uint16_t num)
const IPPTsPng *const temp = get_closelist_IPPTsPng(dht, nodes[i].public_key, nodes[i].ip_port.ip.family);
if (temp) {
- if (!is_timeout(temp->timestamp, BAD_NODE_TIMEOUT)) {
+ if (!mono_time_is_timeout(dht->mono_time, temp->timestamp, BAD_NODE_TIMEOUT)) {
++counter;
}
}
@@ -2464,7 +2479,7 @@ static int handle_hardening(void *object, IP_Port source, const uint8_t *source_
return 1;
}
- if (is_timeout(temp->hardening.send_nodes_timestamp, HARDENING_INTERVAL)) {
+ if (mono_time_is_timeout(dht->mono_time, temp->hardening.send_nodes_timestamp, HARDENING_INTERVAL)) {
return 1;
}
@@ -2512,7 +2527,8 @@ static Node_format random_node(DHT *dht, Family sa_family)
*
* return the number of nodes.
*/
-static uint16_t list_nodes(Client_data *list, size_t length, Node_format *nodes, uint16_t max_num)
+static uint16_t list_nodes(Client_data *list, size_t length, const Mono_Time *mono_time, Node_format *nodes,
+ uint16_t max_num)
{
if (max_num == 0) {
return 0;
@@ -2523,11 +2539,11 @@ static uint16_t list_nodes(Client_data *list, size_t length, Node_format *nodes,
for (size_t i = length; i != 0; --i) {
const IPPTsPng *assoc = nullptr;
- if (!is_timeout(list[i - 1].assoc4.timestamp, BAD_NODE_TIMEOUT)) {
+ if (!mono_time_is_timeout(mono_time, list[i - 1].assoc4.timestamp, BAD_NODE_TIMEOUT)) {
assoc = &list[i - 1].assoc4;
}
- if (!is_timeout(list[i - 1].assoc6.timestamp, BAD_NODE_TIMEOUT)) {
+ if (!mono_time_is_timeout(mono_time, list[i - 1].assoc6.timestamp, BAD_NODE_TIMEOUT)) {
if (assoc == nullptr) {
assoc = &list[i - 1].assoc6;
} else if (random_u08() % 2) {
@@ -2563,8 +2579,8 @@ 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, nodes + count,
- max_num - count);
+ count += list_nodes(dht->friends_list[(i + r) % DHT_FAKE_FRIEND_NUMBER].client_list, MAX_FRIEND_CLIENTS, dht->mono_time,
+ nodes + count, max_num - count);
if (count >= max_num) {
break;
@@ -2580,7 +2596,7 @@ uint16_t randfriends_nodes(DHT *dht, Node_format *nodes, uint16_t max_num)
*/
uint16_t closelist_nodes(DHT *dht, Node_format *nodes, uint16_t max_num)
{
- return list_nodes(dht->close_clientlist, LCLIENT_LIST, nodes, max_num);
+ return list_nodes(dht->close_clientlist, LCLIENT_LIST, dht->mono_time, nodes, max_num);
}
#if DHT_HARDENING
@@ -2599,12 +2615,12 @@ static void do_hardening(DHT *dht)
sa_family = net_family_ipv6;
}
- if (is_timeout(cur_iptspng->timestamp, BAD_NODE_TIMEOUT)) {
+ if (mono_time_is_timeout(dht->mono_time, cur_iptspng->timestamp, BAD_NODE_TIMEOUT)) {
continue;
}
if (cur_iptspng->hardening.send_nodes_ok == 0) {
- if (is_timeout(cur_iptspng->hardening.send_nodes_timestamp, HARDENING_INTERVAL)) {
+ 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)) {
@@ -2622,11 +2638,11 @@ static void do_hardening(DHT *dht)
// 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 = unix_time();
+ cur_iptspng->hardening.send_nodes_timestamp = mono_time_get(dht->mono_time);
}
}
} else {
- if (is_timeout(cur_iptspng->hardening.send_nodes_timestamp, HARDEN_TIMEOUT)) {
+ if (mono_time_is_timeout(dht->mono_time, cur_iptspng->hardening.send_nodes_timestamp, HARDEN_TIMEOUT)) {
cur_iptspng->hardening.send_nodes_ok = 0;
}
}
@@ -2688,11 +2704,8 @@ static int cryptopacket_handle(void *object, IP_Port source, const uint8_t *pack
/*----------------------------------------------------------------------------------*/
-DHT *new_dht(const Logger *log, Networking_Core *net, bool holepunching_enabled)
+DHT *new_dht(const Logger *log, Mono_Time *mono_time, Networking_Core *net, bool holepunching_enabled)
{
- /* init time */
- unix_time_update();
-
if (net == nullptr) {
return nullptr;
}
@@ -2703,12 +2716,13 @@ DHT *new_dht(const Logger *log, Networking_Core *net, bool holepunching_enabled)
return nullptr;
}
+ dht->mono_time = mono_time;
dht->log = log;
dht->net = net;
dht->hole_punching_enabled = holepunching_enabled;
- dht->ping = ping_new(dht);
+ dht->ping = ping_new(mono_time, dht);
if (dht->ping == nullptr) {
kill_dht(dht);
@@ -2741,9 +2755,7 @@ DHT *new_dht(const Logger *log, Networking_Core *net, bool holepunching_enabled)
void do_dht(DHT *dht)
{
- unix_time_update();
-
- if (dht->last_run == unix_time()) {
+ if (dht->last_run == mono_time_get(dht->mono_time)) {
return;
}
@@ -2759,7 +2771,7 @@ void do_dht(DHT *dht)
#if DHT_HARDENING
do_hardening(dht);
#endif
- dht->last_run = unix_time();
+ dht->last_run = mono_time_get(dht->mono_time);
}
void kill_dht(DHT *dht)
@@ -2811,26 +2823,16 @@ uint32_t dht_size(const DHT *dht)
return size32 + sizesubhead + packed_node_size(net_family_ipv4) * numv4 + packed_node_size(net_family_ipv6) * numv6;
}
-static uint8_t *dht_save_subheader(uint8_t *data, uint32_t len, uint16_t type)
-{
- host_to_lendian32(data, len);
- data += sizeof(uint32_t);
- host_to_lendian32(data, (host_tolendian16(DHT_STATE_COOKIE_TYPE) << 16) | host_tolendian16(type));
- data += sizeof(uint32_t);
- return data;
-}
-
-
/* 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_lendian32(data, DHT_STATE_COOKIE_GLOBAL);
+ host_to_lendian32(data, DHT_STATE_COOKIE_GLOBAL);
data += sizeof(uint32_t);
uint8_t *const old_data = data;
/* get right offset. we write the actual header later. */
- data = dht_save_subheader(data, 0, 0);
+ data = state_write_section_header(data, DHT_STATE_COOKIE_TYPE, 0, 0);
Node_format clients[MAX_SAVED_DHT_NODES];
@@ -2868,7 +2870,8 @@ void dht_save(const DHT *dht, uint8_t *data)
}
}
- dht_save_subheader(old_data, pack_nodes(data, sizeof(Node_format) * num, clients, num), DHT_STATE_TYPE_NODES);
+ state_write_section_header(old_data, DHT_STATE_COOKIE_TYPE, pack_nodes(data, sizeof(Node_format) * num, clients, num),
+ DHT_STATE_TYPE_NODES);
}
/* Bootstrap from this number of nodes every time dht_connect_after_load() is called */
@@ -2963,13 +2966,11 @@ int dht_load(DHT *dht, const uint8_t *data, uint32_t length)
*/
bool dht_isconnected(const DHT *dht)
{
- unix_time_update();
-
for (uint32_t i = 0; i < LCLIENT_LIST; ++i) {
const Client_data *const client = &dht->close_clientlist[i];
- if (!is_timeout(client->assoc4.timestamp, BAD_NODE_TIMEOUT) ||
- !is_timeout(client->assoc6.timestamp, BAD_NODE_TIMEOUT)) {
+ if (!mono_time_is_timeout(dht->mono_time, client->assoc4.timestamp, BAD_NODE_TIMEOUT) ||
+ !mono_time_is_timeout(dht->mono_time, client->assoc6.timestamp, BAD_NODE_TIMEOUT)) {
return true;
}
}
@@ -2982,16 +2983,16 @@ bool dht_isconnected(const DHT *dht)
*/
bool dht_non_lan_connected(const DHT *dht)
{
- unix_time_update();
-
for (uint32_t i = 0; i < LCLIENT_LIST; ++i) {
const Client_data *const client = &dht->close_clientlist[i];
- if (!is_timeout(client->assoc4.timestamp, BAD_NODE_TIMEOUT) && ip_is_lan(client->assoc4.ip_port.ip) == -1) {
+ if (!mono_time_is_timeout(dht->mono_time, client->assoc4.timestamp, BAD_NODE_TIMEOUT)
+ && !ip_is_lan(client->assoc4.ip_port.ip)) {
return true;
}
- if (!is_timeout(client->assoc6.timestamp, BAD_NODE_TIMEOUT) && ip_is_lan(client->assoc6.ip_port.ip) == -1) {
+ if (!mono_time_is_timeout(dht->mono_time, client->assoc6.timestamp, BAD_NODE_TIMEOUT)
+ && !ip_is_lan(client->assoc6.ip_port.ip)) {
return true;
}
}
diff --git a/protocols/Tox/libtox/src/toxcore/DHT.h b/protocols/Tox/libtox/src/toxcore/DHT.h
index 0852827c8d..5feb74d275 100644
--- a/protocols/Tox/libtox/src/toxcore/DHT.h
+++ b/protocols/Tox/libtox/src/toxcore/DHT.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright © 2016-2017 The TokTok team.
+ * Copyright © 2016-2018 The TokTok team.
* Copyright © 2013 Tox project.
*
* This file is part of Tox, the free peer to peer instant messenger.
@@ -21,11 +21,12 @@
* You should have received a copy of the GNU General Public License
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef DHT_H
-#define DHT_H
+#ifndef C_TOXCORE_TOXCORE_DHT_H
+#define C_TOXCORE_TOXCORE_DHT_H
#include "crypto_core.h"
#include "logger.h"
+#include "mono_time.h"
#include "network.h"
#include "ping_array.h"
@@ -173,7 +174,7 @@ int pack_ip_port(uint8_t *data, uint16_t length, const IP_Port *ip_port);
* 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, uint8_t tcp_enabled);
+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.
*
@@ -190,7 +191,7 @@ int pack_nodes(uint8_t *data, uint16_t length, const Node_format *nodes, uint16_
* return -1 on failure.
*/
int unpack_nodes(Node_format *nodes, uint16_t max_num_nodes, uint16_t *processed_data_len, const uint8_t *data,
- uint16_t length, uint8_t tcp_enabled);
+ uint16_t length, bool tcp_enabled);
/*----------------------------------------------------------------------------------*/
@@ -202,7 +203,7 @@ typedef struct Shared_Key {
uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE];
uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE];
uint32_t times_requested;
- uint8_t stored; /* 0 if not, 1 if is */
+ bool stored;
uint64_t time_last_requested;
} Shared_Key;
@@ -234,14 +235,14 @@ const uint8_t *dht_get_friend_public_key(const DHT *dht, uint32_t friend_num);
/*----------------------------------------------------------------------------------*/
-/* Shared key generations are costly, it is therefor smart to store commonly used
+/* 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.
*
* 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
*/
-void get_shared_key(Shared_Keys *shared_keys, uint8_t *shared_key, const uint8_t *secret_key,
- const uint8_t *public_key);
+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
* for packets that we receive.
@@ -301,9 +302,12 @@ 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.
+/**
+ * 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, unsigned int length, const uint8_t *pk, IP_Port ip_port,
+bool add_to_list(Node_format *nodes_list, uint32_t length, const uint8_t *pk, IP_Port ip_port,
const uint8_t *cmp_pk);
/* Return 1 if node can be added to close list, 0 if it can't.
@@ -321,7 +325,7 @@ 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,
- uint8_t is_LAN, uint8_t want_good);
+ bool is_LAN, uint8_t want_good);
/* Put up to max_num nodes in nodes from the random friends.
@@ -401,7 +405,7 @@ void dht_save(const DHT *dht, uint8_t *data);
int dht_load(DHT *dht, const uint8_t *data, uint32_t length);
/* Initialize DHT. */
-DHT *new_dht(const Logger *log, Networking_Core *net, bool holepunching_enabled);
+DHT *new_dht(const Logger *log, Mono_Time *mono_time, Networking_Core *net, bool holepunching_enabled);
void kill_dht(DHT *dht);
diff --git a/protocols/Tox/libtox/src/toxcore/LAN_discovery.api.h b/protocols/Tox/libtox/src/toxcore/LAN_discovery.api.h
index 9e6c648164..31d6a5f64b 100644
--- a/protocols/Tox/libtox/src/toxcore/LAN_discovery.api.h
+++ b/protocols/Tox/libtox/src/toxcore/LAN_discovery.api.h
@@ -4,7 +4,7 @@
*/
/*
- * Copyright © 2016-2017 The TokTok team.
+ * Copyright © 2016-2018 The TokTok team.
* Copyright © 2013 Tox project.
*
* This file is part of Tox, the free peer to peer instant messenger.
@@ -22,8 +22,8 @@
* You should have received a copy of the GNU General Public License
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef LAN_DISCOVERY_H
-#define LAN_DISCOVERY_H
+#ifndef C_TOXCORE_TOXCORE_LAN_DISCOVERY_H
+#define C_TOXCORE_TOXCORE_LAN_DISCOVERY_H
#include "DHT.h"
%}
@@ -61,13 +61,12 @@ static void kill(dHT::this *dht);
static bool ip_is_local(iP::this ip);
/**
- * checks if a given IP isn't routable
+ * Checks if a given IP isn't routable.
*
- * return 0 if ip is a LAN ip.
- * return -1 if it is not.
+ * @return true if ip is a LAN ip, false if it is not.
*/
-static int32_t ip_is_lan(iP::this ip);
+static bool ip_is_lan(iP::this ip);
%{
-#endif
+#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 0b2a87831b..aeeea5661a 100644
--- a/protocols/Tox/libtox/src/toxcore/LAN_discovery.c
+++ b/protocols/Tox/libtox/src/toxcore/LAN_discovery.c
@@ -3,7 +3,7 @@
*/
/*
- * Copyright © 2016-2017 The TokTok team.
+ * Copyright © 2016-2018 The TokTok team.
* Copyright © 2013 Tox project.
*
* This file is part of Tox, the free peer to peer instant messenger.
@@ -272,91 +272,93 @@ static IP broadcast_ip(Family family_socket, Family family_broadcast)
return ip;
}
+static bool ip4_is_local(IP4 ip4)
+{
+ /* Loopback. */
+ return ip4.uint8[0] == 127;
+}
+
/* Is IP a local ip or not. */
bool ip_is_local(IP ip)
{
if (net_family_is_ipv4(ip.family)) {
- IP4 ip4 = ip.ip.v4;
+ return ip4_is_local(ip.ip.v4);
+ }
- /* Loopback. */
- if (ip4.uint8[0] == 127) {
- return 1;
- }
- } else {
- /* embedded IPv4-in-IPv6 */
- if (ipv6_ipv4_in_v6(ip.ip.v6)) {
- IP ip4;
- ip4.family = net_family_ipv4;
- ip4.ip.v4.uint32 = ip.ip.v6.uint32[3];
- return ip_is_local(ip4);
- }
+ /* embedded IPv4-in-IPv6 */
+ if (ipv6_ipv4_in_v6(ip.ip.v6)) {
+ IP4 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)) {
- return 1;
- }
+ /* 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)) {
+ return true;
}
- return 0;
+ return false;
}
-/* return 0 if ip is a LAN ip.
- * return -1 if it is not.
- */
-int ip_is_lan(IP ip)
+static bool ip4_is_lan(IP4 ip4)
{
- if (ip_is_local(ip)) {
- return 0;
+ /* 10.0.0.0 to 10.255.255.255 range. */
+ if (ip4.uint8[0] == 10) {
+ return true;
}
- if (net_family_is_ipv4(ip.family)) {
- IP4 ip4 = ip.ip.v4;
+ /* 172.16.0.0 to 172.31.255.255 range. */
+ if (ip4.uint8[0] == 172 && ip4.uint8[1] >= 16 && ip4.uint8[1] <= 31) {
+ return true;
+ }
- /* 10.0.0.0 to 10.255.255.255 range. */
- if (ip4.uint8[0] == 10) {
- return 0;
- }
+ /* 192.168.0.0 to 192.168.255.255 range. */
+ if (ip4.uint8[0] == 192 && ip4.uint8[1] == 168) {
+ 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) {
- return 0;
- }
+ /* 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) {
+ return true;
+ }
- /* 192.168.0.0 to 192.168.255.255 range. */
- if (ip4.uint8[0] == 192 && ip4.uint8[1] == 168) {
- return 0;
- }
+ /* 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)) {
+ 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) {
- return 0;
- }
+ return false;
+}
- /* 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)) {
- return 0;
- }
- } else if (net_family_is_ipv6(ip.family)) {
+bool ip_is_lan(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_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))) {
- return 0;
+ return true;
}
/* embedded IPv4-in-IPv6 */
if (ipv6_ipv4_in_v6(ip.ip.v6)) {
- IP ip4;
- ip4.family = net_family_ipv4;
- ip4.ip.v4.uint32 = ip.ip.v6.uint32[3];
- return ip_is_lan(ip4);
+ IP4 ip4;
+ ip4.uint32 = ip.ip.v6.uint32[3];
+ return ip4_is_lan(ip4);
}
}
- return -1;
+ return false;
}
static int handle_LANdiscovery(void *object, IP_Port source, const uint8_t *packet, uint16_t length, void *userdata)
@@ -366,7 +368,7 @@ static int handle_LANdiscovery(void *object, IP_Port source, const uint8_t *pack
char ip_str[IP_NTOA_LEN] = { 0 };
ip_ntoa(&source.ip, ip_str, sizeof(ip_str));
- if (ip_is_lan(source.ip) == -1) {
+ if (!ip_is_lan(source.ip)) {
return 1;
}
diff --git a/protocols/Tox/libtox/src/toxcore/LAN_discovery.h b/protocols/Tox/libtox/src/toxcore/LAN_discovery.h
index 6d9d17b664..8c48316d9e 100644
--- a/protocols/Tox/libtox/src/toxcore/LAN_discovery.h
+++ b/protocols/Tox/libtox/src/toxcore/LAN_discovery.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright © 2016-2017 The TokTok team.
+ * Copyright © 2016-2018 The TokTok team.
* Copyright © 2013 Tox project.
*
* This file is part of Tox, the free peer to peer instant messenger.
@@ -21,8 +21,8 @@
* You should have received a copy of the GNU General Public License
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef LAN_DISCOVERY_H
-#define LAN_DISCOVERY_H
+#ifndef C_TOXCORE_TOXCORE_LAN_DISCOVERY_H
+#define C_TOXCORE_TOXCORE_LAN_DISCOVERY_H
#include "DHT.h"
@@ -64,11 +64,10 @@ void lan_discovery_kill(DHT *dht);
bool ip_is_local(IP ip);
/**
- * checks if a given IP isn't routable
+ * Checks if a given IP isn't routable.
*
- * return 0 if ip is a LAN ip.
- * return -1 if it is not.
+ * @return true if ip is a LAN ip, false if it is not.
*/
-int32_t ip_is_lan(IP ip);
+bool ip_is_lan(IP ip);
#endif
diff --git a/protocols/Tox/libtox/src/toxcore/Messenger.c b/protocols/Tox/libtox/src/toxcore/Messenger.c
index acf9f806f7..594fc79a07 100644
--- a/protocols/Tox/libtox/src/toxcore/Messenger.c
+++ b/protocols/Tox/libtox/src/toxcore/Messenger.c
@@ -3,7 +3,7 @@
*/
/*
- * Copyright © 2016-2017 The TokTok team.
+ * Copyright © 2016-2018 The TokTok team.
* Copyright © 2013 Tox project.
*
* This file is part of Tox, the free peer to peer instant messenger.
@@ -41,6 +41,7 @@
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);
// friend_not_valid determines if the friendnumber passed is valid in the Messenger object
static uint8_t friend_not_valid(const Messenger *m, int32_t friendnumber)
@@ -1949,7 +1950,7 @@ static int friend_already_added(const uint8_t *real_pk, void *data)
}
/* Run this at startup. */
-Messenger *new_messenger(Messenger_Options *options, unsigned int *error)
+Messenger *new_messenger(Mono_Time *mono_time, Messenger_Options *options, unsigned int *error)
{
if (!options) {
return nullptr;
@@ -1965,6 +1966,8 @@ Messenger *new_messenger(Messenger_Options *options, unsigned int *error)
return nullptr;
}
+ m->mono_time = mono_time;
+
m->fr = friendreq_new();
if (!m->fr) {
@@ -2010,7 +2013,7 @@ Messenger *new_messenger(Messenger_Options *options, unsigned int *error)
return nullptr;
}
- m->dht = new_dht(m->log, m->net, options->hole_punching_enabled);
+ m->dht = new_dht(m->log, m->mono_time, m->net, options->hole_punching_enabled);
if (m->dht == nullptr) {
kill_networking(m->net);
@@ -2020,7 +2023,7 @@ Messenger *new_messenger(Messenger_Options *options, unsigned int *error)
return nullptr;
}
- m->net_crypto = new_net_crypto(m->log, m->dht, &options->proxy_info);
+ m->net_crypto = new_net_crypto(m->log, m->mono_time, m->dht, &options->proxy_info);
if (m->net_crypto == nullptr) {
kill_networking(m->net);
@@ -2031,10 +2034,10 @@ Messenger *new_messenger(Messenger_Options *options, unsigned int *error)
return nullptr;
}
- m->onion = new_onion(m->dht);
- m->onion_a = new_onion_announce(m->dht);
- m->onion_c = new_onion_client(m->net_crypto);
- m->fr_c = new_friend_connections(m->onion_c, options->local_discovery_enabled);
+ m->onion = new_onion(m->mono_time, m->dht);
+ m->onion_a = new_onion_announce(m->mono_time, m->dht);
+ m->onion_c = new_onion_client(m->mono_time, m->net_crypto);
+ m->fr_c = new_friend_connections(m->mono_time, m->onion_c, options->local_discovery_enabled);
if (!(m->onion && m->onion_a && m->onion_c)) {
kill_friend_connections(m->fr_c);
@@ -2081,6 +2084,8 @@ Messenger *new_messenger(Messenger_Options *options, unsigned int *error)
m->lastdump = 0;
+ m_register_default_plugins(m);
+
if (error) {
*error = MESSENGER_ERROR_NONE;
}
@@ -2116,6 +2121,8 @@ void kill_messenger(Messenger *m)
logger_kill(m->log);
free(m->friendlist);
friendreq_kill(m->fr);
+
+ free(m->options.state_plugins);
free(m);
}
@@ -2468,7 +2475,7 @@ 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 = unix_time();
+ uint64_t temp_time = mono_time_get(m->mono_time);
for (i = 0; i < m->numfriends; ++i) {
if (m->friendlist[i].status == FRIEND_ADDED) {
@@ -2583,8 +2590,8 @@ uint32_t messenger_run_interval(const Messenger *m)
void do_messenger(Messenger *m, void *userdata)
{
// Add the TCP relays, but only if this is the first time calling do_messenger
- if (m->has_added_relays == 0) {
- m->has_added_relays = 1;
+ if (!m->has_added_relays) {
+ m->has_added_relays = true;
int i;
@@ -2603,15 +2610,13 @@ void do_messenger(Messenger *m, void *userdata)
}
}
- unix_time_update();
-
if (!m->options.udp_disabled) {
networking_poll(m->net, userdata);
do_dht(m->dht);
}
if (m->tcp_server) {
- do_TCP_server(m->tcp_server);
+ do_TCP_server(m->tcp_server, m->mono_time);
}
do_net_crypto(m->net_crypto, userdata);
@@ -2620,8 +2625,8 @@ void do_messenger(Messenger *m, void *userdata)
do_friends(m, userdata);
connection_status_callback(m, userdata);
- if (unix_time() > m->lastdump + DUMPING_CLIENTS_FRIENDS_EVERY_N_SECONDS) {
- m->lastdump = unix_time();
+ if (mono_time_get(m->mono_time) > m->lastdump + DUMPING_CLIENTS_FRIENDS_EVERY_N_SECONDS) {
+ m->lastdump = mono_time_get(m->mono_time);
uint32_t client, last_pinged;
for (client = 0; client < LCLIENT_LIST; ++client) {
@@ -2737,15 +2742,6 @@ void do_messenger(Messenger *m, void *userdata)
#define MESSENGER_STATE_COOKIE_GLOBAL 0x15ed1b1f
#define MESSENGER_STATE_COOKIE_TYPE 0x01ce
-#define MESSENGER_STATE_TYPE_NOSPAMKEYS 1
-#define MESSENGER_STATE_TYPE_DHT 2
-#define MESSENGER_STATE_TYPE_FRIENDS 3
-#define MESSENGER_STATE_TYPE_NAME 4
-#define MESSENGER_STATE_TYPE_STATUSMESSAGE 5
-#define MESSENGER_STATE_TYPE_STATUS 6
-#define MESSENGER_STATE_TYPE_TCP_RELAY 10
-#define MESSENGER_STATE_TYPE_PATH_NODE 11
-#define MESSENGER_STATE_TYPE_END 255
#define SAVED_FRIEND_REQUEST_SIZE 1024
#define NUM_SAVED_PATH_NODES 8
@@ -2794,11 +2790,6 @@ static uint32_t friend_size(void)
return data;
}
-static uint32_t saved_friendslist_size(const Messenger *m)
-{
- return count_friendlist(m) * friend_size();
-}
-
static uint8_t *friend_save(const struct Saved_Friend *temp, uint8_t *data)
{
#define VALUE_MEMBER(name) do { \
@@ -2833,13 +2824,202 @@ static uint8_t *friend_save(const struct Saved_Friend *temp, uint8_t *data)
return data;
}
-static uint32_t friends_list_save(const Messenger *m, uint8_t *data)
+
+static const uint8_t *friend_load(struct Saved_Friend *temp, const uint8_t *data)
{
- uint32_t i;
+#define VALUE_MEMBER(name) do { \
+ memcpy(&temp->name, data, sizeof(temp->name)); \
+ data += sizeof(temp->name); \
+} while (0)
+
+#define ARRAY_MEMBER(name) do { \
+ memcpy(temp->name, data, sizeof(temp->name)); \
+ data += sizeof(temp->name); \
+} while (0)
+
+ // Exactly the same in friend_load, friend_save, and friend_size
+ VALUE_MEMBER(status);
+ ARRAY_MEMBER(real_pk);
+ ARRAY_MEMBER(info);
+ ++data; // padding
+ VALUE_MEMBER(info_size);
+ ARRAY_MEMBER(name);
+ VALUE_MEMBER(name_length);
+ ARRAY_MEMBER(statusmessage);
+ ++data; // padding
+ VALUE_MEMBER(statusmessage_length);
+ VALUE_MEMBER(userstatus);
+ data += 3; // padding
+ VALUE_MEMBER(friendrequest_nospam);
+ VALUE_MEMBER(last_seen_time);
+
+#undef VALUE_MEMBER
+#undef ARRAY_MEMBER
+
+ return data;
+}
+
+
+static uint32_t m_state_plugins_size(const Messenger *m)
+{
+ const uint32_t size32 = sizeof(uint32_t);
+ const uint32_t sizesubhead = size32 * 2;
+
+ uint32_t size = 0;
+
+ for (const Messenger_State_Plugin *plugin = m->options.state_plugins;
+ plugin != m->options.state_plugins + m->options.state_plugins_length;
+ ++plugin) {
+ size += sizesubhead + plugin->size(m);
+ }
+
+ return size;
+}
+
+/*
+ * Registers a state plugin with the messenger
+ * returns true on success
+ * returns false on failure
+ */
+bool m_register_state_plugin(Messenger *m, Messenger_State_Type type, m_state_size_cb size_callback,
+ m_state_load_cb load_callback,
+ m_state_save_cb save_callback)
+{
+ Messenger_State_Plugin *temp = (Messenger_State_Plugin *)realloc(m->options.state_plugins,
+ sizeof(Messenger_State_Plugin) * (m->options.state_plugins_length + 1));
+
+ if (!temp) {
+ return false;
+ }
+
+ m->options.state_plugins = temp;
+ ++m->options.state_plugins_length;
+
+ const uint8_t index = m->options.state_plugins_length - 1;
+ m->options.state_plugins[index].type = type;
+ m->options.state_plugins[index].size = size_callback;
+ m->options.state_plugins[index].load = load_callback;
+ m->options.state_plugins[index].save = save_callback;
+
+ return true;
+}
+
+static uint32_t m_plugin_size(const Messenger *m, Messenger_State_Type type)
+{
+ for (uint8_t i = 0; i < m->options.state_plugins_length; ++i) {
+ const Messenger_State_Plugin plugin = m->options.state_plugins[i];
+
+ if (plugin.type == type) {
+ return plugin.size(m);
+ }
+ }
+
+ LOGGER_ERROR(m->log, "Unknown type encountered: %u", type);
+
+ return UINT32_MAX;
+}
+
+/* return size of the messenger data (for saving) */
+uint32_t messenger_size(const Messenger *m)
+{
+ const uint32_t size32 = sizeof(uint32_t);
+ const uint32_t sizesubhead = size32 * 2;
+ return size32 * 2 // global cookie
+ + m_state_plugins_size(m)
+ + sizesubhead;
+}
+
+/* Save the messenger in data of size Messenger_size(). */
+void messenger_save(const Messenger *m, uint8_t *data)
+{
+ memset(data, 0, messenger_size(m));
+
+ const uint32_t size32 = sizeof(uint32_t);
+
+ // write cookie
+ memset(data, 0, size32);
+ data += size32;
+ host_to_lendian32(data, MESSENGER_STATE_COOKIE_GLOBAL);
+ data += size32;
+
+ for (uint8_t i = 0; i < m->options.state_plugins_length; ++i) {
+ const Messenger_State_Plugin plugin = m->options.state_plugins[i];
+ data = plugin.save(m, data);
+ }
+}
+
+// nospam state plugin
+static uint32_t nospam_keys_size(const Messenger *m)
+{
+ return sizeof(uint32_t) + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SECRET_KEY_SIZE;
+}
+
+static State_Load_Status load_nospam_keys(Messenger *m, const uint8_t *data, uint32_t length)
+{
+ if (length != m_plugin_size(m, MESSENGER_STATE_TYPE_NOSPAMKEYS)) {
+ return STATE_LOAD_STATUS_ERROR;
+ }
+
+ uint32_t nospam;
+ lendian_to_host32(&nospam, data);
+ set_nospam(m->fr, nospam);
+ load_secret_key(m->net_crypto, data + sizeof(uint32_t) + CRYPTO_PUBLIC_KEY_SIZE);
+
+ if (public_key_cmp(data + sizeof(uint32_t), nc_get_self_public_key(m->net_crypto)) != 0) {
+ return STATE_LOAD_STATUS_ERROR;
+ }
+
+ return STATE_LOAD_STATUS_CONTINUE;
+}
+
+static uint8_t *save_nospam_keys(const Messenger *m, uint8_t *data)
+{
+ const uint32_t len = m_plugin_size(m, MESSENGER_STATE_TYPE_NOSPAMKEYS);
+ assert(sizeof(get_nospam(m->fr)) == sizeof(uint32_t));
+ data = state_write_section_header(data, MESSENGER_STATE_COOKIE_TYPE, len, MESSENGER_STATE_TYPE_NOSPAMKEYS);
+ uint32_t nospam = get_nospam(m->fr);
+ host_to_lendian32(data, nospam);
+ save_keys(m->net_crypto, data + sizeof(uint32_t));
+ data += len;
+ return data;
+}
+
+// DHT state plugin
+static uint32_t m_dht_size(const Messenger *m)
+{
+ return dht_size(m->dht);
+}
+
+static uint8_t *save_dht(const Messenger *m, uint8_t *data)
+{
+ const uint32_t len = m_plugin_size(m, MESSENGER_STATE_TYPE_DHT);
+ data = state_write_section_header(data, MESSENGER_STATE_COOKIE_TYPE, len, MESSENGER_STATE_TYPE_DHT);
+ dht_save(m->dht, data);
+ data += len;
+ return data;
+}
+
+static State_Load_Status m_dht_load(Messenger *m, const uint8_t *data, uint32_t length)
+{
+ dht_load(m->dht, data, length); // TODO(endoffile78): Should we throw an error if dht_load fails?
+ return STATE_LOAD_STATUS_CONTINUE;
+}
+
+// friendlist state plugin
+static uint32_t saved_friendslist_size(const Messenger *m)
+{
+ return count_friendlist(m) * friend_size();
+}
+
+static uint8_t *friends_list_save(const Messenger *m, uint8_t *data)
+{
+ const uint32_t len = m_plugin_size(m, MESSENGER_STATE_TYPE_FRIENDS);
+ data = state_write_section_header(data, MESSENGER_STATE_COOKIE_TYPE, len, MESSENGER_STATE_TYPE_FRIENDS);
+
uint32_t num = 0;
uint8_t *cur_data = data;
- for (i = 0; i < m->numfriends; ++i) {
+ for (uint32_t i = 0; i < m->numfriends; ++i) {
if (m->friendlist[i].status > 0) {
struct Saved_Friend temp = { 0 };
temp.status = m->friendlist[i].status;
@@ -2878,47 +3058,15 @@ static uint32_t friends_list_save(const Messenger *m, uint8_t *data)
}
assert(cur_data - data == num * friend_size());
- return cur_data - data;
-}
-
-static const uint8_t *friend_load(struct Saved_Friend *temp, const uint8_t *data)
-{
-#define VALUE_MEMBER(name) do { \
- memcpy(&temp->name, data, sizeof(temp->name)); \
- data += sizeof(temp->name); \
-} while (0)
-
-#define ARRAY_MEMBER(name) do { \
- memcpy(temp->name, data, sizeof(temp->name)); \
- data += sizeof(temp->name); \
-} while (0)
-
- // Exactly the same in friend_load, friend_save, and friend_size
- VALUE_MEMBER(status);
- ARRAY_MEMBER(real_pk);
- ARRAY_MEMBER(info);
- ++data; // padding
- VALUE_MEMBER(info_size);
- ARRAY_MEMBER(name);
- VALUE_MEMBER(name_length);
- ARRAY_MEMBER(statusmessage);
- ++data; // padding
- VALUE_MEMBER(statusmessage_length);
- VALUE_MEMBER(userstatus);
- data += 3; // padding
- VALUE_MEMBER(friendrequest_nospam);
- VALUE_MEMBER(last_seen_time);
-
-#undef VALUE_MEMBER
-#undef ARRAY_MEMBER
+ data += len;
return data;
}
-static int friends_list_load(Messenger *m, const uint8_t *data, uint32_t length)
+static State_Load_Status friends_list_load(Messenger *m, const uint8_t *data, uint32_t length)
{
if (length % friend_size() != 0) {
- return -1;
+ return STATE_LOAD_STATUS_ERROR; // TODO(endoffile78): error or continue?
}
uint32_t num = length / friend_size();
@@ -2959,205 +3107,202 @@ static int friends_list_load(Messenger *m, const uint8_t *data, uint32_t length)
}
}
- return num;
+ return STATE_LOAD_STATUS_CONTINUE;
}
-/* return size of the messenger data (for saving) */
-uint32_t messenger_size(const Messenger *m)
+// name state plugin
+static uint32_t name_size(const Messenger *m)
{
- uint32_t size32 = sizeof(uint32_t), sizesubhead = size32 * 2;
- return size32 * 2 // global cookie
- + sizesubhead + sizeof(uint32_t) + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SECRET_KEY_SIZE
- + sizesubhead + dht_size(m->dht) // DHT
- + sizesubhead + saved_friendslist_size(m) // Friendlist itself.
- + sizesubhead + m->name_length // Own nickname.
- + sizesubhead + m->statusmessage_length // status message
- + sizesubhead + 1 // status
- + sizesubhead + NUM_SAVED_TCP_RELAYS * packed_node_size(net_family_tcp_ipv6) // TCP relays
- + sizesubhead + NUM_SAVED_PATH_NODES * packed_node_size(net_family_tcp_ipv6) // saved path nodes
- + sizesubhead;
+ return m->name_length;
}
-static uint8_t *messenger_save_subheader(uint8_t *data, uint32_t len, uint16_t type)
+static uint8_t *save_name(const Messenger *m, uint8_t *data)
{
- host_to_lendian32(data, len);
- data += sizeof(uint32_t);
- host_to_lendian32(data, (host_tolendian16(MESSENGER_STATE_COOKIE_TYPE) << 16) | host_tolendian16(type));
- data += sizeof(uint32_t);
+ const uint32_t len = m_plugin_size(m, MESSENGER_STATE_TYPE_NAME);
+ data = state_write_section_header(data, MESSENGER_STATE_COOKIE_TYPE, len, MESSENGER_STATE_TYPE_NAME);
+ memcpy(data, m->name, len);
+ data += len;
return data;
}
-/* Save the messenger in data of size Messenger_size(). */
-void messenger_save(const Messenger *m, uint8_t *data)
+static State_Load_Status load_name(Messenger *m, const uint8_t *data, uint32_t length)
{
- memset(data, 0, messenger_size(m));
+ if (length > 0 && length <= MAX_NAME_LENGTH) {
+ setname(m, data, length);
+ }
- uint32_t len;
- uint16_t type;
- uint32_t size32 = sizeof(uint32_t);
+ return STATE_LOAD_STATUS_CONTINUE;
+}
- memset(data, 0, size32);
- data += size32;
- host_to_lendian32(data, MESSENGER_STATE_COOKIE_GLOBAL);
- data += size32;
+// status message state plugin
+static uint32_t status_message_size(const Messenger *m)
+{
+ return m->statusmessage_length;
+}
- assert(sizeof(get_nospam(m->fr)) == sizeof(uint32_t));
- len = size32 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SECRET_KEY_SIZE;
- type = MESSENGER_STATE_TYPE_NOSPAMKEYS;
- data = messenger_save_subheader(data, len, type);
- *(uint32_t *)data = get_nospam(m->fr);
- save_keys(m->net_crypto, data + size32);
+static uint8_t *save_status_message(const Messenger *m, uint8_t *data)
+{
+ const uint32_t len = m_plugin_size(m, MESSENGER_STATE_TYPE_STATUSMESSAGE);
+ data = state_write_section_header(data, MESSENGER_STATE_COOKIE_TYPE, len, MESSENGER_STATE_TYPE_STATUSMESSAGE);
+ memcpy(data, m->statusmessage, len);
data += len;
+ return data;
+}
- len = saved_friendslist_size(m);
- type = MESSENGER_STATE_TYPE_FRIENDS;
- data = messenger_save_subheader(data, len, type);
- friends_list_save(m, data);
- data += len;
+static State_Load_Status load_status_message(Messenger *m, const uint8_t *data, uint32_t length)
+{
+ if (length > 0 && length <= MAX_STATUSMESSAGE_LENGTH) {
+ m_set_statusmessage(m, data, length);
+ }
- len = m->name_length;
- type = MESSENGER_STATE_TYPE_NAME;
- data = messenger_save_subheader(data, len, type);
- memcpy(data, m->name, len);
- data += len;
+ return STATE_LOAD_STATUS_CONTINUE;
+}
- len = m->statusmessage_length;
- type = MESSENGER_STATE_TYPE_STATUSMESSAGE;
- data = messenger_save_subheader(data, len, type);
- memcpy(data, m->statusmessage, len);
- data += len;
+// status state plugin
+static uint32_t status_size(const Messenger *m)
+{
+ return 1;
+}
- len = 1;
- type = MESSENGER_STATE_TYPE_STATUS;
- data = messenger_save_subheader(data, len, type);
+static uint8_t *save_status(const Messenger *m, uint8_t *data)
+{
+ const uint32_t len = m_plugin_size(m, MESSENGER_STATE_TYPE_STATUS);
+ data = state_write_section_header(data, MESSENGER_STATE_COOKIE_TYPE, len, MESSENGER_STATE_TYPE_STATUS);
*data = m->userstatus;
data += len;
+ return data;
+}
- len = dht_size(m->dht);
- type = MESSENGER_STATE_TYPE_DHT;
- data = messenger_save_subheader(data, len, type);
- dht_save(m->dht, data);
- data += len;
+static State_Load_Status load_status(Messenger *m, const uint8_t *data, uint32_t length)
+{
+ if (length == 1) {
+ m_set_userstatus(m, *data);
+ }
+ return STATE_LOAD_STATUS_CONTINUE;
+}
+
+// TCP Relay state plugin
+static uint32_t tcp_relay_size(const Messenger *m)
+{
+ return NUM_SAVED_TCP_RELAYS * packed_node_size(net_family_tcp_ipv6);
+}
+
+static uint8_t *save_tcp_relays(const Messenger *m, uint8_t *data)
+{
Node_format relays[NUM_SAVED_TCP_RELAYS];
- type = MESSENGER_STATE_TYPE_TCP_RELAY;
uint8_t *temp_data = data;
- data = messenger_save_subheader(temp_data, 0, type);
+ data = state_write_section_header(temp_data, MESSENGER_STATE_COOKIE_TYPE, 0, MESSENGER_STATE_TYPE_TCP_RELAY);
unsigned int num = copy_connected_tcp_relays(m->net_crypto, relays, NUM_SAVED_TCP_RELAYS);
int l = pack_nodes(data, NUM_SAVED_TCP_RELAYS * packed_node_size(net_family_tcp_ipv6), relays, num);
if (l > 0) {
- len = l;
- data = messenger_save_subheader(temp_data, len, type);
+ const uint32_t len = l;
+ data = state_write_section_header(temp_data, MESSENGER_STATE_COOKIE_TYPE, len, MESSENGER_STATE_TYPE_TCP_RELAY);
data += len;
}
- Node_format nodes[NUM_SAVED_PATH_NODES];
- type = MESSENGER_STATE_TYPE_PATH_NODE;
- temp_data = data;
- data = messenger_save_subheader(data, 0, type);
- memset(nodes, 0, sizeof(nodes));
- num = onion_backup_nodes(m->onion_c, nodes, NUM_SAVED_PATH_NODES);
- l = pack_nodes(data, NUM_SAVED_PATH_NODES * packed_node_size(net_family_tcp_ipv6), nodes, num);
+ return data;
+}
- if (l > 0) {
- len = l;
- data = messenger_save_subheader(temp_data, len, type);
- data += len;
+static State_Load_Status load_tcp_relays(Messenger *m, const uint8_t *data, uint32_t length)
+{
+ if (length != 0) {
+ unpack_nodes(m->loaded_relays, NUM_SAVED_TCP_RELAYS, nullptr, data, length, 1);
+ m->has_added_relays = false;
}
- messenger_save_subheader(data, 0, MESSENGER_STATE_TYPE_END);
+ return STATE_LOAD_STATUS_CONTINUE;
}
-static State_Load_Status messenger_load_state_callback(void *outer, const uint8_t *data, uint32_t length, uint16_t type)
+// path node state plugin
+static uint32_t path_node_size(const Messenger *m)
{
- Messenger *m = (Messenger *)outer;
-
- switch (type) {
- case MESSENGER_STATE_TYPE_NOSPAMKEYS:
- if (length == CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SECRET_KEY_SIZE + sizeof(uint32_t)) {
- set_nospam(m->fr, *(const uint32_t *)data);
- load_secret_key(m->net_crypto, (&data[sizeof(uint32_t)]) + CRYPTO_PUBLIC_KEY_SIZE);
-
- if (public_key_cmp((&data[sizeof(uint32_t)]), nc_get_self_public_key(m->net_crypto)) != 0) {
- return STATE_LOAD_STATUS_ERROR;
- }
- } else {
- return STATE_LOAD_STATUS_ERROR; /* critical */
- }
-
- break;
-
- case MESSENGER_STATE_TYPE_DHT:
- dht_load(m->dht, data, length);
- break;
-
- case MESSENGER_STATE_TYPE_FRIENDS:
- friends_list_load(m, data, length);
- break;
-
- case MESSENGER_STATE_TYPE_NAME:
- if ((length > 0) && (length <= MAX_NAME_LENGTH)) {
- setname(m, data, length);
- }
+ return NUM_SAVED_PATH_NODES * packed_node_size(net_family_tcp_ipv6);
+}
- break;
+static uint8_t *save_path_nodes(const Messenger *m, uint8_t *data)
+{
+ Node_format nodes[NUM_SAVED_PATH_NODES];
+ uint8_t *temp_data = data;
+ data = state_write_section_header(data, MESSENGER_STATE_COOKIE_TYPE, 0, MESSENGER_STATE_TYPE_PATH_NODE);
+ memset(nodes, 0, sizeof(nodes));
+ const unsigned int num = onion_backup_nodes(m->onion_c, nodes, NUM_SAVED_PATH_NODES);
+ const int l = pack_nodes(data, NUM_SAVED_PATH_NODES * packed_node_size(net_family_tcp_ipv6), nodes, num);
- case MESSENGER_STATE_TYPE_STATUSMESSAGE:
- if ((length > 0) && (length <= MAX_STATUSMESSAGE_LENGTH)) {
- m_set_statusmessage(m, data, length);
- }
+ if (l > 0) {
+ const uint32_t len = l;
+ data = state_write_section_header(temp_data, MESSENGER_STATE_COOKIE_TYPE, len, MESSENGER_STATE_TYPE_PATH_NODE);
+ data += len;
+ }
- break;
+ return data;
+}
- case MESSENGER_STATE_TYPE_STATUS:
- if (length == 1) {
- m_set_userstatus(m, *data);
- }
+static State_Load_Status load_path_nodes(Messenger *m, const uint8_t *data, uint32_t length)
+{
+ Node_format nodes[NUM_SAVED_PATH_NODES];
- break;
+ if (length != 0) {
+ const int num = unpack_nodes(nodes, NUM_SAVED_PATH_NODES, nullptr, data, length, 0);
- case MESSENGER_STATE_TYPE_TCP_RELAY: {
- if (length == 0) {
- break;
- }
+ for (int i = 0; i < num; ++i) {
+ onion_add_bs_path_node(m->onion_c, nodes[i].ip_port, nodes[i].public_key);
+ }
+ }
- unpack_nodes(m->loaded_relays, NUM_SAVED_TCP_RELAYS, nullptr, data, length, 1);
- m->has_added_relays = 0;
+ return STATE_LOAD_STATUS_CONTINUE;
+}
- break;
- }
+// end state plugin
+static uint32_t end_size(const Messenger *m)
+{
+ return 0;
+}
- case MESSENGER_STATE_TYPE_PATH_NODE: {
- Node_format nodes[NUM_SAVED_PATH_NODES];
+static uint8_t *save_end(const Messenger *m, uint8_t *data)
+{
+ return state_write_section_header(data, MESSENGER_STATE_COOKIE_TYPE, 0, MESSENGER_STATE_TYPE_END);
+}
- if (length == 0) {
- break;
- }
+static State_Load_Status load_end(Messenger *m, const uint8_t *data, uint32_t length)
+{
+ if (length != 0) {
+ return STATE_LOAD_STATUS_ERROR;
+ }
- int i, num = unpack_nodes(nodes, NUM_SAVED_PATH_NODES, nullptr, data, length, 0);
+ return STATE_LOAD_STATUS_END;
+}
- for (i = 0; i < num; ++i) {
- onion_add_bs_path_node(m->onion_c, nodes[i].ip_port, nodes[i].public_key);
- }
+static void m_register_default_plugins(Messenger *m)
+{
+ m_register_state_plugin(m, MESSENGER_STATE_TYPE_NOSPAMKEYS, nospam_keys_size, load_nospam_keys, save_nospam_keys);
+ m_register_state_plugin(m, MESSENGER_STATE_TYPE_DHT, m_dht_size, m_dht_load, save_dht);
+ m_register_state_plugin(m, MESSENGER_STATE_TYPE_FRIENDS, saved_friendslist_size, friends_list_load, friends_list_save);
+ m_register_state_plugin(m, MESSENGER_STATE_TYPE_NAME, name_size, load_name, save_name);
+ m_register_state_plugin(m, MESSENGER_STATE_TYPE_STATUSMESSAGE, status_message_size, load_status_message,
+ save_status_message);
+ m_register_state_plugin(m, MESSENGER_STATE_TYPE_STATUS, status_size, load_status, save_status);
+ m_register_state_plugin(m, MESSENGER_STATE_TYPE_TCP_RELAY, tcp_relay_size, load_tcp_relays, save_tcp_relays);
+ m_register_state_plugin(m, MESSENGER_STATE_TYPE_PATH_NODE, path_node_size, load_path_nodes, save_path_nodes);
+ m_register_state_plugin(m, MESSENGER_STATE_TYPE_END, end_size, load_end, save_end);
+}
- break;
- }
+static State_Load_Status messenger_load_state_callback(void *outer, const uint8_t *data, uint32_t length, uint16_t type)
+{
+ Messenger *m = (Messenger *)outer;
- case MESSENGER_STATE_TYPE_END: {
- if (length != 0) {
- return STATE_LOAD_STATUS_ERROR;
- }
+ for (uint8_t i = 0; i < m->options.state_plugins_length; ++i) {
+ const Messenger_State_Plugin *const plugin = &m->options.state_plugins[i];
- return STATE_LOAD_STATUS_END;
+ if (plugin->type == type) {
+ return plugin->load(m, data, length);
}
-
- default:
- LOGGER_ERROR(m->log, "Load state: contains unrecognized part (len %u, type %u)\n",
- length, type);
- break;
}
+ LOGGER_ERROR(m->log, "Load state: contains unrecognized part (len %u, type %u)\n",
+ length, type);
+
return STATE_LOAD_STATUS_CONTINUE;
}
diff --git a/protocols/Tox/libtox/src/toxcore/Messenger.h b/protocols/Tox/libtox/src/toxcore/Messenger.h
index 6fc4df024c..ab9d72568e 100644
--- a/protocols/Tox/libtox/src/toxcore/Messenger.h
+++ b/protocols/Tox/libtox/src/toxcore/Messenger.h
@@ -4,7 +4,7 @@
*/
/*
- * Copyright © 2016-2017 The TokTok team.
+ * Copyright © 2016-2018 The TokTok team.
* Copyright © 2013 Tox project.
*
* This file is part of Tox, the free peer to peer instant messenger.
@@ -22,13 +22,14 @@
* You should have received a copy of the GNU General Public License
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef MESSENGER_H
-#define MESSENGER_H
+#ifndef C_TOXCORE_TOXCORE_MESSENGER_H
+#define C_TOXCORE_TOXCORE_MESSENGER_H
#include "friend_connection.h"
#include "friend_requests.h"
#include "logger.h"
#include "net_crypto.h"
+#include "state.h"
#define MAX_NAME_LENGTH 128
/* TODO(irungentoo): this must depend on other variable. */
@@ -50,6 +51,36 @@ typedef enum Message_Type {
MESSAGE_ACTION
} Message_Type;
+typedef struct Messenger Messenger;
+
+// Returns the size of the data
+typedef uint32_t m_state_size_cb(const Messenger *m);
+
+// Returns the new pointer to data
+typedef uint8_t *m_state_save_cb(const Messenger *m, uint8_t *data);
+
+// Returns if there were any erros during loading
+typedef State_Load_Status m_state_load_cb(Messenger *m, const uint8_t *data, uint32_t length);
+
+typedef enum Messenger_State_Type {
+ MESSENGER_STATE_TYPE_NOSPAMKEYS = 1,
+ MESSENGER_STATE_TYPE_DHT = 2,
+ MESSENGER_STATE_TYPE_FRIENDS = 3,
+ MESSENGER_STATE_TYPE_NAME = 4,
+ MESSENGER_STATE_TYPE_STATUSMESSAGE = 5,
+ MESSENGER_STATE_TYPE_STATUS = 6,
+ MESSENGER_STATE_TYPE_TCP_RELAY = 10,
+ MESSENGER_STATE_TYPE_PATH_NODE = 11,
+ MESSENGER_STATE_TYPE_END = 255,
+} Messenger_State_Type;
+
+typedef struct Messenger_State_Plugin {
+ Messenger_State_Type type;
+ m_state_size_cb *size;
+ m_state_save_cb *save;
+ m_state_load_cb *load;
+} Messenger_State_Plugin;
+
typedef struct Messenger_Options {
bool ipv6enabled;
bool udp_disabled;
@@ -63,6 +94,9 @@ typedef struct Messenger_Options {
logger_cb *log_callback;
void *log_context;
void *log_user_data;
+
+ Messenger_State_Plugin *state_plugins;
+ uint8_t state_plugins_length;
} Messenger_Options;
@@ -156,8 +190,6 @@ typedef enum Filekind {
} Filekind;
-typedef struct Messenger Messenger;
-
typedef void m_self_connection_status_cb(Messenger *m, unsigned int connection_status, void *user_data);
typedef void m_friend_status_cb(Messenger *m, uint32_t friend_number, unsigned int status, void *user_data);
typedef void m_friend_connection_status_cb(Messenger *m, uint32_t friend_number, unsigned int connection_status,
@@ -233,6 +265,7 @@ typedef struct Friend {
struct Messenger {
Logger *log;
+ Mono_Time *mono_time;
Networking_Core *net;
Net_Crypto *net_crypto;
@@ -259,7 +292,7 @@ struct Messenger {
time_t lastdump;
- uint8_t has_added_relays; // If the first connection has occurred in do_messenger
+ bool has_added_relays; // If the first connection has occurred in do_messenger
Node_format loaded_relays[NUM_SAVED_TCP_RELAYS]; // Relays loaded from config
m_friend_message_cb *friend_message;
@@ -738,7 +771,7 @@ typedef enum Messenger_Error {
*
* if error is not NULL it will be set to one of the values in the enum above.
*/
-Messenger *new_messenger(Messenger_Options *options, unsigned int *error);
+Messenger *new_messenger(Mono_Time *mono_time, Messenger_Options *options, unsigned int *error);
/* Run this before closing shop
* Free all datastructures.
@@ -757,6 +790,14 @@ 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
+ *
+ * returns true on success
+ * returns false on error
+ */
+bool m_register_state_plugin(Messenger *m, Messenger_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). */
uint32_t messenger_size(const Messenger *m);
diff --git a/protocols/Tox/libtox/src/toxcore/TCP_client.c b/protocols/Tox/libtox/src/toxcore/TCP_client.c
index 381d9b801a..6eae84086a 100644
--- a/protocols/Tox/libtox/src/toxcore/TCP_client.c
+++ b/protocols/Tox/libtox/src/toxcore/TCP_client.c
@@ -3,7 +3,7 @@
*/
/*
- * Copyright © 2016-2017 The TokTok team.
+ * Copyright © 2016-2018 The TokTok team.
* Copyright © 2014 Tox project.
*
* This file is part of Tox, the free peer to peer instant messenger.
@@ -419,17 +419,6 @@ static bool client_add_priority(TCP_Client_Connection *con, const uint8_t *packe
return 1;
}
-static void wipe_priority_list(TCP_Client_Connection *con)
-{
- TCP_Priority_List *p = con->priority_queue_start;
-
- while (p) {
- TCP_Priority_List *pp = p;
- p = p->next;
- free(pp);
- }
-}
-
/* return 1 on success.
* return 0 if could not send packet.
* return -1 on failure (connection must be killed).
@@ -688,8 +677,8 @@ void onion_response_handler(TCP_Client_Connection *con, tcp_onion_response_cb *o
/* Create new TCP connection to ip_port/public_key
*/
-TCP_Client_Connection *new_TCP_connection(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 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)
{
if (networking_at_startup() != 0) {
return nullptr;
@@ -765,7 +754,7 @@ TCP_Client_Connection *new_TCP_connection(IP_Port ip_port, const uint8_t *public
break;
}
- temp->kill_at = unix_time() + TCP_CONNECTION_TIMEOUT;
+ temp->kill_at = mono_time_get(mono_time) + TCP_CONNECTION_TIMEOUT;
return temp;
}
@@ -949,13 +938,13 @@ static bool tcp_process_packet(TCP_Client_Connection *conn, void *userdata)
return true;
}
-static int do_confirmed_TCP(TCP_Client_Connection *conn, void *userdata)
+static int do_confirmed_TCP(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);
- if (is_timeout(conn->last_pinged, TCP_PING_FREQUENCY)) {
+ if (mono_time_is_timeout(mono_time, conn->last_pinged, TCP_PING_FREQUENCY)) {
uint64_t ping_id = random_u64();
if (!ping_id) {
@@ -965,10 +954,10 @@ static int do_confirmed_TCP(TCP_Client_Connection *conn, void *userdata)
conn->ping_request_id = ping_id;
conn->ping_id = ping_id;
tcp_send_ping_request(conn);
- conn->last_pinged = unix_time();
+ conn->last_pinged = mono_time_get(mono_time);
}
- if (conn->ping_id && is_timeout(conn->last_pinged, TCP_PING_TIMEOUT)) {
+ if (conn->ping_id && mono_time_is_timeout(mono_time, conn->last_pinged, TCP_PING_TIMEOUT)) {
conn->status = TCP_CLIENT_DISCONNECTED;
return 0;
}
@@ -983,10 +972,8 @@ static int do_confirmed_TCP(TCP_Client_Connection *conn, void *userdata)
/* Run the TCP connection
*/
-void do_TCP_connection(TCP_Client_Connection *tcp_connection, void *userdata)
+void do_TCP_connection(Mono_Time *mono_time, TCP_Client_Connection *tcp_connection, void *userdata)
{
- unix_time_update();
-
if (tcp_connection->status == TCP_CLIENT_DISCONNECTED) {
return;
}
@@ -1061,10 +1048,10 @@ void do_TCP_connection(TCP_Client_Connection *tcp_connection, void *userdata)
}
if (tcp_connection->status == TCP_CLIENT_CONFIRMED) {
- do_confirmed_TCP(tcp_connection, userdata);
+ do_confirmed_TCP(tcp_connection, mono_time, userdata);
}
- if (tcp_connection->kill_at <= unix_time()) {
+ if (tcp_connection->kill_at <= mono_time_get(mono_time)) {
tcp_connection->status = TCP_CLIENT_DISCONNECTED;
}
}
@@ -1077,7 +1064,7 @@ void kill_TCP_connection(TCP_Client_Connection *tcp_connection)
return;
}
- wipe_priority_list(tcp_connection);
+ wipe_priority_list(tcp_connection->priority_queue_start);
kill_sock(tcp_connection->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 6d1cbb3bd3..9d43d642b3 100644
--- a/protocols/Tox/libtox/src/toxcore/TCP_client.h
+++ b/protocols/Tox/libtox/src/toxcore/TCP_client.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright © 2016-2017 The TokTok team.
+ * Copyright © 2016-2018 The TokTok team.
* Copyright © 2014 Tox project.
*
* This file is part of Tox, the free peer to peer instant messenger.
@@ -21,8 +21,8 @@
* You should have received a copy of the GNU General Public License
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef TCP_CLIENT_H
-#define TCP_CLIENT_H
+#ifndef C_TOXCORE_TOXCORE_TCP_CLIENT_H
+#define C_TOXCORE_TOXCORE_TCP_CLIENT_H
#include "TCP_server.h"
#include "crypto_core.h"
@@ -64,12 +64,12 @@ void tcp_con_set_custom_uint(TCP_Client_Connection *con, uint32_t value);
/* Create new TCP connection to ip_port/public_key
*/
-TCP_Client_Connection *new_TCP_connection(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 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);
/* Run the TCP connection
*/
-void do_TCP_connection(TCP_Client_Connection *tcp_connection, void *userdata);
+void do_TCP_connection(Mono_Time *mono_time, TCP_Client_Connection *tcp_connection, void *userdata);
/* Kill the TCP connection
*/
diff --git a/protocols/Tox/libtox/src/toxcore/TCP_connection.c b/protocols/Tox/libtox/src/toxcore/TCP_connection.c
index 6763328da4..b11b1e3b08 100644
--- a/protocols/Tox/libtox/src/toxcore/TCP_connection.c
+++ b/protocols/Tox/libtox/src/toxcore/TCP_connection.c
@@ -3,7 +3,7 @@
*/
/*
- * Copyright © 2016-2017 The TokTok team.
+ * Copyright © 2016-2018 The TokTok team.
* Copyright © 2015 Tox project.
*
* This file is part of Tox, the free peer to peer instant messenger.
@@ -36,6 +36,7 @@
struct TCP_Connections {
+ Mono_Time *mono_time;
DHT *dht;
uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE];
@@ -794,8 +795,8 @@ 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(ip_port, relay_pk, tcp_c->self_public_key, tcp_c->self_secret_key,
- &tcp_c->proxy_info);
+ tcp_con->connection = new_TCP_connection(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) {
kill_tcp_relay_connection(tcp_c, tcp_connections_number);
@@ -884,7 +885,7 @@ static int unsleep_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connecti
return -1;
}
- tcp_con->connection = new_TCP_connection(tcp_con->ip_port, tcp_con->relay_pk, tcp_c->self_public_key,
+ 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);
if (!tcp_con->connection) {
@@ -1122,7 +1123,7 @@ static int tcp_relay_on_online(TCP_Connections *tcp_c, int tcp_connections_numbe
/* If this connection isn't used by any connection, we don't need to wait for them to come online. */
if (sent) {
- tcp_con->connected_time = unix_time();
+ tcp_con->connected_time = mono_time_get(tcp_c->mono_time);
} else {
tcp_con->connected_time = 0;
}
@@ -1155,8 +1156,8 @@ 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(ip_port, relay_pk, tcp_c->self_public_key, tcp_c->self_secret_key,
- &tcp_c->proxy_info);
+ tcp_con->connection = new_TCP_connection(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) {
return -1;
@@ -1216,7 +1217,7 @@ int add_tcp_number_relay_connection(TCP_Connections *tcp_c, int connections_numb
if (tcp_con->status == TCP_CONN_CONNECTED) {
if (send_tcp_relay_routing_request(tcp_c, tcp_connections_number, con_to->public_key) == 0) {
- tcp_con->connected_time = unix_time();
+ tcp_con->connected_time = mono_time_get(tcp_c->mono_time);
}
}
@@ -1391,7 +1392,7 @@ int set_tcp_onion_status(TCP_Connections *tcp_c, bool status)
*
* Returns NULL on failure.
*/
-TCP_Connections *new_tcp_connections(const uint8_t *secret_key, TCP_Proxy_Info *proxy_info)
+TCP_Connections *new_tcp_connections(Mono_Time *mono_time, const uint8_t *secret_key, TCP_Proxy_Info *proxy_info)
{
if (secret_key == nullptr) {
return nullptr;
@@ -1403,6 +1404,8 @@ TCP_Connections *new_tcp_connections(const uint8_t *secret_key, TCP_Proxy_Info *
return nullptr;
}
+ temp->mono_time = mono_time;
+
memcpy(temp->self_secret_key, secret_key, CRYPTO_SECRET_KEY_SIZE);
crypto_derive_public_key(temp->self_public_key, temp->self_secret_key);
temp->proxy_info = *proxy_info;
@@ -1419,7 +1422,7 @@ static void do_tcp_conns(TCP_Connections *tcp_c, void *userdata)
if (tcp_con) {
if (tcp_con->status != TCP_CONN_SLEEPING) {
- do_TCP_connection(tcp_con->connection, userdata);
+ do_TCP_connection(tcp_c->mono_time, tcp_con->connection, userdata);
/* callbacks can change TCP connection address. */
tcp_con = get_tcp_connection(tcp_c, i);
@@ -1443,7 +1446,7 @@ static void do_tcp_conns(TCP_Connections *tcp_c, void *userdata)
if (tcp_con->status == TCP_CONN_CONNECTED && !tcp_con->onion && tcp_con->lock_count
&& tcp_con->lock_count == tcp_con->sleep_count
- && is_timeout(tcp_con->connected_time, TCP_CONNECTION_ANNOUNCE_TIMEOUT)) {
+ && mono_time_is_timeout(tcp_c->mono_time, tcp_con->connected_time, TCP_CONNECTION_ANNOUNCE_TIMEOUT)) {
sleep_tcp_relay_connection(tcp_c, i);
}
}
@@ -1471,7 +1474,8 @@ static void kill_nonused_tcp(TCP_Connections *tcp_c)
if (tcp_con) {
if (tcp_con->status == TCP_CONN_CONNECTED) {
- if (!tcp_con->onion && !tcp_con->lock_count && is_timeout(tcp_con->connected_time, TCP_CONNECTION_ANNOUNCE_TIMEOUT)) {
+ 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;
}
diff --git a/protocols/Tox/libtox/src/toxcore/TCP_connection.h b/protocols/Tox/libtox/src/toxcore/TCP_connection.h
index 2d99e12288..1962fb1aca 100644
--- a/protocols/Tox/libtox/src/toxcore/TCP_connection.h
+++ b/protocols/Tox/libtox/src/toxcore/TCP_connection.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright © 2016-2017 The TokTok team.
+ * Copyright © 2016-2018 The TokTok team.
* Copyright © 2015 Tox project.
*
* This file is part of Tox, the free peer to peer instant messenger.
@@ -21,8 +21,8 @@
* You should have received a copy of the GNU General Public License
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef TCP_CONNECTION_H
-#define TCP_CONNECTION_H
+#ifndef C_TOXCORE_TOXCORE_TCP_CONNECTION_H
+#define C_TOXCORE_TOXCORE_TCP_CONNECTION_H
#include "TCP_client.h"
@@ -219,7 +219,7 @@ uint32_t tcp_copy_connected_relays(TCP_Connections *tcp_c, Node_format *tcp_rela
*
* Returns NULL on failure.
*/
-TCP_Connections *new_tcp_connections(const uint8_t *secret_key, TCP_Proxy_Info *proxy_info);
+TCP_Connections *new_tcp_connections(Mono_Time *mono_time, const uint8_t *secret_key, TCP_Proxy_Info *proxy_info);
void do_tcp_connections(TCP_Connections *tcp_c, void *userdata);
void kill_tcp_connections(TCP_Connections *tcp_c);
diff --git a/protocols/Tox/libtox/src/toxcore/TCP_server.c b/protocols/Tox/libtox/src/toxcore/TCP_server.c
index cc59d08824..23b9594015 100644
--- a/protocols/Tox/libtox/src/toxcore/TCP_server.c
+++ b/protocols/Tox/libtox/src/toxcore/TCP_server.c
@@ -3,7 +3,7 @@
*/
/*
- * Copyright © 2016-2017 The TokTok team.
+ * Copyright © 2016-2018 The TokTok team.
* Copyright © 2014 Tox project.
*
* This file is part of Tox, the free peer to peer instant messenger.
@@ -124,43 +124,74 @@ size_t tcp_server_listen_count(const TCP_Server *tcp_server)
#endif
#endif
-/* Set the size of the connection list to numfriends.
+/* Increase the size of the connection list
*
- * return -1 if realloc fails.
- * return 0 if it succeeds.
+ * return -1 on failure
+ * return 0 on success.
*/
-static int realloc_connection(TCP_Server *tcp_server, uint32_t num)
+static int alloc_new_connections(TCP_Server *tcp_server, uint32_t num)
{
- if (num == 0) {
- free(tcp_server->accepted_connection_array);
- tcp_server->accepted_connection_array = nullptr;
- tcp_server->size_accepted_connections = 0;
- return 0;
- }
+ const uint32_t new_size = tcp_server->size_accepted_connections + num;
- if (num == tcp_server->size_accepted_connections) {
- return 0;
+ if (new_size < tcp_server->size_accepted_connections) {
+ return -1;
}
TCP_Secure_Connection *new_connections = (TCP_Secure_Connection *)realloc(
tcp_server->accepted_connection_array,
- num * sizeof(TCP_Secure_Connection));
+ new_size * sizeof(TCP_Secure_Connection));
if (new_connections == nullptr) {
return -1;
}
- if (num > tcp_server->size_accepted_connections) {
- uint32_t old_size = tcp_server->size_accepted_connections;
- uint32_t size_new_entries = (num - old_size) * sizeof(TCP_Secure_Connection);
- memset(new_connections + old_size, 0, size_new_entries);
- }
+ const uint32_t old_size = tcp_server->size_accepted_connections;
+ const uint32_t size_new_entries = num * sizeof(TCP_Secure_Connection);
+ memset(new_connections + old_size, 0, size_new_entries);
tcp_server->accepted_connection_array = new_connections;
- tcp_server->size_accepted_connections = num;
+ tcp_server->size_accepted_connections = new_size;
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);
+ 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));
+ crypto_memzero(con_old, sizeof(TCP_Secure_Connection));
+}
+
+static void free_accepted_connection_array(TCP_Server *tcp_server)
+{
+ if (tcp_server->accepted_connection_array == nullptr) {
+ return;
+ }
+
+ for (uint32_t i = 0; i < tcp_server->size_accepted_connections; ++i) {
+ wipe_secure_connection(&tcp_server->accepted_connection_array[i]);
+ }
+
+ free(tcp_server->accepted_connection_array);
+ tcp_server->accepted_connection_array = nullptr;
+ tcp_server->size_accepted_connections = 0;
+}
+
/* return index corresponding to connection with peer on success
* return -1 on failure.
*/
@@ -177,7 +208,7 @@ static int kill_accepted(TCP_Server *tcp_server, int index);
* return index on success
* return -1 on failure
*/
-static int add_accepted(TCP_Server *tcp_server, const TCP_Secure_Connection *con)
+static int add_accepted(TCP_Server *tcp_server, const Mono_Time *mono_time, TCP_Secure_Connection *con)
{
int index = get_TCP_connection_index(tcp_server, con->public_key);
@@ -187,7 +218,7 @@ static int add_accepted(TCP_Server *tcp_server, const TCP_Secure_Connection *con
}
if (tcp_server->size_accepted_connections == tcp_server->num_accepted_connections) {
- if (realloc_connection(tcp_server, tcp_server->size_accepted_connections + 4) == -1) {
+ if (alloc_new_connections(tcp_server, 4) == -1) {
return -1;
}
@@ -212,11 +243,12 @@ static int add_accepted(TCP_Server *tcp_server, const TCP_Secure_Connection *con
return -1;
}
- memcpy(&tcp_server->accepted_connection_array[index], con, sizeof(TCP_Secure_Connection));
+ move_secure_connection(&tcp_server->accepted_connection_array[index], con);
+
tcp_server->accepted_connection_array[index].status = TCP_STATUS_CONFIRMED;
++tcp_server->num_accepted_connections;
tcp_server->accepted_connection_array[index].identifier = ++tcp_server->counter;
- tcp_server->accepted_connection_array[index].last_pinged = unix_time();
+ tcp_server->accepted_connection_array[index].last_pinged = mono_time_get(mono_time);
tcp_server->accepted_connection_array[index].ping_id = 0;
return index;
@@ -241,11 +273,11 @@ static int del_accepted(TCP_Server *tcp_server, int index)
return -1;
}
- crypto_memzero(&tcp_server->accepted_connection_array[index], sizeof(TCP_Secure_Connection));
+ wipe_secure_connection(&tcp_server->accepted_connection_array[index]);
--tcp_server->num_accepted_connections;
if (tcp_server->num_accepted_connections == 0) {
- realloc_connection(tcp_server, 0);
+ free_accepted_connection_array(tcp_server);
}
return 0;
@@ -513,7 +545,7 @@ static int write_packet_TCP_secure_connection(TCP_Secure_Connection *con, const
static void kill_TCP_secure_connection(TCP_Secure_Connection *con)
{
kill_sock(con->sock);
- crypto_memzero(con, sizeof(TCP_Secure_Connection));
+ wipe_secure_connection(con);
}
static int rm_connection_index(TCP_Server *tcp_server, TCP_Secure_Connection *con, uint8_t con_number);
@@ -954,17 +986,18 @@ static int handle_TCP_packet(TCP_Server *tcp_server, uint32_t con_id, const uint
}
-static int confirm_TCP_connection(TCP_Server *tcp_server, TCP_Secure_Connection *con, const uint8_t *data,
+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)
{
- int index = add_accepted(tcp_server, con);
+ int index = add_accepted(tcp_server, mono_time, con);
if (index == -1) {
kill_TCP_secure_connection(con);
return -1;
}
- crypto_memzero(con, sizeof(TCP_Secure_Connection));
+ wipe_secure_connection(con);
if (handle_TCP_packet(tcp_server, index, data, length) == -1) {
kill_accepted(tcp_server, index);
@@ -1151,8 +1184,7 @@ static int do_incoming(TCP_Server *tcp_server, uint32_t i)
kill_TCP_secure_connection(conn_new);
}
- memcpy(conn_new, conn_old, sizeof(TCP_Secure_Connection));
- crypto_memzero(conn_old, sizeof(TCP_Secure_Connection));
+ move_secure_connection(conn_new, conn_old);
++tcp_server->unconfirmed_connection_queue_index;
return index_new;
@@ -1161,7 +1193,7 @@ static int do_incoming(TCP_Server *tcp_server, uint32_t i)
return -1;
}
-static int do_unconfirmed(TCP_Server *tcp_server, uint32_t i)
+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];
@@ -1182,7 +1214,7 @@ static int do_unconfirmed(TCP_Server *tcp_server, uint32_t i)
return -1;
}
- return confirm_TCP_connection(tcp_server, conn, packet, len);
+ return confirm_TCP_connection(tcp_server, mono_time, conn, packet, len);
}
static bool tcp_process_secure_packet(TCP_Server *tcp_server, uint32_t i)
@@ -1221,32 +1253,28 @@ static void do_confirmed_recv(TCP_Server *tcp_server, uint32_t i)
#ifndef TCP_SERVER_USE_EPOLL
static void do_TCP_incoming(TCP_Server *tcp_server)
{
- uint32_t i;
-
- for (i = 0; i < MAX_INCOMING_CONNECTIONS; ++i) {
+ for (uint32_t i = 0; i < MAX_INCOMING_CONNECTIONS; ++i) {
do_incoming(tcp_server, i);
}
}
-static void do_TCP_unconfirmed(TCP_Server *tcp_server)
+static void do_TCP_unconfirmed(TCP_Server *tcp_server, const Mono_Time *mono_time)
{
- uint32_t i;
-
- for (i = 0; i < MAX_INCOMING_CONNECTIONS; ++i) {
- do_unconfirmed(tcp_server, i);
+ for (uint32_t i = 0; i < MAX_INCOMING_CONNECTIONS; ++i) {
+ do_unconfirmed(tcp_server, mono_time, i);
}
}
#endif
-static void do_TCP_confirmed(TCP_Server *tcp_server)
+static void do_TCP_confirmed(TCP_Server *tcp_server, const Mono_Time *mono_time)
{
#ifdef TCP_SERVER_USE_EPOLL
- if (tcp_server->last_run_pinged == unix_time()) {
+ if (tcp_server->last_run_pinged == mono_time_get(mono_time)) {
return;
}
- tcp_server->last_run_pinged = unix_time();
+ tcp_server->last_run_pinged = mono_time_get(mono_time);
#endif
uint32_t i;
@@ -1257,7 +1285,7 @@ static void do_TCP_confirmed(TCP_Server *tcp_server)
continue;
}
- if (is_timeout(conn->last_pinged, TCP_PING_FREQUENCY)) {
+ if (mono_time_is_timeout(mono_time, conn->last_pinged, TCP_PING_FREQUENCY)) {
uint8_t ping[1 + sizeof(uint64_t)];
ping[0] = TCP_PACKET_PING;
uint64_t ping_id = random_u64();
@@ -1270,17 +1298,17 @@ static void do_TCP_confirmed(TCP_Server *tcp_server)
int ret = write_packet_TCP_secure_connection(conn, ping, sizeof(ping), 1);
if (ret == 1) {
- conn->last_pinged = unix_time();
+ conn->last_pinged = mono_time_get(mono_time);
conn->ping_id = ping_id;
} else {
- if (is_timeout(conn->last_pinged, TCP_PING_FREQUENCY + TCP_PING_TIMEOUT)) {
+ if (mono_time_is_timeout(mono_time, conn->last_pinged, TCP_PING_FREQUENCY + TCP_PING_TIMEOUT)) {
kill_accepted(tcp_server, i);
continue;
}
}
}
- if (conn->ping_id && is_timeout(conn->last_pinged, TCP_PING_TIMEOUT)) {
+ if (conn->ping_id && mono_time_is_timeout(mono_time, conn->last_pinged, TCP_PING_TIMEOUT)) {
kill_accepted(tcp_server, i);
continue;
}
@@ -1296,7 +1324,7 @@ static void do_TCP_confirmed(TCP_Server *tcp_server)
}
#ifdef TCP_SERVER_USE_EPOLL
-static bool tcp_epoll_process(TCP_Server *tcp_server)
+static bool tcp_epoll_process(TCP_Server *tcp_server, const Mono_Time *mono_time)
{
#define MAX_EVENTS 16
struct epoll_event events[MAX_EVENTS];
@@ -1387,7 +1415,7 @@ static bool tcp_epoll_process(TCP_Server *tcp_server)
}
case TCP_SOCKET_UNCONFIRMED: {
- const int index_new = do_unconfirmed(tcp_server, index);
+ const int index_new = do_unconfirmed(tcp_server, mono_time, index);
if (index_new != -1) {
events[n].events = EPOLLIN | EPOLLET | EPOLLRDHUP;
@@ -1413,36 +1441,32 @@ static bool tcp_epoll_process(TCP_Server *tcp_server)
return nfds > 0;
}
-static void do_TCP_epoll(TCP_Server *tcp_server)
+static void do_TCP_epoll(TCP_Server *tcp_server, const Mono_Time *mono_time)
{
- while (tcp_epoll_process(tcp_server)) {
+ while (tcp_epoll_process(tcp_server, mono_time)) {
// Keep processing packets until there are no more FDs ready for reading.
continue;
}
}
#endif
-void do_TCP_server(TCP_Server *tcp_server)
+void do_TCP_server(TCP_Server *tcp_server, Mono_Time *mono_time)
{
- unix_time_update();
-
#ifdef TCP_SERVER_USE_EPOLL
- do_TCP_epoll(tcp_server);
+ do_TCP_epoll(tcp_server, mono_time);
#else
do_TCP_accept_new(tcp_server);
do_TCP_incoming(tcp_server);
- do_TCP_unconfirmed(tcp_server);
+ do_TCP_unconfirmed(tcp_server, mono_time);
#endif
- do_TCP_confirmed(tcp_server);
+ do_TCP_confirmed(tcp_server, mono_time);
}
void kill_TCP_server(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) {
kill_sock(tcp_server->socks_listening[i]);
}
@@ -1456,7 +1480,13 @@ void kill_TCP_server(TCP_Server *tcp_server)
close(tcp_server->efd);
#endif
+ for (uint32_t i = 0; i < MAX_INCOMING_CONNECTIONS; ++i) {
+ wipe_secure_connection(&tcp_server->incoming_connection_queue[i]);
+ wipe_secure_connection(&tcp_server->unconfirmed_connection_queue[i]);
+ }
+
+ free_accepted_connection_array(tcp_server);
+
free(tcp_server->socks_listening);
- free(tcp_server->accepted_connection_array);
free(tcp_server);
}
diff --git a/protocols/Tox/libtox/src/toxcore/TCP_server.h b/protocols/Tox/libtox/src/toxcore/TCP_server.h
index 632a5e79b9..252df9faf2 100644
--- a/protocols/Tox/libtox/src/toxcore/TCP_server.h
+++ b/protocols/Tox/libtox/src/toxcore/TCP_server.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright © 2016-2017 The TokTok team.
+ * Copyright © 2016-2018 The TokTok team.
* Copyright © 2014 Tox project.
*
* This file is part of Tox, the free peer to peer instant messenger.
@@ -21,8 +21,8 @@
* You should have received a copy of the GNU General Public License
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef TCP_SERVER_H
-#define TCP_SERVER_H
+#ifndef C_TOXCORE_TOXCORE_TCP_SERVER_H
+#define C_TOXCORE_TOXCORE_TCP_SERVER_H
#include "crypto_core.h"
#include "list.h"
@@ -75,6 +75,8 @@ struct TCP_Priority_List {
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);
@@ -87,7 +89,7 @@ TCP_Server *new_TCP_server(uint8_t ipv6_enabled, uint16_t num_sockets, const uin
/* Run the TCP_server
*/
-void do_TCP_server(TCP_Server *tcp_server);
+void do_TCP_server(TCP_Server *tcp_server, Mono_Time *mono_time);
/* Kill the TCP server
*/
diff --git a/protocols/Tox/libtox/src/toxcore/ccompat.h b/protocols/Tox/libtox/src/toxcore/ccompat.h
index 5b37a29457..ba8c7fe8da 100644
--- a/protocols/Tox/libtox/src/toxcore/ccompat.h
+++ b/protocols/Tox/libtox/src/toxcore/ccompat.h
@@ -1,8 +1,8 @@
/*
* C language compatibility macros for varying compiler support.
*/
-#ifndef CCOMPAT_H
-#define CCOMPAT_H
+#ifndef C_TOXCORE_TOXCORE_CCOMPAT_H
+#define C_TOXCORE_TOXCORE_CCOMPAT_H
// Variable length arrays.
// VLA(type, name, size) allocates a variable length array with automatic
@@ -48,4 +48,4 @@
#define GNU_PRINTF(f, a)
#endif
-#endif /* CCOMPAT_H */
+#endif // C_TOXCORE_TOXCORE_CCOMPAT_H
diff --git a/protocols/Tox/libtox/src/toxcore/crypto_core.api.h b/protocols/Tox/libtox/src/toxcore/crypto_core.api.h
index 4b40860d44..b6b49624e3 100644
--- a/protocols/Tox/libtox/src/toxcore/crypto_core.api.h
+++ b/protocols/Tox/libtox/src/toxcore/crypto_core.api.h
@@ -4,7 +4,7 @@
*/
/*
- * Copyright © 2016-2017 The TokTok team.
+ * Copyright © 2016-2018 The TokTok team.
* Copyright © 2013 Tox project.
*
* This file is part of Tox, the free peer to peer instant messenger.
@@ -22,8 +22,8 @@
* You should have received a copy of the GNU General Public License
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef CRYPTO_CORE_H
-#define CRYPTO_CORE_H
+#ifndef C_TOXCORE_TOXCORE_CRYPTO_CORE_H
+#define C_TOXCORE_TOXCORE_CRYPTO_CORE_H
#include <stdbool.h>
#include <stddef.h>
@@ -207,7 +207,7 @@ static int32_t decrypt_data(
/**
* 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 preformed on every encrypt/decrypt.
+ * to be performed on every encrypt/decrypt.
*/
static int32_t encrypt_precompute(
const uint8_t[CRYPTO_PUBLIC_KEY_SIZE] public_key,
@@ -264,5 +264,5 @@ static void new_symmetric_key(uint8_t[CRYPTO_SYMMETRIC_KEY_SIZE] key);
} // extern "C"
#endif
-#endif /* CRYPTO_CORE_H */
+#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 b9ec23a80d..1fd6286681 100644
--- a/protocols/Tox/libtox/src/toxcore/crypto_core.c
+++ b/protocols/Tox/libtox/src/toxcore/crypto_core.c
@@ -5,7 +5,7 @@
*/
/*
- * Copyright © 2016-2017 The TokTok team.
+ * Copyright © 2016-2018 The TokTok team.
* Copyright © 2013 Tox project.
*
* This file is part of Tox, the free peer to peer instant messenger.
@@ -129,13 +129,14 @@ bool public_key_valid(const uint8_t *public_key)
* 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)
+int32_t encrypt_precompute(const uint8_t *public_key, const uint8_t *secret_key,
+ uint8_t *shared_key)
{
return crypto_box_beforenm(shared_key, public_key, secret_key);
}
-int32_t encrypt_data_symmetric(const uint8_t *secret_key, const uint8_t *nonce, const uint8_t *plain, size_t length,
- uint8_t *encrypted)
+int32_t encrypt_data_symmetric(const uint8_t *secret_key, const uint8_t *nonce,
+ const uint8_t *plain, size_t length, uint8_t *encrypted)
{
if (length == 0 || !secret_key || !nonce || !plain || !encrypted) {
return -1;
@@ -145,19 +146,21 @@ int32_t encrypt_data_symmetric(const uint8_t *secret_key, const uint8_t *nonce,
VLA(uint8_t, temp_encrypted, length + crypto_box_MACBYTES + crypto_box_BOXZEROBYTES);
memset(temp_plain, 0, crypto_box_ZEROBYTES);
- memcpy(temp_plain + crypto_box_ZEROBYTES, plain, length); // Pad the message with 32 0 bytes.
+ // Pad the message with 32 0 bytes.
+ memcpy(temp_plain + crypto_box_ZEROBYTES, plain, length);
- if (crypto_box_afternm(temp_encrypted, temp_plain, length + crypto_box_ZEROBYTES, nonce, secret_key) != 0) {
+ if (crypto_box_afternm(temp_encrypted, temp_plain, length + crypto_box_ZEROBYTES, nonce,
+ secret_key) != 0) {
return -1;
}
- /* Unpad the encrypted message. */
+ // Unpad the encrypted message.
memcpy(encrypted, temp_encrypted + crypto_box_BOXZEROBYTES, length + crypto_box_MACBYTES);
return length + crypto_box_MACBYTES;
}
-int32_t decrypt_data_symmetric(const uint8_t *secret_key, const uint8_t *nonce, const uint8_t *encrypted, size_t length,
- uint8_t *plain)
+int32_t decrypt_data_symmetric(const uint8_t *secret_key, const uint8_t *nonce,
+ const uint8_t *encrypted, size_t length, uint8_t *plain)
{
if (length <= crypto_box_BOXZEROBYTES || !secret_key || !nonce || !encrypted || !plain) {
return -1;
@@ -167,9 +170,11 @@ int32_t decrypt_data_symmetric(const uint8_t *secret_key, const uint8_t *nonce,
VLA(uint8_t, temp_encrypted, length + crypto_box_BOXZEROBYTES);
memset(temp_encrypted, 0, crypto_box_BOXZEROBYTES);
- memcpy(temp_encrypted + crypto_box_BOXZEROBYTES, encrypted, length); // Pad the message with 16 0 bytes.
+ // Pad the message with 16 0 bytes.
+ memcpy(temp_encrypted + crypto_box_BOXZEROBYTES, encrypted, length);
- if (crypto_box_open_afternm(temp_plain, temp_encrypted, length + crypto_box_BOXZEROBYTES, nonce, secret_key) != 0) {
+ if (crypto_box_open_afternm(temp_plain, temp_encrypted, length + crypto_box_BOXZEROBYTES, nonce,
+ secret_key) != 0) {
return -1;
}
@@ -205,12 +210,13 @@ 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 sodium_increment (change to little endian)
- * NOTE don't use breaks inside this loop
+ /* TODO(irungentoo): use increment_nonce_number(nonce, 1) or
+ * sodium_increment (change to little endian).
+ *
+ * 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).
@@ -219,8 +225,8 @@ void increment_nonce(uint8_t *nonce)
uint_fast16_t carry = 1U;
for (; i != 0; --i) {
- carry += (uint_fast16_t) nonce[i - 1];
- nonce[i - 1] = (uint8_t) carry;
+ carry += (uint_fast16_t)nonce[i - 1];
+ nonce[i - 1] = (uint8_t)carry;
carry >>= 8;
}
}
@@ -228,11 +234,10 @@ void increment_nonce(uint8_t *nonce)
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
+ 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
@@ -247,7 +252,7 @@ void increment_nonce_number(uint8_t *nonce, uint32_t host_order_num)
* 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;
+ 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];
@@ -258,7 +263,7 @@ void increment_nonce_number(uint8_t *nonce, uint32_t host_order_num)
uint_fast16_t carry = 0U;
for (; i != 0; --i) {
- carry += (uint_fast16_t) nonce[i - 1] + (uint_fast16_t) num_as_nonce[i - 1];
+ carry += (uint_fast16_t)nonce[i - 1] + (uint_fast16_t)num_as_nonce[i - 1];
nonce[i - 1] = (uint8_t)carry;
carry >>= 8;
}
diff --git a/protocols/Tox/libtox/src/toxcore/crypto_core.h b/protocols/Tox/libtox/src/toxcore/crypto_core.h
index 18c1339e65..c2f0296e15 100644
--- a/protocols/Tox/libtox/src/toxcore/crypto_core.h
+++ b/protocols/Tox/libtox/src/toxcore/crypto_core.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright © 2016-2017 The TokTok team.
+ * Copyright © 2016-2018 The TokTok team.
* Copyright © 2013 Tox project.
*
* This file is part of Tox, the free peer to peer instant messenger.
@@ -21,8 +21,8 @@
* You should have received a copy of the GNU General Public License
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef CRYPTO_CORE_H
-#define CRYPTO_CORE_H
+#ifndef C_TOXCORE_TOXCORE_CRYPTO_CORE_H
+#define C_TOXCORE_TOXCORE_CRYPTO_CORE_H
#include <stdbool.h>
#include <stddef.h>
@@ -202,7 +202,7 @@ int32_t decrypt_data(const uint8_t *public_key, const uint8_t *secret_key, const
/**
* 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 preformed on every encrypt/decrypt.
+ * 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);
@@ -249,4 +249,4 @@ void new_symmetric_key(uint8_t *key);
} // extern "C"
#endif
-#endif /* CRYPTO_CORE_H */
+#endif // C_TOXCORE_TOXCORE_CRYPTO_CORE_H
diff --git a/protocols/Tox/libtox/src/toxcore/friend_connection.c b/protocols/Tox/libtox/src/toxcore/friend_connection.c
index 4d24587147..9c805b45ed 100644
--- a/protocols/Tox/libtox/src/toxcore/friend_connection.c
+++ b/protocols/Tox/libtox/src/toxcore/friend_connection.c
@@ -3,7 +3,7 @@
*/
/*
- * Copyright © 2016-2017 The TokTok team.
+ * Copyright © 2016-2018 The TokTok team.
* Copyright © 2014 Tox project.
*
* This file is part of Tox, the free peer to peer instant messenger.
@@ -74,6 +74,7 @@ typedef struct Friend_Conn {
struct Friend_Connections {
+ const Mono_Time *mono_time;
Net_Crypto *net_crypto;
DHT *dht;
Onion_Client *onion_c;
@@ -298,7 +299,7 @@ static unsigned int send_relays(Friend_Connections *fr_c, int friendcon_id)
++length;
if (write_cryptpacket(fr_c->net_crypto, friend_con->crypt_connection_id, data, length, 0) != -1) {
- friend_con->share_relays_lastsent = unix_time();
+ friend_con->share_relays_lastsent = mono_time_get(fr_c->mono_time);
return 1;
}
@@ -339,7 +340,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_lastrecv = unix_time();
+ friend_con->dht_ip_port_lastrecv = mono_time_get(fr_c->mono_time);
if (friend_con->hosting_tcp_relay) {
friend_add_tcp_relay(fr_c, number, ip_port, friend_con->dht_temp_pk);
@@ -355,7 +356,7 @@ static void change_dht_pk(Friend_Connections *fr_c, int friendcon_id, const uint
return;
}
- friend_con->dht_pk_lastrecv = unix_time();
+ friend_con->dht_pk_lastrecv = mono_time_get(fr_c->mono_time);
if (friend_con->dht_lock) {
if (dht_delfriend(fr_c->dht, friend_con->dht_temp_pk, friend_con->dht_lock) != 0) {
@@ -384,13 +385,13 @@ static int handle_status(void *object, int number, uint8_t status, void *userdat
if (status) { /* Went online. */
status_changed = 1;
friend_con->status = FRIENDCONN_STATUS_CONNECTED;
- friend_con->ping_lastrecv = unix_time();
+ friend_con->ping_lastrecv = mono_time_get(fr_c->mono_time);
friend_con->share_relays_lastsent = 0;
onion_set_friend_online(fr_c->onion_c, friend_con->onion_friendnum, status);
} else { /* Went offline. */
if (friend_con->status != FRIENDCONN_STATUS_CONNECTING) {
status_changed = 1;
- friend_con->dht_pk_lastrecv = unix_time();
+ friend_con->dht_pk_lastrecv = mono_time_get(fr_c->mono_time);
onion_set_friend_online(fr_c->onion_c, friend_con->onion_friendnum, status);
}
@@ -463,7 +464,7 @@ static int handle_packet(void *object, int number, const uint8_t *data, uint16_t
}
if (data[0] == PACKET_ID_ALIVE) {
- friend_con->ping_lastrecv = unix_time();
+ friend_con->ping_lastrecv = mono_time_get(fr_c->mono_time);
return 0;
}
@@ -558,7 +559,7 @@ static int handle_new_connections(void *object, New_Connection *n_c)
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 = unix_time();
+ friend_con->dht_ip_port_lastrecv = mono_time_get(fr_c->mono_time);
}
if (public_key_cmp(friend_con->dht_temp_pk, n_c->dht_public_key) != 0) {
@@ -613,7 +614,7 @@ static int send_ping(const Friend_Connections *fr_c, int friendcon_id)
const int64_t ret = write_cryptpacket(fr_c->net_crypto, friend_con->crypt_connection_id, &ping, sizeof(ping), 0);
if (ret != -1) {
- friend_con->ping_lastsent = unix_time();
+ friend_con->ping_lastsent = mono_time_get(fr_c->mono_time);
return 0;
}
@@ -850,7 +851,8 @@ int send_friend_request_packet(Friend_Connections *fr_c, int friendcon_id, uint3
}
/* Create new friend_connections instance. */
-Friend_Connections *new_friend_connections(Onion_Client *onion_c, bool local_discovery_enabled)
+Friend_Connections *new_friend_connections(const Mono_Time *mono_time, Onion_Client *onion_c,
+ bool local_discovery_enabled)
{
if (onion_c == nullptr) {
return nullptr;
@@ -862,6 +864,7 @@ Friend_Connections *new_friend_connections(Onion_Client *onion_c, bool local_dis
return nullptr;
}
+ temp->mono_time = mono_time;
temp->dht = onion_get_dht(onion_c);
temp->net_crypto = onion_get_net_crypto(onion_c);
temp->onion_c = onion_c;
@@ -881,7 +884,7 @@ Friend_Connections *new_friend_connections(Onion_Client *onion_c, bool local_dis
/* 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 < unix_time()) {
+ if (fr_c->last_lan_discovery + LAN_DISCOVERY_INTERVAL < mono_time_get(fr_c->mono_time)) {
const uint16_t first = fr_c->next_lan_port;
uint16_t last = first + PORTS_PER_DISCOVERY;
last = last > TOX_PORTRANGE_TO ? TOX_PORTRANGE_TO : last;
@@ -896,14 +899,14 @@ static void lan_discovery(Friend_Connections *fr_c)
// Don't include default port in port range
fr_c->next_lan_port = last != TOX_PORTRANGE_TO ? last : TOX_PORTRANGE_FROM + 1;
- fr_c->last_lan_discovery = unix_time();
+ fr_c->last_lan_discovery = mono_time_get(fr_c->mono_time);
}
}
/* main friend_connections loop. */
void do_friend_connections(Friend_Connections *fr_c, void *userdata)
{
- const uint64_t temp_time = unix_time();
+ const uint64_t temp_time = mono_time_get(fr_c->mono_time);
for (uint32_t i = 0; i < fr_c->num_cons; ++i) {
Friend_Conn *const friend_con = get_conn(fr_c, i);
diff --git a/protocols/Tox/libtox/src/toxcore/friend_connection.h b/protocols/Tox/libtox/src/toxcore/friend_connection.h
index 024befeec8..149a4fa7ec 100644
--- a/protocols/Tox/libtox/src/toxcore/friend_connection.h
+++ b/protocols/Tox/libtox/src/toxcore/friend_connection.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright © 2016-2017 The TokTok team.
+ * Copyright © 2016-2018 The TokTok team.
* Copyright © 2014 Tox project.
*
* This file is part of Tox, the free peer to peer instant messenger.
@@ -21,8 +21,8 @@
* You should have received a copy of the GNU General Public License
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef FRIEND_CONNECTION_H
-#define FRIEND_CONNECTION_H
+#ifndef C_TOXCORE_TOXCORE_FRIEND_CONNECTION_H
+#define C_TOXCORE_TOXCORE_FRIEND_CONNECTION_H
#include "DHT.h"
#include "LAN_discovery.h"
@@ -158,7 +158,8 @@ typedef int fr_request_cb(void *object, const uint8_t *source_pubkey, const uint
void set_friend_request_callback(Friend_Connections *fr_c, fr_request_cb *fr_request_callback, void *object);
/* Create new friend_connections instance. */
-Friend_Connections *new_friend_connections(Onion_Client *onion_c, bool local_discovery_enabled);
+Friend_Connections *new_friend_connections(const Mono_Time *mono_time, Onion_Client *onion_c,
+ bool local_discovery_enabled);
/* main friend_connections loop. */
void do_friend_connections(Friend_Connections *fr_c, void *userdata);
diff --git a/protocols/Tox/libtox/src/toxcore/friend_requests.c b/protocols/Tox/libtox/src/toxcore/friend_requests.c
index c4f2512722..fa1defc843 100644
--- a/protocols/Tox/libtox/src/toxcore/friend_requests.c
+++ b/protocols/Tox/libtox/src/toxcore/friend_requests.c
@@ -3,7 +3,7 @@
*/
/*
- * Copyright © 2016-2017 The TokTok team.
+ * Copyright © 2016-2018 The TokTok team.
* Copyright © 2013 Tox project.
*
* This file is part of Tox, the free peer to peer instant messenger.
diff --git a/protocols/Tox/libtox/src/toxcore/friend_requests.h b/protocols/Tox/libtox/src/toxcore/friend_requests.h
index 77c3af6890..7fcd3f0d35 100644
--- a/protocols/Tox/libtox/src/toxcore/friend_requests.h
+++ b/protocols/Tox/libtox/src/toxcore/friend_requests.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright © 2016-2017 The TokTok team.
+ * Copyright © 2016-2018 The TokTok team.
* Copyright © 2014 Tox project.
*
* This file is part of Tox, the free peer to peer instant messenger.
@@ -21,8 +21,8 @@
* You should have received a copy of the GNU General Public License
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef FRIEND_REQUESTS_H
-#define FRIEND_REQUESTS_H
+#ifndef C_TOXCORE_TOXCORE_FRIEND_REQUESTS_H
+#define C_TOXCORE_TOXCORE_FRIEND_REQUESTS_H
#include "friend_connection.h"
diff --git a/protocols/Tox/libtox/src/toxcore/group.c b/protocols/Tox/libtox/src/toxcore/group.c
index 20075c8b92..5feb483b74 100644
--- a/protocols/Tox/libtox/src/toxcore/group.c
+++ b/protocols/Tox/libtox/src/toxcore/group.c
@@ -3,7 +3,7 @@
*/
/*
- * Copyright © 2016-2017 The TokTok team.
+ * Copyright © 2016-2018 The TokTok team.
* Copyright © 2014 Tox project.
*
* This file is part of Tox, the free peer to peer instant messenger.
@@ -60,10 +60,10 @@ typedef enum Invite_Id {
#define ONLINE_PACKET_DATA_SIZE (sizeof(uint16_t) + 1 + GROUP_ID_LENGTH)
typedef enum Peer_Id {
- PEER_KILL_ID = 1,
- PEER_QUERY_ID = 8,
- PEER_RESPONSE_ID = 9,
- PEER_TITLE_ID = 10,
+ PEER_INTRODUCED_ID = 1,
+ PEER_QUERY_ID = 8,
+ PEER_RESPONSE_ID = 9,
+ PEER_TITLE_ID = 10,
} Peer_Id;
#define MIN_MESSAGE_PACKET_LEN (sizeof(uint16_t) * 2 + sizeof(uint32_t) + 1)
@@ -232,7 +232,7 @@ int32_t conference_by_id(const Group_Chats *g_c, const uint8_t *id)
/*
* check if peer with peer_number is in peer array.
*
- * return peer number if peer is in chat.
+ * return peer index if peer is in chat.
* return -1 if peer is not in chat.
*
* TODO(irungentoo): make this more efficient.
@@ -267,10 +267,6 @@ typedef enum Groupchat_Closest {
GROUPCHAT_CLOSEST_REMOVED
} Groupchat_Closest;
-static int friend_in_close(Group_c *g, int friendcon_id);
-static int add_conn_to_groupchat(Group_Chats *g_c, int friendcon_id, uint32_t groupnumber, uint8_t closest,
- uint8_t lock);
-
static int add_to_closest(Group_Chats *g_c, uint32_t groupnumber, const uint8_t *real_pk, const uint8_t *temp_pk)
{
Group_c *g = get_group_c(g_c, groupnumber);
@@ -371,6 +367,11 @@ static unsigned int pk_in_closest_peers(Group_c *g, uint8_t *real_pk)
return 0;
}
+static int add_conn_to_groupchat(Group_Chats *g_c, int friendcon_id, uint32_t groupnumber, uint8_t reason,
+ uint8_t lock);
+
+static void remove_conn_reason(Group_Chats *g_c, uint32_t groupnumber, uint16_t i, uint8_t reason);
+
static int send_packet_online(Friend_Connections *fr_c, int friendcon_id, uint16_t group_num, uint8_t type,
uint8_t *id);
@@ -397,7 +398,7 @@ static int connect_to_closest(Group_Chats *g_c, uint32_t groupnumber, void *user
continue;
}
- if (!g->close[i].closest) {
+ if (!(g->close[i].reasons & GROUPCHAT_CLOSE_REASON_CLOSEST)) {
continue;
}
@@ -406,12 +407,7 @@ static int connect_to_closest(Group_Chats *g_c, uint32_t groupnumber, void *user
get_friendcon_public_keys(real_pk, dht_temp_pk, g_c->fr_c, g->close[i].number);
if (!pk_in_closest_peers(g, real_pk)) {
- g->close[i].closest = false;
-
- if (!g->close[i].introducer && !g->close[i].introduced) {
- g->close[i].type = GROUPCHAT_CLOSE_NONE;
- kill_friend_connection(g_c->fr_c, g->close[i].number);
- }
+ remove_conn_reason(g_c, groupnumber, i, GROUPCHAT_CLOSE_REASON_CLOSEST);
}
}
@@ -435,7 +431,7 @@ static int connect_to_closest(Group_Chats *g_c, uint32_t groupnumber, void *user
set_dht_temp_pk(g_c->fr_c, friendcon_id, g->closest_peers[i].temp_pk, userdata);
}
- add_conn_to_groupchat(g_c, friendcon_id, groupnumber, 1, lock);
+ add_conn_to_groupchat(g_c, friendcon_id, groupnumber, GROUPCHAT_CLOSE_REASON_CLOSEST, lock);
if (friend_con_connected(g_c->fr_c, friendcon_id) == FRIENDCONN_STATUS_CONNECTED) {
send_packet_online(g_c->fr_c, friendcon_id, groupnumber, g->type, g->id);
@@ -447,7 +443,96 @@ static int connect_to_closest(Group_Chats *g_c, uint32_t groupnumber, void *user
return 0;
}
-/* Add a peer to the group chat.
+static int get_frozen_index(Group_c *g, uint16_t peer_number)
+{
+ for (uint32_t i = 0; i < g->numfrozen; ++i) {
+ if (g->frozen[i].peer_number == peer_number) {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+/* 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.
+ */
+static int note_peer_active(Group_Chats *g_c, uint32_t groupnumber, uint16_t peer_number, void *userdata)
+{
+ Group_c *g = get_group_c(g_c, groupnumber);
+
+ if (!g) {
+ return -1;
+ }
+
+ const int peer_index = get_peer_index(g, peer_number);
+
+ if (peer_index != -1) {
+ g->group[peer_index].last_active = mono_time_get(g_c->mono_time);
+ return peer_index;
+ }
+
+ const int frozen_index = get_frozen_index(g, peer_number);
+
+ if (frozen_index == -1) {
+ return -1;
+ }
+
+ /* Now thaw the peer */
+
+ Group_Peer *temp = (Group_Peer *)realloc(g->group, sizeof(Group_Peer) * (g->numpeers + 1));
+
+ if (temp == nullptr) {
+ return -1;
+ }
+
+ g->group = temp;
+ g->group[g->numpeers] = g->frozen[frozen_index];
+ g->group[g->numpeers].temp_pk_updated = false;
+ g->group[g->numpeers].last_active = mono_time_get(g_c->mono_time);
+
+ add_to_closest(g_c, groupnumber, g->group[g->numpeers].real_pk, g->group[g->numpeers].temp_pk);
+
+ ++g->numpeers;
+
+ --g->numfrozen;
+
+ if (g->numfrozen == 0) {
+ free(g->frozen);
+ g->frozen = nullptr;
+ } else {
+ if (g->numfrozen != (uint32_t)frozen_index) {
+ g->frozen[frozen_index] = g->frozen[g->numfrozen];
+ }
+
+ Group_Peer *frozen_temp = (Group_Peer *)realloc(g->frozen, sizeof(Group_Peer) * (g->numfrozen));
+
+ if (frozen_temp == nullptr) {
+ return -1;
+ }
+
+ g->frozen = frozen_temp;
+ }
+
+ if (g_c->peer_list_changed_callback) {
+ g_c->peer_list_changed_callback(g_c->m, groupnumber, userdata);
+ }
+
+ if (g->peer_on_join) {
+ g->peer_on_join(g->object, groupnumber, g->numpeers - 1);
+ }
+
+ g->need_send_name = true;
+
+ return g->numpeers - 1;
+}
+
+/* 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.
*
* 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
@@ -457,7 +542,7 @@ static int connect_to_closest(Group_Chats *g_c, uint32_t groupnumber, void *user
* return -1 if error.
*/
static int addpeer(Group_Chats *g_c, uint32_t groupnumber, const uint8_t *real_pk, const uint8_t *temp_pk,
- uint16_t peer_number, void *userdata, bool do_gc_callback)
+ uint16_t peer_number, void *userdata, bool fresh, bool do_gc_callback)
{
Group_c *g = get_group_c(g_c, groupnumber);
@@ -465,23 +550,35 @@ static int addpeer(Group_Chats *g_c, uint32_t groupnumber, const uint8_t *real_p
return -1;
}
- // TODO(irungentoo):
- int peer_index = peer_in_chat(g, real_pk);
+ const int peer_index = fresh ?
+ note_peer_active(g_c, groupnumber, peer_number, userdata) :
+ get_peer_index(g, peer_number);
if (peer_index != -1) {
- id_copy(g->group[peer_index].temp_pk, temp_pk);
-
- if (g->group[peer_index].peer_number != peer_number) {
+ if (!id_equal(g->group[peer_index].real_pk, real_pk)) {
return -1;
}
+ if (fresh || !g->group[peer_index].temp_pk_updated) {
+ id_copy(g->group[peer_index].temp_pk, temp_pk);
+ g->group[peer_index].temp_pk_updated = true;
+ }
+
return peer_index;
}
- peer_index = get_peer_index(g, peer_number);
+ if (!fresh) {
+ const int frozen_index = get_frozen_index(g, peer_number);
- if (peer_index != -1) {
- return -1;
+ if (frozen_index != -1) {
+ if (!id_equal(g->frozen[frozen_index].real_pk, real_pk)) {
+ return -1;
+ }
+
+ id_copy(g->frozen[frozen_index].temp_pk, temp_pk);
+
+ return -1;
+ }
}
Group_Peer *temp = (Group_Peer *)realloc(g->group, sizeof(Group_Peer) * (g->numpeers + 1));
@@ -495,9 +592,10 @@ static int addpeer(Group_Chats *g_c, uint32_t groupnumber, const uint8_t *real_p
id_copy(g->group[g->numpeers].real_pk, real_pk);
id_copy(g->group[g->numpeers].temp_pk, temp_pk);
+ g->group[g->numpeers].temp_pk_updated = true;
g->group[g->numpeers].peer_number = peer_number;
- g->group[g->numpeers].last_recv = unix_time();
+ g->group[g->numpeers].last_active = mono_time_get(g_c->mono_time);
++g->numpeers;
add_to_closest(g_c, groupnumber, real_pk, temp_pk);
@@ -539,13 +637,24 @@ static int remove_close_conn(Group_Chats *g_c, uint32_t groupnumber, int friendc
}
+static void remove_from_closest(Group_c *g, int peer_index)
+{
+ for (uint32_t i = 0; i < DESIRED_CLOSE_CONNECTIONS; ++i) {
+ if (g->closest_peers[i].entry && id_equal(g->closest_peers[i].real_pk, g->group[peer_index].real_pk)) {
+ g->closest_peers[i].entry = 0;
+ g->changed = GROUPCHAT_CLOSEST_REMOVED;
+ break;
+ }
+ }
+}
+
/*
* Delete a peer from the group chat.
*
* return 0 if success
* return -1 if error.
*/
-static int delpeer(Group_Chats *g_c, uint32_t groupnumber, int peer_index, void *userdata)
+static int delpeer(Group_Chats *g_c, uint32_t groupnumber, int peer_index, void *userdata, bool keep_connection)
{
Group_c *g = get_group_c(g_c, groupnumber);
@@ -553,19 +662,11 @@ static int delpeer(Group_Chats *g_c, uint32_t groupnumber, int peer_index, void
return -1;
}
- uint32_t i;
+ remove_from_closest(g, peer_index);
- for (i = 0; i < DESIRED_CLOSE_CONNECTIONS; ++i) { /* If peer is in closest_peers list, remove it. */
- if (g->closest_peers[i].entry && id_equal(g->closest_peers[i].real_pk, g->group[peer_index].real_pk)) {
- g->closest_peers[i].entry = 0;
- g->changed = GROUPCHAT_CLOSEST_REMOVED;
- break;
- }
- }
-
- int friendcon_id = getfriend_conn_id_pk(g_c->fr_c, g->group[peer_index].real_pk);
+ const int friendcon_id = getfriend_conn_id_pk(g_c->fr_c, g->group[peer_index].real_pk);
- if (friendcon_id != -1) {
+ if (friendcon_id != -1 && !keep_connection) {
remove_close_conn(g_c, groupnumber, friendcon_id);
}
@@ -578,7 +679,7 @@ static int delpeer(Group_Chats *g_c, uint32_t groupnumber, int peer_index, void
g->group = nullptr;
} else {
if (g->numpeers != (uint32_t)peer_index) {
- memcpy(&g->group[peer_index], &g->group[g->numpeers], sizeof(Group_Peer));
+ g->group[peer_index] = g->group[g->numpeers];
}
Group_Peer *temp = (Group_Peer *)realloc(g->group, sizeof(Group_Peer) * (g->numpeers));
@@ -601,6 +702,32 @@ static int delpeer(Group_Chats *g_c, uint32_t groupnumber, int peer_index, void
return 0;
}
+static bool try_send_rejoin(Group_Chats *g_c, uint32_t groupnumber, const uint8_t *real_pk);
+
+static int freeze_peer(Group_Chats *g_c, uint32_t groupnumber, int peer_index, void *userdata)
+{
+ Group_c *g = get_group_c(g_c, groupnumber);
+
+ if (!g) {
+ return -1;
+ }
+
+ try_send_rejoin(g_c, groupnumber, g->group[peer_index].real_pk);
+
+ Group_Peer *temp = (Group_Peer *)realloc(g->frozen, sizeof(Group_Peer) * (g->numfrozen + 1));
+
+ if (temp == nullptr) {
+ return -1;
+ }
+
+ g->frozen = temp;
+ g->frozen[g->numfrozen] = g->group[peer_index];
+ ++g->numfrozen;
+
+ return delpeer(g_c, groupnumber, peer_index, userdata, true);
+}
+
+
/* Set the nick for a peer.
*
* do_gc_callback indicates whether we want to trigger callbacks set by the client
@@ -666,6 +793,8 @@ static int settitle(Group_Chats *g_c, uint32_t groupnumber, int peer_index, cons
memcpy(g->title, title, title_len);
g->title_len = title_len;
+ g->title_fresh = true;
+
if (g_c->title_callback) {
g_c->title_callback(g_c->m, groupnumber, peer_index, title, title_len, userdata);
}
@@ -673,7 +802,29 @@ static int settitle(Group_Chats *g_c, uint32_t groupnumber, int peer_index, cons
return 0;
}
-static void set_conns_type_close(Group_Chats *g_c, uint32_t groupnumber, int friendcon_id, uint8_t type)
+/* 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);
+
+ if (!g) {
+ return;
+ }
+
+ for (uint32_t i = 0; i < MAX_GROUP_CONNECTIONS; ++i) {
+ if (g->close[i].type == GROUPCHAT_CLOSE_ONLINE) {
+ return;
+ }
+ }
+
+ for (uint32_t i = 0; i < g->numpeers; ++i) {
+ while (i < g->numpeers && !id_equal(g->group[i].real_pk, g->real_pk)) {
+ freeze_peer(g_c, groupnumber, i, userdata);
+ }
+ }
+}
+
+static void set_conns_type_close(Group_Chats *g_c, uint32_t groupnumber, int friendcon_id, uint8_t type, void *userdata)
{
Group_c *g = get_group_c(g_c, groupnumber);
@@ -696,14 +847,36 @@ static void set_conns_type_close(Group_Chats *g_c, uint32_t groupnumber, int fri
send_packet_online(g_c->fr_c, friendcon_id, groupnumber, g->type, g->id);
} else {
g->close[i].type = type;
+ check_disconnected(g_c, groupnumber, userdata);
}
}
}
/* Set the type for all close connections with friendcon_id */
-static void set_conns_status_groups(Group_Chats *g_c, int friendcon_id, uint8_t type)
+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) {
+ set_conns_type_close(g_c, i, friendcon_id, type, userdata);
+ }
+}
+
+static void rejoin_frozen_friend(Group_Chats *g_c, int friendcon_id)
{
+ uint8_t real_pk[CRYPTO_PUBLIC_KEY_SIZE];
+ get_friendcon_public_keys(real_pk, nullptr, g_c->fr_c, friendcon_id);
+
for (uint16_t i = 0; i < g_c->num_chats; ++i) {
- set_conns_type_close(g_c, i, friendcon_id, type);
+ Group_c *g = get_group_c(g_c, i);
+
+ if (!g) {
+ continue;
+ }
+
+ for (uint32_t j = 0; j < g->numfrozen; ++j) {
+ if (id_equal(g->frozen[j].real_pk, real_pk)) {
+ try_send_rejoin(g_c, i, real_pk);
+ break;
+ }
+ }
}
}
@@ -712,9 +885,10 @@ static int g_handle_status(void *object, int friendcon_id, uint8_t status, void
Group_Chats *g_c = (Group_Chats *)object;
if (status) { /* Went online */
- set_conns_status_groups(g_c, friendcon_id, GROUPCHAT_CLOSE_ONLINE);
+ set_conns_status_groups(g_c, friendcon_id, GROUPCHAT_CLOSE_ONLINE, userdata);
+ rejoin_frozen_friend(g_c, friendcon_id);
} else { /* Went offline */
- set_conns_status_groups(g_c, friendcon_id, GROUPCHAT_CLOSE_CONNECTION);
+ set_conns_status_groups(g_c, friendcon_id, GROUPCHAT_CLOSE_CONNECTION, userdata);
// TODO(irungentoo): remove timedout connections?
}
@@ -729,7 +903,7 @@ static int handle_lossy(void *object, int friendcon_id, const uint8_t *data, uin
* return close index on success
* return -1 on failure.
*/
-static int add_conn_to_groupchat(Group_Chats *g_c, int friendcon_id, uint32_t groupnumber, uint8_t closest,
+static int add_conn_to_groupchat(Group_Chats *g_c, int friendcon_id, uint32_t groupnumber, uint8_t reason,
uint8_t lock)
{
Group_c *g = get_group_c(g_c, groupnumber);
@@ -738,40 +912,81 @@ static int add_conn_to_groupchat(Group_Chats *g_c, int friendcon_id, uint32_t gr
return -1;
}
- uint16_t i, ind = MAX_GROUP_CONNECTIONS;
+ uint16_t empty = MAX_GROUP_CONNECTIONS;
+ uint16_t ind = MAX_GROUP_CONNECTIONS;
- for (i = 0; i < MAX_GROUP_CONNECTIONS; ++i) {
+ for (uint16_t i = 0; i < MAX_GROUP_CONNECTIONS; ++i) {
if (g->close[i].type == GROUPCHAT_CLOSE_NONE) {
- ind = i;
+ empty = i;
continue;
}
if (g->close[i].number == (uint32_t)friendcon_id) {
- g->close[i].closest |= closest;
- return i; /* Already in list. */
+ ind = i; /* Already in list. */
+ break;
}
}
+ if (ind == MAX_GROUP_CONNECTIONS && empty != MAX_GROUP_CONNECTIONS) {
+ if (lock) {
+ friend_connection_lock(g_c->fr_c, friendcon_id);
+ }
+
+ g->close[empty].type = GROUPCHAT_CLOSE_CONNECTION;
+ g->close[empty].number = friendcon_id;
+ g->close[empty].reasons = 0;
+ // TODO(irungentoo):
+ friend_connection_callbacks(g_c->m->fr_c, friendcon_id, GROUPCHAT_CALLBACK_INDEX, &g_handle_status, &g_handle_packet,
+ &handle_lossy, g_c, friendcon_id);
+ ind = empty;
+ }
+
if (ind == MAX_GROUP_CONNECTIONS) {
return -1;
}
- if (lock) {
- friend_connection_lock(g_c->fr_c, friendcon_id);
- }
+ if (!(g->close[ind].reasons & reason)) {
+ g->close[ind].reasons |= reason;
- g->close[ind].type = GROUPCHAT_CLOSE_CONNECTION;
- g->close[ind].number = friendcon_id;
- g->close[ind].closest = closest;
- g->close[ind].introducer = false;
- g->close[ind].introduced = false;
- // TODO(irungentoo):
- friend_connection_callbacks(g_c->m->fr_c, friendcon_id, GROUPCHAT_CALLBACK_INDEX, &g_handle_status, &g_handle_packet,
- &handle_lossy, g_c, friendcon_id);
+ if (reason == GROUPCHAT_CLOSE_REASON_INTRODUCER) {
+ ++g->num_introducer_connections;
+ }
+ }
return ind;
}
+static unsigned int send_peer_introduced(Group_Chats *g_c, int friendcon_id, uint16_t group_num);
+
+/* Removes reason for keeping connection.
+ *
+ * Kills connection if this was the last reason.
+ */
+static void remove_conn_reason(Group_Chats *g_c, uint32_t groupnumber, uint16_t i, uint8_t reason)
+{
+ Group_c *g = get_group_c(g_c, groupnumber);
+
+ if (!g) {
+ return;
+ }
+
+ if (!(g->close[i].reasons & reason)) {
+ return;
+ }
+
+ g->close[i].reasons &= ~reason;
+
+ if (reason == GROUPCHAT_CLOSE_REASON_INTRODUCER) {
+ --g->num_introducer_connections;
+ send_peer_introduced(g_c, g->close[i].number, g->close[i].group_number);
+ }
+
+ if (g->close[i].reasons == 0) {
+ kill_friend_connection(g_c->fr_c, g->close[i].number);
+ g->close[i].type = GROUPCHAT_CLOSE_NONE;
+ }
+}
+
/* Creates a new groupchat and puts it in the chats array.
*
* type is one of GROUPCHAT_TYPE_*
@@ -781,7 +996,7 @@ static int add_conn_to_groupchat(Group_Chats *g_c, int friendcon_id, uint32_t gr
*/
int add_groupchat(Group_Chats *g_c, uint8_t type)
{
- int32_t groupnumber = create_group_chat(g_c);
+ const int32_t groupnumber = create_group_chat(g_c);
if (groupnumber == -1) {
return -1;
@@ -790,12 +1005,12 @@ int add_groupchat(Group_Chats *g_c, uint8_t type)
Group_c *g = &g_c->chats[groupnumber];
g->status = GROUPCHAT_STATUS_CONNECTED;
- g->number_joined = -1;
g->type = type;
new_symmetric_key(g->id);
g->peer_number = 0; /* Founder is peer 0. */
memcpy(g->real_pk, nc_get_self_public_key(g_c->m->net_crypto), CRYPTO_PUBLIC_KEY_SIZE);
- int peer_index = addpeer(g_c, groupnumber, g->real_pk, dht_get_self_public_key(g_c->m->dht), 0, nullptr, false);
+ const int peer_index = addpeer(g_c, groupnumber, g->real_pk, dht_get_self_public_key(g_c->m->dht), 0, nullptr, true,
+ false);
if (peer_index == -1) {
return -1;
@@ -822,9 +1037,7 @@ int del_groupchat(Group_Chats *g_c, uint32_t groupnumber)
group_kill_peer_send(g_c, groupnumber, g->peer_number);
- unsigned int i;
-
- for (i = 0; i < MAX_GROUP_CONNECTIONS; ++i) {
+ for (uint32_t i = 0; i < MAX_GROUP_CONNECTIONS; ++i) {
if (g->close[i].type == GROUPCHAT_CLOSE_NONE) {
continue;
}
@@ -833,11 +1046,14 @@ int del_groupchat(Group_Chats *g_c, uint32_t groupnumber)
kill_friend_connection(g_c->fr_c, g->close[i].number);
}
- if (g->peer_on_leave) {
- g->peer_on_leave(g->object, groupnumber, g->group[i].object);
+ for (uint32_t i = 0; i < g->numpeers; ++i) {
+ if (g->peer_on_leave) {
+ g->peer_on_leave(g->object, groupnumber, g->group[i].object);
+ }
}
free(g->group);
+ free(g->frozen);
if (g->group_on_delete) {
g->group_on_delete(g->object, groupnumber);
@@ -1087,7 +1303,7 @@ int invite_friend(Group_Chats *g_c, uint32_t friendnumber, uint32_t groupnumber)
uint8_t invite[INVITE_PACKET_SIZE];
invite[0] = INVITE_ID;
- uint16_t groupchat_num = net_htons((uint16_t)groupnumber);
+ const uint16_t groupchat_num = net_htons((uint16_t)groupnumber);
memcpy(invite + 1, &groupchat_num, sizeof(groupchat_num));
invite[1 + sizeof(groupchat_num)] = g->type;
memcpy(invite + 1 + sizeof(groupchat_num) + 1, g->id, GROUP_ID_LENGTH);
@@ -1099,6 +1315,39 @@ 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.
+ * return true if a packet was sent.
+ * return false otherwise.
+ */
+static bool try_send_rejoin(Group_Chats *g_c, uint32_t groupnumber, const uint8_t *real_pk)
+{
+ Group_c *g = get_group_c(g_c, groupnumber);
+
+ if (!g) {
+ return false;
+ }
+
+ const int friendcon_id = getfriend_conn_id_pk(g_c->fr_c, real_pk);
+
+ if (friendcon_id == -1) {
+ return false;
+ }
+
+ uint8_t packet[1 + 1 + GROUP_ID_LENGTH];
+ packet[0] = PACKET_ID_REJOIN_CONFERENCE;
+ packet[1] = g->type;
+ memcpy(packet + 2, g->id, GROUP_ID_LENGTH);
+
+ if (write_cryptpacket(friendconn_net_crypto(g_c->fr_c), friend_connection_crypt_connection_id(g_c->fr_c, friendcon_id),
+ packet, sizeof(packet), 0) == -1) {
+ return false;
+ }
+
+ add_conn_to_groupchat(g_c, friendcon_id, groupnumber, GROUPCHAT_CLOSE_REASON_INTRODUCER, 1);
+
+ return true;
+}
+
static unsigned int send_peer_query(Group_Chats *g_c, int friendcon_id, uint16_t group_num);
/* Join a group (you need to have been invited first.)
@@ -1123,7 +1372,7 @@ int join_groupchat(Group_Chats *g_c, uint32_t friendnumber, uint8_t expected_typ
return -2;
}
- int friendcon_id = getfriendcon_id(g_c->m, friendnumber);
+ const int friendcon_id = getfriendcon_id(g_c->m, friendnumber);
if (friendcon_id == -1) {
return -3;
@@ -1133,7 +1382,7 @@ int join_groupchat(Group_Chats *g_c, uint32_t friendnumber, uint8_t expected_typ
return -4;
}
- int groupnumber = create_group_chat(g_c);
+ const int groupnumber = create_group_chat(g_c);
if (groupnumber == -1) {
return -5;
@@ -1141,9 +1390,8 @@ int join_groupchat(Group_Chats *g_c, uint32_t friendnumber, uint8_t expected_typ
Group_c *g = &g_c->chats[groupnumber];
- uint16_t group_num = net_htons(groupnumber);
+ const uint16_t group_num = net_htons(groupnumber);
g->status = GROUPCHAT_STATUS_VALID;
- g->number_joined = -1;
memcpy(g->real_pk, nc_get_self_public_key(g_c->m->net_crypto), CRYPTO_PUBLIC_KEY_SIZE);
uint8_t response[INVITE_RESPONSE_PACKET_SIZE];
@@ -1157,13 +1405,11 @@ int join_groupchat(Group_Chats *g_c, uint32_t friendnumber, uint8_t expected_typ
other_groupnum = net_ntohs(other_groupnum);
g->type = data[sizeof(uint16_t)];
memcpy(g->id, data + sizeof(uint16_t) + 1, GROUP_ID_LENGTH);
- int close_index = add_conn_to_groupchat(g_c, friendcon_id, groupnumber, 0, 1);
+ const int close_index = add_conn_to_groupchat(g_c, friendcon_id, groupnumber, GROUPCHAT_CLOSE_REASON_INTRODUCER, 1);
if (close_index != -1) {
g->close[close_index].group_number = other_groupnum;
g->close[close_index].type = GROUPCHAT_CLOSE_ONLINE;
- g->number_joined = friendcon_id;
- g->close[close_index].introducer = true;
}
send_peer_query(g_c, friendcon_id, other_groupnum);
@@ -1420,6 +1666,25 @@ int group_title_get(const Group_Chats *g_c, uint32_t groupnumber, uint8_t *title
return g->title_len;
}
+static bool get_peer_number(const Group_c *g, const uint8_t *real_pk, uint16_t *peer_number)
+{
+ const int peer_index = peer_in_chat(g, real_pk);
+
+ if (peer_index >= 0) {
+ *peer_number = g->group[peer_index].peer_number;
+ return true;
+ }
+
+ for (uint32_t i = 0; i < g->numfrozen; ++i) {
+ if (id_equal(g->frozen[i].real_pk, real_pk)) {
+ *peer_number = g->frozen[i].peer_number;
+ return true;
+ }
+ }
+
+ return false;
+}
+
static void handle_friend_invite_packet(Messenger *m, uint32_t friendnumber, const uint8_t *data, uint16_t length,
void *userdata)
{
@@ -1430,7 +1695,7 @@ static void handle_friend_invite_packet(Messenger *m, uint32_t friendnumber, con
}
const uint8_t *invite_data = data + 1;
- uint16_t invite_length = length - 1;
+ const uint16_t invite_length = length - 1;
switch (data[0]) {
case INVITE_ID: {
@@ -1438,7 +1703,7 @@ static void handle_friend_invite_packet(Messenger *m, uint32_t friendnumber, con
return;
}
- int groupnumber = get_group_num(g_c, data[1 + sizeof(uint16_t)], data + 1 + sizeof(uint16_t) + 1);
+ const int groupnumber = get_group_num(g_c, data[1 + sizeof(uint16_t)], data + 1 + sizeof(uint16_t) + 1);
if (groupnumber == -1) {
if (g_c->invite_callback) {
@@ -1480,7 +1745,7 @@ static void handle_friend_invite_packet(Messenger *m, uint32_t friendnumber, con
unsigned int tries = 0;
- while (get_peer_index(g, peer_number) != -1) {
+ while (get_peer_index(g, peer_number) != -1 || get_frozen_index(g, peer_number) != -1) {
peer_number = random_u16();
++tries;
@@ -1502,19 +1767,19 @@ static void handle_friend_invite_packet(Messenger *m, uint32_t friendnumber, con
uint8_t real_pk[CRYPTO_PUBLIC_KEY_SIZE], temp_pk[CRYPTO_PUBLIC_KEY_SIZE];
get_friendcon_public_keys(real_pk, temp_pk, g_c->fr_c, friendcon_id);
- addpeer(g_c, groupnum, real_pk, temp_pk, peer_number, userdata, true);
- int close_index = add_conn_to_groupchat(g_c, friendcon_id, groupnum, 0, 1);
+ addpeer(g_c, groupnum, real_pk, temp_pk, peer_number, userdata, true, true);
+ const int close_index = add_conn_to_groupchat(g_c, friendcon_id, groupnum, GROUPCHAT_CLOSE_REASON_INTRODUCING, 1);
if (close_index != -1) {
g->close[close_index].group_number = other_groupnum;
g->close[close_index].type = GROUPCHAT_CLOSE_ONLINE;
- g->close[close_index].introduced = true;
}
group_new_peer_send(g_c, groupnum, peer_number, real_pk, temp_pk);
break;
}
+
default:
return;
}
@@ -1572,7 +1837,7 @@ static int send_packet_online(Friend_Connections *fr_c, int friendcon_id, uint16
sizeof(packet), 0) != -1;
}
-static unsigned int send_peer_kill(Group_Chats *g_c, int friendcon_id, uint16_t group_num);
+static int ping_groupchat(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)
{
@@ -1580,7 +1845,7 @@ static int handle_packet_online(Group_Chats *g_c, int friendcon_id, const uint8_
return -1;
}
- int groupnumber = get_group_num(g_c, data[sizeof(uint16_t)], data + sizeof(uint16_t) + 1);
+ const int groupnumber = get_group_num(g_c, data[sizeof(uint16_t)], data + sizeof(uint16_t) + 1);
if (groupnumber == -1) {
return -1;
@@ -1596,7 +1861,7 @@ static int handle_packet_online(Group_Chats *g_c, int friendcon_id, const uint8_
return -1;
}
- int index = friend_in_close(g, friendcon_id);
+ const int index = friend_in_close(g, friendcon_id);
if (index == -1) {
return -1;
@@ -1606,7 +1871,7 @@ static int handle_packet_online(Group_Chats *g_c, int friendcon_id, const uint8_
return -1;
}
- if (count_close_connected(g) == 0) {
+ if (count_close_connected(g) == 0 || (g->close[index].reasons & GROUPCHAT_CLOSE_REASON_INTRODUCER)) {
send_peer_query(g_c, friendcon_id, other_groupnum);
}
@@ -1614,18 +1879,68 @@ static int handle_packet_online(Group_Chats *g_c, int friendcon_id, const uint8_
g->close[index].type = GROUPCHAT_CLOSE_ONLINE;
send_packet_online(g_c->fr_c, friendcon_id, groupnumber, g->type, g->id);
+ if (g->close[index].reasons & GROUPCHAT_CLOSE_REASON_INTRODUCING) {
+ uint8_t real_pk[CRYPTO_PUBLIC_KEY_SIZE], temp_pk[CRYPTO_PUBLIC_KEY_SIZE];
+ get_friendcon_public_keys(real_pk, temp_pk, g_c->fr_c, friendcon_id);
+
+ const int peer_index = peer_in_chat(g, real_pk);
+
+ if (peer_index != -1) {
+ group_new_peer_send(g_c, groupnumber, g->group[peer_index].peer_number, real_pk, temp_pk);
+ }
+
+ g->need_send_name = true;
+ }
+
+ ping_groupchat(g_c, groupnumber);
+
return 0;
}
+static int handle_packet_rejoin(Group_Chats *g_c, int friendcon_id, const uint8_t *data, uint16_t length,
+ void *userdata)
+{
+ if (length < 1 + GROUP_ID_LENGTH) {
+ return -1;
+ }
+
+ const int32_t groupnum = get_group_num(g_c, *data, data + 1);
+
+ Group_c *g = get_group_c(g_c, groupnum);
+
+ if (!g) {
+ return -1;
+ }
+
+ uint8_t real_pk[CRYPTO_PUBLIC_KEY_SIZE], temp_pk[CRYPTO_PUBLIC_KEY_SIZE];
+ get_friendcon_public_keys(real_pk, temp_pk, g_c->fr_c, friendcon_id);
+
+ uint16_t peer_number;
+
+ if (!get_peer_number(g, real_pk, &peer_number)) {
+ return -1;
+ }
+
+ addpeer(g_c, groupnum, real_pk, temp_pk, peer_number, userdata, true, true);
+ const int close_index = add_conn_to_groupchat(g_c, friendcon_id, groupnum, GROUPCHAT_CLOSE_REASON_INTRODUCING, 1);
+
+ if (close_index != -1) {
+ send_packet_online(g_c->fr_c, friendcon_id, groupnum, g->type, g->id);
+ }
+
+ return 0;
+}
+
+
// 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 0 on failure
*/
-static unsigned int send_peer_kill(Group_Chats *g_c, int friendcon_id, uint16_t group_num)
+static unsigned int send_peer_introduced(Group_Chats *g_c, int friendcon_id, uint16_t group_num)
{
uint8_t packet[1];
- packet[0] = PEER_KILL_ID;
+ packet[0] = PEER_INTRODUCED_ID;
return send_packet_group_peer(g_c->fr_c, friendcon_id, PACKET_ID_DIRECT_CONFERENCE, group_num, packet, sizeof(packet));
}
@@ -1671,7 +1986,7 @@ static unsigned int send_peers(Group_Chats *g_c, uint32_t groupnumber, int frien
p = response_packet + 1;
}
- uint16_t peer_num = net_htons(g->group[i].peer_number);
+ const uint16_t peer_num = net_htons(g->group[i].peer_number);
memcpy(p, &peer_num, sizeof(peer_num));
p += sizeof(peer_num);
memcpy(p, g->group[i].real_pk, CRYPTO_PUBLIC_KEY_SIZE);
@@ -1732,17 +2047,17 @@ static int handle_send_peers(Group_Chats *g_c, uint32_t groupnumber, const uint8
g_c->connected_callback(g_c->m, groupnumber, userdata);
}
- group_name_send(g_c, groupnumber, g_c->m->name, g_c->m->name_length);
+ g->need_send_name = true;
}
- int peer_index = addpeer(g_c, groupnumber, d, d + CRYPTO_PUBLIC_KEY_SIZE, peer_num, userdata, true);
+ const int peer_index = addpeer(g_c, groupnumber, d, d + CRYPTO_PUBLIC_KEY_SIZE, peer_num, userdata, false, true);
if (peer_index == -1) {
return -1;
}
d += CRYPTO_PUBLIC_KEY_SIZE * 2;
- uint8_t name_length = *d;
+ const uint8_t name_length = *d;
d += 1;
if (name_length > (length - (d - data)) || name_length > MAX_NAME_LENGTH) {
@@ -1767,17 +2082,14 @@ static void handle_direct_packet(Group_Chats *g_c, uint32_t groupnumber, const u
}
switch (data[0]) {
- case PEER_KILL_ID: {
+ case PEER_INTRODUCED_ID: {
Group_c *g = get_group_c(g_c, groupnumber);
if (!g) {
return;
}
- if (!g->close[close_index].closest) {
- g->close[close_index].type = GROUPCHAT_CLOSE_NONE;
- kill_friend_connection(g_c->fr_c, g->close[close_index].number);
- }
+ remove_conn_reason(g_c, groupnumber, close_index, GROUPCHAT_CLOSE_REASON_INTRODUCING);
}
break;
@@ -1801,7 +2113,15 @@ static void handle_direct_packet(Group_Chats *g_c, uint32_t groupnumber, const u
break;
case PEER_TITLE_ID: {
- settitle(g_c, groupnumber, -1, data + 1, length - 1, userdata);
+ Group_c *g = get_group_c(g_c, groupnumber);
+
+ if (!g) {
+ break;
+ }
+
+ if (!g->title_fresh) {
+ settitle(g_c, groupnumber, -1, data + 1, length - 1, userdata);
+ }
}
break;
@@ -1868,7 +2188,7 @@ static unsigned int send_lossy_all_close(const Group_Chats *g_c, uint32_t groupn
continue;
}
- if (g->close[i].closest) {
+ if (g->close[i].reasons & GROUPCHAT_CLOSE_REASON_CLOSEST) {
connected_closest[num_connected_closest] = i;
++num_connected_closest;
continue;
@@ -1891,7 +2211,7 @@ static unsigned int send_lossy_all_close(const Group_Chats *g_c, uint32_t groupn
uint8_t real_pk[CRYPTO_PUBLIC_KEY_SIZE] = {0};
uint8_t dht_temp_pk[CRYPTO_PUBLIC_KEY_SIZE] = {0};
get_friendcon_public_keys(real_pk, dht_temp_pk, g_c->fr_c, g->close[connected_closest[i]].number);
- uint64_t comp_val = calculate_comp_value(g->real_pk, real_pk);
+ const uint64_t comp_val = calculate_comp_value(g->real_pk, real_pk);
if (comp_val < comp_val_old) {
to_send = connected_closest[i];
@@ -1911,7 +2231,7 @@ static unsigned int send_lossy_all_close(const Group_Chats *g_c, uint32_t groupn
uint8_t real_pk[CRYPTO_PUBLIC_KEY_SIZE] = {0};
uint8_t dht_temp_pk[CRYPTO_PUBLIC_KEY_SIZE] = {0};
get_friendcon_public_keys(real_pk, dht_temp_pk, g_c->fr_c, g->close[connected_closest[i]].number);
- uint64_t comp_val = calculate_comp_value(real_pk, g->real_pk);
+ const uint64_t comp_val = calculate_comp_value(real_pk, g->real_pk);
if (comp_val < comp_val_old) {
to_send_other = connected_closest[i];
@@ -1957,7 +2277,7 @@ static int send_message_group(const Group_Chats *g_c, uint32_t groupnumber, uint
}
VLA(uint8_t, packet, sizeof(uint16_t) + sizeof(uint32_t) + 1 + len);
- uint16_t peer_num = net_htons(g->peer_number);
+ const uint16_t peer_num = net_htons(g->peer_number);
memcpy(packet, &peer_num, sizeof(peer_num));
++g->message_number;
@@ -1966,7 +2286,7 @@ static int send_message_group(const Group_Chats *g_c, uint32_t groupnumber, uint
++g->message_number;
}
- uint32_t message_num = net_htonl(g->message_number);
+ const uint32_t message_num = net_htonl(g->message_number);
memcpy(packet + sizeof(uint16_t), &message_num, sizeof(message_num));
packet[sizeof(uint16_t) + sizeof(uint32_t)] = message_id;
@@ -1986,7 +2306,7 @@ static int send_message_group(const Group_Chats *g_c, uint32_t groupnumber, uint
*/
int group_message_send(const Group_Chats *g_c, uint32_t groupnumber, const uint8_t *message, uint16_t length)
{
- int ret = send_message_group(g_c, groupnumber, PACKET_ID_MESSAGE, message, length);
+ const int ret = send_message_group(g_c, groupnumber, PACKET_ID_MESSAGE, message, length);
if (ret > 0) {
return 0;
@@ -2001,7 +2321,7 @@ int group_message_send(const Group_Chats *g_c, uint32_t groupnumber, const uint8
*/
int group_action_send(const Group_Chats *g_c, uint32_t groupnumber, const uint8_t *action, uint16_t length)
{
- int ret = send_message_group(g_c, groupnumber, PACKET_ID_ACTION, action, length);
+ const int ret = send_message_group(g_c, groupnumber, PACKET_ID_ACTION, action, length);
if (ret > 0) {
return 0;
@@ -2025,9 +2345,9 @@ int send_group_lossy_packet(const Group_Chats *g_c, uint32_t groupnumber, const
}
VLA(uint8_t, packet, sizeof(uint16_t) * 2 + length);
- uint16_t peer_number = net_htons(g->peer_number);
+ const uint16_t peer_number = net_htons(g->peer_number);
memcpy(packet, &peer_number, sizeof(uint16_t));
- uint16_t message_num = net_htons(g->lossy_message_number);
+ const uint16_t message_num = net_htons(g->lossy_message_number);
memcpy(packet + sizeof(uint16_t), &message_num, sizeof(uint16_t));
memcpy(packet + sizeof(uint16_t) * 2, data, length);
@@ -2108,33 +2428,31 @@ static void handle_message_packet_group(Group_Chats *g_c, uint32_t groupnumber,
memcpy(&peer_number, data, sizeof(uint16_t));
peer_number = net_ntohs(peer_number);
- int index = get_peer_index(g, peer_number);
+ const int index = note_peer_active(g_c, groupnumber, peer_number, userdata);
if (index == -1) {
- /* We don't know the peer this packet came from so we query the list of peers from that peer.
- (They would not have relayed it if they didn't know the peer.) */
+ /* If we don't know the peer this packet came from, then we query the
+ * list of peers from the relaying peer.
+ * (They would not have relayed it if they didn't know the peer.) */
send_peer_query(g_c, g->close[close_index].number, g->close[close_index].group_number);
return;
}
- if (g->number_joined != -1 && count_close_connected(g) >= DESIRED_CLOSE_CONNECTIONS) {
- const int fr_close_index = friend_in_close(g, g->number_joined);
+ if (g->num_introducer_connections > 0 && count_close_connected(g) > DESIRED_CLOSE_CONNECTIONS) {
+ for (uint32_t i = 0; i < MAX_GROUP_CONNECTIONS; ++i) {
+ if (g->close[i].type == GROUPCHAT_CLOSE_NONE
+ || !(g->close[i].reasons & GROUPCHAT_CLOSE_REASON_INTRODUCER)
+ || i == close_index) {
+ continue;
+ }
- if (fr_close_index >= 0 && fr_close_index != close_index && !g->close[fr_close_index].closest) {
uint8_t real_pk[CRYPTO_PUBLIC_KEY_SIZE];
- get_friendcon_public_keys(real_pk, nullptr, g_c->fr_c, g->close[fr_close_index].number);
+ get_friendcon_public_keys(real_pk, nullptr, g_c->fr_c, g->close[i].number);
if (id_equal(g->group[index].real_pk, real_pk)) {
/* Received message from peer relayed via another peer, so
* the introduction was successful */
- g->number_joined = -1;
- g->close[fr_close_index].introducer = false;
-
- if (!g->close[fr_close_index].closest && !g->close[fr_close_index].introduced) {
- g->close[fr_close_index].type = GROUPCHAT_CLOSE_NONE;
- send_peer_kill(g_c, g->close[fr_close_index].number, g->close[fr_close_index].group_number);
- kill_friend_connection(g_c->fr_c, g->close[fr_close_index].number);
- }
+ remove_conn_reason(g_c, groupnumber, i, GROUPCHAT_CLOSE_REASON_INTRODUCER);
}
}
}
@@ -2143,24 +2461,17 @@ static void handle_message_packet_group(Group_Chats *g_c, uint32_t groupnumber,
memcpy(&message_number, data + sizeof(uint16_t), sizeof(message_number));
message_number = net_ntohl(message_number);
- uint8_t message_id = data[sizeof(uint16_t) + sizeof(message_number)];
+ const uint8_t message_id = data[sizeof(uint16_t) + sizeof(message_number)];
const uint8_t *msg_data = data + sizeof(uint16_t) + sizeof(message_number) + 1;
- uint16_t msg_data_len = length - (sizeof(uint16_t) + sizeof(message_number) + 1);
+ const uint16_t msg_data_len = length - (sizeof(uint16_t) + sizeof(message_number) + 1);
- // FIXME(zugz) update discussion of message numbers in the spec
if (!check_message_info(message_number, message_id, &g->group[index])) {
return;
}
switch (message_id) {
- case GROUP_MESSAGE_PING_ID: {
- if (msg_data_len != 0) {
- return;
- }
-
- g->group[index].last_recv = unix_time();
- }
- break;
+ case GROUP_MESSAGE_PING_ID:
+ break;
case GROUP_MESSAGE_NEW_PEER_ID: {
if (msg_data_len != GROUP_MESSAGE_NEW_PEER_LENGTH) {
@@ -2171,7 +2482,7 @@ static void handle_message_packet_group(Group_Chats *g_c, uint32_t groupnumber,
memcpy(&new_peer_number, msg_data, sizeof(uint16_t));
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);
+ new_peer_number, userdata, true, true);
}
break;
@@ -2185,7 +2496,7 @@ static void handle_message_packet_group(Group_Chats *g_c, uint32_t groupnumber,
kill_peer_number = net_ntohs(kill_peer_number);
if (peer_number == kill_peer_number) {
- delpeer(g_c, groupnumber, index, userdata);
+ delpeer(g_c, groupnumber, index, userdata, false);
} else {
return;
// TODO(irungentoo):
@@ -2260,6 +2571,10 @@ static int g_handle_packet(void *object, int friendcon_id, const uint8_t *data,
return handle_packet_online(g_c, friendcon_id, data + 1, length - 1);
}
+ if (data[0] == PACKET_ID_REJOIN_CONFERENCE) {
+ return handle_packet_rejoin(g_c, friendcon_id, data + 1, length - 1, userdata);
+ }
+
if (data[0] != PACKET_ID_DIRECT_CONFERENCE && data[0] != PACKET_ID_MESSAGE_CONFERENCE) {
return -1;
}
@@ -2273,7 +2588,7 @@ static int g_handle_packet(void *object, int friendcon_id, const uint8_t *data,
return -1;
}
- int index = friend_in_close(g, friendcon_id);
+ const int index = friend_in_close(g, friendcon_id);
if (index == -1) {
return -1;
@@ -2335,7 +2650,7 @@ static unsigned int lossy_packet_not_received(Group_c *g, int peer_index, uint16
return -1;
}
- uint16_t top_distance = message_number - g->group[peer_index].top_lossy_number;
+ const uint16_t top_distance = message_number - g->group[peer_index].top_lossy_number;
if (top_distance >= MAX_LOSSY_COUNT) {
crypto_memzero(g->group[peer_index].recv_lossy, sizeof(g->group[peer_index].recv_lossy));
@@ -2384,7 +2699,7 @@ static int handle_lossy(void *object, int friendcon_id, const uint8_t *data, uin
return -1;
}
- int index = friend_in_close(g, friendcon_id);
+ const int index = friend_in_close(g, friendcon_id);
if (index == -1) {
return -1;
@@ -2394,7 +2709,7 @@ static int handle_lossy(void *object, int friendcon_id, const uint8_t *data, uin
return -1;
}
- int peer_index = get_peer_index(g, peer_number);
+ const int peer_index = get_peer_index(g, peer_number);
if (peer_index == -1) {
return -1;
@@ -2406,7 +2721,7 @@ static int handle_lossy(void *object, int friendcon_id, const uint8_t *data, uin
const uint8_t *lossy_data = data + 1 + sizeof(uint16_t) * 3;
uint16_t lossy_length = length - (1 + sizeof(uint16_t) * 3);
- uint8_t message_id = lossy_data[0];
+ const uint8_t message_id = lossy_data[0];
++lossy_data;
--lossy_length;
@@ -2508,16 +2823,16 @@ static int ping_groupchat(Group_Chats *g_c, uint32_t groupnumber)
return -1;
}
- if (is_timeout(g->last_sent_ping, GROUP_PING_INTERVAL)) {
+ if (mono_time_is_timeout(g_c->mono_time, g->last_sent_ping, GROUP_PING_INTERVAL)) {
if (group_ping_send(g_c, groupnumber) != -1) { /* Ping */
- g->last_sent_ping = unix_time();
+ g->last_sent_ping = mono_time_get(g_c->mono_time);
}
}
return 0;
}
-static int groupchat_clear_timedout(Group_Chats *g_c, uint32_t groupnumber, void *userdata)
+static int groupchat_freeze_timedout(Group_Chats *g_c, uint32_t groupnumber, void *userdata)
{
Group_c *g = get_group_c(g_c, groupnumber);
@@ -2526,15 +2841,19 @@ static int groupchat_clear_timedout(Group_Chats *g_c, uint32_t groupnumber, void
}
for (uint32_t i = 0; i < g->numpeers; ++i) {
- if (g->peer_number != g->group[i].peer_number && is_timeout(g->group[i].last_recv, GROUP_PING_INTERVAL * 3)) {
- delpeer(g_c, groupnumber, i, userdata);
+ if (g->group[i].peer_number == g->peer_number) {
+ continue;
}
- if (g->group == nullptr || i >= g->numpeers) {
- break;
+ if (mono_time_is_timeout(g_c->mono_time, g->group[i].last_active, GROUP_PING_INTERVAL * 3)) {
+ freeze_peer(g_c, groupnumber, i, userdata);
}
}
+ if (g->numpeers <= 1) {
+ g->title_fresh = false;
+ }
+
return 0;
}
@@ -2551,12 +2870,13 @@ void send_name_all_groups(Group_Chats *g_c)
if (g->status == GROUPCHAT_STATUS_CONNECTED) {
group_name_send(g_c, i, g_c->m->name, g_c->m->name_length);
+ g->need_send_name = false;
}
}
}
/* Create new groupchat instance. */
-Group_Chats *new_groupchats(Messenger *m)
+Group_Chats *new_groupchats(Mono_Time *mono_time, Messenger *m)
{
if (!m) {
return nullptr;
@@ -2568,6 +2888,7 @@ Group_Chats *new_groupchats(Messenger *m)
return nullptr;
}
+ temp->mono_time = mono_time;
temp->m = m;
temp->fr_c = m->fr_c;
m->conferences_object = temp;
@@ -2589,7 +2910,12 @@ void do_groupchats(Group_Chats *g_c, void *userdata)
if (g->status == GROUPCHAT_STATUS_CONNECTED) {
connect_to_closest(g_c, i, userdata);
ping_groupchat(g_c, i);
- groupchat_clear_timedout(g_c, i, userdata);
+ groupchat_freeze_timedout(g_c, i, userdata);
+
+ if (g->need_send_name) {
+ group_name_send(g_c, i, g_c->m->name, g_c->m->name_length);
+ g->need_send_name = false;
+ }
}
}
diff --git a/protocols/Tox/libtox/src/toxcore/group.h b/protocols/Tox/libtox/src/toxcore/group.h
index 175999ae78..7acd46371e 100644
--- a/protocols/Tox/libtox/src/toxcore/group.h
+++ b/protocols/Tox/libtox/src/toxcore/group.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright © 2016-2017 The TokTok team.
+ * Copyright © 2016-2018 The TokTok team.
* Copyright © 2014 Tox project.
*
* This file is part of Tox, the free peer to peer instant messenger.
@@ -21,8 +21,8 @@
* You should have received a copy of the GNU General Public License
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef GROUP_H
-#define GROUP_H
+#ifndef C_TOXCORE_TOXCORE_GROUP_H
+#define C_TOXCORE_TOXCORE_GROUP_H
#include "Messenger.h"
@@ -49,12 +49,13 @@ typedef struct Message_Info {
typedef struct Group_Peer {
uint8_t real_pk[CRYPTO_PUBLIC_KEY_SIZE];
uint8_t temp_pk[CRYPTO_PUBLIC_KEY_SIZE];
+ bool temp_pk_updated;
- uint64_t last_recv;
+ uint64_t last_active;
Message_Info
last_message_infos[MAX_LAST_MESSAGE_INFOS]; /* received messages, strictly decreasing in message_number */
- uint8_t num_last_message_infos;
+ uint8_t num_last_message_infos;
uint8_t nick[MAX_NAME_LENGTH];
uint8_t nick_len;
@@ -79,11 +80,18 @@ typedef enum Groupchat_Close_Type {
GROUPCHAT_CLOSE_ONLINE
} Groupchat_Close_Type;
+/* Connection is to one of the closest DESIRED_CLOSE_CONNECTIONS peers */
+#define GROUPCHAT_CLOSE_REASON_CLOSEST (1 << 0)
+
+/* Connection is to a peer we are introducing to the conference */
+#define GROUPCHAT_CLOSE_REASON_INTRODUCING (1 << 1)
+
+/* Connection is to a peer who is introducing us to the conference */
+#define GROUPCHAT_CLOSE_REASON_INTRODUCER (1 << 2)
+
typedef struct Groupchat_Close {
uint8_t type; /* GROUPCHAT_CLOSE_* */
- bool closest; /* connected to peer because it is one of our closest peers */
- bool introducer; /* connected to peer because it introduced us to the group */
- bool introduced; /* connected to peer because we introduced it to the group */
+ uint8_t reasons; /* bit field with flags GROUPCHAT_CLOSE_REASON_* */
uint32_t number;
uint16_t group_number;
} Groupchat_Close;
@@ -101,9 +109,15 @@ typedef void group_on_delete_cb(void *object, uint32_t conference_number);
typedef struct Group_c {
uint8_t status;
+ bool need_send_name;
+ bool title_fresh;
+
Group_Peer *group;
uint32_t numpeers;
+ Group_Peer *frozen;
+ uint32_t numfrozen;
+
/* TODO(zugz) rename close to something more accurate - "connected"? */
Groupchat_Close close[MAX_GROUP_CONNECTIONS];
@@ -123,7 +137,7 @@ typedef struct Group_c {
uint64_t last_sent_ping;
- int number_joined; /* friendcon_id of person that invited us to the chat. (-1 means none) */
+ uint32_t num_introducer_connections;
void *object;
@@ -172,6 +186,8 @@ typedef struct Group_Lossy_Handler {
} Group_Lossy_Handler;
typedef struct Group_Chats {
+ const Mono_Time *mono_time;
+
Messenger *m;
Friend_Connections *fr_c;
@@ -433,7 +449,7 @@ int callback_groupchat_peer_delete(Group_Chats *g_c, uint32_t groupnumber, peer_
int callback_groupchat_delete(Group_Chats *g_c, uint32_t groupnumber, group_on_delete_cb *function);
/* Create new groupchat instance. */
-Group_Chats *new_groupchats(Messenger *m);
+Group_Chats *new_groupchats(Mono_Time *mono_time, Messenger *m);
/* main groupchats loop. */
void do_groupchats(Group_Chats *g_c, void *userdata);
diff --git a/protocols/Tox/libtox/src/toxcore/list.c b/protocols/Tox/libtox/src/toxcore/list.c
index e4c160544e..1cc143e24f 100644
--- a/protocols/Tox/libtox/src/toxcore/list.c
+++ b/protocols/Tox/libtox/src/toxcore/list.c
@@ -5,7 +5,7 @@
*/
/*
- * Copyright © 2016-2017 The TokTok team.
+ * Copyright © 2016-2018 The TokTok team.
* Copyright © 2014 Tox project.
*
* This file is part of Tox, the free peer to peer instant messenger.
diff --git a/protocols/Tox/libtox/src/toxcore/list.h b/protocols/Tox/libtox/src/toxcore/list.h
index 628b46a051..c9c72c2a80 100644
--- a/protocols/Tox/libtox/src/toxcore/list.h
+++ b/protocols/Tox/libtox/src/toxcore/list.h
@@ -5,7 +5,7 @@
*/
/*
- * Copyright © 2016-2017 The TokTok team.
+ * Copyright © 2016-2018 The TokTok team.
* Copyright © 2014 Tox project.
*
* This file is part of Tox, the free peer to peer instant messenger.
@@ -23,8 +23,8 @@
* You should have received a copy of the GNU General Public License
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef LIST_H
-#define LIST_H
+#ifndef C_TOXCORE_TOXCORE_LIST_H
+#define C_TOXCORE_TOXCORE_LIST_H
#include <stdint.h>
diff --git a/protocols/Tox/libtox/src/toxcore/logger.c b/protocols/Tox/libtox/src/toxcore/logger.c
index 5e16233c9b..51c30edec4 100644
--- a/protocols/Tox/libtox/src/toxcore/logger.c
+++ b/protocols/Tox/libtox/src/toxcore/logger.c
@@ -3,7 +3,7 @@
*/
/*
- * Copyright © 2016-2017 The TokTok team.
+ * Copyright © 2016-2018 The TokTok team.
* Copyright © 2013,2015 Tox project.
*
* This file is part of Tox, the free peer to peer instant messenger.
diff --git a/protocols/Tox/libtox/src/toxcore/logger.h b/protocols/Tox/libtox/src/toxcore/logger.h
index dd7edee768..2cae7a0efd 100644
--- a/protocols/Tox/libtox/src/toxcore/logger.h
+++ b/protocols/Tox/libtox/src/toxcore/logger.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright © 2016-2017 The TokTok team.
+ * Copyright © 2016-2018 The TokTok team.
* Copyright © 2013 Tox project.
*
* This file is part of Tox, the free peer to peer instant messenger.
@@ -21,8 +21,8 @@
* You should have received a copy of the GNU General Public License
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef TOXLOGGER_H
-#define TOXLOGGER_H
+#ifndef C_TOXCORE_TOXCORE_LOGGER_H
+#define C_TOXCORE_TOXCORE_LOGGER_H
#include <stdint.h>
@@ -32,6 +32,7 @@
#define MIN_LOGGER_LEVEL LOGGER_LEVEL_INFO
#endif
+// NOTE: Don't forget to update build system files after modifying the enum.
typedef enum Logger_Level {
LOGGER_LEVEL_TRACE,
LOGGER_LEVEL_DEBUG,
@@ -90,4 +91,4 @@ void logger_write(
#define LOGGER_WARNING(log, ...) LOGGER_WRITE(log, LOGGER_LEVEL_WARNING, __VA_ARGS__)
#define LOGGER_ERROR(log, ...) LOGGER_WRITE(log, LOGGER_LEVEL_ERROR , __VA_ARGS__)
-#endif /* TOXLOGGER_H */
+#endif // 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 0beb72542b..6e4bc067d3 100644
--- a/protocols/Tox/libtox/src/toxcore/mono_time.c
+++ b/protocols/Tox/libtox/src/toxcore/mono_time.c
@@ -28,113 +28,111 @@
struct Mono_Time {
uint64_t time;
uint64_t base_time;
+#ifdef OS_WIN32
+ uint64_t last_clock_mono;
+ uint64_t add_clock_mono;
+#endif
+
+ mono_time_current_time_cb *current_time_callback;
+ void *user_data;
};
-Mono_Time *mono_time_new(void)
+static uint64_t current_time_monotonic_default(Mono_Time *mono_time, void *user_data)
{
- Mono_Time *monotime = (Mono_Time *)malloc(sizeof(Mono_Time));
+ uint64_t time;
+#ifdef OS_WIN32
+ uint64_t old_add_clock_mono = mono_time->add_clock_mono;
+ time = (uint64_t)GetTickCount() + mono_time->add_clock_mono;
- if (monotime == nullptr) {
- return nullptr;
+ /* Check if time has decreased because of 32 bit wrap from GetTickCount(), while avoiding false positives from race
+ * conditions when multiple threads call this function at once */
+ if (time + 0x10000 < mono_time->last_clock_mono) {
+ uint32_t add = ~0;
+ /* use old_add_clock_mono rather than simply incrementing add_clock_mono, to handle the case that many threads
+ * simultaneously detect an overflow */
+ mono_time->add_clock_mono = old_add_clock_mono + add;
+ time += add;
}
- monotime->time = 0;
- monotime->base_time = 0;
+ mono_time->last_clock_mono = time;
+#else
+ struct timespec clock_mono;
+#if defined(__APPLE__)
+ clock_serv_t muhclock;
+ mach_timespec_t machtime;
- return monotime;
-}
+ host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &muhclock);
+ clock_get_time(muhclock, &machtime);
+ mach_port_deallocate(mach_task_self(), muhclock);
-void mono_time_free(Mono_Time *monotime)
-{
- free(monotime);
+ clock_mono.tv_sec = machtime.tv_sec;
+ clock_mono.tv_nsec = machtime.tv_nsec;
+#else
+ clock_gettime(CLOCK_MONOTONIC, &clock_mono);
+#endif
+ time = 1000ULL * clock_mono.tv_sec + (clock_mono.tv_nsec / 1000000ULL);
+#endif
+ return time;
}
-void mono_time_update(Mono_Time *monotime)
+Mono_Time *mono_time_new(void)
{
- if (monotime->base_time == 0) {
- monotime->base_time = ((uint64_t)time(nullptr) - (current_time_monotonic() / 1000ULL));
+ Mono_Time *mono_time = (Mono_Time *)malloc(sizeof(Mono_Time));
+
+ if (mono_time == nullptr) {
+ return nullptr;
}
- monotime->time = (current_time_monotonic() / 1000ULL) + monotime->base_time;
+ mono_time->current_time_callback = current_time_monotonic_default;
+ mono_time->user_data = nullptr;
+
+#ifdef OS_WIN32
+ mono_time->last_clock_mono = 0;
+ mono_time->add_clock_mono = 0;
+#endif
+
+ mono_time->time = 0;
+ mono_time->base_time = (uint64_t)time(nullptr) - (current_time_monotonic(mono_time) / 1000ULL);
+
+ mono_time_update(mono_time);
+
+ return mono_time;
}
-uint64_t mono_time_get(const Mono_Time *monotime)
+void mono_time_free(Mono_Time *mono_time)
{
- return monotime->time;
+ free(mono_time);
}
-bool mono_time_is_timeout(const Mono_Time *monotime, uint64_t timestamp, uint64_t timeout)
+void mono_time_update(Mono_Time *mono_time)
{
- return timestamp + timeout <= mono_time_get(monotime);
+ mono_time->time = (current_time_monotonic(mono_time) / 1000ULL) + mono_time->base_time;
}
-
-//!TOKSTYLE-
-// No global mutable state in Tokstyle.
-static Mono_Time global_time;
-//!TOKSTYLE+
-
-/* XXX: note that this is not thread-safe; if multiple threads call unix_time_update() concurrently, the return value of
- * unix_time() may fail to increase monotonically with increasing time */
-void unix_time_update(void)
+uint64_t mono_time_get(const Mono_Time *mono_time)
{
- mono_time_update(&global_time);
+ return mono_time->time;
}
-uint64_t unix_time(void)
+
+bool mono_time_is_timeout(const Mono_Time *mono_time, uint64_t timestamp, uint64_t timeout)
{
- return mono_time_get(&global_time);
+ return timestamp + timeout <= mono_time_get(mono_time);
}
-int is_timeout(uint64_t timestamp, uint64_t timeout)
+
+void mono_time_set_current_time_callback(Mono_Time *mono_time,
+ mono_time_current_time_cb *current_time_callback, void *user_data)
{
- return mono_time_is_timeout(&global_time, timestamp, timeout);
+ if (current_time_callback == nullptr) {
+ mono_time->current_time_callback = current_time_monotonic_default;
+ mono_time->user_data = nullptr;
+ } else {
+ mono_time->current_time_callback = current_time_callback;
+ mono_time->user_data = user_data;
+ }
}
-
-//!TOKSTYLE-
-// No global mutable state in Tokstyle.
-#ifdef OS_WIN32
-static uint64_t last_monotime;
-static uint64_t add_monotime;
-#endif
-//!TOKSTYLE+
-
/* return current monotonic time in milliseconds (ms). */
-uint64_t current_time_monotonic(void)
+uint64_t current_time_monotonic(Mono_Time *mono_time)
{
- uint64_t time;
-#ifdef OS_WIN32
- uint64_t old_add_monotime = add_monotime;
- time = (uint64_t)GetTickCount() + add_monotime;
-
- /* Check if time has decreased because of 32 bit wrap from GetTickCount(), while avoiding false positives from race
- * conditions when multiple threads call this function at once */
- if (time + 0x10000 < last_monotime) {
- uint32_t add = ~0;
- /* use old_add_monotime rather than simply incrementing add_monotime, to handle the case that many threads
- * simultaneously detect an overflow */
- add_monotime = old_add_monotime + add;
- time += add;
- }
-
- last_monotime = time;
-#else
- struct timespec monotime;
-#if defined(__linux__) && defined(CLOCK_MONOTONIC_RAW)
- clock_gettime(CLOCK_MONOTONIC_RAW, &monotime);
-#elif defined(__APPLE__)
- clock_serv_t muhclock;
- mach_timespec_t machtime;
-
- host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &muhclock);
- clock_get_time(muhclock, &machtime);
- mach_port_deallocate(mach_task_self(), muhclock);
-
- monotime.tv_sec = machtime.tv_sec;
- monotime.tv_nsec = machtime.tv_nsec;
-#else
- clock_gettime(CLOCK_MONOTONIC, &monotime);
-#endif
- time = 1000ULL * monotime.tv_sec + (monotime.tv_nsec / 1000000ULL);
-#endif
- return time;
+ return mono_time->current_time_callback(mono_time, mono_time->user_data);
}
diff --git a/protocols/Tox/libtox/src/toxcore/mono_time.h b/protocols/Tox/libtox/src/toxcore/mono_time.h
index 9775956085..503548f222 100644
--- a/protocols/Tox/libtox/src/toxcore/mono_time.h
+++ b/protocols/Tox/libtox/src/toxcore/mono_time.h
@@ -8,25 +8,62 @@
extern "C" {
#endif
+#ifndef MONO_TIME_DEFINED
+#define MONO_TIME_DEFINED
+/**
+ * The timer portion of the toxcore event loop.
+ *
+ * We update the time exactly once per tox_iterate call. Programs built on lower
+ * level APIs such as the DHT bootstrap node must update the time manually in
+ * each iteration.
+ *
+ * Time is kept per Tox instance, not globally, even though "time" as a concept
+ * is global. This is because by definition `mono_time` represents the time at
+ * the start of an iteration, and also by definition the time when all network
+ * events for the current iteration occurred. This affects mainly two situations:
+ *
+ * 1. Two timers started in the same iteration: e.g. two timers set to expire in
+ * 10 seconds will both expire at the same time, i.e. about 10 seconds later.
+ * If the time were global, `mono_time` would be a random number that is
+ * either the time at the start of an iteration, or 1 second later (since the
+ * timer resolution is 1 second). This can happen when one update happens at
+ * e.g. 10:00:00.995 and a few milliseconds later a concurrently running
+ * instance updates the time at 10:00:01.005, making one timer expire a
+ * second after the other.
+ * 2. One timer based on an event: if we want to encode a behaviour of a timer
+ * expiring e.g. 10 seconds after a network event occurred, we simply start a
+ * timer in the event handler. If a concurrent instance updates the time
+ * underneath us, it may instead expire 9 seconds after the event.
+ *
+ * Both these situations cause incorrect behaviour randomly. In practice,
+ * toxcore is somewhat robust against strange timer behaviour, but the
+ * 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 *monotime);
+void mono_time_free(Mono_Time *mono_time);
-void mono_time_update(Mono_Time *monotime);
-uint64_t mono_time_get(const Mono_Time *monotime);
-bool mono_time_is_timeout(const Mono_Time *monotime, uint64_t timestamp, uint64_t timeout);
-
-// TODO(#405): Use per-tox monotime, delete these functions.
-void unix_time_update(void);
-uint64_t unix_time(void);
-int is_timeout(uint64_t timestamp, uint64_t timeout);
+void mono_time_update(Mono_Time *mono_time);
+uint64_t mono_time_get(const Mono_Time *mono_time);
+bool mono_time_is_timeout(const Mono_Time *mono_time, uint64_t timestamp, uint64_t timeout);
/* return current monotonic time in milliseconds (ms). */
-uint64_t current_time_monotonic(void);
+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).
+ *
+ * The caller is obligated to ensure that current_time_monotonic() continues
+ * to increase monotonically.
+ */
+void mono_time_set_current_time_callback(Mono_Time *mono_time,
+ mono_time_current_time_cb *current_time_callback, void *user_data);
#ifdef __cplusplus
}
#endif
-#endif // C_TOXCORE_TOXCORE_MONO_TIME_H
+#endif // C_TOXCORE_TOXCORE_MONO_TIME_H
diff --git a/protocols/Tox/libtox/src/toxcore/net_crypto.c b/protocols/Tox/libtox/src/toxcore/net_crypto.c
index 8f5fd5071b..736b9c4a25 100644
--- a/protocols/Tox/libtox/src/toxcore/net_crypto.c
+++ b/protocols/Tox/libtox/src/toxcore/net_crypto.c
@@ -5,7 +5,7 @@
*/
/*
- * Copyright © 2016-2017 The TokTok team.
+ * Copyright © 2016-2018 The TokTok team.
* Copyright © 2013 Tox project.
*
* This file is part of Tox, the free peer to peer instant messenger.
@@ -134,6 +134,7 @@ typedef struct Crypto_Connection {
struct Net_Crypto {
const Logger *log;
+ Mono_Time *mono_time;
DHT *dht;
TCP_Connections *tcp_c;
@@ -248,10 +249,11 @@ static int create_cookie_request(const Net_Crypto *c, uint8_t *packet, uint8_t *
* return -1 on failure.
* return 0 on success.
*/
-static int create_cookie(const Logger *log, uint8_t *cookie, const uint8_t *bytes, const uint8_t *encryption_key)
+static int create_cookie(const Logger *log, const Mono_Time *mono_time, uint8_t *cookie, const uint8_t *bytes,
+ const uint8_t *encryption_key)
{
uint8_t contents[COOKIE_CONTENTS_LENGTH];
- const uint64_t temp_time = unix_time();
+ const uint64_t temp_time = mono_time_get(mono_time);
memcpy(contents, &temp_time, sizeof(temp_time));
memcpy(contents + sizeof(temp_time), bytes, COOKIE_DATA_LENGTH);
random_nonce(cookie);
@@ -269,7 +271,8 @@ static int create_cookie(const Logger *log, uint8_t *cookie, const uint8_t *byte
* return -1 on failure.
* return 0 on success.
*/
-static int open_cookie(const Logger *log, uint8_t *bytes, const uint8_t *cookie, const uint8_t *encryption_key)
+static int open_cookie(const Logger *log, const Mono_Time *mono_time, uint8_t *bytes, const uint8_t *cookie,
+ const uint8_t *encryption_key)
{
uint8_t contents[COOKIE_CONTENTS_LENGTH];
const int len = decrypt_data_symmetric(encryption_key, cookie, cookie + CRYPTO_NONCE_SIZE,
@@ -281,7 +284,7 @@ static int open_cookie(const Logger *log, uint8_t *bytes, const uint8_t *cookie,
uint64_t cookie_time;
memcpy(&cookie_time, contents, sizeof(cookie_time));
- const uint64_t temp_time = unix_time();
+ const uint64_t temp_time = mono_time_get(mono_time);
if (cookie_time + COOKIE_TIMEOUT < temp_time || temp_time < cookie_time) {
return -1;
@@ -307,7 +310,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, plain, cookie_plain, c->secret_symmetric_key) != 0) {
+ if (create_cookie(c->log, c->mono_time, plain, cookie_plain, c->secret_symmetric_key) != 0) {
return -1;
}
@@ -475,8 +478,8 @@ 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, plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE, cookie_plain,
- c->secret_symmetric_key) != 0) {
+ if (create_cookie(c->log, c->mono_time, plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE,
+ cookie_plain, c->secret_symmetric_key) != 0) {
return -1;
}
@@ -521,7 +524,7 @@ 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, cookie_plain, packet + 1, c->secret_symmetric_key) != 0) {
+ if (open_cookie(c->log, c->mono_time, cookie_plain, packet + 1, c->secret_symmetric_key) != 0) {
return -1;
}
@@ -581,7 +584,7 @@ static int add_ip_port_connection(Net_Crypto *c, int crypt_connection_id, IP_Por
}
if (net_family_is_ipv4(ip_port.ip.family)) {
- if (!ipport_equal(&ip_port, &conn->ip_portv4) && ip_is_lan(conn->ip_portv4.ip) != 0) {
+ 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)) {
return -1;
}
@@ -620,7 +623,7 @@ static IP_Port return_ip_port_connection(Net_Crypto *c, int crypt_connection_id)
return empty;
}
- uint64_t current_time = unix_time();
+ const uint64_t current_time = mono_time_get(c->mono_time);
bool v6 = 0, v4 = 0;
if ((UDP_DIRECT_TIMEOUT + conn->direct_lastrecv_timev4) > current_time) {
@@ -631,7 +634,10 @@ static IP_Port return_ip_port_connection(Net_Crypto *c, int crypt_connection_id)
v6 = 1;
}
- if (v4 && ip_is_lan(conn->ip_portv4.ip) == 0) {
+ /* 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)) {
return conn->ip_portv4;
}
@@ -639,6 +645,18 @@ static IP_Port return_ip_port_connection(Net_Crypto *c, int crypt_connection_id)
return conn->ip_portv6;
}
+ if (v4 && net_family_is_ipv4(conn->ip_portv4.ip.family)) {
+ return conn->ip_portv4;
+ }
+
+ if (ip_is_lan(conn->ip_portv4.ip)) {
+ return conn->ip_portv4;
+ }
+
+ if (net_family_is_ipv6(conn->ip_portv6.ip.family)) {
+ return conn->ip_portv6;
+ }
+
if (net_family_is_ipv4(conn->ip_portv4.ip.family)) {
return conn->ip_portv4;
}
@@ -681,13 +699,13 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t
}
// TODO(irungentoo): a better way of sending packets directly to confirm the others ip.
- uint64_t current_time = unix_time();
+ const uint64_t current_time = mono_time_get(c->mono_time);
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) {
direct_send_attempt = 1;
- conn->direct_send_attempt_time = unix_time();
+ conn->direct_send_attempt_time = mono_time_get(c->mono_time);
}
}
}
@@ -700,7 +718,7 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t
pthread_mutex_lock(&conn->mutex);
if (ret == 0) {
- conn->last_tcp_sent = current_time_monotonic();
+ conn->last_tcp_sent = current_time_monotonic(c->mono_time);
}
pthread_mutex_unlock(&conn->mutex);
@@ -954,8 +972,8 @@ static int generate_request_packet(const Logger *log, uint8_t *data, uint16_t le
* return -1 on failure.
* return number of requested packets on success.
*/
-static int handle_request_packet(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, const Logger *log, 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;
@@ -975,7 +993,7 @@ static int handle_request_packet(const Logger *log, Packets_Array *send_array, c
uint32_t n = 1;
uint32_t requested = 0;
- const uint64_t temp_time = current_time_monotonic();
+ const uint64_t temp_time = current_time_monotonic(mono_time);
uint64_t l_sent_time = ~0;
for (uint32_t i = send_array->buffer_start; i != send_array->buffer_end; ++i) {
@@ -1117,7 +1135,7 @@ static int reset_max_speed_reached(Net_Crypto *c, int crypt_connection_id)
return -1;
}
- dt->sent_time = current_time_monotonic();
+ dt->sent_time = current_time_monotonic(c->mono_time);
}
conn->maximum_speed_reached = 0;
@@ -1170,7 +1188,7 @@ static int64_t send_lossless_packet(Net_Crypto *c, int crypt_connection_id, cons
Packet_Data *dt1 = nullptr;
if (get_data_pointer(c->log, &conn->send_array, &dt1, packet_num) == 1) {
- dt1->sent_time = current_time_monotonic();
+ dt1->sent_time = current_time_monotonic(c->mono_time);
}
} else {
conn->maximum_speed_reached = 1;
@@ -1276,7 +1294,7 @@ static int send_requested_packets(Net_Crypto *c, int crypt_connection_id, uint32
return -1;
}
- const uint64_t temp_time = current_time_monotonic();
+ const uint64_t temp_time = current_time_monotonic(c->mono_time);
uint32_t i, num_sent = 0, array_size = num_packets_array(&conn->send_array);
for (i = 0; i < array_size; ++i) {
@@ -1392,7 +1410,7 @@ static int send_temp_packet(Net_Crypto *c, int crypt_connection_id)
return -1;
}
- conn->temp_packet_sent_time = current_time_monotonic();
+ conn->temp_packet_sent_time = current_time_monotonic(c->mono_time);
++conn->temp_packet_num_sent;
return 0;
}
@@ -1542,7 +1560,8 @@ 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->log, &conn->send_array, real_data, real_length, &rtt_calc_time, rtt_time);
+ int requested = handle_request_packet(c->mono_time, c->log, &conn->send_array, real_data, real_length, &rtt_calc_time,
+ rtt_time);
if (requested == -1) {
return -1;
@@ -1595,7 +1614,7 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const
}
if (rtt_calc_time != 0) {
- uint64_t rtt_time = current_time_monotonic() - rtt_calc_time;
+ uint64_t rtt_time = current_time_monotonic(c->mono_time) - rtt_calc_time;
if (rtt_time < conn->rtt_time) {
conn->rtt_time = rtt_time;
@@ -1841,9 +1860,9 @@ static int crypto_connection_add_source(Net_Crypto *c, int crypt_connection_id,
}
if (net_family_is_ipv4(source.ip.family)) {
- conn->direct_lastrecv_timev4 = unix_time();
+ conn->direct_lastrecv_timev4 = mono_time_get(c->mono_time);
} else {
- conn->direct_lastrecv_timev6 = unix_time();
+ conn->direct_lastrecv_timev6 = mono_time_get(c->mono_time);
}
return 0;
@@ -2069,7 +2088,7 @@ int set_direct_ip_port(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port,
return -1;
}
- const uint64_t direct_lastrecv_time = connected ? unix_time() : 0;
+ const uint64_t direct_lastrecv_time = connected ? mono_time_get(c->mono_time) : 0;
if (net_family_is_ipv4(ip_port.ip.family)) {
conn->direct_lastrecv_timev4 = direct_lastrecv_time;
@@ -2409,9 +2428,9 @@ 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)) {
- conn->direct_lastrecv_timev4 = unix_time();
+ conn->direct_lastrecv_timev4 = mono_time_get(c->mono_time);
} else {
- conn->direct_lastrecv_timev6 = unix_time();
+ conn->direct_lastrecv_timev6 = mono_time_get(c->mono_time);
}
pthread_mutex_unlock(&conn->mutex);
@@ -2438,7 +2457,7 @@ static int udp_handle_packet(void *object, IP_Port source, const uint8_t *packet
static void send_crypto_packets(Net_Crypto *c)
{
- const uint64_t temp_time = current_time_monotonic();
+ const uint64_t temp_time = current_time_monotonic(c->mono_time);
double total_send_rate = 0;
uint32_t peak_request_packet_interval = ~0;
@@ -2877,7 +2896,7 @@ Crypto_Conn_State crypto_connection_status(const Net_Crypto *c, int crypt_connec
if (direct_connected) {
*direct_connected = 0;
- uint64_t current_time = unix_time();
+ const uint64_t current_time = mono_time_get(c->mono_time);
if ((UDP_DIRECT_TIMEOUT + conn->direct_lastrecv_timev4) > current_time) {
*direct_connected = 1;
@@ -2923,10 +2942,8 @@ void load_secret_key(Net_Crypto *c, const uint8_t *sk)
/* Run this to (re)initialize net_crypto.
* Sets all the global connection variables to their default values.
*/
-Net_Crypto *new_net_crypto(const Logger *log, DHT *dht, TCP_Proxy_Info *proxy_info)
+Net_Crypto *new_net_crypto(const Logger *log, Mono_Time *mono_time, DHT *dht, TCP_Proxy_Info *proxy_info)
{
- unix_time_update();
-
if (dht == nullptr) {
return nullptr;
}
@@ -2938,8 +2955,9 @@ Net_Crypto *new_net_crypto(const Logger *log, DHT *dht, TCP_Proxy_Info *proxy_in
}
temp->log = log;
+ temp->mono_time = mono_time;
- temp->tcp_c = new_tcp_connections(dht_get_self_secret_key(dht), proxy_info);
+ temp->tcp_c = new_tcp_connections(mono_time, dht_get_self_secret_key(dht), proxy_info);
if (temp->tcp_c == nullptr) {
free(temp);
@@ -3016,7 +3034,6 @@ uint32_t crypto_run_interval(const Net_Crypto *c)
/* Main loop. */
void do_net_crypto(Net_Crypto *c, void *userdata)
{
- unix_time_update();
kill_timedout(c, userdata);
do_tcp(c, userdata);
send_crypto_packets(c);
diff --git a/protocols/Tox/libtox/src/toxcore/net_crypto.h b/protocols/Tox/libtox/src/toxcore/net_crypto.h
index e40b7bfd95..45e1a05ea2 100644
--- a/protocols/Tox/libtox/src/toxcore/net_crypto.h
+++ b/protocols/Tox/libtox/src/toxcore/net_crypto.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright © 2016-2017 The TokTok team.
+ * Copyright © 2016-2018 The TokTok team.
* Copyright © 2013 Tox project.
*
* This file is part of Tox, the free peer to peer instant messenger.
@@ -21,8 +21,8 @@
* You should have received a copy of the GNU General Public License
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NET_CRYPTO_H
-#define NET_CRYPTO_H
+#ifndef C_TOXCORE_TOXCORE_NET_CRYPTO_H
+#define C_TOXCORE_TOXCORE_NET_CRYPTO_H
#include "DHT.h"
#include "LAN_discovery.h"
@@ -58,9 +58,9 @@
/** Messages. **/
-#define PACKET_ID_PADDING 0 /* Denotes padding */
-#define PACKET_ID_REQUEST 1 /* Used to request unreceived packets */
-#define PACKET_ID_KILL 2 /* Used to kill connection */
+#define PACKET_ID_PADDING 0 // Denotes padding
+#define PACKET_ID_REQUEST 1 // Used to request unreceived packets
+#define PACKET_ID_KILL 2 // Used to kill connection
#define PACKET_ID_ONLINE 24
#define PACKET_ID_OFFLINE 25
@@ -69,8 +69,8 @@
#define PACKET_ID_USERSTATUS 50
#define PACKET_ID_TYPING 51
#define PACKET_ID_MESSAGE 64
-#define PACKET_ID_ACTION 65 /* PACKET_ID_MESSAGE + MESSAGE_ACTION */
-#define PACKET_ID_MSI 69 /* Used by AV to setup calls and etc */
+#define PACKET_ID_ACTION 65 // PACKET_ID_MESSAGE + MESSAGE_ACTION
+#define PACKET_ID_MSI 69 // Used by AV to setup calls and etc
#define PACKET_ID_FILE_SENDREQUEST 80
#define PACKET_ID_FILE_CONTROL 81
#define PACKET_ID_FILE_DATA 82
@@ -78,6 +78,7 @@
#define PACKET_ID_ONLINE_PACKET 97
#define PACKET_ID_DIRECT_CONFERENCE 98
#define PACKET_ID_MESSAGE_CONFERENCE 99
+#define PACKET_ID_REJOIN_CONFERENCE 100
#define PACKET_ID_LOSSY_CONFERENCE 199
/*** Crypto connections. ***/
@@ -91,7 +92,7 @@ typedef enum Crypto_Conn_State {
} Crypto_Conn_State;
/* Maximum size of receiving and sending packet buffers. */
-#define CRYPTO_PACKET_BUFFER_SIZE 32768 /* Must be a power of 2 */
+#define CRYPTO_PACKET_BUFFER_SIZE 32768 // Must be a power of 2
/* Minimum packet rate per second. */
#define CRYPTO_PACKET_MIN_RATE 4.0
@@ -120,7 +121,8 @@ typedef enum Crypto_Conn_State {
#define MAX_TCP_CONNECTIONS 64
#define MAX_TCP_RELAYS_PEER 4
-#define CRYPTO_MAX_PADDING 8 /* 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
at the dT defined in net_crypto.c */
@@ -343,7 +345,7 @@ void load_secret_key(Net_Crypto *c, const uint8_t *sk);
/* Create new instance of Net_Crypto.
* Sets all the global connection variables to their default values.
*/
-Net_Crypto *new_net_crypto(const Logger *log, DHT *dht, TCP_Proxy_Info *proxy_info);
+Net_Crypto *new_net_crypto(const Logger *log, Mono_Time *mono_time, DHT *dht, TCP_Proxy_Info *proxy_info);
/* return the optimal interval in ms for running do_net_crypto.
*/
diff --git a/protocols/Tox/libtox/src/toxcore/network.c b/protocols/Tox/libtox/src/toxcore/network.c
index 68ca43e5aa..917556ac44 100644
--- a/protocols/Tox/libtox/src/toxcore/network.c
+++ b/protocols/Tox/libtox/src/toxcore/network.c
@@ -3,7 +3,7 @@
*/
/*
- * Copyright © 2016-2017 The TokTok team.
+ * Copyright © 2016-2018 The TokTok team.
* Copyright © 2013 Tox project.
*
* This file is part of Tox, the free peer to peer instant messenger.
@@ -346,12 +346,7 @@ bool net_family_is_tox_tcp_ipv6(Family family)
return family.value == net_family_tox_tcp_ipv6.value;
}
-/* Check if socket is valid.
- *
- * return 1 if valid
- * return 0 if not valid
- */
-int sock_valid(Socket sock)
+bool sock_valid(Socket sock)
{
return sock.socket != net_invalid_socket.socket;
}
@@ -367,60 +362,40 @@ void kill_sock(Socket sock)
#endif
}
-/* Set socket as nonblocking
- *
- * return 1 on success
- * return 0 on failure
- */
-int set_socket_nonblock(Socket sock)
+bool set_socket_nonblock(Socket sock)
{
#ifdef OS_WIN32
u_long mode = 1;
- return (ioctlsocket(sock.socket, FIONBIO, &mode) == 0);
+ return ioctlsocket(sock.socket, FIONBIO, &mode) == 0;
#else
- return (fcntl(sock.socket, F_SETFL, O_NONBLOCK, 1) == 0);
+ return fcntl(sock.socket, F_SETFL, O_NONBLOCK, 1) == 0;
#endif
}
-/* Set socket to not emit SIGPIPE
- *
- * return 1 on success
- * return 0 on failure
- */
-int set_socket_nosigpipe(Socket sock)
+bool set_socket_nosigpipe(Socket sock)
{
#if defined(__APPLE__)
int set = 1;
return setsockopt(sock.socket, SOL_SOCKET, SO_NOSIGPIPE, (const char *)&set, sizeof(int)) == 0;
#else
- return 1;
+ return true;
#endif
}
-/* Enable SO_REUSEADDR on socket.
- *
- * return 1 on success
- * return 0 on failure
- */
-int set_socket_reuseaddr(Socket sock)
+bool set_socket_reuseaddr(Socket sock)
{
int set = 1;
return setsockopt(sock.socket, SOL_SOCKET, SO_REUSEADDR, (const char *)&set, sizeof(set)) == 0;
}
-/* Set socket to dual (IPv4 + IPv6 socket)
- *
- * return 1 on success
- * return 0 on failure
- */
-int set_socket_dualstack(Socket sock)
+bool set_socket_dualstack(Socket sock)
{
int ipv6only = 0;
socklen_t optsize = sizeof(ipv6only);
int res = getsockopt(sock.socket, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&ipv6only, &optsize);
if ((res == 0) && (ipv6only == 0)) {
- return 1;
+ return true;
}
ipv6only = 0;
@@ -641,8 +616,6 @@ void networking_poll(Networking_Core *net, void *userdata)
return;
}
- unix_time_update();
-
IP_Port ip_port;
uint8_t data[MAX_UDP_PACKET_SIZE];
uint32_t length;
@@ -975,16 +948,10 @@ void kill_networking(Networking_Core *net)
}
-/* ip_equal
- * compares two IPAny structures
- * unset means unequal
- *
- * returns 0 when not equal or when uninitialized
- */
-int ip_equal(const IP *a, const IP *b)
+bool ip_equal(const IP *a, const IP *b)
{
if (!a || !b) {
- return 0;
+ return false;
}
/* same family */
@@ -1002,7 +969,7 @@ int ip_equal(const IP *a, const IP *b)
a->ip.v6.uint64[1] == b->ip.v6.uint64[1];
}
- return 0;
+ return false;
}
/* different family: check on the IPv6 one if it is the IPv4 one embedded */
@@ -1020,23 +987,17 @@ int ip_equal(const IP *a, const IP *b)
}
}
- return 0;
+ return false;
}
-/* ipport_equal
- * compares two IPAny_Port structures
- * unset means unequal
- *
- * returns 0 when not equal or when uninitialized
- */
-int ipport_equal(const IP_Port *a, const IP_Port *b)
+bool ipport_equal(const IP_Port *a, const IP_Port *b)
{
if (!a || !b) {
- return 0;
+ return false;
}
if (!a->port || (a->port != b->port)) {
- return 0;
+ return false;
}
return ip_equal(&a->ip, &b->ip);
@@ -1155,25 +1116,10 @@ const char *ip_ntoa(const IP *ip, char *ip_str, size_t length)
return ip_str;
}
-/*
- * ip_parse_addr
- * parses IP structure into an address string
- *
- * input
- * ip: ip of TOX_AF_INET or TOX_AF_INET6 families
- * length: length of the address buffer
- * Must be at least INET_ADDRSTRLEN for TOX_AF_INET
- * and INET6_ADDRSTRLEN for TOX_AF_INET6
- *
- * output
- * address: dotted notation (IPv4: quad, IPv6: 16) or colon notation (IPv6)
- *
- * returns 1 on success, 0 on failure
- */
-int ip_parse_addr(const IP *ip, char *address, size_t length)
+bool ip_parse_addr(const IP *ip, char *address, size_t length)
{
if (!address || !ip) {
- return 0;
+ return false;
}
if (net_family_is_ipv4(ip->family)) {
@@ -1186,26 +1132,13 @@ int ip_parse_addr(const IP *ip, char *address, size_t length)
return inet_ntop(make_family(ip->family), addr, address, length) != nullptr;
}
- return 0;
+ return false;
}
-/*
- * addr_parse_ip
- * directly parses the input into an IP structure
- * tries IPv4 first, then IPv6
- *
- * input
- * address: dotted notation (IPv4: quad, IPv6: 16) or colon notation (IPv6)
- *
- * output
- * IP: family and the value is set on success
- *
- * returns 1 on success, 0 on failure
- */
-int addr_parse_ip(const char *address, IP *to)
+bool addr_parse_ip(const char *address, IP *to)
{
if (!address || !to) {
- return 0;
+ return false;
}
struct in_addr addr4;
@@ -1213,7 +1146,7 @@ int addr_parse_ip(const char *address, IP *to)
if (inet_pton(AF_INET, address, &addr4) == 1) {
to->family = net_family_ipv4;
get_ip4(&to->ip.v4, &addr4);
- return 1;
+ return true;
}
struct in6_addr addr6;
@@ -1221,29 +1154,12 @@ int addr_parse_ip(const char *address, IP *to)
if (inet_pton(AF_INET6, address, &addr6) == 1) {
to->family = net_family_ipv6;
get_ip6(&to->ip.v6, &addr6);
- return 1;
+ return true;
}
- return 0;
+ return false;
}
-/*
- * addr_resolve():
- * uses getaddrinfo to resolve an address into an IP address
- * uses the first IPv4/IPv6 addresses returned by getaddrinfo
- *
- * input
- * address: a hostname (or something parseable to an IP address)
- * to: to.family MUST be initialized, either set to a specific IP version
- * (TOX_AF_INET/TOX_AF_INET6) or to the unspecified AF_UNSPEC (= 0), if both
- * IP versions are acceptable
- * extra can be NULL and is only set in special circumstances, see returns
- *
- * returns in *to a valid IPAny (v4/v6),
- * prefers v6 if ip.family was AF_UNSPEC and both available
- * returns in *extra an IPv4 address, if family was AF_UNSPEC and *to is TOX_AF_INET6
- * returns 0 on failure, TOX_ADDR_RESOLVE_* on success.
- */
int addr_resolve(const char *address, IP *to, IP *extra)
{
if (!address || !to) {
@@ -1334,30 +1250,15 @@ int addr_resolve(const char *address, IP *to, IP *extra)
return result;
}
-/*
- * addr_resolve_or_parse_ip
- * resolves string into an IP address
- *
- * address: a hostname (or something parseable to an IP address)
- * to: to.family MUST be initialized, either set to a specific IP version
- * (TOX_AF_INET/TOX_AF_INET6) or to the unspecified AF_UNSPEC (= 0), if both
- * IP versions are acceptable
- * extra can be NULL and is only set in special circumstances, see returns
- *
- * returns in *tro a matching address (IPv6 or IPv4)
- * returns in *extra, if not NULL, an IPv4 address, if to->family was AF_UNSPEC
- * returns 1 on success
- * returns 0 on failure
- */
-int addr_resolve_or_parse_ip(const char *address, IP *to, IP *extra)
+bool addr_resolve_or_parse_ip(const char *address, IP *to, IP *extra)
{
if (!addr_resolve(address, to, extra)) {
if (!addr_parse_ip(address, to)) {
- return 0;
+ return false;
}
}
- return 1;
+ return true;
}
int net_connect(Socket sock, IP_Port ip_port)
@@ -1468,10 +1369,7 @@ void net_freeipport(IP_Port *ip_ports)
free(ip_ports);
}
-/* return 1 on success
- * return 0 on failure
- */
-int bind_to_port(Socket sock, Family family, uint16_t port)
+bool bind_to_port(Socket sock, Family family, uint16_t port)
{
struct sockaddr_storage addr = {0};
size_t addrsize;
@@ -1489,7 +1387,7 @@ int bind_to_port(Socket sock, Family family, uint16_t port)
addr6->sin6_family = AF_INET6;
addr6->sin6_port = net_htons(port);
} else {
- return 0;
+ return false;
}
return bind(sock.socket, (struct sockaddr *)&addr, addrsize) == 0;
diff --git a/protocols/Tox/libtox/src/toxcore/network.h b/protocols/Tox/libtox/src/toxcore/network.h
index 276896b6b7..a1d838422c 100644
--- a/protocols/Tox/libtox/src/toxcore/network.h
+++ b/protocols/Tox/libtox/src/toxcore/network.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright © 2016-2017 The TokTok team.
+ * Copyright © 2016-2018 The TokTok team.
* Copyright © 2013 Tox project.
*
* This file is part of Tox, the free peer to peer instant messenger.
@@ -21,8 +21,8 @@
* You should have received a copy of the GNU General Public License
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef NETWORK_H
-#define NETWORK_H
+#ifndef C_TOXCORE_TOXCORE_NETWORK_H
+#define C_TOXCORE_TOXCORE_NETWORK_H
#include "logger.h"
@@ -64,12 +64,12 @@ typedef struct Socket {
Socket net_socket(Family domain, int type, int protocol);
-/* Check if socket is valid.
+/**
+ * Check if socket is valid.
*
- * return 1 if valid
- * return 0 if not valid
+ * @return true if valid, false otherwise.
*/
-int sock_valid(Socket sock);
+bool sock_valid(Socket sock);
extern const Socket net_invalid_socket;
@@ -235,53 +235,49 @@ bool ipv6_ipv4_in_v6(IP6 a);
#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);
-/*
- * ip_parse_addr
- * parses IP structure into an address string
+/**
+ * Parses IP structure into an address string.
*
- * input
- * ip: ip of TOX_AF_INET or TOX_AF_INET6 families
- * length: length of the address buffer
- * Must be at least TOX_INET_ADDRSTRLEN for TOX_AF_INET
- * and TOX_INET6_ADDRSTRLEN for TOX_AF_INET6
+ * @param ip IP of TOX_AF_INET or TOX_AF_INET6 families.
+ * @param length length of the address buffer.
+ * Must be at least TOX_INET_ADDRSTRLEN for TOX_AF_INET
+ * and TOX_INET6_ADDRSTRLEN for TOX_AF_INET6
*
- * output
- * address: dotted notation (IPv4: quad, IPv6: 16) or colon notation (IPv6)
+ * @param address dotted notation (IPv4: quad, IPv6: 16) or colon notation (IPv6).
*
- * returns 1 on success, 0 on failure
+ * @return true on success, false on failure.
*/
-int ip_parse_addr(const IP *ip, char *address, size_t length);
+bool ip_parse_addr(const IP *ip, char *address, size_t length);
-/*
- * addr_parse_ip
- * directly parses the input into an IP structure
- * tries IPv4 first, then IPv6
+/**
+ * Directly parses the input into an IP structure.
*
- * input
- * address: dotted notation (IPv4: quad, IPv6: 16) or colon notation (IPv6)
+ * Tries IPv4 first, then IPv6.
*
- * output
- * IP: family and the value is set on success
+ * @param address dotted notation (IPv4: quad, IPv6: 16) or colon notation (IPv6).
+ * @param to family and the value is set on success.
*
- * returns 1 on success, 0 on failure
+ * @return true on success, false on failure.
*/
-int addr_parse_ip(const char *address, IP *to);
+bool addr_parse_ip(const char *address, IP *to);
-/* ip_equal
- * compares two IPAny structures
- * unset means unequal
+/**
+ * Compares two IPAny structures.
*
- * returns 0 when not equal or when uninitialized
+ * Unset means unequal.
+ *
+ * @return false when not equal or when uninitialized.
*/
-int ip_equal(const IP *a, const IP *b);
+bool ip_equal(const IP *a, const IP *b);
-/* ipport_equal
- * compares two IPAny_Port structures
- * unset means unequal
+/**
+ * Compares two IPAny_Port structures.
+ *
+ * Unset means unequal.
*
- * returns 0 when not equal or when uninitialized
+ * @return false when not equal or when uninitialized.
*/
-int ipport_equal(const IP_Port *a, const IP_Port *b);
+bool ipport_equal(const IP_Port *a, const IP_Port *b);
/* nulls out ip */
void ip_reset(IP *ip);
@@ -296,41 +292,40 @@ void ip_copy(IP *target, const IP *source);
/* copies an ip_port structure */
void ipport_copy(IP_Port *target, const IP_Port *source);
-/*
- * addr_resolve():
- * uses getaddrinfo to resolve an address into an IP address
- * uses the first IPv4/IPv6 addresses returned by getaddrinfo
+/**
+ * Uses getaddrinfo to resolve an address into an IP address.
*
- * input
- * address: a hostname (or something parseable to an IP address)
- * to: to.family MUST be initialized, either set to a specific IP version
+ * Uses the first IPv4/IPv6 addresses returned by getaddrinfo.
+ *
+ * @param address a hostname (or something parseable to an IP address)
+ * @param to to.family MUST be initialized, either set to a specific IP version
* (TOX_AF_INET/TOX_AF_INET6) or to the unspecified TOX_AF_UNSPEC (= 0), if both
* IP versions are acceptable
- * extra can be NULL and is only set in special circumstances, see returns
+ * @param extra can be NULL and is only set in special circumstances, see returns
*
* returns in *to a valid IPAny (v4/v6),
* prefers v6 if ip.family was TOX_AF_UNSPEC and both available
* returns in *extra an IPv4 address, if family was TOX_AF_UNSPEC and *to is TOX_AF_INET6
- * returns 0 on failure
+ *
+ * @return 0 on failure, TOX_ADDR_RESOLVE_* on success.
*/
int addr_resolve(const char *address, IP *to, IP *extra);
-/*
- * addr_resolve_or_parse_ip
- * resolves string into an IP address
+/**
+ * Resolves string into an IP address
*
- * address: a hostname (or something parseable to an IP address)
- * to: to.family MUST be initialized, either set to a specific IP version
+ * @param address a hostname (or something parseable to an IP address)
+ * @param to to.family MUST be initialized, either set to a specific IP version
* (TOX_AF_INET/TOX_AF_INET6) or to the unspecified TOX_AF_UNSPEC (= 0), if both
* IP versions are acceptable
- * extra can be NULL and is only set in special circumstances, see returns
+ * @param extra can be NULL and is only set in special circumstances, see returns
+ *
+ * returns in *tro a matching address (IPv6 or IPv4)
+ * returns in *extra, if not NULL, an IPv4 address, if to->family was TOX_AF_UNSPEC
*
- * returns in *tro a matching address (IPv6 or IPv4)
- * returns in *extra, if not NULL, an IPv4 address, if to->family was TOX_AF_UNSPEC
- * returns 1 on success
- * returns 0 on failure
+ * @return true on success, false on failure
*/
-int addr_resolve_or_parse_ip(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.
* Packet data is put into data.
@@ -354,33 +349,33 @@ int networking_at_startup(void);
*/
void kill_sock(Socket sock);
-/* Set socket as nonblocking
+/**
+ * Set socket as nonblocking
*
- * return 1 on success
- * return 0 on failure
+ * @return true on success, false on failure.
*/
-int set_socket_nonblock(Socket sock);
+bool set_socket_nonblock(Socket sock);
-/* Set socket to not emit SIGPIPE
+/**
+ * Set socket to not emit SIGPIPE
*
- * return 1 on success
- * return 0 on failure
+ * @return true on success, false on failure.
*/
-int set_socket_nosigpipe(Socket sock);
+bool set_socket_nosigpipe(Socket sock);
-/* Enable SO_REUSEADDR on socket.
+/**
+ * Enable SO_REUSEADDR on socket.
*
- * return 1 on success
- * return 0 on failure
+ * @return true on success, false on failure.
*/
-int set_socket_reuseaddr(Socket sock);
+bool set_socket_reuseaddr(Socket sock);
-/* Set socket to dual (IPv4 + IPv6 socket)
+/**
+ * Set socket to dual (IPv4 + IPv6 socket)
*
- * return 1 on success
- * return 0 on failure
+ * @return true on success, false on failure.
*/
-int set_socket_dualstack(Socket sock);
+bool set_socket_dualstack(Socket sock);
/* Basic network functions: */
@@ -413,10 +408,10 @@ int32_t net_getipport(const char *node, IP_Port **res, int tox_type);
*/
void net_freeipport(IP_Port *ip_ports);
-/* return 1 on success
- * return 0 on failure
+/**
+ * @return true on success, false on failure.
*/
-int bind_to_port(Socket sock, Family family, uint16_t port);
+bool bind_to_port(Socket sock, Family family, uint16_t port);
/* Get the last networking error code.
*
diff --git a/protocols/Tox/libtox/src/toxcore/onion.c b/protocols/Tox/libtox/src/toxcore/onion.c
index 5ba716fd6d..f1873992d5 100644
--- a/protocols/Tox/libtox/src/toxcore/onion.c
+++ b/protocols/Tox/libtox/src/toxcore/onion.c
@@ -46,9 +46,9 @@
#define KEY_REFRESH_INTERVAL (2 * 60 * 60)
static void change_symmetric_key(Onion *onion)
{
- if (is_timeout(onion->timestamp, KEY_REFRESH_INTERVAL)) {
+ if (mono_time_is_timeout(onion->mono_time, onion->timestamp, KEY_REFRESH_INTERVAL)) {
new_symmetric_key(onion->secret_symmetric_key);
- onion->timestamp = unix_time();
+ onion->timestamp = mono_time_get(onion->mono_time);
}
}
@@ -114,7 +114,7 @@ static int ipport_unpack(IP_Port *target, const uint8_t *data, unsigned int data
*
* Create a new onion path out of nodes (nodes is a list of ONION_PATH_LENGTH nodes)
*
- * new_path must be an empty memory location of atleast Onion_Path size.
+ * new_path must be an empty memory location of at least Onion_Path size.
*
* return -1 on failure.
* return 0 on success.
@@ -343,7 +343,8 @@ static int handle_send_initial(void *object, IP_Port source, const uint8_t *pack
uint8_t plain[ONION_MAX_PACKET_SIZE];
uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE];
- get_shared_key(&onion->shared_keys_1, shared_key, dht_get_self_secret_key(onion->dht), packet + 1 + CRYPTO_NONCE_SIZE);
+ get_shared_key(onion->mono_time, &onion->shared_keys_1, shared_key, dht_get_self_secret_key(onion->dht),
+ packet + 1 + CRYPTO_NONCE_SIZE);
int len = decrypt_data_symmetric(shared_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE,
length - (1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE), plain);
@@ -412,7 +413,8 @@ static int handle_send_1(void *object, IP_Port source, const uint8_t *packet, ui
uint8_t plain[ONION_MAX_PACKET_SIZE];
uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE];
- get_shared_key(&onion->shared_keys_2, shared_key, dht_get_self_secret_key(onion->dht), packet + 1 + CRYPTO_NONCE_SIZE);
+ get_shared_key(onion->mono_time, &onion->shared_keys_2, shared_key, dht_get_self_secret_key(onion->dht),
+ packet + 1 + CRYPTO_NONCE_SIZE);
int len = decrypt_data_symmetric(shared_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE,
length - (1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + RETURN_1), plain);
@@ -468,7 +470,8 @@ static int handle_send_2(void *object, IP_Port source, const uint8_t *packet, ui
uint8_t plain[ONION_MAX_PACKET_SIZE];
uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE];
- get_shared_key(&onion->shared_keys_3, shared_key, dht_get_self_secret_key(onion->dht), packet + 1 + CRYPTO_NONCE_SIZE);
+ get_shared_key(onion->mono_time, &onion->shared_keys_3, shared_key, dht_get_self_secret_key(onion->dht),
+ packet + 1 + CRYPTO_NONCE_SIZE);
int len = decrypt_data_symmetric(shared_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE,
length - (1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + RETURN_2), plain);
@@ -662,7 +665,7 @@ void set_callback_handle_recv_1(Onion *onion, onion_recv_1_cb *function, void *o
onion->callback_object = object;
}
-Onion *new_onion(DHT *dht)
+Onion *new_onion(Mono_Time *mono_time, DHT *dht)
{
if (dht == nullptr) {
return nullptr;
@@ -676,8 +679,9 @@ Onion *new_onion(DHT *dht)
onion->dht = dht;
onion->net = dht_get_net(dht);
+ onion->mono_time = mono_time;
new_symmetric_key(onion->secret_symmetric_key);
- onion->timestamp = unix_time();
+ onion->timestamp = mono_time_get(onion->mono_time);
networking_registerhandler(onion->net, NET_PACKET_ONION_SEND_INITIAL, &handle_send_initial, onion);
networking_registerhandler(onion->net, NET_PACKET_ONION_SEND_1, &handle_send_1, onion);
diff --git a/protocols/Tox/libtox/src/toxcore/onion.h b/protocols/Tox/libtox/src/toxcore/onion.h
index 0e025a1ceb..20cd1e5c2f 100644
--- a/protocols/Tox/libtox/src/toxcore/onion.h
+++ b/protocols/Tox/libtox/src/toxcore/onion.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright © 2016-2017 The TokTok team.
+ * Copyright © 2016-2018 The TokTok team.
* Copyright © 2013 Tox project.
*
* This file is part of Tox, the free peer to peer instant messenger.
@@ -21,15 +21,17 @@
* You should have received a copy of the GNU General Public License
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef ONION_H
-#define ONION_H
+#ifndef C_TOXCORE_TOXCORE_ONION_H
+#define C_TOXCORE_TOXCORE_ONION_H
#include "DHT.h"
+#include "mono_time.h"
typedef int onion_recv_1_cb(void *object, IP_Port dest, const uint8_t *data, uint16_t length);
typedef struct Onion {
- DHT *dht;
+ Mono_Time *mono_time;
+ DHT *dht;
Networking_Core *net;
uint8_t secret_symmetric_key[CRYPTO_SYMMETRIC_KEY_SIZE];
uint64_t timestamp;
@@ -83,7 +85,7 @@ typedef struct Onion_Path {
*
* Create a new onion path out of nodes (nodes is a list of ONION_PATH_LENGTH nodes)
*
- * new_path must be an empty memory location of atleast Onion_Path size.
+ * new_path must be an empty memory location of at least Onion_Path size.
*
* return -1 on failure.
* return 0 on success.
@@ -158,7 +160,7 @@ int onion_send_1(const Onion *onion, const uint8_t *plain, uint16_t len, IP_Port
*/
void set_callback_handle_recv_1(Onion *onion, onion_recv_1_cb *function, void *object);
-Onion *new_onion(DHT *dht);
+Onion *new_onion(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 d368facee8..f38772ddf1 100644
--- a/protocols/Tox/libtox/src/toxcore/onion_announce.c
+++ b/protocols/Tox/libtox/src/toxcore/onion_announce.c
@@ -3,7 +3,7 @@
*/
/*
- * Copyright © 2016-2017 The TokTok team.
+ * Copyright © 2016-2018 The TokTok team.
* Copyright © 2013 Tox project.
*
* This file is part of Tox, the free peer to peer instant messenger.
@@ -50,6 +50,7 @@ typedef struct Onion_Announce_Entry {
} Onion_Announce_Entry;
struct Onion_Announce {
+ Mono_Time *mono_time;
DHT *dht;
Networking_Core *net;
Onion_Announce_Entry entries[ONION_ANNOUNCE_MAX_ENTRIES];
@@ -256,7 +257,7 @@ 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) {
- if (!is_timeout(onion_a->entries[i].time, ONION_ANNOUNCE_TIMEOUT)
+ 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;
}
@@ -266,6 +267,7 @@ static int in_entries(const Onion_Announce *onion_a, const uint8_t *public_key)
}
typedef struct Cmp_data {
+ const Mono_Time *mono_time;
const uint8_t *base_public_key;
Onion_Announce_Entry entry;
} Cmp_data;
@@ -279,8 +281,8 @@ static int cmp_entry(const void *a, const void *b)
Onion_Announce_Entry entry2 = cmp2.entry;
const uint8_t *cmp_public_key = cmp1.base_public_key;
- int t1 = is_timeout(entry1.time, ONION_ANNOUNCE_TIMEOUT);
- int t2 = is_timeout(entry2.time, ONION_ANNOUNCE_TIMEOUT);
+ 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);
if (t1 && t2) {
return 0;
@@ -307,13 +309,15 @@ static int cmp_entry(const void *a, const void *b)
return 0;
}
-static void sort_onion_announce_list(Onion_Announce_Entry *list, unsigned int length, const uint8_t *comp_public_key)
+static void sort_onion_announce_list(Onion_Announce_Entry *list, unsigned int length, const Mono_Time *mono_time,
+ const uint8_t *comp_public_key)
{
// 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);
for (uint32_t i = 0; i < length; ++i) {
+ cmp_list[i].mono_time = mono_time;
cmp_list[i].base_public_key = comp_public_key;
cmp_list[i].entry = list[i];
}
@@ -338,7 +342,7 @@ static int add_to_entries(Onion_Announce *onion_a, IP_Port ret_ip_port, const ui
if (pos == -1) {
for (unsigned i = 0; i < ONION_ANNOUNCE_MAX_ENTRIES; ++i) {
- if (is_timeout(onion_a->entries[i].time, ONION_ANNOUNCE_TIMEOUT)) {
+ if (mono_time_is_timeout(onion_a->mono_time, onion_a->entries[i].time, ONION_ANNOUNCE_TIMEOUT)) {
pos = i;
}
}
@@ -358,9 +362,10 @@ static int add_to_entries(Onion_Announce *onion_a, IP_Port ret_ip_port, const ui
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 = unix_time();
+ onion_a->entries[pos].time = mono_time_get(onion_a->mono_time);
- sort_onion_announce_list(onion_a->entries, ONION_ANNOUNCE_MAX_ENTRIES, dht_get_self_public_key(onion_a->dht));
+ sort_onion_announce_list(onion_a->entries, ONION_ANNOUNCE_MAX_ENTRIES, onion_a->mono_time,
+ dht_get_self_public_key(onion_a->dht));
return in_entries(onion_a, public_key);
}
@@ -374,7 +379,8 @@ static int handle_announce_request(void *object, IP_Port source, const uint8_t *
const uint8_t *packet_public_key = packet + 1 + CRYPTO_NONCE_SIZE;
uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE];
- get_shared_key(&onion_a->shared_keys_recv, shared_key, dht_get_self_secret_key(onion_a->dht), packet_public_key);
+ get_shared_key(onion_a->mono_time, &onion_a->shared_keys_recv, shared_key, dht_get_self_secret_key(onion_a->dht),
+ packet_public_key);
uint8_t plain[ONION_PING_ID_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_PUBLIC_KEY_SIZE +
ONION_ANNOUNCE_SENDBACK_DATA_LENGTH];
@@ -387,10 +393,10 @@ static int handle_announce_request(void *object, IP_Port source, const uint8_t *
}
uint8_t ping_id1[ONION_PING_ID_SIZE];
- generate_ping_id(onion_a, unix_time(), packet_public_key, source, ping_id1);
+ generate_ping_id(onion_a, mono_time_get(onion_a->mono_time), packet_public_key, source, ping_id1);
uint8_t ping_id2[ONION_PING_ID_SIZE];
- generate_ping_id(onion_a, unix_time() + PING_ID_TIMEOUT, packet_public_key, source, ping_id2);
+ generate_ping_id(onion_a, mono_time_get(onion_a->mono_time) + PING_ID_TIMEOUT, packet_public_key, source, ping_id2);
int index;
@@ -406,8 +412,8 @@ 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) == 0, 1);
+ 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);
uint8_t nonce[CRYPTO_NONCE_SIZE];
random_nonce(nonce);
@@ -493,7 +499,7 @@ static int handle_data_request(void *object, IP_Port source, const uint8_t *pack
return 0;
}
-Onion_Announce *new_onion_announce(DHT *dht)
+Onion_Announce *new_onion_announce(Mono_Time *mono_time, DHT *dht)
{
if (dht == nullptr) {
return nullptr;
@@ -505,6 +511,7 @@ Onion_Announce *new_onion_announce(DHT *dht)
return nullptr;
}
+ onion_a->mono_time = mono_time;
onion_a->dht = dht;
onion_a->net = dht_get_net(dht);
new_symmetric_key(onion_a->secret_bytes);
diff --git a/protocols/Tox/libtox/src/toxcore/onion_announce.h b/protocols/Tox/libtox/src/toxcore/onion_announce.h
index 84e76a38a1..2eb5051b1f 100644
--- a/protocols/Tox/libtox/src/toxcore/onion_announce.h
+++ b/protocols/Tox/libtox/src/toxcore/onion_announce.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright © 2016-2017 The TokTok team.
+ * Copyright © 2016-2018 The TokTok team.
* Copyright © 2013 Tox project.
*
* This file is part of Tox, the free peer to peer instant messenger.
@@ -21,8 +21,8 @@
* You should have received a copy of the GNU General Public License
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef ONION_ANNOUNCE_H
-#define ONION_ANNOUNCE_H
+#ifndef C_TOXCORE_TOXCORE_ONION_ANNOUNCE_H
+#define C_TOXCORE_TOXCORE_ONION_ANNOUNCE_H
#include "onion.h"
@@ -120,7 +120,7 @@ int send_data_request(Networking_Core *net, const Onion_Path *path, IP_Port dest
const uint8_t *encrypt_public_key, const uint8_t *nonce, const uint8_t *data, uint16_t length);
-Onion_Announce *new_onion_announce(DHT *dht);
+Onion_Announce *new_onion_announce(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 819bd23fae..1c3b34dabf 100644
--- a/protocols/Tox/libtox/src/toxcore/onion_client.c
+++ b/protocols/Tox/libtox/src/toxcore/onion_client.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright © 2016-2017 The TokTok team.
+ * Copyright © 2016-2018 The TokTok team.
* Copyright © 2013 Tox project.
*
* This file is part of Tox, the free peer to peer instant messenger.
@@ -84,8 +84,6 @@ typedef struct Onion_Friend {
uint8_t temp_public_key[CRYPTO_PUBLIC_KEY_SIZE];
uint8_t temp_secret_key[CRYPTO_SECRET_KEY_SIZE];
- uint64_t last_reported_announced;
-
uint64_t last_dht_pk_onion_sent;
uint64_t last_dht_pk_dht_sent;
@@ -113,6 +111,8 @@ typedef struct Onion_Data_Handler {
} Onion_Data_Handler;
struct Onion_Client {
+ Mono_Time *mono_time;
+
DHT *dht;
Net_Crypto *c;
Networking_Core *net;
@@ -316,16 +316,16 @@ static uint16_t random_nodes_path_onion(const Onion_Client *onion_c, Node_format
* 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 Onion_Client_Paths *onion_paths, const Node_format *nodes)
+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) {
- if (is_timeout(onion_paths->last_path_success[i], ONION_PATH_TIMEOUT)) {
+ if (mono_time_is_timeout(mono_time, onion_paths->last_path_success[i], ONION_PATH_TIMEOUT)) {
continue;
}
- if (is_timeout(onion_paths->path_creation_time[i], ONION_PATH_MAX_LIFETIME)) {
+ if (mono_time_is_timeout(mono_time, onion_paths->path_creation_time[i], ONION_PATH_MAX_LIFETIME)) {
continue;
}
@@ -339,7 +339,7 @@ static int is_path_used(const Onion_Client_Paths *onion_paths, const Node_format
}
/* is path timed out */
-static bool path_timed_out(Onion_Client_Paths *onion_paths, uint32_t pathnum)
+static bool path_timed_out(const Mono_Time *mono_time, Onion_Client_Paths *onion_paths, uint32_t pathnum)
{
pathnum = pathnum % NUMBER_ONION_PATHS;
@@ -347,16 +347,16 @@ static bool path_timed_out(Onion_Client_Paths *onion_paths, uint32_t pathnum)
uint64_t timeout = is_new ? ONION_PATH_FIRST_TIMEOUT : ONION_PATH_TIMEOUT;
return ((onion_paths->last_path_used_times[pathnum] >= ONION_PATH_MAX_NO_RESPONSE_USES
- && is_timeout(onion_paths->last_path_used[pathnum], timeout))
- || is_timeout(onion_paths->path_creation_time[pathnum], ONION_PATH_MAX_LIFETIME));
+ && mono_time_is_timeout(mono_time, onion_paths->last_path_used[pathnum], timeout))
+ || mono_time_is_timeout(mono_time, onion_paths->path_creation_time[pathnum], ONION_PATH_MAX_LIFETIME));
}
/* should node be considered to have timed out */
-static bool onion_node_timed_out(const Onion_Node *node)
+static bool onion_node_timed_out(const Onion_Node *node, const Mono_Time *mono_time)
{
return (node->timestamp == 0
|| (node->unsuccessful_pings >= ONION_NODE_MAX_PINGS
- && is_timeout(node->last_pinged, ONION_NODE_TIMEOUT)));
+ && 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)
@@ -376,21 +376,21 @@ static int random_path(const Onion_Client *onion_c, Onion_Client_Paths *onion_pa
pathnum = pathnum % NUMBER_ONION_PATHS;
}
- if (path_timed_out(onion_paths, pathnum)) {
+ if (path_timed_out(onion_c->mono_time, onion_paths, pathnum)) {
Node_format nodes[ONION_PATH_LENGTH];
if (random_nodes_path_onion(onion_c, nodes, ONION_PATH_LENGTH) != ONION_PATH_LENGTH) {
return -1;
}
- int n = is_path_used(onion_paths, nodes);
+ int n = is_path_used(onion_c->mono_time, onion_paths, nodes);
if (n == -1) {
if (create_onion_path(onion_c->dht, &onion_paths->paths[pathnum], nodes) == -1) {
return -1;
}
- onion_paths->path_creation_time[pathnum] = unix_time();
+ onion_paths->path_creation_time[pathnum] = mono_time_get(onion_c->mono_time);
onion_paths->last_path_success[pathnum] = onion_paths->path_creation_time[pathnum];
onion_paths->last_path_used_times[pathnum] = ONION_PATH_MAX_NO_RESPONSE_USES / 2;
@@ -406,7 +406,7 @@ static int random_path(const Onion_Client *onion_c, Onion_Client_Paths *onion_pa
}
if (onion_paths->last_path_used_times[pathnum] < ONION_PATH_MAX_NO_RESPONSE_USES) {
- onion_paths->last_path_used[pathnum] = unix_time();
+ onion_paths->last_path_used[pathnum] = mono_time_get(onion_c->mono_time);
}
++onion_paths->last_path_used_times[pathnum];
@@ -415,9 +415,9 @@ static int random_path(const Onion_Client *onion_c, Onion_Client_Paths *onion_pa
}
/* Does path with path_num exist. */
-static bool path_exists(Onion_Client_Paths *onion_paths, uint32_t path_num)
+static bool path_exists(const Mono_Time *mono_time, Onion_Client_Paths *onion_paths, uint32_t path_num)
{
- if (path_timed_out(onion_paths, path_num)) {
+ if (path_timed_out(mono_time, onion_paths, path_num)) {
return 0;
}
@@ -442,7 +442,7 @@ static uint32_t set_path_timeouts(Onion_Client *onion_c, uint32_t num, uint32_t
}
if (onion_paths->paths[path_num % NUMBER_ONION_PATHS].path_num == path_num) {
- onion_paths->last_path_success[path_num % NUMBER_ONION_PATHS] = unix_time();
+ onion_paths->last_path_success[path_num % NUMBER_ONION_PATHS] = mono_time_get(onion_c->mono_time);
onion_paths->last_path_used_times[path_num % NUMBER_ONION_PATHS] = 0;
Node_format nodes[ONION_PATH_LENGTH];
@@ -521,7 +521,7 @@ static int new_sendback(Onion_Client *onion_c, uint32_t num, const uint8_t *publ
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 + sizeof(IP_Port), &path_num, sizeof(uint32_t));
- *sendback = ping_array_add(onion_c->announce_ping_array, data, sizeof(data));
+ *sendback = ping_array_add(onion_c->announce_ping_array, onion_c->mono_time, data, sizeof(data));
if (*sendback == 0) {
return -1;
@@ -547,7 +547,7 @@ static uint32_t check_sendback(Onion_Client *onion_c, const uint8_t *sendback, u
memcpy(&sback, sendback, sizeof(uint64_t));
uint8_t data[sizeof(uint32_t) + CRYPTO_PUBLIC_KEY_SIZE + sizeof(IP_Port) + sizeof(uint32_t)];
- if (ping_array_check(onion_c->announce_ping_array, data, sizeof(data), sback) != sizeof(data)) {
+ if (ping_array_check(onion_c->announce_ping_array, onion_c->mono_time, data, sizeof(data), sback) != sizeof(data)) {
return ~0;
}
@@ -611,6 +611,7 @@ static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, IP_
}
typedef struct Onion_Client_Cmp_data {
+ const Mono_Time *mono_time;
const uint8_t *base_public_key;
Onion_Node entry;
} Onion_Client_Cmp_data;
@@ -624,8 +625,8 @@ static int onion_client_cmp_entry(const void *a, const void *b)
Onion_Node entry2 = cmp2.entry;
const uint8_t *cmp_public_key = cmp1.base_public_key;
- int t1 = onion_node_timed_out(&entry1);
- int t2 = onion_node_timed_out(&entry2);
+ int t1 = onion_node_timed_out(&entry1, cmp1.mono_time);
+ int t2 = onion_node_timed_out(&entry2, cmp2.mono_time);
if (t1 && t2) {
return 0;
@@ -652,13 +653,15 @@ static int onion_client_cmp_entry(const void *a, const void *b)
return 0;
}
-static void sort_onion_node_list(Onion_Node *list, unsigned int length, const uint8_t *comp_public_key)
+static void sort_onion_node_list(Onion_Node *list, unsigned int length, const Mono_Time *mono_time,
+ const uint8_t *comp_public_key)
{
// 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);
for (uint32_t i = 0; i < length; ++i) {
+ cmp_list[i].mono_time = mono_time;
cmp_list[i].base_public_key = comp_public_key;
cmp_list[i].entry = list[i];
}
@@ -695,7 +698,7 @@ static int client_add_to_list(Onion_Client *onion_c, uint32_t num, const uint8_t
}
if (is_stored == 1) {
- onion_c->friends_list[num - 1].last_reported_announced = unix_time();
+ onion_c->friends_list[num - 1].last_seen = mono_time_get(onion_c->mono_time);
}
list_nodes = onion_c->friends_list[num - 1].clients_list;
@@ -703,12 +706,12 @@ static int client_add_to_list(Onion_Client *onion_c, uint32_t num, const uint8_t
list_length = MAX_ONION_CLIENTS;
}
- sort_onion_node_list(list_nodes, list_length, reference_id);
+ sort_onion_node_list(list_nodes, list_length, onion_c->mono_time, reference_id);
int index = -1, stored = 0;
unsigned int i;
- if (onion_node_timed_out(&list_nodes[0])
+ 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;
}
@@ -738,24 +741,25 @@ static int client_add_to_list(Onion_Client *onion_c, uint32_t num, const uint8_t
}
list_nodes[index].is_stored = is_stored;
- list_nodes[index].timestamp = unix_time();
+ list_nodes[index].timestamp = mono_time_get(onion_c->mono_time);
list_nodes[index].unsuccessful_pings = 0;
if (!stored) {
list_nodes[index].last_pinged = 0;
- list_nodes[index].added_time = unix_time();
+ list_nodes[index].added_time = mono_time_get(onion_c->mono_time);
}
list_nodes[index].path_used = path_used;
return 0;
}
-static int good_to_ping(Last_Pinged *last_pinged, uint8_t *last_pinged_index, const uint8_t *public_key)
+static int good_to_ping(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) {
- if (!is_timeout(last_pinged[i].timestamp, MIN_NODE_PING_TIME)) {
+ 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;
}
@@ -763,7 +767,7 @@ static int good_to_ping(Last_Pinged *last_pinged, uint8_t *last_pinged_index, co
}
memcpy(last_pinged[*last_pinged_index % MAX_STORED_PINGED_NODES].public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE);
- last_pinged[*last_pinged_index % MAX_STORED_PINGED_NODES].timestamp = unix_time();
+ last_pinged[*last_pinged_index % MAX_STORED_PINGED_NODES].timestamp = mono_time_get(mono_time);
++*last_pinged_index;
return 1;
}
@@ -800,21 +804,21 @@ 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;
}
- unsigned int i, j;
- int lan_ips_accepted = (ip_is_lan(source.ip) == 0);
-
- for (i = 0; i < num_nodes; ++i) {
+ 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) == 0) {
+ if (ip_is_lan(nodes[i].ip_port.ip)) {
continue;
}
}
- if (onion_node_timed_out(&list_nodes[0])
+ if (onion_node_timed_out(&list_nodes[0], onion_c->mono_time)
|| id_closest(reference_id, list_nodes[0].public_key, nodes[i].public_key) == 2
- || onion_node_timed_out(&list_nodes[1])
+ || onion_node_timed_out(&list_nodes[1], onion_c->mono_time)
|| id_closest(reference_id, list_nodes[1].public_key, nodes[i].public_key) == 2) {
+ uint32_t j;
+
/* check if node is already in list. */
for (j = 0; j < list_length; ++j) {
if (public_key_cmp(list_nodes[j].public_key, nodes[i].public_key) == 0) {
@@ -822,7 +826,7 @@ static int client_ping_nodes(Onion_Client *onion_c, uint32_t num, const Node_for
}
}
- if (j == list_length && good_to_ping(last_pinged, last_pinged_index, nodes[i].public_key)) {
+ 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, ~0);
}
}
@@ -894,7 +898,7 @@ static int handle_announce_response(void *object, IP_Port source, const uint8_t
}
// TODO(irungentoo): LAN vs non LAN ips?, if we are connected only to LAN, are we offline?
- onion_c->last_packet_recv = unix_time();
+ onion_c->last_packet_recv = mono_time_get(onion_c->mono_time);
return 0;
}
@@ -975,7 +979,7 @@ static int handle_dhtpk_announce(void *object, const uint8_t *source_pubkey, con
}
onion_set_friend_DHT_pubkey(onion_c, friend_num, data + 1 + sizeof(uint64_t));
- onion_c->friends_list[friend_num].last_seen = unix_time();
+ onion_c->friends_list[friend_num].last_seen = mono_time_get(onion_c->mono_time);
uint16_t len_nodes = length - DHTPK_DATA_MIN_LENGTH;
@@ -1054,7 +1058,7 @@ int send_onion_data(Onion_Client *onion_c, int friend_num, const uint8_t *data,
Onion_Node *list_nodes = onion_c->friends_list[friend_num].clients_list;
for (i = 0; i < MAX_ONION_CLIENTS; ++i) {
- if (onion_node_timed_out(&list_nodes[i])) {
+ if (onion_node_timed_out(&list_nodes[i], onion_c->mono_time)) {
continue;
}
@@ -1196,7 +1200,7 @@ static int send_dhtpk_announce(Onion_Client *onion_c, uint16_t friend_num, uint8
uint8_t data[DHTPK_DATA_MAX_LENGTH];
data[0] = ONION_DATA_DHTPK;
- uint64_t no_replay = unix_time();
+ uint64_t no_replay = mono_time_get(onion_c->mono_time);
host_to_net((uint8_t *)&no_replay, sizeof(no_replay));
memcpy(data + 1, &no_replay, sizeof(no_replay));
memcpy(data + 1 + sizeof(uint64_t), dht_get_self_public_key(onion_c->dht), CRYPTO_PUBLIC_KEY_SIZE);
@@ -1397,7 +1401,7 @@ int onion_dht_pk_callback(Onion_Client *onion_c, int friend_num,
return 0;
}
-/* Set a friends DHT public key.
+/* Set a friend's DHT public key.
*
* return -1 on failure.
* return 0 on success.
@@ -1416,11 +1420,9 @@ int onion_set_friend_DHT_pubkey(Onion_Client *onion_c, int friend_num, const uin
if (public_key_cmp(dht_key, onion_c->friends_list[friend_num].dht_public_key) == 0) {
return -1;
}
-
- onion_c->friends_list[friend_num].know_dht_public_key = 0;
}
- onion_c->friends_list[friend_num].last_seen = unix_time();
+ onion_c->friends_list[friend_num].last_seen = mono_time_get(onion_c->mono_time);
onion_c->friends_list[friend_num].know_dht_public_key = 1;
memcpy(onion_c->friends_list[friend_num].dht_public_key, dht_key, CRYPTO_PUBLIC_KEY_SIZE);
@@ -1485,7 +1487,7 @@ int onion_set_friend_online(Onion_Client *onion_c, int friend_num, uint8_t is_on
}
if (is_online == 0 && onion_c->friends_list[friend_num].is_online == 1) {
- onion_c->friends_list[friend_num].last_seen = unix_time();
+ onion_c->friends_list[friend_num].last_seen = mono_time_get(onion_c->mono_time);
}
onion_c->friends_list[friend_num].is_online = is_online;
@@ -1547,11 +1549,12 @@ static void do_friend(Onion_Client *onion_c, uint16_t friendnum)
if (onion_c->friends_list[friendnum].run_count < RUN_COUNT_FRIEND_ANNOUNCE_BEGINNING) {
interval = ANNOUNCE_FRIEND_BEGINNING;
} else {
- if (onion_c->friends_list[friendnum].last_reported_announced == 0) {
- onion_c->friends_list[friendnum].last_reported_announced = unix_time();
+ if (onion_c->friends_list[friendnum].last_seen == 0) {
+ onion_c->friends_list[friendnum].last_seen = mono_time_get(onion_c->mono_time);
}
- uint64_t backoff_interval = (unix_time() - onion_c->friends_list[friendnum].last_reported_announced)
+ uint64_t backoff_interval = (mono_time_get(onion_c->mono_time) -
+ onion_c->friends_list[friendnum].last_seen)
/ ONION_FRIEND_BACKOFF_FACTOR;
if (backoff_interval > ONION_FRIEND_MAX_PING_INTERVAL) {
@@ -1572,15 +1575,15 @@ static void do_friend(Onion_Client *onion_c, uint16_t friendnum)
bool ping_random = true;
for (unsigned i = 0; i < MAX_ONION_CLIENTS; ++i) {
- if (!(is_timeout(list_nodes[i].timestamp, interval / MAX_ONION_CLIENTS)
- && is_timeout(list_nodes[i].last_pinged, ONION_NODE_PING_INTERVAL))) {
+ if (!(mono_time_is_timeout(onion_c->mono_time, list_nodes[i].timestamp, interval / MAX_ONION_CLIENTS)
+ && mono_time_is_timeout(onion_c->mono_time, list_nodes[i].last_pinged, ONION_NODE_PING_INTERVAL))) {
ping_random = false;
break;
}
}
for (unsigned i = 0; i < MAX_ONION_CLIENTS; ++i) {
- if (onion_node_timed_out(&list_nodes[i])) {
+ if (onion_node_timed_out(&list_nodes[i], onion_c->mono_time)) {
continue;
}
@@ -1588,7 +1591,7 @@ static void do_friend(Onion_Client *onion_c, uint16_t friendnum)
if (list_nodes[i].last_pinged == 0) {
- list_nodes[i].last_pinged = unix_time();
+ list_nodes[i].last_pinged = mono_time_get(onion_c->mono_time);
continue;
}
@@ -1596,11 +1599,11 @@ static void do_friend(Onion_Client *onion_c, uint16_t friendnum)
continue;
}
- if (is_timeout(list_nodes[i].last_pinged, interval)
+ 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,
list_nodes[i].public_key, nullptr, ~0) == 0) {
- list_nodes[i].last_pinged = unix_time();
+ list_nodes[i].last_pinged = mono_time_get(onion_c->mono_time);
++list_nodes[i].unsuccessful_pings;
ping_random = false;
}
@@ -1634,15 +1637,17 @@ static void do_friend(Onion_Client *onion_c, uint16_t friendnum)
}
/* send packets to friend telling them our DHT public key. */
- if (is_timeout(onion_c->friends_list[friendnum].last_dht_pk_onion_sent, ONION_DHTPK_SEND_INTERVAL)) {
+ if (mono_time_is_timeout(onion_c->mono_time, onion_c->friends_list[friendnum].last_dht_pk_onion_sent,
+ ONION_DHTPK_SEND_INTERVAL)) {
if (send_dhtpk_announce(onion_c, friendnum, 0) >= 1) {
- onion_c->friends_list[friendnum].last_dht_pk_onion_sent = unix_time();
+ onion_c->friends_list[friendnum].last_dht_pk_onion_sent = mono_time_get(onion_c->mono_time);
}
}
- if (is_timeout(onion_c->friends_list[friendnum].last_dht_pk_dht_sent, DHT_DHTPK_SEND_INTERVAL)) {
+ if (mono_time_is_timeout(onion_c->mono_time, onion_c->friends_list[friendnum].last_dht_pk_dht_sent,
+ DHT_DHTPK_SEND_INTERVAL)) {
if (send_dhtpk_announce(onion_c, friendnum, 1) >= 1) {
- onion_c->friends_list[friendnum].last_dht_pk_dht_sent = unix_time();
+ onion_c->friends_list[friendnum].last_dht_pk_dht_sent = mono_time_get(onion_c->mono_time);
}
}
}
@@ -1668,7 +1673,7 @@ static void do_announce(Onion_Client *onion_c)
Onion_Node *list_nodes = onion_c->clients_announce_list;
for (i = 0; i < MAX_ONION_CLIENTS_ANNOUNCE; ++i) {
- if (onion_node_timed_out(&list_nodes[i])) {
+ if (onion_node_timed_out(&list_nodes[i], onion_c->mono_time)) {
continue;
}
@@ -1687,7 +1692,7 @@ static void do_announce(Onion_Client *onion_c)
unsigned int interval = ANNOUNCE_INTERVAL_NOT_ANNOUNCED;
- if (list_nodes[i].is_stored && path_exists(&onion_c->onion_paths_self, list_nodes[i].path_used)) {
+ if (list_nodes[i].is_stored && path_exists(onion_c->mono_time, &onion_c->onion_paths_self, list_nodes[i].path_used)) {
interval = ANNOUNCE_INTERVAL_ANNOUNCED;
uint32_t pathnum = list_nodes[i].path_used % NUMBER_ONION_PATHS;
@@ -1696,32 +1701,32 @@ static void do_announce(Onion_Client *onion_c)
* aggressively, if it has survived for at least TIME_TO_STABLE
* and the latest packets sent to it are not timing out.
*/
- if (is_timeout(list_nodes[i].added_time, TIME_TO_STABLE)
+ if (mono_time_is_timeout(onion_c->mono_time, list_nodes[i].added_time, TIME_TO_STABLE)
&& !(list_nodes[i].unsuccessful_pings > 0
- && is_timeout(list_nodes[i].last_pinged, ONION_NODE_TIMEOUT))
- && is_timeout(onion_c->onion_paths_self.path_creation_time[pathnum], TIME_TO_STABLE)
+ && mono_time_is_timeout(onion_c->mono_time, list_nodes[i].last_pinged, ONION_NODE_TIMEOUT))
+ && mono_time_is_timeout(onion_c->mono_time, onion_c->onion_paths_self.path_creation_time[pathnum], TIME_TO_STABLE)
&& !(onion_c->onion_paths_self.last_path_used_times[pathnum] > 0
- && is_timeout(onion_c->onion_paths_self.last_path_used[pathnum], ONION_PATH_TIMEOUT))) {
+ && mono_time_is_timeout(onion_c->mono_time, onion_c->onion_paths_self.last_path_used[pathnum], ONION_PATH_TIMEOUT))) {
interval = ANNOUNCE_INTERVAL_STABLE;
}
}
- if (is_timeout(list_nodes[i].last_pinged, interval)
- || (is_timeout(onion_c->last_announce, ONION_NODE_PING_INTERVAL)
+ 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)) {
uint32_t path_to_use = list_nodes[i].path_used;
if (list_nodes[i].unsuccessful_pings == ONION_NODE_MAX_PINGS - 1
- && is_timeout(list_nodes[i].added_time, TIME_TO_STABLE)) {
+ && mono_time_is_timeout(onion_c->mono_time, list_nodes[i].added_time, TIME_TO_STABLE)) {
/* Last chance for a long-lived node - try a random path */
path_to_use = ~0;
}
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 = unix_time();
+ list_nodes[i].last_pinged = mono_time_get(onion_c->mono_time);
++list_nodes[i].unsuccessful_pings;
- onion_c->last_announce = unix_time();
+ onion_c->last_announce = mono_time_get(onion_c->mono_time);
}
}
}
@@ -1756,7 +1761,7 @@ static int onion_isconnected(const Onion_Client *onion_c)
{
unsigned int i, num = 0, announced = 0;
- if (is_timeout(onion_c->last_packet_recv, ONION_OFFLINE_TIMEOUT)) {
+ if (mono_time_is_timeout(onion_c->mono_time, onion_c->last_packet_recv, ONION_OFFLINE_TIMEOUT)) {
return 0;
}
@@ -1765,7 +1770,7 @@ static int onion_isconnected(const Onion_Client *onion_c)
}
for (i = 0; i < MAX_ONION_CLIENTS_ANNOUNCE; ++i) {
- if (!onion_node_timed_out(&onion_c->clients_announce_list[i])) {
+ if (!onion_node_timed_out(&onion_c->clients_announce_list[i], onion_c->mono_time)) {
++num;
if (onion_c->clients_announce_list[i].is_stored) {
@@ -1812,11 +1817,11 @@ unsigned int onion_connection_status(const Onion_Client *onion_c)
void do_onion_client(Onion_Client *onion_c)
{
- if (onion_c->last_run == unix_time()) {
+ if (onion_c->last_run == mono_time_get(onion_c->mono_time)) {
return;
}
- if (is_timeout(onion_c->first_run, ONION_CONNECTION_SECONDS)) {
+ if (mono_time_is_timeout(onion_c->mono_time, onion_c->first_run, ONION_CONNECTION_SECONDS)) {
populate_path_nodes(onion_c);
do_announce(onion_c);
}
@@ -1835,7 +1840,7 @@ void do_onion_client(Onion_Client *onion_c)
bool udp_connected = dht_non_lan_connected(onion_c->dht);
- if (is_timeout(onion_c->first_run, ONION_CONNECTION_SECONDS * 2)) {
+ if (mono_time_is_timeout(onion_c->mono_time, onion_c->first_run, ONION_CONNECTION_SECONDS * 2)) {
set_tcp_onion_status(nc_get_tcp_c(onion_c->c), !udp_connected);
}
@@ -1849,13 +1854,13 @@ void do_onion_client(Onion_Client *onion_c)
}
if (onion_c->last_run == 0) {
- onion_c->first_run = unix_time();
+ onion_c->first_run = mono_time_get(onion_c->mono_time);
}
- onion_c->last_run = unix_time();
+ onion_c->last_run = mono_time_get(onion_c->mono_time);
}
-Onion_Client *new_onion_client(Net_Crypto *c)
+Onion_Client *new_onion_client(Mono_Time *mono_time, Net_Crypto *c)
{
if (c == nullptr) {
return nullptr;
@@ -1874,6 +1879,7 @@ Onion_Client *new_onion_client(Net_Crypto *c)
return nullptr;
}
+ onion_c->mono_time = mono_time;
onion_c->dht = nc_get_dht(c);
onion_c->net = dht_get_net(onion_c->dht);
onion_c->c = c;
diff --git a/protocols/Tox/libtox/src/toxcore/onion_client.h b/protocols/Tox/libtox/src/toxcore/onion_client.h
index 660ccdd28e..66e417d76c 100644
--- a/protocols/Tox/libtox/src/toxcore/onion_client.h
+++ b/protocols/Tox/libtox/src/toxcore/onion_client.h
@@ -4,7 +4,7 @@
*/
/*
- * Copyright © 2016-2017 The TokTok team.
+ * Copyright © 2016-2018 The TokTok team.
* Copyright © 2013 Tox project.
*
* This file is part of Tox, the free peer to peer instant messenger.
@@ -22,8 +22,8 @@
* You should have received a copy of the GNU General Public License
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef ONION_CLIENT_H
-#define ONION_CLIENT_H
+#ifndef C_TOXCORE_TOXCORE_ONION_CLIENT_H
+#define C_TOXCORE_TOXCORE_ONION_CLIENT_H
#include "net_crypto.h"
#include "onion_announce.h"
@@ -188,7 +188,7 @@ void oniondata_registerhandler(Onion_Client *onion_c, uint8_t byte, oniondata_ha
void do_onion_client(Onion_Client *onion_c);
-Onion_Client *new_onion_client(Net_Crypto *c);
+Onion_Client *new_onion_client(Mono_Time *mono_time, Net_Crypto *c);
void kill_onion_client(Onion_Client *onion_c);
diff --git a/protocols/Tox/libtox/src/toxcore/ping.api.h b/protocols/Tox/libtox/src/toxcore/ping.api.h
index edc04723a0..2ae5b3650b 100644
--- a/protocols/Tox/libtox/src/toxcore/ping.api.h
+++ b/protocols/Tox/libtox/src/toxcore/ping.api.h
@@ -4,7 +4,7 @@
*/
/*
- * Copyright © 2016-2017 The TokTok team.
+ * Copyright © 2016-2018 The TokTok team.
* Copyright © 2013 Tox project.
* Copyright © 2013 plutooo
*
@@ -24,8 +24,8 @@
* You should have received a copy of the GNU General Public License
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef PING_H
-#define PING_H
+#ifndef C_TOXCORE_TOXCORE_PING_H
+#define C_TOXCORE_TOXCORE_PING_H
#include "DHT.h"
#include "network.h"
@@ -35,12 +35,13 @@
class iP_Port { struct this; }
class dHT { struct this; }
+class mono_Time { struct this; }
class ping {
struct this;
-static this new(dHT::this *dht);
+static this new(const mono_Time::this *mono_time, dHT::this *dht);
void kill();
/** Add nodes to the to_ping list.
@@ -61,5 +62,5 @@ int32_t send_request(iP_Port::this ipp, const uint8_t *public_key);
}
%{
-#endif /* PING_H */
+#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 1bf096bfcc..df0adf046d 100644
--- a/protocols/Tox/libtox/src/toxcore/ping.c
+++ b/protocols/Tox/libtox/src/toxcore/ping.c
@@ -3,7 +3,7 @@
*/
/*
- * Copyright © 2016-2017 The TokTok team.
+ * Copyright © 2016-2018 The TokTok team.
* Copyright © 2013 Tox project.
* Copyright © 2013 plutooo
*
@@ -48,6 +48,7 @@
struct Ping {
+ const Mono_Time *mono_time;
DHT *dht;
Ping_Array *ping_array;
@@ -78,7 +79,7 @@ int32_t ping_send_request(Ping *ping, IP_Port ipp, const uint8_t *public_key)
uint8_t data[PING_DATA_SIZE];
id_copy(data, public_key);
memcpy(data + CRYPTO_PUBLIC_KEY_SIZE, &ipp, sizeof(IP_Port));
- ping_id = ping_array_add(ping->ping_array, data, sizeof(data));
+ ping_id = ping_array_add(ping->ping_array, ping->mono_time, data, sizeof(data));
if (ping_id == 0) {
return 1;
@@ -219,7 +220,7 @@ static int handle_ping_response(void *object, IP_Port source, const uint8_t *pac
memcpy(&ping_id, ping_plain + 1, sizeof(ping_id));
uint8_t data[PING_DATA_SIZE];
- if (ping_array_check(ping->ping_array, data, sizeof(data), ping_id) != sizeof(data)) {
+ if (ping_array_check(ping->ping_array, ping->mono_time, data, sizeof(data), ping_id) != sizeof(data)) {
return 1;
}
@@ -243,7 +244,8 @@ static int handle_ping_response(void *object, IP_Port source, const uint8_t *pac
* return 1 if it is.
* return 0 if it isn't.
*/
-static int in_list(const Client_data *list, uint16_t length, const uint8_t *public_key, IP_Port ip_port)
+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)
{
unsigned int i;
@@ -257,7 +259,7 @@ static int in_list(const Client_data *list, uint16_t length, const uint8_t *publ
ipptp = &list[i].assoc6;
}
- if (!is_timeout(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;
}
}
@@ -286,7 +288,7 @@ int32_t ping_add(Ping *ping, const uint8_t *public_key, IP_Port ip_port)
return -1;
}
- if (in_list(dht_get_close_clientlist(ping->dht), LCLIENT_LIST, public_key, ip_port)) {
+ if (in_list(dht_get_close_clientlist(ping->dht), LCLIENT_LIST, ping->mono_time, public_key, ip_port)) {
return -1;
}
@@ -324,7 +326,7 @@ int32_t ping_add(Ping *ping, const uint8_t *public_key, IP_Port ip_port)
*/
void ping_iterate(Ping *ping)
{
- if (!is_timeout(ping->last_to_ping, TIME_TO_PING)) {
+ if (!mono_time_is_timeout(ping->mono_time, ping->last_to_ping, TIME_TO_PING)) {
return;
}
@@ -348,12 +350,12 @@ void ping_iterate(Ping *ping)
}
if (i != 0) {
- ping->last_to_ping = unix_time();
+ ping->last_to_ping = mono_time_get(ping->mono_time);
}
}
-Ping *ping_new(DHT *dht)
+Ping *ping_new(const Mono_Time *mono_time, DHT *dht)
{
Ping *ping = (Ping *)calloc(1, sizeof(Ping));
@@ -368,6 +370,7 @@ Ping *ping_new(DHT *dht)
return nullptr;
}
+ ping->mono_time = mono_time;
ping->dht = dht;
networking_registerhandler(dht_get_net(ping->dht), NET_PACKET_PING_REQUEST, &handle_ping_request, dht);
networking_registerhandler(dht_get_net(ping->dht), NET_PACKET_PING_RESPONSE, &handle_ping_response, dht);
diff --git a/protocols/Tox/libtox/src/toxcore/ping.h b/protocols/Tox/libtox/src/toxcore/ping.h
index 61875a0bd8..0413e2856e 100644
--- a/protocols/Tox/libtox/src/toxcore/ping.h
+++ b/protocols/Tox/libtox/src/toxcore/ping.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright © 2016-2017 The TokTok team.
+ * Copyright © 2016-2018 The TokTok team.
* Copyright © 2013 Tox project.
* Copyright © 2013 plutooo
*
@@ -23,8 +23,8 @@
* You should have received a copy of the GNU General Public License
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef PING_H
-#define PING_H
+#ifndef C_TOXCORE_TOXCORE_PING_H
+#define C_TOXCORE_TOXCORE_PING_H
#include "DHT.h"
#include "network.h"
@@ -41,12 +41,17 @@ typedef struct IP_Port IP_Port;
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 */
+
#ifndef PING_DEFINED
#define PING_DEFINED
typedef struct Ping Ping;
#endif /* PING_DEFINED */
-Ping *ping_new(DHT *dht);
+Ping *ping_new(const struct Mono_Time *mono_time, DHT *dht);
void ping_kill(Ping *ping);
@@ -66,4 +71,4 @@ void ping_iterate(Ping *ping);
int32_t ping_send_request(Ping *ping, struct IP_Port ipp, const uint8_t *public_key);
-#endif /* PING_H */
+#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
index 55b8057056..e0ac333b48 100644
--- a/protocols/Tox/libtox/src/toxcore/ping_array.api.h
+++ b/protocols/Tox/libtox/src/toxcore/ping_array.api.h
@@ -4,7 +4,7 @@
*/
/*
- * Copyright © 2016-2017 The TokTok team.
+ * Copyright © 2016-2018 The TokTok team.
* Copyright © 2013 Tox project.
*
* This file is part of Tox, the free peer to peer instant messenger.
@@ -22,23 +22,30 @@
* You should have received a copy of the GNU General Public License
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef PING_ARRAY_H
-#define PING_ARRAY_H
+#ifndef C_TOXCORE_TOXCORE_PING_ARRAY_H
+#define C_TOXCORE_TOXCORE_PING_ARRAY_H
-#include "network.h"
+#include <stddef.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
%}
+class mono_Time { struct this; }
+
class ping_Array {
struct this;
/**
* Initialize a Ping_Array.
- * size represents the total size of the array and should be a power of 2.
- * timeout represents the maximum timeout in seconds for the entry.
*
- * return 0 on success.
- * return -1 on failure.
+ * @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);
@@ -50,23 +57,25 @@ void kill();
/**
* Add a data with length to the Ping_Array list and return a ping_id.
*
- * return ping_id on success.
- * return 0 on failure.
+ * @return ping_id on success, 0 on failure.
*/
-uint64_t add(const uint8_t *data, uint32_t length);
+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.
- * return -1 on failure.
+ * @return length of data copied on success, -1 on failure.
*/
-int32_t check(uint8_t[length] data, uint64_t ping_id);
+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 142640dd23..c39dc881d9 100644
--- a/protocols/Tox/libtox/src/toxcore/ping_array.c
+++ b/protocols/Tox/libtox/src/toxcore/ping_array.c
@@ -3,7 +3,7 @@
*/
/*
- * Copyright © 2016-2017 The TokTok team.
+ * Copyright © 2016-2018 The TokTok team.
* Copyright © 2014 Tox project.
*
* This file is part of Tox, the free peer to peer instant messenger.
@@ -34,7 +34,6 @@
#include "mono_time.h"
#include "util.h"
-
typedef struct Ping_Array_Entry {
void *data;
uint32_t length;
@@ -46,25 +45,23 @@ struct Ping_Array {
Ping_Array_Entry *entries;
uint32_t last_deleted; /* number representing the next entry to be deleted. */
- uint32_t last_added; /* number representing the last entry to be added. */
- uint32_t total_size; /* The length of entries */
- uint32_t timeout; /* The timeout after which entries are cleared. */
+ uint32_t last_added; /* number representing the last entry to be added. */
+ uint32_t total_size; /* The length of entries */
+ uint32_t timeout; /* The timeout after which entries are cleared. */
};
-/* Initialize a Ping_Array.
- * size represents the total size of the array and should be a power of 2.
- * timeout represents the maximum timeout in seconds for the entry.
- *
- * return 0 on success.
- * return -1 on failure.
- */
Ping_Array *ping_array_new(uint32_t size, uint32_t timeout)
{
if (size == 0 || timeout == 0) {
return nullptr;
}
- Ping_Array *empty_array = (Ping_Array *)calloc(1, sizeof(Ping_Array));
+ if ((size & (size - 1)) != 0) {
+ // Not a power of 2.
+ return nullptr;
+ }
+
+ Ping_Array *const empty_array = (Ping_Array *)calloc(1, sizeof(Ping_Array));
if (empty_array == nullptr) {
return nullptr;
@@ -86,19 +83,15 @@ Ping_Array *ping_array_new(uint32_t size, uint32_t timeout)
static void clear_entry(Ping_Array *array, uint32_t index)
{
+ const Ping_Array_Entry empty = {nullptr};
free(array->entries[index].data);
- array->entries[index].data = nullptr;
- array->entries[index].length = 0;
- array->entries[index].time = 0;
- array->entries[index].ping_id = 0;
+ array->entries[index] = empty;
}
-/* Free all the allocated memory in a Ping_Array.
- */
void ping_array_kill(Ping_Array *array)
{
while (array->last_deleted != array->last_added) {
- uint32_t index = array->last_deleted % array->total_size;
+ const uint32_t index = array->last_deleted % array->total_size;
clear_entry(array, index);
++array->last_deleted;
}
@@ -109,12 +102,12 @@ void ping_array_kill(Ping_Array *array)
/* Clear timed out entries.
*/
-static void ping_array_clear_timedout(Ping_Array *array)
+static void ping_array_clear_timedout(Ping_Array *array, const Mono_Time *mono_time)
{
while (array->last_deleted != array->last_added) {
- uint32_t index = array->last_deleted % array->total_size;
+ const uint32_t index = array->last_deleted % array->total_size;
- if (!is_timeout(array->entries[index].time, array->timeout)) {
+ if (!mono_time_is_timeout(mono_time, array->entries[index].time, array->timeout)) {
break;
}
@@ -123,15 +116,11 @@ static void ping_array_clear_timedout(Ping_Array *array)
}
}
-/* Add a data with length to the Ping_Array list and return a ping_id.
- *
- * return ping_id on success.
- * return 0 on failure.
- */
-uint64_t ping_array_add(Ping_Array *array, const uint8_t *data, uint32_t length)
+uint64_t ping_array_add(Ping_Array *array, const Mono_Time *mono_time, const uint8_t *data,
+ uint32_t length)
{
- ping_array_clear_timedout(array);
- uint32_t index = array->last_added % array->total_size;
+ ping_array_clear_timedout(array, mono_time);
+ const uint32_t index = array->last_added % array->total_size;
if (array->entries[index].data != nullptr) {
array->last_deleted = array->last_added - array->total_size;
@@ -146,7 +135,7 @@ uint64_t ping_array_add(Ping_Array *array, const uint8_t *data, uint32_t length)
memcpy(array->entries[index].data, data, length);
array->entries[index].length = length;
- array->entries[index].time = unix_time();
+ array->entries[index].time = mono_time_get(mono_time);
++array->last_added;
uint64_t ping_id = random_u64();
ping_id /= array->total_size;
@@ -161,27 +150,20 @@ uint64_t ping_array_add(Ping_Array *array, const uint8_t *data, uint32_t length)
return ping_id;
}
-
-/* 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.
- * return -1 on failure.
- */
-int32_t ping_array_check(Ping_Array *array, uint8_t *data, size_t length, uint64_t ping_id)
+int32_t ping_array_check(Ping_Array *array, const Mono_Time *mono_time, uint8_t *data,
+ size_t length, uint64_t ping_id)
{
if (ping_id == 0) {
return -1;
}
- uint32_t index = ping_id % array->total_size;
+ const uint32_t index = ping_id % array->total_size;
if (array->entries[index].ping_id != ping_id) {
return -1;
}
- if (is_timeout(array->entries[index].time, array->timeout)) {
+ if (mono_time_is_timeout(mono_time, array->entries[index].time, array->timeout)) {
return -1;
}
@@ -189,12 +171,13 @@ int32_t ping_array_check(Ping_Array *array, uint8_t *data, size_t length, uint64
return -1;
}
+ // TODO(iphydf): This can't happen? If it indeed can't, turn it into an assert.
if (array->entries[index].data == nullptr) {
return -1;
}
memcpy(data, array->entries[index].data, array->entries[index].length);
- uint32_t len = array->entries[index].length;
+ const uint32_t len = array->entries[index].length;
clear_entry(array, index);
return len;
}
diff --git a/protocols/Tox/libtox/src/toxcore/ping_array.h b/protocols/Tox/libtox/src/toxcore/ping_array.h
index b927bbd42b..a2e57856bd 100644
--- a/protocols/Tox/libtox/src/toxcore/ping_array.h
+++ b/protocols/Tox/libtox/src/toxcore/ping_array.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright © 2016-2017 The TokTok team.
+ * Copyright © 2016-2018 The TokTok team.
* Copyright © 2013 Tox project.
*
* This file is part of Tox, the free peer to peer instant messenger.
@@ -21,10 +21,20 @@
* You should have received a copy of the GNU General Public License
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef PING_ARRAY_H
-#define PING_ARRAY_H
+#ifndef C_TOXCORE_TOXCORE_PING_ARRAY_H
+#define C_TOXCORE_TOXCORE_PING_ARRAY_H
-#include "network.h"
+#include <stddef.h>
+#include <stdint.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
@@ -33,11 +43,11 @@ typedef struct Ping_Array Ping_Array;
/**
* Initialize a Ping_Array.
- * size represents the total size of the array and should be a power of 2.
- * timeout represents the maximum timeout in seconds for the entry.
*
- * return 0 on success.
- * return -1 on failure.
+ * @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.
*/
struct Ping_Array *ping_array_new(uint32_t size, uint32_t timeout);
@@ -49,19 +59,23 @@ void ping_array_kill(struct Ping_Array *_array);
/**
* Add a data with length to the Ping_Array list and return a ping_id.
*
- * return ping_id on success.
- * return 0 on failure.
+ * @return ping_id on success, 0 on failure.
*/
-uint64_t ping_array_add(struct Ping_Array *_array, const uint8_t *data, uint32_t length);
+uint64_t ping_array_add(struct Ping_Array *_array, const struct Mono_Time *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.
- * return -1 on failure.
+ * @return length of data copied on success, -1 on failure.
*/
-int32_t ping_array_check(struct Ping_Array *_array, uint8_t *data, size_t length, uint64_t ping_id);
+int32_t ping_array_check(struct Ping_Array *_array, const struct Mono_Time *mono_time, uint8_t *data, size_t length,
+ uint64_t ping_id);
+#ifdef __cplusplus
+} // extern "C"
#endif
+
+#endif // C_TOXCORE_TOXCORE_PING_ARRAY_H
diff --git a/protocols/Tox/libtox/src/toxcore/state.c b/protocols/Tox/libtox/src/toxcore/state.c
index 8da061f4a6..29b4af88a3 100644
--- a/protocols/Tox/libtox/src/toxcore/state.c
+++ b/protocols/Tox/libtox/src/toxcore/state.c
@@ -45,6 +45,7 @@ int state_load(const Logger *log, state_load_cb *state_load_callback, void *oute
break;
case STATE_LOAD_STATUS_ERROR:
+ LOGGER_ERROR(log, "Error occcured in state file (type: %u).", type);
return -1;
case STATE_LOAD_STATUS_END:
@@ -60,6 +61,15 @@ int state_load(const Logger *log, state_load_cb *state_load_callback, void *oute
return 0;
}
+uint8_t *state_write_section_header(uint8_t *data, uint16_t cookie_type, uint32_t len, uint32_t section_type)
+{
+ host_to_lendian32(data, len);
+ data += sizeof(uint32_t);
+ host_to_lendian32(data, (host_tolendian16(cookie_type) << 16) | host_tolendian16(section_type));
+ data += sizeof(uint32_t);
+ return data;
+}
+
uint16_t lendian_to_host16(uint16_t lendian)
{
#ifdef WORDS_BIGENDIAN
@@ -69,6 +79,11 @@ uint16_t lendian_to_host16(uint16_t lendian)
#endif
}
+uint16_t host_tolendian16(uint16_t host)
+{
+ return lendian_to_host16(host);
+}
+
void host_to_lendian32(uint8_t *dest, uint32_t num)
{
#ifdef WORDS_BIGENDIAN
diff --git a/protocols/Tox/libtox/src/toxcore/state.h b/protocols/Tox/libtox/src/toxcore/state.h
index 3f7ff04333..2d1f62c36d 100644
--- a/protocols/Tox/libtox/src/toxcore/state.h
+++ b/protocols/Tox/libtox/src/toxcore/state.h
@@ -34,10 +34,12 @@ typedef State_Load_Status state_load_cb(void *outer, const uint8_t *data, uint32
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);
+uint8_t *state_write_section_header(uint8_t *data, uint16_t cookie_type, uint32_t len, uint32_t section_type);
+
// Utilities for state data serialisation.
uint16_t lendian_to_host16(uint16_t lendian);
-#define host_tolendian16(x) lendian_to_host16(x)
+uint16_t host_tolendian16(uint16_t host);
void host_to_lendian32(uint8_t *dest, uint32_t num);
void lendian_to_host32(uint32_t *dest, const uint8_t *lendian);
diff --git a/protocols/Tox/libtox/src/toxcore/tox.api.h b/protocols/Tox/libtox/src/toxcore/tox.api.h
index 3629bed1b4..5378847358 100644
--- a/protocols/Tox/libtox/src/toxcore/tox.api.h
+++ b/protocols/Tox/libtox/src/toxcore/tox.api.h
@@ -4,7 +4,7 @@
*/
/*
- * Copyright © 2016-2017 The TokTok team.
+ * Copyright © 2016-2018 The TokTok team.
* Copyright © 2013 Tox project.
*
* This file is part of Tox, the free peer to peer instant messenger.
@@ -22,8 +22,8 @@
* You should have received a copy of the GNU General Public License
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef TOX_H
-#define TOX_H
+#ifndef C_TOXCORE_TOXCORE_TOX_H
+#define C_TOXCORE_TOXCORE_TOX_H
#include <stdbool.h>
#include <stddef.h>
@@ -182,7 +182,7 @@ 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 = 6;
+const VERSION_PATCH = 8;
/**
* A macro to check at preprocessing time whether the client code is compatible
@@ -2772,5 +2772,5 @@ typedef TOX_CONNECTION Tox_Connection;
typedef TOX_FILE_CONTROL Tox_File_Control;
typedef TOX_CONFERENCE_TYPE Tox_Conference_Type;
-#endif
+#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 cd1b71f095..5258e9b6e3 100644
--- a/protocols/Tox/libtox/src/toxcore/tox.c
+++ b/protocols/Tox/libtox/src/toxcore/tox.c
@@ -3,7 +3,7 @@
*/
/*
- * Copyright © 2016-2017 The TokTok team.
+ * Copyright © 2016-2018 The TokTok team.
* Copyright © 2013 Tox project.
*
* This file is part of Tox, the free peer to peer instant messenger.
@@ -38,6 +38,7 @@
#include "Messenger.h"
#include "group.h"
#include "logger.h"
+#include "mono_time.h"
#include "../toxencryptsave/defines.h"
@@ -77,6 +78,8 @@
struct Tox {
Messenger *m;
+ Mono_Time *mono_time;
+
tox_self_connection_status_cb *self_connection_status_callback;
tox_friend_name_cb *friend_name_callback;
tox_friend_status_message_cb *friend_status_message_callback;
@@ -452,13 +455,22 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error)
m_options.proxy_info.ip_port.port = net_htons(tox_options_get_proxy_port(opts));
}
+ tox->mono_time = mono_time_new();
+
+ if (tox->mono_time == nullptr) {
+ SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC);
+ tox_options_free(default_options);
+ free(tox);
+ return nullptr;
+ }
+
unsigned int m_error;
- Messenger *const m = new_messenger(&m_options, &m_error);
+ Messenger *const m = new_messenger(tox->mono_time, &m_options, &m_error);
tox->m = m;
// TODO(iphydf): Clarify this code, check for NULL before new_groupchats, so
// new_groupchats can assume m is non-NULL.
- if (!new_groupchats(m)) {
+ if (!new_groupchats(tox->mono_time, m)) {
kill_messenger(m);
if (m_error == MESSENGER_ERROR_PORT) {
@@ -469,6 +481,7 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error)
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC);
}
+ mono_time_free(tox->mono_time);
tox_options_free(default_options);
free(tox);
return nullptr;
@@ -517,8 +530,10 @@ void tox_kill(Tox *tox)
}
Messenger *m = tox->m;
+ assert(m->msi_packet == nullptr && "Attempted to kill tox while toxav is still alive");
kill_groupchats(m->conferences_object);
kill_messenger(m);
+ mono_time_free(tox->mono_time);
free(tox);
}
@@ -653,6 +668,8 @@ uint32_t tox_iteration_interval(const Tox *tox)
void tox_iterate(Tox *tox, void *user_data)
{
+ mono_time_update(tox->mono_time);
+
Messenger *m = tox->m;
struct Tox_Userdata tox_data = { tox, user_data };
do_messenger(m, &tox_data);
@@ -997,7 +1014,7 @@ bool tox_friend_get_status_message(const Tox *tox, uint32_t friend_number, uint8
{
if (!status_message) {
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_QUERY_NULL);
- return 0;
+ return false;
}
const Messenger *const m = tox->m;
@@ -1005,14 +1022,14 @@ bool tox_friend_get_status_message(const Tox *tox, uint32_t friend_number, uint8
if (size == -1) {
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_QUERY_FRIEND_NOT_FOUND);
- return 0;
+ return false;
}
const int ret = m_copy_statusmessage(m, friend_number, status_message, size);
assert(ret == size && "concurrency problem: friend status message changed");
SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_QUERY_OK);
- return 1;
+ return ret == size;
}
void tox_callback_friend_status_message(Tox *tox, tox_friend_status_message_cb *callback)
diff --git a/protocols/Tox/libtox/src/toxcore/tox.h b/protocols/Tox/libtox/src/toxcore/tox.h
index 9f3072a7bf..ee8a01cc7d 100644
--- a/protocols/Tox/libtox/src/toxcore/tox.h
+++ b/protocols/Tox/libtox/src/toxcore/tox.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright © 2016-2017 The TokTok team.
+ * Copyright © 2016-2018 The TokTok team.
* Copyright © 2013 Tox project.
*
* This file is part of Tox, the free peer to peer instant messenger.
@@ -21,8 +21,8 @@
* You should have received a copy of the GNU General Public License
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef TOX_H
-#define TOX_H
+#ifndef C_TOXCORE_TOXCORE_TOX_H
+#define C_TOXCORE_TOXCORE_TOX_H
#include <stdbool.h>
#include <stddef.h>
@@ -183,7 +183,7 @@ uint32_t tox_version_minor(void);
* The patch or revision number. Incremented when bugfixes are applied without
* changing any functionality or API or ABI.
*/
-#define TOX_VERSION_PATCH 6
+#define TOX_VERSION_PATCH 8
uint32_t tox_version_patch(void);
@@ -3167,4 +3167,4 @@ typedef TOX_CONNECTION Tox_Connection;
typedef TOX_FILE_CONTROL Tox_File_Control;
typedef TOX_CONFERENCE_TYPE Tox_Conference_Type;
-#endif
+#endif // C_TOXCORE_TOXCORE_TOX_H
diff --git a/protocols/Tox/libtox/src/toxcore/util.c b/protocols/Tox/libtox/src/toxcore/util.c
index de01625eae..adc0dc09dc 100644
--- a/protocols/Tox/libtox/src/toxcore/util.c
+++ b/protocols/Tox/libtox/src/toxcore/util.c
@@ -3,7 +3,7 @@
*/
/*
- * Copyright © 2016-2017 The TokTok team.
+ * Copyright © 2016-2018 The TokTok team.
* Copyright © 2013 Tox project.
* Copyright © 2013 plutooo
*
diff --git a/protocols/Tox/libtox/src/toxcore/util.h b/protocols/Tox/libtox/src/toxcore/util.h
index 842c97a444..8558672473 100644
--- a/protocols/Tox/libtox/src/toxcore/util.h
+++ b/protocols/Tox/libtox/src/toxcore/util.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright © 2016-2017 The TokTok team.
+ * Copyright © 2016-2018 The TokTok team.
* Copyright © 2013 Tox project.
* Copyright © 2013 plutooo
*
@@ -23,8 +23,8 @@
* You should have received a copy of the GNU General Public License
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef UTIL_H
-#define UTIL_H
+#ifndef C_TOXCORE_TOXCORE_UTIL_H
+#define C_TOXCORE_TOXCORE_UTIL_H
#include <pthread.h>
#include <stdbool.h>
@@ -55,4 +55,4 @@ uint64_t min_u64(uint64_t a, uint64_t b);
} // extern "C"
#endif
-#endif /* UTIL_H */
+#endif // C_TOXCORE_TOXCORE_UTIL_H
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
index 5cb32f8dcf..8249fa1c97 100644
--- 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
@@ -1,3 +1,6 @@
+#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
@@ -90,3 +93,5 @@ int crypto_pwhash_scryptsalsa208sha256_ll(const uint8_t * passwd, size_t passwdl
#endif
#endif
+
+#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
index 3f0b7d72f5..978ac918d0 100644
--- a/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/crypto_scrypt.h
+++ b/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/crypto_scrypt.h
@@ -1,3 +1,6 @@
+#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
@@ -91,3 +94,5 @@ extern uint8_t * escrypt_gensalt_r(
#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
index ee5b30f7f1..ebf8d9dfb9 100644
--- a/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/export.h
+++ b/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/export.h
@@ -1,3 +1,6 @@
+#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
@@ -36,3 +39,5 @@
#endif
#endif
+
+#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
index b74bc6a340..17cd211258 100644
--- a/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/pbkdf2-sha256.h
+++ b/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/pbkdf2-sha256.h
@@ -1,3 +1,6 @@
+#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
@@ -50,3 +53,5 @@ void PBKDF2_SHA256(const uint8_t *, size_t, const uint8_t *, size_t,
#endif /* !_SHA256_H_ */
#endif
+
+#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
index 874915ef42..260a4550a9 100644
--- a/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/runtime.h
+++ b/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/runtime.h
@@ -1,3 +1,6 @@
+#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
@@ -31,3 +34,5 @@ int sodium_runtime_has_sse3(void);
#endif
#endif
+
+#endif
diff --git a/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/sysendian.h b/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/sysendian.h
index 04e5c1ed45..4deca4c645 100644
--- a/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/sysendian.h
+++ b/protocols/Tox/libtox/src/toxencryptsave/crypto_pwhash_scryptsalsa208sha256/sysendian.h
@@ -1,3 +1,6 @@
+#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
@@ -151,3 +154,5 @@ le64enc(void *pp, uint64_t x)
#endif /* !_SYSENDIAN_H_ */
#endif
+
+#endif
diff --git a/protocols/Tox/libtox/src/toxencryptsave/defines.h b/protocols/Tox/libtox/src/toxencryptsave/defines.h
index e3fca073e3..0bc1d9ed5e 100644
--- a/protocols/Tox/libtox/src/toxencryptsave/defines.h
+++ b/protocols/Tox/libtox/src/toxencryptsave/defines.h
@@ -1,2 +1,7 @@
+#ifndef C_TOXCORE_TOXENCRYPTSAVE_DEFINES_H
+#define C_TOXCORE_TOXENCRYPTSAVE_DEFINES_H
+
#define TOX_ENC_SAVE_MAGIC_NUMBER "toxEsave"
#define TOX_ENC_SAVE_MAGIC_LENGTH 8
+
+#endif
diff --git a/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.api.h b/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.api.h
index 3adf3a9def..28d7a650a4 100644
--- a/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.api.h
+++ b/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.api.h
@@ -4,7 +4,7 @@
*/
/*
- * Copyright © 2016-2017 The TokTok team.
+ * Copyright © 2016-2018 The TokTok team.
* Copyright © 2013-2016 Tox Developers.
*
* This file is part of Tox, the free peer to peer instant messenger.
@@ -22,8 +22,8 @@
* You should have received a copy of the GNU General Public License
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef TOXENCRYPTSAVE_H
-#define TOXENCRYPTSAVE_H
+#ifndef C_TOXCORE_TOXENCRYPTSAVE_TOXENCRYPTSAVE_H
+#define C_TOXCORE_TOXENCRYPTSAVE_TOXENCRYPTSAVE_H
#ifdef __cplusplus
extern "C" {
@@ -313,5 +313,5 @@ static bool is_data_encrypted(const uint8_t *data);
}
#endif
-#endif
+#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 7c81f72272..6221b0b6b9 100644
--- a/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.c
+++ b/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.c
@@ -3,7 +3,7 @@
*/
/*
- * Copyright © 2016-2017 The TokTok team.
+ * Copyright © 2016-2018 The TokTok team.
* Copyright © 2013 Tox project.
*
* This file is part of Tox, the free peer to peer instant messenger.
diff --git a/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.h b/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.h
index c5a1dff961..400483cba8 100644
--- a/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.h
+++ b/protocols/Tox/libtox/src/toxencryptsave/toxencryptsave.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright © 2016-2017 The TokTok team.
+ * Copyright © 2016-2018 The TokTok team.
* Copyright © 2013-2016 Tox Developers.
*
* This file is part of Tox, the free peer to peer instant messenger.
@@ -21,8 +21,8 @@
* You should have received a copy of the GNU General Public License
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef TOXENCRYPTSAVE_H
-#define TOXENCRYPTSAVE_H
+#ifndef C_TOXCORE_TOXENCRYPTSAVE_TOXENCRYPTSAVE_H
+#define C_TOXCORE_TOXENCRYPTSAVE_TOXENCRYPTSAVE_H
#ifdef __cplusplus
extern "C" {
@@ -375,4 +375,4 @@ bool tox_is_data_encrypted(const uint8_t *data);
}
#endif
-#endif
+#endif // C_TOXCORE_TOXENCRYPTSAVE_TOXENCRYPTSAVE_H