diff options
author | aunsane <aunsane@gmail.com> | 2018-10-08 20:45:34 +0300 |
---|---|---|
committer | aunsane <aunsane@gmail.com> | 2018-10-08 20:45:34 +0300 |
commit | b8ad6c3cc2edef99dc2a416667c3933c1061994c (patch) | |
tree | 040c82bc03349628c9937215562ee93935672366 /protocols/Tox/libtox/src | |
parent | 0c470817d4d49a872bd068e717c6439f2b6cd5c0 (diff) |
Tox: toxcore updated to v0.2.8
Diffstat (limited to 'protocols/Tox/libtox/src')
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 |