Squashed 'external/toxcore/c-toxcore/' changes from 67badf694..82460b212
82460b212 feat: add ngc events 24b54722a fix: Ensure we have allocators available for the error paths. 48dbcfebc cleanup: Remove redundant `-DSODIUM_EXPORT` from definitions. 0cef46ee9 cleanup: Fix a few more clang-tidy warnings. 0c5b918e9 cleanup: Fix a few more clang-tidy warnings. 4d3c97f49 cleanup: Enforce stricter identifier naming using clang-tidy. a549807df refactor: Add `mem` module to allow tests to override allocators. 6133fb153 chore: Add devcontainer setup for codespaces. 620e07ecd chore: Set a timeout for tests started using Conan c0ec33b16 chore: Migrate Windows CI from Appveyor to Azure DevOps 8ed47f3ef fix incorrect documentation a1e245841 docs: Fix doxygen config and remove some redundant comments. b0f633185 chore: Fix the Android CI job 7469a529b fix: Add missing `#include <array>`. 2b1a6b0d2 add missing ngc constants getter declarations and definitions 2e02d5637 chore: Add missing module dependencies. REVERT: 67badf694 feat: add ngc events git-subtree-dir: external/toxcore/c-toxcore git-subtree-split: 82460b2124216af1ac9d63060de310a682a2fd15
This commit is contained in:
@ -23,6 +23,28 @@ cc_library(
|
||||
deps = [":attributes"],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "mem",
|
||||
srcs = ["mem.c"],
|
||||
hdrs = ["mem.h"],
|
||||
visibility = ["//c-toxcore:__subpackages__"],
|
||||
deps = [
|
||||
":attributes",
|
||||
":ccompat",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "mem_test",
|
||||
size = "small",
|
||||
srcs = ["mem_test.cc"],
|
||||
deps = [
|
||||
":mem",
|
||||
"@com_google_googletest//:gtest",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "util",
|
||||
srcs = ["util.c"],
|
||||
@ -37,6 +59,7 @@ cc_library(
|
||||
deps = [
|
||||
":attributes",
|
||||
":ccompat",
|
||||
":mem",
|
||||
"@pthread",
|
||||
],
|
||||
)
|
||||
@ -59,6 +82,7 @@ cc_library(
|
||||
hdrs = ["bin_pack.h"],
|
||||
visibility = ["//c-toxcore:__subpackages__"],
|
||||
deps = [
|
||||
":attributes",
|
||||
":ccompat",
|
||||
"//c-toxcore/third_party:cmp",
|
||||
],
|
||||
@ -70,6 +94,7 @@ cc_library(
|
||||
hdrs = ["bin_unpack.h"],
|
||||
visibility = ["//c-toxcore:__subpackages__"],
|
||||
deps = [
|
||||
":attributes",
|
||||
":ccompat",
|
||||
"//c-toxcore/third_party:cmp",
|
||||
],
|
||||
@ -93,6 +118,7 @@ cc_library(
|
||||
hdrs = ["crypto_core.h"],
|
||||
visibility = ["//c-toxcore:__subpackages__"],
|
||||
deps = [
|
||||
":attributes",
|
||||
":ccompat",
|
||||
"@libsodium",
|
||||
],
|
||||
@ -115,7 +141,10 @@ cc_library(
|
||||
name = "list",
|
||||
srcs = ["list.c"],
|
||||
hdrs = ["list.h"],
|
||||
deps = [":ccompat"],
|
||||
deps = [
|
||||
":attributes",
|
||||
":ccompat",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
@ -139,7 +168,10 @@ cc_library(
|
||||
"//c-toxcore/other/bootstrap_daemon:__pkg__",
|
||||
"//c-toxcore/toxav:__pkg__",
|
||||
],
|
||||
deps = [":ccompat"],
|
||||
deps = [
|
||||
":attributes",
|
||||
":ccompat",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
@ -164,7 +196,9 @@ cc_library(
|
||||
"//c-toxcore/toxav:__pkg__",
|
||||
],
|
||||
deps = [
|
||||
":attributes",
|
||||
":ccompat",
|
||||
":mem",
|
||||
"@pthread",
|
||||
],
|
||||
)
|
||||
@ -194,6 +228,7 @@ cc_library(
|
||||
deps = [
|
||||
":ccompat",
|
||||
":crypto_core",
|
||||
":mem",
|
||||
":mono_time",
|
||||
],
|
||||
)
|
||||
@ -213,6 +248,7 @@ cc_library(
|
||||
":ccompat",
|
||||
":crypto_core",
|
||||
":logger",
|
||||
":mem",
|
||||
":mono_time",
|
||||
":util",
|
||||
"@libsodium",
|
||||
@ -250,6 +286,7 @@ cc_library(
|
||||
deps = [
|
||||
":ccompat",
|
||||
":crypto_core",
|
||||
":mem",
|
||||
":mono_time",
|
||||
":util",
|
||||
],
|
||||
@ -301,9 +338,11 @@ cc_library(
|
||||
],
|
||||
deps = [
|
||||
":LAN_discovery",
|
||||
":attributes",
|
||||
":ccompat",
|
||||
":crypto_core",
|
||||
":logger",
|
||||
":mem",
|
||||
":mono_time",
|
||||
":network",
|
||||
":ping_array",
|
||||
@ -344,6 +383,7 @@ cc_library(
|
||||
":DHT",
|
||||
":ccompat",
|
||||
":crypto_core",
|
||||
":logger",
|
||||
":mono_time",
|
||||
":shared_key_cache",
|
||||
":util",
|
||||
@ -398,7 +438,10 @@ cc_library(
|
||||
hdrs = ["TCP_common.h"],
|
||||
visibility = ["//c-toxcore/auto_tests:__pkg__"],
|
||||
deps = [
|
||||
":attributes",
|
||||
":ccompat",
|
||||
":crypto_core",
|
||||
":mem",
|
||||
":network",
|
||||
],
|
||||
)
|
||||
@ -436,8 +479,10 @@ cc_library(
|
||||
deps = [
|
||||
":TCP_common",
|
||||
":ccompat",
|
||||
":crypto_core",
|
||||
":forwarding",
|
||||
":mono_time",
|
||||
":network",
|
||||
":util",
|
||||
],
|
||||
)
|
||||
@ -478,9 +523,11 @@ cc_library(
|
||||
visibility = ["//c-toxcore/auto_tests:__pkg__"],
|
||||
deps = [
|
||||
":DHT",
|
||||
":LAN_discovery",
|
||||
":TCP_connection",
|
||||
":ccompat",
|
||||
":list",
|
||||
":logger",
|
||||
":mono_time",
|
||||
":util",
|
||||
],
|
||||
@ -499,6 +546,7 @@ cc_library(
|
||||
":DHT",
|
||||
":LAN_discovery",
|
||||
":ccompat",
|
||||
":logger",
|
||||
":mono_time",
|
||||
":onion",
|
||||
":shared_key_cache",
|
||||
@ -577,6 +625,7 @@ cc_library(
|
||||
":net_crypto",
|
||||
":network",
|
||||
":onion_announce",
|
||||
":ping_array",
|
||||
":util",
|
||||
],
|
||||
)
|
||||
@ -588,6 +637,7 @@ cc_library(
|
||||
visibility = ["//c-toxcore/auto_tests:__pkg__"],
|
||||
deps = [
|
||||
":DHT",
|
||||
":LAN_discovery",
|
||||
":ccompat",
|
||||
":mono_time",
|
||||
":net_crypto",
|
||||
@ -698,6 +748,7 @@ cc_library(
|
||||
":forwarding",
|
||||
":friend_connection",
|
||||
":friend_requests",
|
||||
":group_announce",
|
||||
":group_moderation",
|
||||
":group_onion_announce",
|
||||
":logger",
|
||||
@ -744,6 +795,7 @@ cc_library(
|
||||
":group",
|
||||
":group_moderation",
|
||||
":logger",
|
||||
":mem",
|
||||
":mono_time",
|
||||
":network",
|
||||
"//c-toxcore/toxencryptsave:defines",
|
||||
@ -768,6 +820,7 @@ cc_library(
|
||||
hdrs = ["tox_unpack.h"],
|
||||
visibility = ["//c-toxcore:__subpackages__"],
|
||||
deps = [
|
||||
":attributes",
|
||||
":bin_unpack",
|
||||
":ccompat",
|
||||
":tox",
|
||||
@ -783,9 +836,11 @@ cc_library(
|
||||
hdrs = ["tox_events.h"],
|
||||
visibility = ["//c-toxcore:__subpackages__"],
|
||||
deps = [
|
||||
":attributes",
|
||||
":bin_pack",
|
||||
":bin_unpack",
|
||||
":ccompat",
|
||||
":mem",
|
||||
":tox",
|
||||
":tox_unpack",
|
||||
"//c-toxcore/third_party:cmp",
|
||||
@ -798,6 +853,7 @@ cc_test(
|
||||
srcs = ["tox_events_test.cc"],
|
||||
deps = [
|
||||
":crypto_core",
|
||||
":tox",
|
||||
":tox_events",
|
||||
"@com_google_googletest//:gtest",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
@ -808,7 +864,10 @@ cc_fuzz_test(
|
||||
name = "tox_events_fuzz_test",
|
||||
srcs = ["tox_events_fuzz_test.cc"],
|
||||
corpus = ["//tools/toktok-fuzzer/corpus:tox_events_fuzz_test"],
|
||||
deps = [":tox_events"],
|
||||
deps = [
|
||||
":tox_events",
|
||||
"//c-toxcore/testing/fuzzing:fuzz_support",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
|
231
toxcore/DHT.c
231
toxcore/DHT.c
@ -91,6 +91,7 @@ struct DHT {
|
||||
const Logger *log;
|
||||
const Network *ns;
|
||||
Mono_Time *mono_time;
|
||||
const Memory *mem;
|
||||
const Random *rng;
|
||||
Networking_Core *net;
|
||||
|
||||
@ -211,12 +212,6 @@ static IP_Port ip_port_normalize(const IP_Port *ip_port)
|
||||
return res;
|
||||
}
|
||||
|
||||
/** @brief Compares pk1 and pk2 with pk.
|
||||
*
|
||||
* @retval 0 if both are same distance.
|
||||
* @retval 1 if pk1 is closer.
|
||||
* @retval 2 if pk2 is closer.
|
||||
*/
|
||||
int id_closest(const uint8_t *pk, const uint8_t *pk1, const uint8_t *pk2)
|
||||
{
|
||||
for (size_t i = 0; i < CRYPTO_PUBLIC_KEY_SIZE; ++i) {
|
||||
@ -280,27 +275,6 @@ const uint8_t *dht_get_shared_key_sent(DHT *dht, const uint8_t *public_key)
|
||||
|
||||
#define CRYPTO_SIZE (1 + CRYPTO_PUBLIC_KEY_SIZE * 2 + CRYPTO_NONCE_SIZE)
|
||||
|
||||
/**
|
||||
* @brief Create a request to peer.
|
||||
*
|
||||
* Packs the data and sender public key and encrypts the packet.
|
||||
*
|
||||
* @param[in] send_public_key public key of the sender.
|
||||
* @param[in] send_secret_key secret key of the sender.
|
||||
* @param[out] packet an array of @ref MAX_CRYPTO_REQUEST_SIZE big.
|
||||
* @param[in] recv_public_key public key of the receiver.
|
||||
* @param[in] data represents the data we send with the request.
|
||||
* @param[in] data_length the length of the data.
|
||||
* @param[in] request_id the id of the request (32 = friend request, 254 = ping request).
|
||||
*
|
||||
* @attention Constraints:
|
||||
* @code
|
||||
* sizeof(packet) >= MAX_CRYPTO_REQUEST_SIZE
|
||||
* @endcode
|
||||
*
|
||||
* @retval -1 on failure.
|
||||
* @return the length of the created packet on success.
|
||||
*/
|
||||
int create_request(const Random *rng, const uint8_t *send_public_key, const uint8_t *send_secret_key,
|
||||
uint8_t *packet, const uint8_t *recv_public_key,
|
||||
const uint8_t *data, uint32_t data_length, uint8_t request_id)
|
||||
@ -334,28 +308,6 @@ int create_request(const Random *rng, const uint8_t *send_public_key, const uint
|
||||
return len + CRYPTO_SIZE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Decrypts and unpacks a DHT request packet.
|
||||
*
|
||||
* Puts the senders public key in the request in @p public_key, the data from
|
||||
* the request in @p data.
|
||||
*
|
||||
* @param[in] self_public_key public key of the receiver (us).
|
||||
* @param[in] self_secret_key secret key of the receiver (us).
|
||||
* @param[out] public_key public key of the sender, copied from the input packet.
|
||||
* @param[out] data decrypted request data, copied from the input packet, must
|
||||
* have room for @ref MAX_CRYPTO_REQUEST_SIZE bytes.
|
||||
* @param[in] packet is the request packet.
|
||||
* @param[in] packet_length length of the packet.
|
||||
*
|
||||
* @attention Constraints:
|
||||
* @code
|
||||
* sizeof(data) >= MAX_CRYPTO_REQUEST_SIZE
|
||||
* @endcode
|
||||
*
|
||||
* @retval -1 if not valid request.
|
||||
* @return the length of the unpacked data.
|
||||
*/
|
||||
int handle_request(const uint8_t *self_public_key, const uint8_t *self_secret_key, uint8_t *public_key, uint8_t *data,
|
||||
uint8_t *request_id, const uint8_t *packet, uint16_t packet_length)
|
||||
{
|
||||
@ -394,9 +346,6 @@ int handle_request(const uint8_t *self_public_key, const uint8_t *self_secret_ke
|
||||
return len1;
|
||||
}
|
||||
|
||||
/** @return packet size of packed node with ip_family on success.
|
||||
* @retval -1 on failure.
|
||||
*/
|
||||
int packed_node_size(Family ip_family)
|
||||
{
|
||||
if (net_family_is_ipv4(ip_family) || net_family_is_tcp_ipv4(ip_family)) {
|
||||
@ -411,13 +360,6 @@ int packed_node_size(Family ip_family)
|
||||
}
|
||||
|
||||
|
||||
/** @brief Pack an IP_Port structure into data of max size length.
|
||||
*
|
||||
* Packed_length is the offset of data currently packed.
|
||||
*
|
||||
* @return size of packed IP_Port data on success.
|
||||
* @retval -1 on failure.
|
||||
*/
|
||||
int pack_ip_port(const Logger *logger, uint8_t *data, uint16_t length, const IP_Port *ip_port)
|
||||
{
|
||||
if (data == nullptr) {
|
||||
@ -473,17 +415,13 @@ int pack_ip_port(const Logger *logger, uint8_t *data, uint16_t length, const IP_
|
||||
}
|
||||
}
|
||||
|
||||
/** @brief Encrypt plain and write resulting DHT packet into packet with max size length.
|
||||
*
|
||||
* @return size of packet on success.
|
||||
* @retval -1 on failure.
|
||||
*/
|
||||
int dht_create_packet(const Random *rng, const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
|
||||
int dht_create_packet(const Memory *mem, const Random *rng,
|
||||
const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
|
||||
const uint8_t *shared_key, const uint8_t type,
|
||||
const uint8_t *plain, size_t plain_length,
|
||||
uint8_t *packet, size_t length)
|
||||
{
|
||||
uint8_t *encrypted = (uint8_t *)malloc(plain_length + CRYPTO_MAC_SIZE);
|
||||
uint8_t *encrypted = (uint8_t *)mem_balloc(mem, plain_length + CRYPTO_MAC_SIZE);
|
||||
uint8_t nonce[CRYPTO_NONCE_SIZE];
|
||||
|
||||
if (encrypted == nullptr) {
|
||||
@ -495,12 +433,12 @@ int dht_create_packet(const Random *rng, const uint8_t public_key[CRYPTO_PUBLIC_
|
||||
const int encrypted_length = encrypt_data_symmetric(shared_key, nonce, plain, plain_length, encrypted);
|
||||
|
||||
if (encrypted_length == -1) {
|
||||
free(encrypted);
|
||||
mem_delete(mem, encrypted);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (length < 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + encrypted_length) {
|
||||
free(encrypted);
|
||||
mem_delete(mem, encrypted);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -509,17 +447,10 @@ int dht_create_packet(const Random *rng, const uint8_t public_key[CRYPTO_PUBLIC_
|
||||
memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, nonce, CRYPTO_NONCE_SIZE);
|
||||
memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, encrypted, encrypted_length);
|
||||
|
||||
free(encrypted);
|
||||
mem_delete(mem, encrypted);
|
||||
return 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + encrypted_length;
|
||||
}
|
||||
|
||||
/** @brief Unpack IP_Port structure from data of max size length into ip_port.
|
||||
*
|
||||
* len_processed is the offset of data currently unpacked.
|
||||
*
|
||||
* @return size of unpacked ip_port on success.
|
||||
* @retval -1 on failure.
|
||||
*/
|
||||
int unpack_ip_port(IP_Port *ip_port, const uint8_t *data, uint16_t length, bool tcp_enabled)
|
||||
{
|
||||
if (data == nullptr) {
|
||||
@ -580,11 +511,6 @@ int unpack_ip_port(IP_Port *ip_port, const uint8_t *data, uint16_t length, bool
|
||||
}
|
||||
}
|
||||
|
||||
/** @brief Pack number of nodes into data of maxlength length.
|
||||
*
|
||||
* @return length of packed nodes on success.
|
||||
* @retval -1 on failure.
|
||||
*/
|
||||
int pack_nodes(const Logger *logger, uint8_t *data, uint16_t length, const Node_format *nodes, uint16_t number)
|
||||
{
|
||||
uint32_t packed_length = 0;
|
||||
@ -614,13 +540,6 @@ int pack_nodes(const Logger *logger, uint8_t *data, uint16_t length, const Node_
|
||||
return packed_length;
|
||||
}
|
||||
|
||||
/** @brief Unpack data of length into nodes of size max_num_nodes.
|
||||
* Put the length of the data processed in processed_data_len.
|
||||
* tcp_enabled sets if TCP nodes are expected (true) or not (false).
|
||||
*
|
||||
* @return number of unpacked nodes on success.
|
||||
* @retval -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, bool tcp_enabled)
|
||||
{
|
||||
@ -840,7 +759,7 @@ bool add_to_list(Node_format *nodes_list, uint32_t length, const uint8_t *pk, co
|
||||
non_null()
|
||||
static void get_close_nodes_inner(uint64_t cur_time, const uint8_t *public_key, Node_format *nodes_list,
|
||||
Family sa_family, const Client_data *client_list, uint32_t client_list_length,
|
||||
uint32_t *num_nodes_ptr, bool is_LAN,
|
||||
uint32_t *num_nodes_ptr, bool is_lan,
|
||||
bool want_announce)
|
||||
{
|
||||
if (!net_family_is_ipv4(sa_family) && !net_family_is_ipv6(sa_family) && !net_family_is_unspec(sa_family)) {
|
||||
@ -875,7 +794,7 @@ static void get_close_nodes_inner(uint64_t cur_time, const uint8_t *public_key,
|
||||
}
|
||||
|
||||
/* don't send LAN ips to non LAN peers */
|
||||
if (ip_is_lan(&ipptp->ip_port.ip) && !is_LAN) {
|
||||
if (ip_is_lan(&ipptp->ip_port.ip) && !is_lan) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -909,27 +828,27 @@ static void get_close_nodes_inner(uint64_t cur_time, const uint8_t *public_key,
|
||||
*/
|
||||
non_null()
|
||||
static int get_somewhat_close_nodes(const DHT *dht, const uint8_t *public_key, Node_format *nodes_list,
|
||||
Family sa_family, bool is_LAN, bool want_announce)
|
||||
Family sa_family, bool is_lan, bool want_announce)
|
||||
{
|
||||
uint32_t num_nodes = 0;
|
||||
get_close_nodes_inner(dht->cur_time, public_key, nodes_list, sa_family,
|
||||
dht->close_clientlist, LCLIENT_LIST, &num_nodes, is_LAN, want_announce);
|
||||
dht->close_clientlist, LCLIENT_LIST, &num_nodes, is_lan, want_announce);
|
||||
|
||||
for (uint32_t i = 0; i < dht->num_friends; ++i) {
|
||||
get_close_nodes_inner(dht->cur_time, public_key, nodes_list, sa_family,
|
||||
dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS,
|
||||
&num_nodes, is_LAN, want_announce);
|
||||
&num_nodes, is_lan, want_announce);
|
||||
}
|
||||
|
||||
return num_nodes;
|
||||
}
|
||||
|
||||
int get_close_nodes(const DHT *dht, const uint8_t *public_key, Node_format *nodes_list, Family sa_family,
|
||||
bool is_LAN, bool want_announce)
|
||||
bool is_lan, bool want_announce)
|
||||
{
|
||||
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_announce);
|
||||
is_lan, want_announce);
|
||||
}
|
||||
|
||||
typedef struct DHT_Cmp_Data {
|
||||
@ -1020,7 +939,8 @@ static bool send_announce_ping(DHT *dht, const uint8_t *public_key, const IP_Por
|
||||
|
||||
uint8_t request[1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + sizeof(plain) + CRYPTO_MAC_SIZE];
|
||||
|
||||
if (dht_create_packet(dht->rng, dht->self_public_key, shared_key, NET_PACKET_DATA_SEARCH_REQUEST,
|
||||
if (dht_create_packet(dht->mem, dht->rng,
|
||||
dht->self_public_key, shared_key, NET_PACKET_DATA_SEARCH_REQUEST,
|
||||
plain, sizeof(plain), request, sizeof(request)) != sizeof(request)) {
|
||||
return false;
|
||||
}
|
||||
@ -1091,12 +1011,12 @@ static bool store_node_ok(const Client_data *client, uint64_t cur_time, const ui
|
||||
}
|
||||
|
||||
non_null()
|
||||
static void sort_client_list(Client_data *list, uint64_t cur_time, unsigned int length,
|
||||
static void sort_client_list(const Memory *mem, Client_data *list, uint64_t cur_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.
|
||||
DHT_Cmp_Data *cmp_list = (DHT_Cmp_Data *)calloc(length, sizeof(DHT_Cmp_Data));
|
||||
DHT_Cmp_Data *cmp_list = (DHT_Cmp_Data *)mem_valloc(mem, length, sizeof(DHT_Cmp_Data));
|
||||
|
||||
if (cmp_list == nullptr) {
|
||||
return;
|
||||
@ -1114,7 +1034,7 @@ static void sort_client_list(Client_data *list, uint64_t cur_time, unsigned int
|
||||
list[i] = cmp_list[i].entry;
|
||||
}
|
||||
|
||||
free(cmp_list);
|
||||
mem_delete(mem, cmp_list);
|
||||
}
|
||||
|
||||
non_null()
|
||||
@ -1175,7 +1095,7 @@ static bool replace_all(const DHT *dht,
|
||||
return false;
|
||||
}
|
||||
|
||||
sort_client_list(list, dht->cur_time, length, comp_public_key);
|
||||
sort_client_list(dht->mem, list, dht->cur_time, length, comp_public_key);
|
||||
|
||||
Client_data *const client = &list[0];
|
||||
pk_copy(client->public_key, public_key);
|
||||
@ -1475,7 +1395,7 @@ bool dht_getnodes(DHT *dht, const IP_Port *ip_port, const uint8_t *public_key, c
|
||||
|
||||
const uint8_t *shared_key = dht_get_shared_key_sent(dht, public_key);
|
||||
|
||||
const int len = dht_create_packet(dht->rng,
|
||||
const int len = dht_create_packet(dht->mem, dht->rng,
|
||||
dht->self_public_key, shared_key, NET_PACKET_GET_NODES,
|
||||
plain, sizeof(plain), data, sizeof(data));
|
||||
|
||||
@ -1525,7 +1445,7 @@ static int sendnodes_ipv6(const DHT *dht, const IP_Port *ip_port, const uint8_t
|
||||
const uint32_t crypto_size = 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_MAC_SIZE;
|
||||
VLA(uint8_t, data, 1 + nodes_length + length + crypto_size);
|
||||
|
||||
const int len = dht_create_packet(dht->rng,
|
||||
const int len = dht_create_packet(dht->mem, dht->rng,
|
||||
dht->self_public_key, shared_encryption_key, NET_PACKET_SEND_NODES_IPV6,
|
||||
plain, 1 + nodes_length + length, data, SIZEOF_VLA(data));
|
||||
|
||||
@ -1764,7 +1684,7 @@ int dht_addfriend(DHT *dht, const uint8_t *public_key, dht_ip_cb *ip_callback,
|
||||
return 0;
|
||||
}
|
||||
|
||||
DHT_Friend *const temp = (DHT_Friend *)realloc(dht->friends_list, sizeof(DHT_Friend) * (dht->num_friends + 1));
|
||||
DHT_Friend *const temp = (DHT_Friend *)mem_vrealloc(dht->mem, dht->friends_list, dht->num_friends + 1, sizeof(DHT_Friend));
|
||||
|
||||
if (temp == nullptr) {
|
||||
return -1;
|
||||
@ -1809,12 +1729,12 @@ int dht_delfriend(DHT *dht, const uint8_t *public_key, uint32_t lock_token)
|
||||
}
|
||||
|
||||
if (dht->num_friends == 0) {
|
||||
free(dht->friends_list);
|
||||
mem_delete(dht->mem, dht->friends_list);
|
||||
dht->friends_list = nullptr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
DHT_Friend *const temp = (DHT_Friend *)realloc(dht->friends_list, sizeof(DHT_Friend) * dht->num_friends);
|
||||
DHT_Friend *const temp = (DHT_Friend *)mem_vrealloc(dht->mem, dht->friends_list, dht->num_friends, sizeof(DHT_Friend));
|
||||
|
||||
if (temp == nullptr) {
|
||||
return -1;
|
||||
@ -1867,14 +1787,14 @@ static uint8_t do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, co
|
||||
const uint64_t temp_time = mono_time_get(dht->mono_time);
|
||||
|
||||
uint32_t num_nodes = 0;
|
||||
Client_data **client_list = (Client_data **)calloc(list_count * 2, sizeof(Client_data *));
|
||||
IPPTsPng **assoc_list = (IPPTsPng **)calloc(list_count * 2, sizeof(IPPTsPng *));
|
||||
Client_data **client_list = (Client_data **)mem_valloc(dht->mem, list_count * 2, sizeof(Client_data *));
|
||||
IPPTsPng **assoc_list = (IPPTsPng **)mem_valloc(dht->mem, list_count * 2, sizeof(IPPTsPng *));
|
||||
unsigned int sort = 0;
|
||||
bool sort_ok = false;
|
||||
|
||||
if (client_list == nullptr || assoc_list == nullptr) {
|
||||
free(assoc_list);
|
||||
free(client_list);
|
||||
mem_delete(dht->mem, assoc_list);
|
||||
mem_delete(dht->mem, client_list);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1914,7 +1834,7 @@ static uint8_t do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, co
|
||||
}
|
||||
|
||||
if (sortable && sort_ok) {
|
||||
sort_client_list(list, dht->cur_time, list_count, public_key);
|
||||
sort_client_list(dht->mem, list, dht->cur_time, list_count, public_key);
|
||||
}
|
||||
|
||||
if (num_nodes > 0 && (mono_time_is_timeout(dht->mono_time, *lastgetnode, GET_NODE_INTERVAL)
|
||||
@ -1931,8 +1851,8 @@ static uint8_t do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, co
|
||||
++*bootstrap_times;
|
||||
}
|
||||
|
||||
free(assoc_list);
|
||||
free(client_list);
|
||||
mem_delete(dht->mem, assoc_list);
|
||||
mem_delete(dht->mem, client_list);
|
||||
return not_kill;
|
||||
}
|
||||
|
||||
@ -1964,7 +1884,7 @@ static void do_dht_friends(DHT *dht)
|
||||
* Send a get nodes request every GET_NODE_INTERVAL seconds to a random good node in the list.
|
||||
*/
|
||||
non_null()
|
||||
static void do_Close(DHT *dht)
|
||||
static void do_close(DHT *dht)
|
||||
{
|
||||
for (size_t i = 0; i < dht->num_to_bootstrap; ++i) {
|
||||
dht_getnodes(dht, &dht->to_bootstrap[i].ip_port, dht->to_bootstrap[i].public_key, dht->self_public_key);
|
||||
@ -2043,11 +1963,6 @@ int dht_bootstrap_from_address(DHT *dht, const char *address, bool ipv6enabled,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** @brief Send the given packet to node with public_key.
|
||||
*
|
||||
* @return number of bytes sent.
|
||||
* @retval -1 if failure.
|
||||
*/
|
||||
int route_packet(const DHT *dht, const uint8_t *public_key, const uint8_t *packet, uint16_t length)
|
||||
{
|
||||
for (uint32_t i = 0; i < LCLIENT_LIST; ++i) {
|
||||
@ -2294,7 +2209,7 @@ static uint32_t routeone_to_friend(const DHT *dht, const uint8_t *friend_id, con
|
||||
/*---------------------BEGINNING OF NAT PUNCHING FUNCTIONS--------------------------*/
|
||||
|
||||
non_null()
|
||||
static int send_NATping(const DHT *dht, const uint8_t *public_key, uint64_t ping_id, uint8_t type)
|
||||
static int send_nat_ping(const DHT *dht, const uint8_t *public_key, uint64_t ping_id, uint8_t type)
|
||||
{
|
||||
uint8_t data[sizeof(uint64_t) + 1];
|
||||
uint8_t packet_data[MAX_CRYPTO_REQUEST_SIZE];
|
||||
@ -2329,8 +2244,8 @@ static int send_NATping(const DHT *dht, const uint8_t *public_key, uint64_t ping
|
||||
|
||||
/** Handle a received ping request for. */
|
||||
non_null()
|
||||
static int handle_NATping(void *object, const IP_Port *source, const uint8_t *source_pubkey, const uint8_t *packet,
|
||||
uint16_t length, void *userdata)
|
||||
static int handle_nat_ping(void *object, const IP_Port *source, const uint8_t *source_pubkey, const uint8_t *packet,
|
||||
uint16_t length, void *userdata)
|
||||
{
|
||||
if (length != sizeof(uint64_t) + 1) {
|
||||
return 1;
|
||||
@ -2350,7 +2265,7 @@ static int handle_NATping(void *object, const IP_Port *source, const uint8_t *so
|
||||
|
||||
if (packet[0] == NAT_PING_REQUEST) {
|
||||
/* 1 is reply */
|
||||
send_NATping(dht, source_pubkey, ping_id, NAT_PING_RESPONSE);
|
||||
send_nat_ping(dht, source_pubkey, ping_id, NAT_PING_RESPONSE);
|
||||
dht_friend->nat.recv_nat_ping_timestamp = mono_time_get(dht->mono_time);
|
||||
return 0;
|
||||
}
|
||||
@ -2482,7 +2397,7 @@ static void punch_holes(DHT *dht, const IP *ip, const uint16_t *port_list, uint1
|
||||
}
|
||||
|
||||
non_null()
|
||||
static void do_NAT(DHT *dht)
|
||||
static void do_nat(DHT *dht)
|
||||
{
|
||||
const uint64_t temp_time = mono_time_get(dht->mono_time);
|
||||
|
||||
@ -2496,7 +2411,7 @@ static void do_NAT(DHT *dht)
|
||||
}
|
||||
|
||||
if (dht->friends_list[i].nat.nat_ping_timestamp + PUNCH_INTERVAL < temp_time) {
|
||||
send_NATping(dht, dht->friends_list[i].public_key, dht->friends_list[i].nat.nat_ping_id, NAT_PING_REQUEST);
|
||||
send_nat_ping(dht, dht->friends_list[i].public_key, dht->friends_list[i].nat.nat_ping_id, NAT_PING_REQUEST);
|
||||
dht->friends_list[i].nat.nat_ping_timestamp = temp_time;
|
||||
}
|
||||
|
||||
@ -2551,9 +2466,7 @@ static uint16_t list_nodes(const Random *rng, const Client_data *list, size_t le
|
||||
}
|
||||
|
||||
if (!assoc_timeout(cur_time, &list[i - 1].assoc6)) {
|
||||
if (assoc == nullptr) {
|
||||
assoc = &list[i - 1].assoc6;
|
||||
} else if ((random_u08(rng) % 2) != 0) {
|
||||
if (assoc == nullptr || (random_u08(rng) % 2) != 0) {
|
||||
assoc = &list[i - 1].assoc6;
|
||||
}
|
||||
}
|
||||
@ -2671,8 +2584,8 @@ void dht_callback_get_nodes_response(DHT *dht, dht_get_nodes_response_cb *functi
|
||||
}
|
||||
|
||||
non_null(1, 2, 3) nullable(5)
|
||||
static int handle_LANdiscovery(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length,
|
||||
void *userdata)
|
||||
static int handle_lan_discovery(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length,
|
||||
void *userdata)
|
||||
{
|
||||
DHT *dht = (DHT *)object;
|
||||
|
||||
@ -2694,14 +2607,15 @@ static int handle_LANdiscovery(void *object, const IP_Port *source, const uint8_
|
||||
|
||||
/*----------------------------------------------------------------------------------*/
|
||||
|
||||
DHT *new_dht(const Logger *log, const Random *rng, const Network *ns, Mono_Time *mono_time, Networking_Core *net,
|
||||
DHT *new_dht(const Logger *log, const Memory *mem, const Random *rng, const Network *ns,
|
||||
Mono_Time *mono_time, Networking_Core *net,
|
||||
bool hole_punching_enabled, bool lan_discovery_enabled)
|
||||
{
|
||||
if (net == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
DHT *const dht = (DHT *)calloc(1, sizeof(DHT));
|
||||
DHT *const dht = (DHT *)mem_alloc(mem, sizeof(DHT));
|
||||
|
||||
if (dht == nullptr) {
|
||||
return nullptr;
|
||||
@ -2713,11 +2627,12 @@ DHT *new_dht(const Logger *log, const Random *rng, const Network *ns, Mono_Time
|
||||
dht->log = log;
|
||||
dht->net = net;
|
||||
dht->rng = rng;
|
||||
dht->mem = mem;
|
||||
|
||||
dht->hole_punching_enabled = hole_punching_enabled;
|
||||
dht->lan_discovery_enabled = lan_discovery_enabled;
|
||||
|
||||
dht->ping = ping_new(mono_time, rng, dht);
|
||||
dht->ping = ping_new(mem, mono_time, rng, dht);
|
||||
|
||||
if (dht->ping == nullptr) {
|
||||
kill_dht(dht);
|
||||
@ -2727,8 +2642,8 @@ DHT *new_dht(const Logger *log, const Random *rng, const Network *ns, Mono_Time
|
||||
networking_registerhandler(dht->net, NET_PACKET_GET_NODES, &handle_getnodes, dht);
|
||||
networking_registerhandler(dht->net, NET_PACKET_SEND_NODES_IPV6, &handle_sendnodes_ipv6, dht);
|
||||
networking_registerhandler(dht->net, NET_PACKET_CRYPTO, &cryptopacket_handle, dht);
|
||||
networking_registerhandler(dht->net, NET_PACKET_LAN_DISCOVERY, &handle_LANdiscovery, dht);
|
||||
cryptopacket_registerhandler(dht, CRYPTO_PACKET_NAT_PING, &handle_NATping, dht);
|
||||
networking_registerhandler(dht->net, NET_PACKET_LAN_DISCOVERY, &handle_lan_discovery, dht);
|
||||
cryptopacket_registerhandler(dht, CRYPTO_PACKET_NAT_PING, &handle_nat_ping, dht);
|
||||
|
||||
#ifdef CHECK_ANNOUNCE_NODE
|
||||
networking_registerhandler(dht->net, NET_PACKET_DATA_SEARCH_RESPONSE, &handle_data_search_response, dht);
|
||||
@ -2736,8 +2651,8 @@ DHT *new_dht(const Logger *log, const Random *rng, const Network *ns, Mono_Time
|
||||
|
||||
crypto_new_keypair(rng, dht->self_public_key, dht->self_secret_key);
|
||||
|
||||
dht->shared_keys_recv = shared_key_cache_new(mono_time, dht->self_secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT);
|
||||
dht->shared_keys_sent = shared_key_cache_new(mono_time, dht->self_secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT);
|
||||
dht->shared_keys_recv = shared_key_cache_new(mono_time, mem, dht->self_secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT);
|
||||
dht->shared_keys_sent = shared_key_cache_new(mono_time, mem, dht->self_secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT);
|
||||
|
||||
if (dht->shared_keys_recv == nullptr || dht->shared_keys_sent == nullptr) {
|
||||
kill_dht(dht);
|
||||
@ -2745,7 +2660,7 @@ DHT *new_dht(const Logger *log, const Random *rng, const Network *ns, Mono_Time
|
||||
}
|
||||
|
||||
|
||||
dht->dht_ping_array = ping_array_new(DHT_PING_ARRAY_SIZE, PING_TIMEOUT);
|
||||
dht->dht_ping_array = ping_array_new(mem, DHT_PING_ARRAY_SIZE, PING_TIMEOUT);
|
||||
|
||||
if (dht->dht_ping_array == nullptr) {
|
||||
kill_dht(dht);
|
||||
@ -2789,9 +2704,9 @@ void do_dht(DHT *dht)
|
||||
dht_connect_after_load(dht);
|
||||
}
|
||||
|
||||
do_Close(dht);
|
||||
do_close(dht);
|
||||
do_dht_friends(dht);
|
||||
do_NAT(dht);
|
||||
do_nat(dht);
|
||||
ping_iterate(dht->ping);
|
||||
}
|
||||
|
||||
@ -2810,11 +2725,11 @@ void kill_dht(DHT *dht)
|
||||
shared_key_cache_free(dht->shared_keys_recv);
|
||||
shared_key_cache_free(dht->shared_keys_sent);
|
||||
ping_array_kill(dht->dht_ping_array);
|
||||
ping_kill(dht->ping);
|
||||
free(dht->friends_list);
|
||||
free(dht->loaded_nodes_list);
|
||||
ping_kill(dht->mem, dht->ping);
|
||||
mem_delete(dht->mem, dht->friends_list);
|
||||
mem_delete(dht->mem, dht->loaded_nodes_list);
|
||||
crypto_memzero(dht->self_secret_key, sizeof(dht->self_secret_key));
|
||||
free(dht);
|
||||
mem_delete(dht->mem, dht);
|
||||
}
|
||||
|
||||
/* new DHT format for load/save, more robust and forward compatible */
|
||||
@ -2868,7 +2783,7 @@ void dht_save(const DHT *dht, uint8_t *data)
|
||||
/* get right offset. we write the actual header later. */
|
||||
data = state_write_section_header(data, DHT_STATE_COOKIE_TYPE, 0, 0);
|
||||
|
||||
Node_format *clients = (Node_format *)calloc(MAX_SAVED_DHT_NODES, sizeof(Node_format));
|
||||
Node_format *clients = (Node_format *)mem_valloc(dht->mem, MAX_SAVED_DHT_NODES, sizeof(Node_format));
|
||||
|
||||
if (clients == nullptr) {
|
||||
LOGGER_ERROR(dht->log, "could not allocate %u nodes", MAX_SAVED_DHT_NODES);
|
||||
@ -2917,17 +2832,12 @@ void dht_save(const DHT *dht, uint8_t *data)
|
||||
state_write_section_header(old_data, DHT_STATE_COOKIE_TYPE, pack_nodes(dht->log, data, sizeof(Node_format) * num,
|
||||
clients, num), DHT_STATE_TYPE_NODES);
|
||||
|
||||
free(clients);
|
||||
mem_delete(dht->mem, clients);
|
||||
}
|
||||
|
||||
/** Bootstrap from this number of nodes every time `dht_connect_after_load()` is called */
|
||||
#define SAVE_BOOTSTAP_FREQUENCY 8
|
||||
|
||||
/** @brief Start sending packets after DHT loaded_friends_list and loaded_clients_list are set.
|
||||
*
|
||||
* @retval 0 if successful
|
||||
* @retval -1 otherwise
|
||||
*/
|
||||
int dht_connect_after_load(DHT *dht)
|
||||
{
|
||||
if (dht == nullptr) {
|
||||
@ -2940,7 +2850,7 @@ int dht_connect_after_load(DHT *dht)
|
||||
|
||||
/* DHT is connected, stop. */
|
||||
if (dht_non_lan_connected(dht)) {
|
||||
free(dht->loaded_nodes_list);
|
||||
mem_delete(dht->mem, dht->loaded_nodes_list);
|
||||
dht->loaded_nodes_list = nullptr;
|
||||
dht->loaded_num_nodes = 0;
|
||||
return 0;
|
||||
@ -2966,9 +2876,9 @@ static State_Load_Status dht_load_state_callback(void *outer, const uint8_t *dat
|
||||
break;
|
||||
}
|
||||
|
||||
free(dht->loaded_nodes_list);
|
||||
mem_delete(dht->mem, dht->loaded_nodes_list);
|
||||
// Copy to loaded_clients_list
|
||||
dht->loaded_nodes_list = (Node_format *)calloc(MAX_SAVED_DHT_NODES, sizeof(Node_format));
|
||||
dht->loaded_nodes_list = (Node_format *)mem_valloc(dht->mem, MAX_SAVED_DHT_NODES, sizeof(Node_format));
|
||||
|
||||
if (dht->loaded_nodes_list == nullptr) {
|
||||
LOGGER_ERROR(dht->log, "could not allocate %u nodes", MAX_SAVED_DHT_NODES);
|
||||
@ -2997,11 +2907,6 @@ static State_Load_Status dht_load_state_callback(void *outer, const uint8_t *dat
|
||||
return STATE_LOAD_STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
/** @brief Load the DHT from data of size size.
|
||||
*
|
||||
* @retval -1 if failure.
|
||||
* @retval 0 if success.
|
||||
*/
|
||||
int dht_load(DHT *dht, const uint8_t *data, uint32_t length)
|
||||
{
|
||||
const uint32_t cookie_len = sizeof(uint32_t);
|
||||
@ -3060,16 +2965,6 @@ bool dht_non_lan_connected(const DHT *dht)
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @brief Copies our own ip_port structure to `dest`.
|
||||
*
|
||||
* WAN addresses take priority over LAN addresses.
|
||||
*
|
||||
* This function will zero the `dest` buffer before use.
|
||||
*
|
||||
* @retval 0 if our ip port can't be found (this usually means we're not connected to the DHT).
|
||||
* @retval 1 if IP is a WAN address.
|
||||
* @retval 2 if IP is a LAN address.
|
||||
*/
|
||||
unsigned int ipport_self_copy(const DHT *dht, IP_Port *dest)
|
||||
{
|
||||
ipport_reset(dest);
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "attributes.h"
|
||||
#include "crypto_core.h"
|
||||
#include "logger.h"
|
||||
#include "mem.h"
|
||||
#include "mono_time.h"
|
||||
#include "network.h"
|
||||
#include "ping_array.h"
|
||||
@ -219,7 +220,7 @@ int pack_ip_port(const Logger *logger, uint8_t *data, uint16_t length, const IP_
|
||||
* @retval -1 on failure.
|
||||
*/
|
||||
non_null()
|
||||
int dht_create_packet(const Random *rng,
|
||||
int dht_create_packet(const Memory *mem, const Random *rng,
|
||||
const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
|
||||
const uint8_t *shared_key, const uint8_t type,
|
||||
const uint8_t *plain, size_t plain_length,
|
||||
@ -393,7 +394,7 @@ void set_announce_node(DHT *dht, const uint8_t *public_key);
|
||||
*/
|
||||
non_null()
|
||||
int get_close_nodes(const DHT *dht, const uint8_t *public_key, Node_format *nodes_list, Family sa_family,
|
||||
bool is_LAN, bool want_announce);
|
||||
bool is_lan, bool want_announce);
|
||||
|
||||
|
||||
/** @brief Put up to max_num nodes in nodes from the random friends.
|
||||
@ -494,8 +495,8 @@ int dht_load(DHT *dht, const uint8_t *data, uint32_t length);
|
||||
|
||||
/** Initialize DHT. */
|
||||
non_null()
|
||||
DHT *new_dht(const Logger *log, const Random *rng, const Network *ns, Mono_Time *mono_time, Networking_Core *net,
|
||||
bool hole_punching_enabled, bool lan_discovery_enabled);
|
||||
DHT *new_dht(const Logger *log, const Memory *mem, const Random *rng, const Network *ns,
|
||||
Mono_Time *mono_time, Networking_Core *net, bool hole_punching_enabled, bool lan_discovery_enabled);
|
||||
|
||||
nullable(1)
|
||||
void kill_dht(DHT *dht);
|
||||
|
@ -187,12 +187,14 @@ TEST(Request, CreateAndParse)
|
||||
|
||||
TEST(AnnounceNodes, SetAndTest)
|
||||
{
|
||||
Logger *log = logger_new();
|
||||
Mono_Time *mono_time = mono_time_new(nullptr, nullptr);
|
||||
const Random *rng = system_random();
|
||||
const Network *ns = system_network();
|
||||
Networking_Core *net = new_networking_no_udp(log, ns);
|
||||
DHT *dht = new_dht(log, rng, ns, mono_time, net, true, true);
|
||||
const Memory *mem = system_memory();
|
||||
|
||||
Logger *log = logger_new();
|
||||
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
|
||||
Networking_Core *net = new_networking_no_udp(log, mem, ns);
|
||||
DHT *dht = new_dht(log, mem, rng, ns, mono_time, net, true, true);
|
||||
ASSERT_NE(dht, nullptr);
|
||||
|
||||
uint8_t pk_data[CRYPTO_PUBLIC_KEY_SIZE];
|
||||
@ -224,7 +226,7 @@ TEST(AnnounceNodes, SetAndTest)
|
||||
|
||||
kill_dht(dht);
|
||||
kill_networking(net);
|
||||
mono_time_free(mono_time);
|
||||
mono_time_free(mem, mono_time);
|
||||
logger_kill(log);
|
||||
}
|
||||
|
||||
|
@ -57,6 +57,8 @@ libtoxcore_la_SOURCES = ../third_party/cmp/cmp.c \
|
||||
../toxcore/events/group_voice_state.c \
|
||||
../toxcore/DHT.h \
|
||||
../toxcore/DHT.c \
|
||||
../toxcore/mem.h \
|
||||
../toxcore/mem.c \
|
||||
../toxcore/mono_time.h \
|
||||
../toxcore/mono_time.c \
|
||||
../toxcore/network.h \
|
||||
|
@ -41,18 +41,18 @@ bool friend_is_valid(const Messenger *m, int32_t friendnumber)
|
||||
|
||||
/** @brief Set the size of the friend list to numfriends.
|
||||
*
|
||||
* @retval -1 if realloc fails.
|
||||
* @retval -1 if mem_vrealloc fails.
|
||||
*/
|
||||
non_null()
|
||||
static int realloc_friendlist(Messenger *m, uint32_t num)
|
||||
{
|
||||
if (num == 0) {
|
||||
free(m->friendlist);
|
||||
mem_delete(m->mem, m->friendlist);
|
||||
m->friendlist = nullptr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Friend *newfriendlist = (Friend *)realloc(m->friendlist, num * sizeof(Friend));
|
||||
Friend *newfriendlist = (Friend *)mem_vrealloc(m->mem, m->friendlist, num, sizeof(Friend));
|
||||
|
||||
if (newfriendlist == nullptr) {
|
||||
return -1;
|
||||
@ -313,7 +313,7 @@ static int clear_receipts(Messenger *m, int32_t friendnumber)
|
||||
|
||||
while (receipts != nullptr) {
|
||||
struct Receipts *temp_r = receipts->next;
|
||||
free(receipts);
|
||||
mem_delete(m->mem, receipts);
|
||||
receipts = temp_r;
|
||||
}
|
||||
|
||||
@ -329,7 +329,7 @@ static int add_receipt(Messenger *m, int32_t friendnumber, uint32_t packet_num,
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct Receipts *new_receipts = (struct Receipts *)calloc(1, sizeof(struct Receipts));
|
||||
struct Receipts *new_receipts = (struct Receipts *)mem_alloc(m->mem, sizeof(struct Receipts));
|
||||
|
||||
if (new_receipts == nullptr) {
|
||||
return -1;
|
||||
@ -430,7 +430,7 @@ static int do_receipts(Messenger *m, int32_t friendnumber, void *userdata)
|
||||
|
||||
struct Receipts *r_next = receipts->next;
|
||||
|
||||
free(receipts);
|
||||
mem_delete(m->mem, receipts);
|
||||
|
||||
m->friendlist[friendnumber].receipts_start = r_next;
|
||||
|
||||
@ -2640,7 +2640,7 @@ void do_messenger(Messenger *m, void *userdata)
|
||||
}
|
||||
|
||||
if (m->tcp_server != nullptr) {
|
||||
do_TCP_server(m->tcp_server, m->mono_time);
|
||||
do_tcp_server(m->tcp_server, m->mono_time);
|
||||
}
|
||||
|
||||
do_net_crypto(m->net_crypto, userdata);
|
||||
@ -2915,15 +2915,16 @@ bool m_register_state_plugin(Messenger *m, State_Type type, m_state_size_cb *siz
|
||||
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));
|
||||
const uint32_t new_length = m->options.state_plugins_length + 1;
|
||||
Messenger_State_Plugin *temp = (Messenger_State_Plugin *)mem_vrealloc(
|
||||
m->mem, m->options.state_plugins, new_length, sizeof(Messenger_State_Plugin));
|
||||
|
||||
if (temp == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m->options.state_plugins = temp;
|
||||
++m->options.state_plugins_length;
|
||||
m->options.state_plugins_length = new_length;
|
||||
|
||||
const uint8_t index = m->options.state_plugins_length - 1;
|
||||
m->options.state_plugins[index].type = type;
|
||||
@ -3502,7 +3503,8 @@ static void m_handle_friend_request(
|
||||
*
|
||||
* if error is not NULL it will be set to one of the values in the enum above.
|
||||
*/
|
||||
Messenger *new_messenger(Mono_Time *mono_time, const Random *rng, const Network *ns, Messenger_Options *options, Messenger_Error *error)
|
||||
Messenger *new_messenger(Mono_Time *mono_time, const Memory *mem, const Random *rng, const Network *ns,
|
||||
Messenger_Options *options, Messenger_Error *error)
|
||||
{
|
||||
if (options == nullptr) {
|
||||
return nullptr;
|
||||
@ -3512,20 +3514,21 @@ Messenger *new_messenger(Mono_Time *mono_time, const Random *rng, const Network
|
||||
*error = MESSENGER_ERROR_OTHER;
|
||||
}
|
||||
|
||||
Messenger *m = (Messenger *)calloc(1, sizeof(Messenger));
|
||||
Messenger *m = (Messenger *)mem_alloc(mem, sizeof(Messenger));
|
||||
|
||||
if (m == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
m->mono_time = mono_time;
|
||||
m->mem = mem;
|
||||
m->rng = rng;
|
||||
m->ns = ns;
|
||||
|
||||
m->fr = friendreq_new();
|
||||
|
||||
if (m->fr == nullptr) {
|
||||
free(m);
|
||||
mem_delete(mem, m);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -3533,7 +3536,7 @@ Messenger *new_messenger(Mono_Time *mono_time, const Random *rng, const Network
|
||||
|
||||
if (m->log == nullptr) {
|
||||
friendreq_kill(m->fr);
|
||||
free(m);
|
||||
mem_delete(mem, m);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -3548,17 +3551,17 @@ Messenger *new_messenger(Mono_Time *mono_time, const Random *rng, const Network
|
||||
}
|
||||
|
||||
if (options->udp_disabled) {
|
||||
m->net = new_networking_no_udp(m->log, m->ns);
|
||||
m->net = new_networking_no_udp(m->log, m->mem, m->ns);
|
||||
} else {
|
||||
IP ip;
|
||||
ip_init(&ip, options->ipv6enabled);
|
||||
m->net = new_networking_ex(m->log, m->ns, &ip, options->port_range[0], options->port_range[1], &net_err);
|
||||
m->net = new_networking_ex(m->log, m->mem, m->ns, &ip, options->port_range[0], options->port_range[1], &net_err);
|
||||
}
|
||||
|
||||
if (m->net == nullptr) {
|
||||
friendreq_kill(m->fr);
|
||||
logger_kill(m->log);
|
||||
free(m);
|
||||
mem_delete(mem, m);
|
||||
|
||||
if (error != nullptr && net_err == 1) {
|
||||
*error = MESSENGER_ERROR_PORT;
|
||||
@ -3567,24 +3570,24 @@ Messenger *new_messenger(Mono_Time *mono_time, const Random *rng, const Network
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
m->dht = new_dht(m->log, m->rng, m->ns, m->mono_time, m->net, options->hole_punching_enabled, options->local_discovery_enabled);
|
||||
m->dht = new_dht(m->log, m->mem, m->rng, m->ns, m->mono_time, m->net, options->hole_punching_enabled, options->local_discovery_enabled);
|
||||
|
||||
if (m->dht == nullptr) {
|
||||
kill_networking(m->net);
|
||||
friendreq_kill(m->fr);
|
||||
logger_kill(m->log);
|
||||
free(m);
|
||||
mem_delete(mem, m);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
m->net_crypto = new_net_crypto(m->log, m->rng, m->ns, m->mono_time, m->dht, &options->proxy_info);
|
||||
m->net_crypto = new_net_crypto(m->log, m->mem, m->rng, m->ns, m->mono_time, m->dht, &options->proxy_info);
|
||||
|
||||
if (m->net_crypto == nullptr) {
|
||||
kill_dht(m->dht);
|
||||
kill_networking(m->net);
|
||||
friendreq_kill(m->fr);
|
||||
logger_kill(m->log);
|
||||
free(m);
|
||||
mem_delete(mem, m);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -3597,7 +3600,7 @@ Messenger *new_messenger(Mono_Time *mono_time, const Random *rng, const Network
|
||||
kill_networking(m->net);
|
||||
friendreq_kill(m->fr);
|
||||
logger_kill(m->log);
|
||||
free(m);
|
||||
mem_delete(mem, m);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -3605,15 +3608,15 @@ Messenger *new_messenger(Mono_Time *mono_time, const Random *rng, const Network
|
||||
|
||||
if (options->dht_announcements_enabled) {
|
||||
m->forwarding = new_forwarding(m->log, m->rng, m->mono_time, m->dht);
|
||||
m->announce = new_announcements(m->log, m->rng, m->mono_time, m->forwarding);
|
||||
m->announce = new_announcements(m->log, m->mem, m->rng, m->mono_time, m->forwarding);
|
||||
} else {
|
||||
m->forwarding = nullptr;
|
||||
m->announce = nullptr;
|
||||
}
|
||||
|
||||
m->onion = new_onion(m->log, m->mono_time, m->rng, m->dht);
|
||||
m->onion_a = new_onion_announce(m->log, m->rng, m->mono_time, m->dht);
|
||||
m->onion_c = new_onion_client(m->log, m->rng, m->mono_time, m->net_crypto);
|
||||
m->onion = new_onion(m->log, m->mem, m->mono_time, m->rng, m->dht);
|
||||
m->onion_a = new_onion_announce(m->log, m->mem, m->rng, m->mono_time, m->dht);
|
||||
m->onion_c = new_onion_client(m->log, m->mem, m->rng, m->mono_time, m->net_crypto);
|
||||
m->fr_c = new_friend_connections(m->log, m->mono_time, m->ns, m->onion_c, options->local_discovery_enabled);
|
||||
|
||||
if ((options->dht_announcements_enabled && (m->forwarding == nullptr || m->announce == nullptr)) ||
|
||||
@ -3632,7 +3635,7 @@ Messenger *new_messenger(Mono_Time *mono_time, const Random *rng, const Network
|
||||
kill_networking(m->net);
|
||||
friendreq_kill(m->fr);
|
||||
logger_kill(m->log);
|
||||
free(m);
|
||||
mem_delete(mem, m);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -3654,15 +3657,16 @@ Messenger *new_messenger(Mono_Time *mono_time, const Random *rng, const Network
|
||||
kill_networking(m->net);
|
||||
friendreq_kill(m->fr);
|
||||
logger_kill(m->log);
|
||||
free(m);
|
||||
mem_delete(mem, m);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#endif /* VANILLA_NACL */
|
||||
|
||||
if (options->tcp_server_port != 0) {
|
||||
m->tcp_server = new_TCP_server(m->log, m->rng, m->ns, options->ipv6enabled, 1, &options->tcp_server_port,
|
||||
dht_get_self_secret_key(m->dht), m->onion, m->forwarding);
|
||||
m->tcp_server = new_tcp_server(m->log, m->mem, m->rng, m->ns, options->ipv6enabled, 1,
|
||||
&options->tcp_server_port, dht_get_self_secret_key(m->dht),
|
||||
m->onion, m->forwarding);
|
||||
|
||||
if (m->tcp_server == nullptr) {
|
||||
kill_onion(m->onion);
|
||||
@ -3682,7 +3686,7 @@ Messenger *new_messenger(Mono_Time *mono_time, const Random *rng, const Network
|
||||
kill_networking(m->net);
|
||||
friendreq_kill(m->fr);
|
||||
logger_kill(m->log);
|
||||
free(m);
|
||||
mem_delete(mem, m);
|
||||
|
||||
if (error != nullptr) {
|
||||
*error = MESSENGER_ERROR_TCP_SERVER;
|
||||
@ -3721,7 +3725,7 @@ void kill_messenger(Messenger *m)
|
||||
}
|
||||
|
||||
if (m->tcp_server != nullptr) {
|
||||
kill_TCP_server(m->tcp_server);
|
||||
kill_tcp_server(m->tcp_server);
|
||||
}
|
||||
|
||||
kill_onion(m->onion);
|
||||
@ -3745,11 +3749,11 @@ void kill_messenger(Messenger *m)
|
||||
}
|
||||
|
||||
logger_kill(m->log);
|
||||
free(m->friendlist);
|
||||
mem_delete(m->mem, m->friendlist);
|
||||
friendreq_kill(m->fr);
|
||||
|
||||
free(m->options.state_plugins);
|
||||
free(m);
|
||||
mem_delete(m->mem, m->options.state_plugins);
|
||||
mem_delete(m->mem, m);
|
||||
}
|
||||
|
||||
bool m_is_receiving_file(Messenger *m)
|
||||
|
@ -245,6 +245,7 @@ typedef struct Friend {
|
||||
struct Messenger {
|
||||
Logger *log;
|
||||
Mono_Time *mono_time;
|
||||
const Memory *mem;
|
||||
const Random *rng;
|
||||
const Network *ns;
|
||||
|
||||
@ -813,7 +814,8 @@ typedef enum Messenger_Error {
|
||||
* if error is not NULL it will be set to one of the values in the enum above.
|
||||
*/
|
||||
non_null()
|
||||
Messenger *new_messenger(Mono_Time *mono_time, const Random *rng, const Network *ns, Messenger_Options *options, Messenger_Error *error);
|
||||
Messenger *new_messenger(Mono_Time *mono_time, const Memory *mem, const Random *rng, const Network *ns,
|
||||
Messenger_Options *options, Messenger_Error *error);
|
||||
|
||||
/** @brief Run this before closing shop.
|
||||
*
|
||||
|
@ -8,6 +8,7 @@
|
||||
*/
|
||||
#include "TCP_client.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -101,12 +102,12 @@ void tcp_con_set_custom_uint(TCP_Client_Connection *con, uint32_t value)
|
||||
* @retval false on failure
|
||||
*/
|
||||
non_null()
|
||||
static bool connect_sock_to(const Logger *logger, Socket sock, const IP_Port *ip_port, const TCP_Proxy_Info *proxy_info)
|
||||
static bool connect_sock_to(const Logger *logger, const Memory *mem, Socket sock, const IP_Port *ip_port, const TCP_Proxy_Info *proxy_info)
|
||||
{
|
||||
if (proxy_info->proxy_type != TCP_PROXY_NONE) {
|
||||
return net_connect(logger, sock, &proxy_info->ip_port);
|
||||
return net_connect(mem, logger, sock, &proxy_info->ip_port);
|
||||
} else {
|
||||
return net_connect(logger, sock, ip_port);
|
||||
return net_connect(mem, logger, sock, ip_port);
|
||||
}
|
||||
}
|
||||
|
||||
@ -151,8 +152,8 @@ static int proxy_http_read_connection_response(const Logger *logger, const TCP_C
|
||||
char success[] = "200";
|
||||
uint8_t data[16]; // draining works the best if the length is a power of 2
|
||||
|
||||
const int ret = read_TCP_packet(logger, tcp_conn->con.ns, tcp_conn->con.sock, data, sizeof(data) - 1,
|
||||
&tcp_conn->con.ip_port);
|
||||
const TCP_Connection *con0 = &tcp_conn->con;
|
||||
const int ret = read_tcp_packet(logger, con0->mem, con0->ns, con0->sock, data, sizeof(data) - 1, &con0->ip_port);
|
||||
|
||||
if (ret == -1) {
|
||||
return 0;
|
||||
@ -167,9 +168,10 @@ static int proxy_http_read_connection_response(const Logger *logger, const TCP_C
|
||||
while (data_left > 0) {
|
||||
uint8_t temp_data[16];
|
||||
const uint16_t temp_data_size = min_u16(data_left, sizeof(temp_data));
|
||||
const TCP_Connection *con = &tcp_conn->con;
|
||||
|
||||
if (read_TCP_packet(logger, tcp_conn->con.ns, tcp_conn->con.sock, temp_data, temp_data_size,
|
||||
&tcp_conn->con.ip_port) == -1) {
|
||||
if (read_tcp_packet(logger, con->mem, con->ns, con->sock, temp_data, temp_data_size,
|
||||
&con->ip_port) == -1) {
|
||||
LOGGER_ERROR(logger, "failed to drain TCP data (but ignoring failure)");
|
||||
return 1;
|
||||
}
|
||||
@ -212,7 +214,8 @@ non_null()
|
||||
static int socks5_read_handshake_response(const Logger *logger, const TCP_Client_Connection *tcp_conn)
|
||||
{
|
||||
uint8_t data[2];
|
||||
const int ret = read_TCP_packet(logger, tcp_conn->con.ns, tcp_conn->con.sock, data, sizeof(data), &tcp_conn->con.ip_port);
|
||||
const TCP_Connection *con = &tcp_conn->con;
|
||||
const int ret = read_tcp_packet(logger, con->mem, con->ns, con->sock, data, sizeof(data), &con->ip_port);
|
||||
|
||||
if (ret == -1) {
|
||||
return 0;
|
||||
@ -262,7 +265,8 @@ static int proxy_socks5_read_connection_response(const Logger *logger, const TCP
|
||||
{
|
||||
if (net_family_is_ipv4(tcp_conn->ip_port.ip.family)) {
|
||||
uint8_t data[4 + sizeof(IP4) + sizeof(uint16_t)];
|
||||
const int ret = read_TCP_packet(logger, tcp_conn->con.ns, tcp_conn->con.sock, data, sizeof(data), &tcp_conn->con.ip_port);
|
||||
const TCP_Connection *con = &tcp_conn->con;
|
||||
const int ret = read_tcp_packet(logger, con->mem, con->ns, con->sock, data, sizeof(data), &con->ip_port);
|
||||
|
||||
if (ret == -1) {
|
||||
return 0;
|
||||
@ -273,7 +277,8 @@ static int proxy_socks5_read_connection_response(const Logger *logger, const TCP
|
||||
}
|
||||
} else {
|
||||
uint8_t data[4 + sizeof(IP6) + sizeof(uint16_t)];
|
||||
int ret = read_TCP_packet(logger, tcp_conn->con.ns, tcp_conn->con.sock, data, sizeof(data), &tcp_conn->con.ip_port);
|
||||
const TCP_Connection *con = &tcp_conn->con;
|
||||
int ret = read_tcp_packet(logger, con->mem, con->ns, con->sock, data, sizeof(data), &con->ip_port);
|
||||
|
||||
if (ret == -1) {
|
||||
return 0;
|
||||
@ -345,7 +350,7 @@ int send_routing_request(const Logger *logger, TCP_Client_Connection *con, const
|
||||
uint8_t packet[1 + CRYPTO_PUBLIC_KEY_SIZE];
|
||||
packet[0] = TCP_PACKET_ROUTING_REQUEST;
|
||||
memcpy(packet + 1, public_key, CRYPTO_PUBLIC_KEY_SIZE);
|
||||
return write_packet_TCP_secure_connection(logger, &con->con, packet, sizeof(packet), true);
|
||||
return write_packet_tcp_secure_connection(logger, &con->con, packet, sizeof(packet), true);
|
||||
}
|
||||
|
||||
void routing_response_handler(TCP_Client_Connection *con, tcp_routing_response_cb *response_callback, void *object)
|
||||
@ -385,7 +390,7 @@ int send_data(const Logger *logger, TCP_Client_Connection *con, uint8_t con_id,
|
||||
VLA(uint8_t, packet, 1 + length);
|
||||
packet[0] = con_id + NUM_RESERVED_PORTS;
|
||||
memcpy(packet + 1, data, length);
|
||||
return write_packet_TCP_secure_connection(logger, &con->con, packet, SIZEOF_VLA(packet), false);
|
||||
return write_packet_tcp_secure_connection(logger, &con->con, packet, SIZEOF_VLA(packet), false);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -404,7 +409,7 @@ int send_oob_packet(const Logger *logger, TCP_Client_Connection *con, const uint
|
||||
packet[0] = TCP_PACKET_OOB_SEND;
|
||||
memcpy(packet + 1, public_key, CRYPTO_PUBLIC_KEY_SIZE);
|
||||
memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, data, length);
|
||||
return write_packet_TCP_secure_connection(logger, &con->con, packet, SIZEOF_VLA(packet), false);
|
||||
return write_packet_tcp_secure_connection(logger, &con->con, packet, SIZEOF_VLA(packet), false);
|
||||
}
|
||||
|
||||
|
||||
@ -452,7 +457,7 @@ static int client_send_disconnect_notification(const Logger *logger, TCP_Client_
|
||||
uint8_t packet[1 + 1];
|
||||
packet[0] = TCP_PACKET_DISCONNECT_NOTIFICATION;
|
||||
packet[1] = id;
|
||||
return write_packet_TCP_secure_connection(logger, &con->con, packet, sizeof(packet), true);
|
||||
return write_packet_tcp_secure_connection(logger, &con->con, packet, sizeof(packet), true);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -469,7 +474,7 @@ static int tcp_send_ping_request(const Logger *logger, TCP_Client_Connection *co
|
||||
uint8_t packet[1 + sizeof(uint64_t)];
|
||||
packet[0] = TCP_PACKET_PING;
|
||||
memcpy(packet + 1, &con->ping_request_id, sizeof(uint64_t));
|
||||
const int ret = write_packet_TCP_secure_connection(logger, &con->con, packet, sizeof(packet), true);
|
||||
const int ret = write_packet_tcp_secure_connection(logger, &con->con, packet, sizeof(packet), true);
|
||||
|
||||
if (ret == 1) {
|
||||
con->ping_request_id = 0;
|
||||
@ -492,7 +497,7 @@ static int tcp_send_ping_response(const Logger *logger, TCP_Client_Connection *c
|
||||
uint8_t packet[1 + sizeof(uint64_t)];
|
||||
packet[0] = TCP_PACKET_PONG;
|
||||
memcpy(packet + 1, &con->ping_response_id, sizeof(uint64_t));
|
||||
const int ret = write_packet_TCP_secure_connection(logger, &con->con, packet, sizeof(packet), true);
|
||||
const int ret = write_packet_tcp_secure_connection(logger, &con->con, packet, sizeof(packet), true);
|
||||
|
||||
if (ret == 1) {
|
||||
con->ping_response_id = 0;
|
||||
@ -527,7 +532,7 @@ int send_onion_request(const Logger *logger, TCP_Client_Connection *con, const u
|
||||
VLA(uint8_t, packet, 1 + length);
|
||||
packet[0] = TCP_PACKET_ONION_REQUEST;
|
||||
memcpy(packet + 1, data, length);
|
||||
return write_packet_TCP_secure_connection(logger, &con->con, packet, SIZEOF_VLA(packet), false);
|
||||
return write_packet_tcp_secure_connection(logger, &con->con, packet, SIZEOF_VLA(packet), false);
|
||||
}
|
||||
|
||||
void onion_response_handler(TCP_Client_Connection *con, tcp_onion_response_cb *onion_callback, void *object)
|
||||
@ -555,7 +560,7 @@ int send_forward_request_tcp(const Logger *logger, TCP_Client_Connection *con, c
|
||||
}
|
||||
|
||||
memcpy(packet + 1 + ipport_length, data, length);
|
||||
return write_packet_TCP_secure_connection(logger, &con->con, packet, 1 + ipport_length + length, false);
|
||||
return write_packet_tcp_secure_connection(logger, &con->con, packet, 1 + ipport_length + length, false);
|
||||
}
|
||||
|
||||
void forwarding_handler(TCP_Client_Connection *con, forwarded_response_cb *forwarded_response_callback, void *object)
|
||||
@ -565,11 +570,17 @@ void forwarding_handler(TCP_Client_Connection *con, forwarded_response_cb *forwa
|
||||
}
|
||||
|
||||
/** Create new TCP connection to ip_port/public_key */
|
||||
TCP_Client_Connection *new_TCP_connection(
|
||||
const Logger *logger, const Mono_Time *mono_time, const Random *rng, const Network *ns, const IP_Port *ip_port,
|
||||
const uint8_t *public_key, const uint8_t *self_public_key, const uint8_t *self_secret_key,
|
||||
TCP_Client_Connection *new_tcp_connection(
|
||||
const Logger *logger, const Memory *mem, const Mono_Time *mono_time, const Random *rng, const Network *ns,
|
||||
const IP_Port *ip_port, const uint8_t *public_key, const uint8_t *self_public_key, const uint8_t *self_secret_key,
|
||||
const TCP_Proxy_Info *proxy_info)
|
||||
{
|
||||
assert(logger != nullptr);
|
||||
assert(mem != nullptr);
|
||||
assert(mono_time != nullptr);
|
||||
assert(rng != nullptr);
|
||||
assert(ns != nullptr);
|
||||
|
||||
if (!net_family_is_ipv4(ip_port->ip.family) && !net_family_is_ipv6(ip_port->ip.family)) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -597,12 +608,12 @@ TCP_Client_Connection *new_TCP_connection(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!(set_socket_nonblock(ns, sock) && connect_sock_to(logger, sock, ip_port, proxy_info))) {
|
||||
if (!(set_socket_nonblock(ns, sock) && connect_sock_to(logger, mem, sock, ip_port, proxy_info))) {
|
||||
kill_sock(ns, sock);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TCP_Client_Connection *temp = (TCP_Client_Connection *)calloc(1, sizeof(TCP_Client_Connection));
|
||||
TCP_Client_Connection *temp = (TCP_Client_Connection *)mem_alloc(mem, sizeof(TCP_Client_Connection));
|
||||
|
||||
if (temp == nullptr) {
|
||||
kill_sock(ns, sock);
|
||||
@ -610,6 +621,7 @@ TCP_Client_Connection *new_TCP_connection(
|
||||
}
|
||||
|
||||
temp->con.ns = ns;
|
||||
temp->con.mem = mem;
|
||||
temp->con.rng = rng;
|
||||
temp->con.sock = sock;
|
||||
temp->con.ip_port = *ip_port;
|
||||
@ -637,7 +649,7 @@ TCP_Client_Connection *new_TCP_connection(
|
||||
|
||||
if (generate_handshake(temp) == -1) {
|
||||
kill_sock(ns, sock);
|
||||
free(temp);
|
||||
mem_delete(mem, temp);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -651,7 +663,7 @@ TCP_Client_Connection *new_TCP_connection(
|
||||
}
|
||||
|
||||
non_null()
|
||||
static int handle_TCP_client_routing_response(TCP_Client_Connection *conn, const uint8_t *data, uint16_t length)
|
||||
static int handle_tcp_client_routing_response(TCP_Client_Connection *conn, const uint8_t *data, uint16_t length)
|
||||
{
|
||||
if (length != 1 + 1 + CRYPTO_PUBLIC_KEY_SIZE) {
|
||||
return -1;
|
||||
@ -679,7 +691,7 @@ static int handle_TCP_client_routing_response(TCP_Client_Connection *conn, const
|
||||
}
|
||||
|
||||
non_null()
|
||||
static int handle_TCP_client_connection_notification(TCP_Client_Connection *conn, const uint8_t *data, uint16_t length)
|
||||
static int handle_tcp_client_connection_notification(TCP_Client_Connection *conn, const uint8_t *data, uint16_t length)
|
||||
{
|
||||
if (length != 1 + 1) {
|
||||
return -1;
|
||||
@ -706,7 +718,7 @@ static int handle_TCP_client_connection_notification(TCP_Client_Connection *conn
|
||||
}
|
||||
|
||||
non_null()
|
||||
static int handle_TCP_client_disconnect_notification(TCP_Client_Connection *conn, const uint8_t *data, uint16_t length)
|
||||
static int handle_tcp_client_disconnect_notification(TCP_Client_Connection *conn, const uint8_t *data, uint16_t length)
|
||||
{
|
||||
if (length != 1 + 1) {
|
||||
return -1;
|
||||
@ -737,7 +749,7 @@ static int handle_TCP_client_disconnect_notification(TCP_Client_Connection *conn
|
||||
}
|
||||
|
||||
non_null()
|
||||
static int handle_TCP_client_ping(const Logger *logger, TCP_Client_Connection *conn, const uint8_t *data, uint16_t length)
|
||||
static int handle_tcp_client_ping(const Logger *logger, TCP_Client_Connection *conn, const uint8_t *data, uint16_t length)
|
||||
{
|
||||
if (length != 1 + sizeof(uint64_t)) {
|
||||
return -1;
|
||||
@ -751,7 +763,7 @@ static int handle_TCP_client_ping(const Logger *logger, TCP_Client_Connection *c
|
||||
}
|
||||
|
||||
non_null()
|
||||
static int handle_TCP_client_pong(TCP_Client_Connection *conn, const uint8_t *data, uint16_t length)
|
||||
static int handle_tcp_client_pong(TCP_Client_Connection *conn, const uint8_t *data, uint16_t length)
|
||||
{
|
||||
if (length != 1 + sizeof(uint64_t)) {
|
||||
return -1;
|
||||
@ -772,7 +784,7 @@ static int handle_TCP_client_pong(TCP_Client_Connection *conn, const uint8_t *da
|
||||
}
|
||||
|
||||
non_null(1, 2) nullable(4)
|
||||
static int handle_TCP_client_oob_recv(TCP_Client_Connection *conn, const uint8_t *data, uint16_t length, void *userdata)
|
||||
static int handle_tcp_client_oob_recv(TCP_Client_Connection *conn, const uint8_t *data, uint16_t length, void *userdata)
|
||||
{
|
||||
if (length <= 1 + CRYPTO_PUBLIC_KEY_SIZE) {
|
||||
return -1;
|
||||
@ -791,7 +803,7 @@ static int handle_TCP_client_oob_recv(TCP_Client_Connection *conn, const uint8_t
|
||||
* @retval -1 on failure
|
||||
*/
|
||||
non_null(1, 2, 3) nullable(5)
|
||||
static int handle_TCP_client_packet(const Logger *logger, TCP_Client_Connection *conn, const uint8_t *data,
|
||||
static int handle_tcp_client_packet(const Logger *logger, TCP_Client_Connection *conn, const uint8_t *data,
|
||||
uint16_t length, void *userdata)
|
||||
{
|
||||
if (length <= 1) {
|
||||
@ -800,22 +812,22 @@ static int handle_TCP_client_packet(const Logger *logger, TCP_Client_Connection
|
||||
|
||||
switch (data[0]) {
|
||||
case TCP_PACKET_ROUTING_RESPONSE:
|
||||
return handle_TCP_client_routing_response(conn, data, length);
|
||||
return handle_tcp_client_routing_response(conn, data, length);
|
||||
|
||||
case TCP_PACKET_CONNECTION_NOTIFICATION:
|
||||
return handle_TCP_client_connection_notification(conn, data, length);
|
||||
return handle_tcp_client_connection_notification(conn, data, length);
|
||||
|
||||
case TCP_PACKET_DISCONNECT_NOTIFICATION:
|
||||
return handle_TCP_client_disconnect_notification(conn, data, length);
|
||||
return handle_tcp_client_disconnect_notification(conn, data, length);
|
||||
|
||||
case TCP_PACKET_PING:
|
||||
return handle_TCP_client_ping(logger, conn, data, length);
|
||||
return handle_tcp_client_ping(logger, conn, data, length);
|
||||
|
||||
case TCP_PACKET_PONG:
|
||||
return handle_TCP_client_pong(conn, data, length);
|
||||
return handle_tcp_client_pong(conn, data, length);
|
||||
|
||||
case TCP_PACKET_OOB_RECV:
|
||||
return handle_TCP_client_oob_recv(conn, data, length, userdata);
|
||||
return handle_tcp_client_oob_recv(conn, data, length, userdata);
|
||||
|
||||
case TCP_PACKET_ONION_RESPONSE: {
|
||||
if (conn->onion_callback != nullptr) {
|
||||
@ -852,7 +864,7 @@ non_null(1, 2) nullable(3)
|
||||
static bool tcp_process_packet(const Logger *logger, TCP_Client_Connection *conn, void *userdata)
|
||||
{
|
||||
uint8_t packet[MAX_PACKET_SIZE];
|
||||
const int len = read_packet_TCP_secure_connection(logger, conn->con.ns, conn->con.sock, &conn->next_packet_length, conn->con.shared_key, conn->recv_nonce, packet, sizeof(packet), &conn->ip_port);
|
||||
const int len = read_packet_tcp_secure_connection(logger, conn->con.mem, conn->con.ns, conn->con.sock, &conn->next_packet_length, conn->con.shared_key, conn->recv_nonce, packet, sizeof(packet), &conn->ip_port);
|
||||
|
||||
if (len == 0) {
|
||||
return false;
|
||||
@ -863,7 +875,7 @@ static bool tcp_process_packet(const Logger *logger, TCP_Client_Connection *conn
|
||||
return false;
|
||||
}
|
||||
|
||||
if (handle_TCP_client_packet(logger, conn, packet, len, userdata) == -1) {
|
||||
if (handle_tcp_client_packet(logger, conn, packet, len, userdata) == -1) {
|
||||
conn->status = TCP_CLIENT_DISCONNECTED;
|
||||
return false;
|
||||
}
|
||||
@ -872,7 +884,7 @@ static bool tcp_process_packet(const Logger *logger, TCP_Client_Connection *conn
|
||||
}
|
||||
|
||||
non_null(1, 2, 3) nullable(4)
|
||||
static int do_confirmed_TCP(const Logger *logger, TCP_Client_Connection *conn, const Mono_Time *mono_time,
|
||||
static int do_confirmed_tcp(const Logger *logger, TCP_Client_Connection *conn, const Mono_Time *mono_time,
|
||||
void *userdata)
|
||||
{
|
||||
send_pending_data(logger, &conn->con);
|
||||
@ -906,7 +918,7 @@ static int do_confirmed_TCP(const Logger *logger, TCP_Client_Connection *conn, c
|
||||
}
|
||||
|
||||
/** Run the TCP connection */
|
||||
void do_TCP_connection(const Logger *logger, const Mono_Time *mono_time,
|
||||
void do_tcp_connection(const Logger *logger, const Mono_Time *mono_time,
|
||||
TCP_Client_Connection *tcp_connection, void *userdata)
|
||||
{
|
||||
if (tcp_connection->status == TCP_CLIENT_DISCONNECTED) {
|
||||
@ -969,7 +981,8 @@ void do_TCP_connection(const Logger *logger, const Mono_Time *mono_time,
|
||||
|
||||
if (tcp_connection->status == TCP_CLIENT_UNCONFIRMED) {
|
||||
uint8_t data[TCP_SERVER_HANDSHAKE_SIZE];
|
||||
const int len = read_TCP_packet(logger, tcp_connection->con.ns, tcp_connection->con.sock, data, sizeof(data), &tcp_connection->con.ip_port);
|
||||
const TCP_Connection *con = &tcp_connection->con;
|
||||
const int len = read_tcp_packet(logger, con->mem, con->ns, con->sock, data, sizeof(data), &con->ip_port);
|
||||
|
||||
if (sizeof(data) == len) {
|
||||
if (handle_handshake(tcp_connection, data) == 0) {
|
||||
@ -983,7 +996,7 @@ void do_TCP_connection(const Logger *logger, const Mono_Time *mono_time,
|
||||
}
|
||||
|
||||
if (tcp_connection->status == TCP_CLIENT_CONFIRMED) {
|
||||
do_confirmed_TCP(logger, tcp_connection, mono_time, userdata);
|
||||
do_confirmed_tcp(logger, tcp_connection, mono_time, userdata);
|
||||
}
|
||||
|
||||
if (tcp_connection->kill_at <= mono_time_get(mono_time)) {
|
||||
@ -992,14 +1005,16 @@ void do_TCP_connection(const Logger *logger, const Mono_Time *mono_time,
|
||||
}
|
||||
|
||||
/** Kill the TCP connection */
|
||||
void kill_TCP_connection(TCP_Client_Connection *tcp_connection)
|
||||
void kill_tcp_connection(TCP_Client_Connection *tcp_connection)
|
||||
{
|
||||
if (tcp_connection == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
wipe_priority_list(tcp_connection->con.priority_queue_start);
|
||||
const Memory *mem = tcp_connection->con.mem;
|
||||
|
||||
wipe_priority_list(tcp_connection->con.mem, tcp_connection->con.priority_queue_start);
|
||||
kill_sock(tcp_connection->con.ns, tcp_connection->con.sock);
|
||||
crypto_memzero(tcp_connection, sizeof(TCP_Client_Connection));
|
||||
free(tcp_connection);
|
||||
mem_delete(mem, tcp_connection);
|
||||
}
|
||||
|
@ -57,20 +57,20 @@ non_null()
|
||||
void tcp_con_set_custom_uint(TCP_Client_Connection *con, uint32_t value);
|
||||
|
||||
/** Create new TCP connection to ip_port/public_key */
|
||||
non_null(1, 2, 3, 4, 5, 6, 7, 8) nullable(9)
|
||||
TCP_Client_Connection *new_TCP_connection(
|
||||
const Logger *logger, const Mono_Time *mono_time, const Random *rng, const Network *ns, const IP_Port *ip_port,
|
||||
const uint8_t *public_key, const uint8_t *self_public_key, const uint8_t *self_secret_key,
|
||||
non_null(1, 2, 3, 4, 5, 6, 7, 8, 9) nullable(10)
|
||||
TCP_Client_Connection *new_tcp_connection(
|
||||
const Logger *logger, const Memory *mem, const Mono_Time *mono_time, const Random *rng, const Network *ns,
|
||||
const IP_Port *ip_port, const uint8_t *public_key, const uint8_t *self_public_key, const uint8_t *self_secret_key,
|
||||
const TCP_Proxy_Info *proxy_info);
|
||||
|
||||
/** Run the TCP connection */
|
||||
non_null(1, 2, 3) nullable(4)
|
||||
void do_TCP_connection(const Logger *logger, const Mono_Time *mono_time,
|
||||
void do_tcp_connection(const Logger *logger, const Mono_Time *mono_time,
|
||||
TCP_Client_Connection *tcp_connection, void *userdata);
|
||||
|
||||
/** Kill the TCP connection */
|
||||
nullable(1)
|
||||
void kill_TCP_connection(TCP_Client_Connection *tcp_connection);
|
||||
void kill_tcp_connection(TCP_Client_Connection *tcp_connection);
|
||||
|
||||
typedef int tcp_onion_response_cb(void *object, const uint8_t *data, uint16_t length, void *userdata);
|
||||
|
||||
|
@ -10,13 +10,13 @@
|
||||
|
||||
#include "ccompat.h"
|
||||
|
||||
void wipe_priority_list(TCP_Priority_List *p)
|
||||
void wipe_priority_list(const Memory *mem, TCP_Priority_List *p)
|
||||
{
|
||||
while (p != nullptr) {
|
||||
TCP_Priority_List *pp = p;
|
||||
p = p->next;
|
||||
free(pp->data);
|
||||
free(pp);
|
||||
mem_delete(mem, pp->data);
|
||||
mem_delete(mem, pp);
|
||||
}
|
||||
}
|
||||
|
||||
@ -74,8 +74,8 @@ int send_pending_data(const Logger *logger, TCP_Connection *con)
|
||||
|
||||
TCP_Priority_List *pp = p;
|
||||
p = p->next;
|
||||
free(pp->data);
|
||||
free(pp);
|
||||
mem_delete(con->mem, pp->data);
|
||||
mem_delete(con->mem, pp);
|
||||
}
|
||||
|
||||
con->priority_queue_start = p;
|
||||
@ -89,14 +89,14 @@ int send_pending_data(const Logger *logger, TCP_Connection *con)
|
||||
}
|
||||
|
||||
/**
|
||||
* @retval false on failure (only if calloc fails)
|
||||
* @retval false on failure (only if mem_alloc fails)
|
||||
* @retval true on success
|
||||
*/
|
||||
non_null()
|
||||
static bool add_priority(TCP_Connection *con, const uint8_t *packet, uint16_t size, uint16_t sent)
|
||||
{
|
||||
TCP_Priority_List *p = con->priority_queue_end;
|
||||
TCP_Priority_List *new_list = (TCP_Priority_List *)calloc(1, sizeof(TCP_Priority_List));
|
||||
TCP_Priority_List *new_list = (TCP_Priority_List *)mem_alloc(con->mem, sizeof(TCP_Priority_List));
|
||||
|
||||
if (new_list == nullptr) {
|
||||
return false;
|
||||
@ -105,10 +105,10 @@ static bool add_priority(TCP_Connection *con, const uint8_t *packet, uint16_t si
|
||||
new_list->next = nullptr;
|
||||
new_list->size = size;
|
||||
new_list->sent = sent;
|
||||
new_list->data = (uint8_t *)malloc(size);
|
||||
new_list->data = (uint8_t *)mem_balloc(con->mem, size);
|
||||
|
||||
if (new_list->data == nullptr) {
|
||||
free(new_list);
|
||||
mem_delete(con->mem, new_list);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -129,7 +129,7 @@ static bool add_priority(TCP_Connection *con, const uint8_t *packet, uint16_t si
|
||||
* @retval 0 if could not send packet.
|
||||
* @retval -1 on failure (connection must be killed).
|
||||
*/
|
||||
int write_packet_TCP_secure_connection(const Logger *logger, TCP_Connection *con, const uint8_t *data, uint16_t length,
|
||||
int write_packet_tcp_secure_connection(const Logger *logger, TCP_Connection *con, const uint8_t *data, uint16_t length,
|
||||
bool priority)
|
||||
{
|
||||
if (length + CRYPTO_MAC_SIZE > MAX_PACKET_SIZE) {
|
||||
@ -195,7 +195,8 @@ int write_packet_TCP_secure_connection(const Logger *logger, TCP_Connection *con
|
||||
* return length on success
|
||||
* return -1 on failure/no data in buffer.
|
||||
*/
|
||||
int read_TCP_packet(const Logger *logger, const Network *ns, Socket sock, uint8_t *data, uint16_t length, const IP_Port *ip_port)
|
||||
int read_tcp_packet(
|
||||
const Logger *logger, const Memory *mem, const Network *ns, Socket sock, uint8_t *data, uint16_t length, const IP_Port *ip_port)
|
||||
{
|
||||
const uint16_t count = net_socket_data_recv_buffer(ns, sock);
|
||||
|
||||
@ -222,7 +223,7 @@ int read_TCP_packet(const Logger *logger, const Network *ns, Socket sock, uint8_
|
||||
* return -1 on failure.
|
||||
*/
|
||||
non_null()
|
||||
static uint16_t read_TCP_length(const Logger *logger, const Network *ns, Socket sock, const IP_Port *ip_port)
|
||||
static uint16_t read_tcp_length(const Logger *logger, const Memory *mem, const Network *ns, Socket sock, const IP_Port *ip_port)
|
||||
{
|
||||
const uint16_t count = net_socket_data_recv_buffer(ns, sock);
|
||||
|
||||
@ -254,13 +255,14 @@ static uint16_t read_TCP_length(const Logger *logger, const Network *ns, Socket
|
||||
* @retval 0 if could not read any packet.
|
||||
* @retval -1 on failure (connection must be killed).
|
||||
*/
|
||||
int read_packet_TCP_secure_connection(
|
||||
const Logger *logger, const Network *ns, Socket sock, uint16_t *next_packet_length,
|
||||
int read_packet_tcp_secure_connection(
|
||||
const Logger *logger, const Memory *mem, const Network *ns,
|
||||
Socket sock, uint16_t *next_packet_length,
|
||||
const uint8_t *shared_key, uint8_t *recv_nonce, uint8_t *data,
|
||||
uint16_t max_len, const IP_Port *ip_port)
|
||||
{
|
||||
if (*next_packet_length == 0) {
|
||||
const uint16_t len = read_TCP_length(logger, ns, sock, ip_port);
|
||||
const uint16_t len = read_tcp_length(logger, mem, ns, sock, ip_port);
|
||||
|
||||
if (len == (uint16_t) -1) {
|
||||
return -1;
|
||||
@ -279,7 +281,7 @@ int read_packet_TCP_secure_connection(
|
||||
}
|
||||
|
||||
VLA(uint8_t, data_encrypted, (int) *next_packet_length);
|
||||
const int len_packet = read_TCP_packet(logger, ns, sock, data_encrypted, *next_packet_length, ip_port);
|
||||
const int len_packet = read_tcp_packet(logger, mem, ns, sock, data_encrypted, *next_packet_length, ip_port);
|
||||
|
||||
if (len_packet == -1) {
|
||||
return 0;
|
||||
|
@ -7,6 +7,7 @@
|
||||
#define C_TOXCORE_TOXCORE_TCP_COMMON_H
|
||||
|
||||
#include "crypto_core.h"
|
||||
#include "mem.h"
|
||||
#include "network.h"
|
||||
|
||||
typedef struct TCP_Priority_List TCP_Priority_List;
|
||||
@ -17,8 +18,8 @@ struct TCP_Priority_List {
|
||||
uint8_t *data;
|
||||
};
|
||||
|
||||
nullable(1)
|
||||
void wipe_priority_list(TCP_Priority_List *p);
|
||||
non_null(1) nullable(2)
|
||||
void wipe_priority_list(const Memory *mem, TCP_Priority_List *p);
|
||||
|
||||
#define NUM_RESERVED_PORTS 16
|
||||
#define NUM_CLIENT_CONNECTIONS (256 - NUM_RESERVED_PORTS)
|
||||
@ -63,6 +64,7 @@ void wipe_priority_list(TCP_Priority_List *p);
|
||||
#define MAX_PACKET_SIZE 2048
|
||||
|
||||
typedef struct TCP_Connection {
|
||||
const Memory *mem;
|
||||
const Random *rng;
|
||||
const Network *ns;
|
||||
Socket sock;
|
||||
@ -97,7 +99,7 @@ int send_pending_data(const Logger *logger, TCP_Connection *con);
|
||||
* @retval -1 on failure (connection must be killed).
|
||||
*/
|
||||
non_null()
|
||||
int write_packet_TCP_secure_connection(
|
||||
int write_packet_tcp_secure_connection(
|
||||
const Logger *logger, TCP_Connection *con, const uint8_t *data, uint16_t length,
|
||||
bool priority);
|
||||
|
||||
@ -107,8 +109,8 @@ int write_packet_TCP_secure_connection(
|
||||
* return -1 on failure/no data in buffer.
|
||||
*/
|
||||
non_null()
|
||||
int read_TCP_packet(
|
||||
const Logger *logger, const Network *ns, Socket sock, uint8_t *data, uint16_t length, const IP_Port *ip_port);
|
||||
int read_tcp_packet(
|
||||
const Logger *logger, const Memory *mem, const Network *ns, Socket sock, uint8_t *data, uint16_t length, const IP_Port *ip_port);
|
||||
|
||||
/**
|
||||
* @return length of received packet on success.
|
||||
@ -116,8 +118,9 @@ int read_TCP_packet(
|
||||
* @retval -1 on failure (connection must be killed).
|
||||
*/
|
||||
non_null()
|
||||
int read_packet_TCP_secure_connection(
|
||||
const Logger *logger, const Network *ns, Socket sock, uint16_t *next_packet_length,
|
||||
int read_packet_tcp_secure_connection(
|
||||
const Logger *logger, const Memory *mem, const Network *ns,
|
||||
Socket sock, uint16_t *next_packet_length,
|
||||
const uint8_t *shared_key, uint8_t *recv_nonce, uint8_t *data,
|
||||
uint16_t max_len, const IP_Port *ip_port);
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
struct TCP_Connections {
|
||||
const Logger *logger;
|
||||
const Memory *mem;
|
||||
const Random *rng;
|
||||
Mono_Time *mono_time;
|
||||
const Network *ns;
|
||||
@ -69,20 +70,20 @@ uint32_t tcp_connections_count(const TCP_Connections *tcp_c)
|
||||
|
||||
/** @brief Set the size of the array to num.
|
||||
*
|
||||
* @retval -1 if realloc fails.
|
||||
* @retval -1 if mem_vrealloc fails.
|
||||
* @retval 0 if it succeeds.
|
||||
*/
|
||||
non_null()
|
||||
static int realloc_TCP_Connection_to(TCP_Connection_to **array, size_t num)
|
||||
static int realloc_tcp_connection_to(const Memory *mem, TCP_Connection_to **array, size_t num)
|
||||
{
|
||||
if (num == 0) {
|
||||
free(*array);
|
||||
mem_delete(mem, *array);
|
||||
*array = nullptr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
TCP_Connection_to *temp_pointer =
|
||||
(TCP_Connection_to *)realloc(*array, num * sizeof(TCP_Connection_to));
|
||||
(TCP_Connection_to *)mem_vrealloc(mem, *array, num, sizeof(TCP_Connection_to));
|
||||
|
||||
if (temp_pointer == nullptr) {
|
||||
return -1;
|
||||
@ -94,15 +95,15 @@ static int realloc_TCP_Connection_to(TCP_Connection_to **array, size_t num)
|
||||
}
|
||||
|
||||
non_null()
|
||||
static int realloc_TCP_con(TCP_con **array, size_t num)
|
||||
static int realloc_tcp_con(const Memory *mem, TCP_con **array, size_t num)
|
||||
{
|
||||
if (num == 0) {
|
||||
free(*array);
|
||||
mem_delete(mem, *array);
|
||||
*array = nullptr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
TCP_con *temp_pointer = (TCP_con *)realloc(*array, num * sizeof(TCP_con));
|
||||
TCP_con *temp_pointer = (TCP_con *)mem_vrealloc(mem, *array, num, sizeof(TCP_con));
|
||||
|
||||
if (temp_pointer == nullptr) {
|
||||
return -1;
|
||||
@ -164,7 +165,7 @@ static int create_connection(TCP_Connections *tcp_c)
|
||||
|
||||
int id = -1;
|
||||
|
||||
if (realloc_TCP_Connection_to(&tcp_c->connections, tcp_c->connections_length + 1) == 0) {
|
||||
if (realloc_tcp_connection_to(tcp_c->mem, &tcp_c->connections, tcp_c->connections_length + 1) == 0) {
|
||||
id = tcp_c->connections_length;
|
||||
++tcp_c->connections_length;
|
||||
tcp_c->connections[id] = empty_tcp_connection_to;
|
||||
@ -189,7 +190,7 @@ static int create_tcp_connection(TCP_Connections *tcp_c)
|
||||
|
||||
int id = -1;
|
||||
|
||||
if (realloc_TCP_con(&tcp_c->tcp_connections, tcp_c->tcp_connections_length + 1) == 0) {
|
||||
if (realloc_tcp_con(tcp_c->mem, &tcp_c->tcp_connections, tcp_c->tcp_connections_length + 1) == 0) {
|
||||
id = tcp_c->tcp_connections_length;
|
||||
++tcp_c->tcp_connections_length;
|
||||
tcp_c->tcp_connections[id] = empty_tcp_con;
|
||||
@ -221,7 +222,9 @@ static int wipe_connection(TCP_Connections *tcp_c, int connections_number)
|
||||
|
||||
if (tcp_c->connections_length != i) {
|
||||
tcp_c->connections_length = i;
|
||||
realloc_TCP_Connection_to(&tcp_c->connections, tcp_c->connections_length);
|
||||
if (realloc_tcp_connection_to(tcp_c->mem, &tcp_c->connections, tcp_c->connections_length) != 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -251,7 +254,9 @@ static int wipe_tcp_connection(TCP_Connections *tcp_c, int tcp_connections_numbe
|
||||
|
||||
if (tcp_c->tcp_connections_length != i) {
|
||||
tcp_c->tcp_connections_length = i;
|
||||
realloc_TCP_con(&tcp_c->tcp_connections, tcp_c->tcp_connections_length);
|
||||
if (realloc_tcp_con(tcp_c->mem, &tcp_c->tcp_connections, tcp_c->tcp_connections_length) != 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -898,7 +903,7 @@ int kill_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connections_number
|
||||
--tcp_c->onion_num_conns;
|
||||
}
|
||||
|
||||
kill_TCP_connection(tcp_con->connection);
|
||||
kill_tcp_connection(tcp_con->connection);
|
||||
|
||||
return wipe_tcp_connection(tcp_c, tcp_connections_number);
|
||||
}
|
||||
@ -919,8 +924,8 @@ static int reconnect_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connec
|
||||
IP_Port ip_port = tcp_con_ip_port(tcp_con->connection);
|
||||
uint8_t relay_pk[CRYPTO_PUBLIC_KEY_SIZE];
|
||||
memcpy(relay_pk, tcp_con_public_key(tcp_con->connection), CRYPTO_PUBLIC_KEY_SIZE);
|
||||
kill_TCP_connection(tcp_con->connection);
|
||||
tcp_con->connection = new_TCP_connection(tcp_c->logger, tcp_c->mono_time, tcp_c->rng, tcp_c->ns, &ip_port, relay_pk, tcp_c->self_public_key, tcp_c->self_secret_key, &tcp_c->proxy_info);
|
||||
kill_tcp_connection(tcp_con->connection);
|
||||
tcp_con->connection = new_tcp_connection(tcp_c->logger, tcp_c->mem, tcp_c->mono_time, tcp_c->rng, tcp_c->ns, &ip_port, relay_pk, tcp_c->self_public_key, tcp_c->self_secret_key, &tcp_c->proxy_info);
|
||||
|
||||
if (tcp_con->connection == nullptr) {
|
||||
kill_tcp_relay_connection(tcp_c, tcp_connections_number);
|
||||
@ -969,7 +974,7 @@ static int sleep_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connection
|
||||
tcp_con->ip_port = tcp_con_ip_port(tcp_con->connection);
|
||||
memcpy(tcp_con->relay_pk, tcp_con_public_key(tcp_con->connection), CRYPTO_PUBLIC_KEY_SIZE);
|
||||
|
||||
kill_TCP_connection(tcp_con->connection);
|
||||
kill_tcp_connection(tcp_con->connection);
|
||||
tcp_con->connection = nullptr;
|
||||
|
||||
for (uint32_t i = 0; i < tcp_c->connections_length; ++i) {
|
||||
@ -1007,8 +1012,8 @@ static int unsleep_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connecti
|
||||
return -1;
|
||||
}
|
||||
|
||||
tcp_con->connection = new_TCP_connection(
|
||||
tcp_c->logger, tcp_c->mono_time, tcp_c->rng, tcp_c->ns, &tcp_con->ip_port,
|
||||
tcp_con->connection = new_tcp_connection(
|
||||
tcp_c->logger, tcp_c->mem, tcp_c->mono_time, tcp_c->rng, tcp_c->ns, &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 == nullptr) {
|
||||
@ -1303,8 +1308,8 @@ static int add_tcp_relay_instance(TCP_Connections *tcp_c, const IP_Port *ip_port
|
||||
|
||||
TCP_con *tcp_con = &tcp_c->tcp_connections[tcp_connections_number];
|
||||
|
||||
tcp_con->connection = new_TCP_connection(
|
||||
tcp_c->logger, tcp_c->mono_time, tcp_c->rng, tcp_c->ns, &ipp_copy,
|
||||
tcp_con->connection = new_tcp_connection(
|
||||
tcp_c->logger, tcp_c->mem, tcp_c->mono_time, tcp_c->rng, tcp_c->ns, &ipp_copy,
|
||||
relay_pk, tcp_c->self_public_key, tcp_c->self_secret_key, &tcp_c->proxy_info);
|
||||
|
||||
if (tcp_con->connection == nullptr) {
|
||||
@ -1580,21 +1585,27 @@ int set_tcp_onion_status(TCP_Connections *tcp_c, bool status)
|
||||
*
|
||||
* Returns NULL on failure.
|
||||
*/
|
||||
TCP_Connections *new_tcp_connections(
|
||||
const Logger *logger, const Random *rng, const Network *ns, Mono_Time *mono_time, const uint8_t *secret_key,
|
||||
const TCP_Proxy_Info *proxy_info)
|
||||
TCP_Connections *new_tcp_connections(const Logger *logger, const Memory *mem, const Random *rng, const Network *ns,
|
||||
Mono_Time *mono_time, const uint8_t *secret_key, const TCP_Proxy_Info *proxy_info)
|
||||
{
|
||||
assert(logger != nullptr);
|
||||
assert(mem != nullptr);
|
||||
assert(rng != nullptr);
|
||||
assert(ns != nullptr);
|
||||
assert(mono_time != nullptr);
|
||||
|
||||
if (secret_key == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TCP_Connections *temp = (TCP_Connections *)calloc(1, sizeof(TCP_Connections));
|
||||
TCP_Connections *temp = (TCP_Connections *)mem_alloc(mem, sizeof(TCP_Connections));
|
||||
|
||||
if (temp == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
temp->logger = logger;
|
||||
temp->mem = mem;
|
||||
temp->rng = rng;
|
||||
temp->mono_time = mono_time;
|
||||
temp->ns = ns;
|
||||
@ -1617,7 +1628,7 @@ static void do_tcp_conns(const Logger *logger, TCP_Connections *tcp_c, void *use
|
||||
}
|
||||
|
||||
if (tcp_con->status != TCP_CONN_SLEEPING) {
|
||||
do_TCP_connection(logger, tcp_c->mono_time, tcp_con->connection, userdata);
|
||||
do_tcp_connection(logger, tcp_c->mono_time, tcp_con->connection, userdata);
|
||||
|
||||
/* callbacks can change TCP connection address. */
|
||||
tcp_con = get_tcp_connection(tcp_c, i);
|
||||
@ -1702,12 +1713,12 @@ void kill_tcp_connections(TCP_Connections *tcp_c)
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < tcp_c->tcp_connections_length; ++i) {
|
||||
kill_TCP_connection(tcp_c->tcp_connections[i].connection);
|
||||
kill_tcp_connection(tcp_c->tcp_connections[i].connection);
|
||||
}
|
||||
|
||||
crypto_memzero(tcp_c->self_secret_key, sizeof(tcp_c->self_secret_key));
|
||||
|
||||
free(tcp_c->tcp_connections);
|
||||
free(tcp_c->connections);
|
||||
free(tcp_c);
|
||||
mem_delete(tcp_c->mem, tcp_c->tcp_connections);
|
||||
mem_delete(tcp_c->mem, tcp_c->connections);
|
||||
mem_delete(tcp_c->mem, tcp_c);
|
||||
}
|
||||
|
@ -298,9 +298,8 @@ uint32_t tcp_copy_connected_relays_index(const TCP_Connections *tcp_c, Node_form
|
||||
* Returns NULL on failure.
|
||||
*/
|
||||
non_null()
|
||||
TCP_Connections *new_tcp_connections(
|
||||
const Logger *logger, const Random *rng, const Network *ns, Mono_Time *mono_time,
|
||||
const uint8_t *secret_key, const TCP_Proxy_Info *proxy_info);
|
||||
TCP_Connections *new_tcp_connections(const Logger *logger, const Memory *mem, const Random *rng, const Network *ns,
|
||||
Mono_Time *mono_time, const uint8_t *secret_key, const TCP_Proxy_Info *proxy_info);
|
||||
|
||||
non_null()
|
||||
int kill_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connections_number);
|
||||
|
@ -58,6 +58,7 @@ typedef struct TCP_Secure_Connection {
|
||||
|
||||
struct TCP_Server {
|
||||
const Logger *logger;
|
||||
const Memory *mem;
|
||||
const Random *rng;
|
||||
const Network *ns;
|
||||
Onion *onion;
|
||||
@ -117,9 +118,9 @@ static int alloc_new_connections(TCP_Server *tcp_server, uint32_t num)
|
||||
return -1;
|
||||
}
|
||||
|
||||
TCP_Secure_Connection *new_connections = (TCP_Secure_Connection *)realloc(
|
||||
tcp_server->accepted_connection_array,
|
||||
new_size * sizeof(TCP_Secure_Connection));
|
||||
TCP_Secure_Connection *new_connections = (TCP_Secure_Connection *)mem_vrealloc(
|
||||
tcp_server->mem, tcp_server->accepted_connection_array,
|
||||
new_size, sizeof(TCP_Secure_Connection));
|
||||
|
||||
if (new_connections == nullptr) {
|
||||
return -1;
|
||||
@ -138,7 +139,7 @@ non_null()
|
||||
static void wipe_secure_connection(TCP_Secure_Connection *con)
|
||||
{
|
||||
if (con->status != 0) {
|
||||
wipe_priority_list(con->con.priority_queue_start);
|
||||
wipe_priority_list(con->con.mem, con->con.priority_queue_start);
|
||||
crypto_memzero(con, sizeof(TCP_Secure_Connection));
|
||||
}
|
||||
}
|
||||
@ -161,7 +162,7 @@ static void free_accepted_connection_array(TCP_Server *tcp_server)
|
||||
wipe_secure_connection(&tcp_server->accepted_connection_array[i]);
|
||||
}
|
||||
|
||||
free(tcp_server->accepted_connection_array);
|
||||
mem_delete(tcp_server->mem, tcp_server->accepted_connection_array);
|
||||
tcp_server->accepted_connection_array = nullptr;
|
||||
tcp_server->size_accepted_connections = 0;
|
||||
}
|
||||
@ -171,7 +172,7 @@ static void free_accepted_connection_array(TCP_Server *tcp_server)
|
||||
* @retval -1 on failure.
|
||||
*/
|
||||
non_null()
|
||||
static int get_TCP_connection_index(const TCP_Server *tcp_server, const uint8_t *public_key)
|
||||
static int get_tcp_connection_index(const TCP_Server *tcp_server, const uint8_t *public_key)
|
||||
{
|
||||
return bs_list_find(&tcp_server->accepted_key_list, public_key);
|
||||
}
|
||||
@ -188,7 +189,7 @@ static int kill_accepted(TCP_Server *tcp_server, int index);
|
||||
non_null()
|
||||
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);
|
||||
int index = get_tcp_connection_index(tcp_server, con->public_key);
|
||||
|
||||
if (index != -1) { /* If an old connection to the same public key exists, kill it. */
|
||||
kill_accepted(tcp_server, index);
|
||||
@ -262,7 +263,7 @@ static int del_accepted(TCP_Server *tcp_server, int index)
|
||||
|
||||
/** Kill a TCP_Secure_Connection */
|
||||
non_null()
|
||||
static void kill_TCP_secure_connection(TCP_Secure_Connection *con)
|
||||
static void kill_tcp_secure_connection(TCP_Secure_Connection *con)
|
||||
{
|
||||
kill_sock(con->con.ns, con->con.sock);
|
||||
wipe_secure_connection(con);
|
||||
@ -301,7 +302,7 @@ static int kill_accepted(TCP_Server *tcp_server, int index)
|
||||
* @retval -1 if the connection must be killed.
|
||||
*/
|
||||
non_null()
|
||||
static int handle_TCP_handshake(const Logger *logger, TCP_Secure_Connection *con, const uint8_t *data, uint16_t length,
|
||||
static int handle_tcp_handshake(const Logger *logger, TCP_Secure_Connection *con, const uint8_t *data, uint16_t length,
|
||||
const uint8_t *self_secret_key)
|
||||
{
|
||||
if (length != TCP_CLIENT_HANDSHAKE_SIZE) {
|
||||
@ -369,14 +370,14 @@ non_null()
|
||||
static int read_connection_handshake(const Logger *logger, TCP_Secure_Connection *con, const uint8_t *self_secret_key)
|
||||
{
|
||||
uint8_t data[TCP_CLIENT_HANDSHAKE_SIZE];
|
||||
const int len = read_TCP_packet(logger, con->con.ns, con->con.sock, data, TCP_CLIENT_HANDSHAKE_SIZE, &con->con.ip_port);
|
||||
const int len = read_tcp_packet(logger, con->con.mem, con->con.ns, con->con.sock, data, TCP_CLIENT_HANDSHAKE_SIZE, &con->con.ip_port);
|
||||
|
||||
if (len == -1) {
|
||||
LOGGER_TRACE(logger, "connection handshake is not ready yet");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return handle_TCP_handshake(logger, con, data, len, self_secret_key);
|
||||
return handle_tcp_handshake(logger, con, data, len, self_secret_key);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -393,7 +394,7 @@ static int send_routing_response(const Logger *logger, TCP_Secure_Connection *co
|
||||
data[1] = rpid;
|
||||
memcpy(data + 2, public_key, CRYPTO_PUBLIC_KEY_SIZE);
|
||||
|
||||
return write_packet_TCP_secure_connection(logger, &con->con, data, sizeof(data), true);
|
||||
return write_packet_tcp_secure_connection(logger, &con->con, data, sizeof(data), true);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -405,7 +406,7 @@ non_null()
|
||||
static int send_connect_notification(const Logger *logger, TCP_Secure_Connection *con, uint8_t id)
|
||||
{
|
||||
uint8_t data[2] = {TCP_PACKET_CONNECTION_NOTIFICATION, (uint8_t)(id + NUM_RESERVED_PORTS)};
|
||||
return write_packet_TCP_secure_connection(logger, &con->con, data, sizeof(data), true);
|
||||
return write_packet_tcp_secure_connection(logger, &con->con, data, sizeof(data), true);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -417,7 +418,7 @@ non_null()
|
||||
static int send_disconnect_notification(const Logger *logger, TCP_Secure_Connection *con, uint8_t id)
|
||||
{
|
||||
uint8_t data[2] = {TCP_PACKET_DISCONNECT_NOTIFICATION, (uint8_t)(id + NUM_RESERVED_PORTS)};
|
||||
return write_packet_TCP_secure_connection(logger, &con->con, data, sizeof(data), true);
|
||||
return write_packet_tcp_secure_connection(logger, &con->con, data, sizeof(data), true);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -425,7 +426,7 @@ static int send_disconnect_notification(const Logger *logger, TCP_Secure_Connect
|
||||
* @retval -1 on failure (connection must be killed).
|
||||
*/
|
||||
non_null()
|
||||
static int handle_TCP_routing_req(TCP_Server *tcp_server, uint32_t con_id, const uint8_t *public_key)
|
||||
static int handle_tcp_routing_req(TCP_Server *tcp_server, uint32_t con_id, const uint8_t *public_key)
|
||||
{
|
||||
uint32_t index = -1;
|
||||
TCP_Secure_Connection *con = &tcp_server->accepted_connection_array[con_id];
|
||||
@ -473,7 +474,7 @@ static int handle_TCP_routing_req(TCP_Server *tcp_server, uint32_t con_id, const
|
||||
|
||||
con->connections[index].status = 1;
|
||||
memcpy(con->connections[index].public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE);
|
||||
const int other_index = get_TCP_connection_index(tcp_server, public_key);
|
||||
const int other_index = get_tcp_connection_index(tcp_server, public_key);
|
||||
|
||||
if (other_index != -1) {
|
||||
uint32_t other_id = -1;
|
||||
@ -508,7 +509,7 @@ static int handle_TCP_routing_req(TCP_Server *tcp_server, uint32_t con_id, const
|
||||
* @retval -1 on failure (connection must be killed).
|
||||
*/
|
||||
non_null()
|
||||
static int handle_TCP_oob_send(TCP_Server *tcp_server, uint32_t con_id, const uint8_t *public_key, const uint8_t *data,
|
||||
static int handle_tcp_oob_send(TCP_Server *tcp_server, uint32_t con_id, const uint8_t *public_key, const uint8_t *data,
|
||||
uint16_t length)
|
||||
{
|
||||
if (length == 0 || length > TCP_MAX_OOB_DATA_LENGTH) {
|
||||
@ -517,14 +518,14 @@ static int handle_TCP_oob_send(TCP_Server *tcp_server, uint32_t con_id, const ui
|
||||
|
||||
const TCP_Secure_Connection *con = &tcp_server->accepted_connection_array[con_id];
|
||||
|
||||
const int other_index = get_TCP_connection_index(tcp_server, public_key);
|
||||
const int other_index = get_tcp_connection_index(tcp_server, public_key);
|
||||
|
||||
if (other_index != -1) {
|
||||
VLA(uint8_t, resp_packet, 1 + CRYPTO_PUBLIC_KEY_SIZE + length);
|
||||
resp_packet[0] = TCP_PACKET_OOB_RECV;
|
||||
memcpy(resp_packet + 1, con->public_key, CRYPTO_PUBLIC_KEY_SIZE);
|
||||
memcpy(resp_packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, data, length);
|
||||
write_packet_TCP_secure_connection(tcp_server->logger, &tcp_server->accepted_connection_array[other_index].con,
|
||||
write_packet_tcp_secure_connection(tcp_server->logger, &tcp_server->accepted_connection_array[other_index].con,
|
||||
resp_packet, SIZEOF_VLA(resp_packet), false);
|
||||
}
|
||||
|
||||
@ -612,7 +613,7 @@ static int handle_onion_recv_1(void *object, const IP_Port *dest, const uint8_t
|
||||
memcpy(packet + 1, data, length);
|
||||
packet[0] = TCP_PACKET_ONION_RESPONSE;
|
||||
|
||||
if (write_packet_TCP_secure_connection(tcp_server->logger, &con->con, packet, SIZEOF_VLA(packet), false) != 1) {
|
||||
if (write_packet_tcp_secure_connection(tcp_server->logger, &con->con, packet, SIZEOF_VLA(packet), false) != 1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -652,7 +653,7 @@ static bool handle_forward_reply_tcp(void *object, const uint8_t *sendback_data,
|
||||
memcpy(packet + 1, data, length);
|
||||
packet[0] = TCP_PACKET_FORWARDING;
|
||||
|
||||
return write_packet_TCP_secure_connection(tcp_server->logger, &con->con, packet, SIZEOF_VLA(packet), false) == 1;
|
||||
return write_packet_tcp_secure_connection(tcp_server->logger, &con->con, packet, SIZEOF_VLA(packet), false) == 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -660,7 +661,7 @@ static bool handle_forward_reply_tcp(void *object, const uint8_t *sendback_data,
|
||||
* @retval -1 on failure
|
||||
*/
|
||||
non_null()
|
||||
static int handle_TCP_packet(TCP_Server *tcp_server, uint32_t con_id, const uint8_t *data, uint16_t length)
|
||||
static int handle_tcp_packet(TCP_Server *tcp_server, uint32_t con_id, const uint8_t *data, uint16_t length)
|
||||
{
|
||||
if (length == 0) {
|
||||
return -1;
|
||||
@ -675,7 +676,7 @@ static int handle_TCP_packet(TCP_Server *tcp_server, uint32_t con_id, const uint
|
||||
}
|
||||
|
||||
LOGGER_TRACE(tcp_server->logger, "handling routing request for %d", con_id);
|
||||
return handle_TCP_routing_req(tcp_server, con_id, data + 1);
|
||||
return handle_tcp_routing_req(tcp_server, con_id, data + 1);
|
||||
}
|
||||
|
||||
case TCP_PACKET_CONNECTION_NOTIFICATION: {
|
||||
@ -706,7 +707,7 @@ static int handle_TCP_packet(TCP_Server *tcp_server, uint32_t con_id, const uint
|
||||
uint8_t response[1 + sizeof(uint64_t)];
|
||||
response[0] = TCP_PACKET_PONG;
|
||||
memcpy(response + 1, data + 1, sizeof(uint64_t));
|
||||
write_packet_TCP_secure_connection(tcp_server->logger, &con->con, response, sizeof(response), true);
|
||||
write_packet_tcp_secure_connection(tcp_server->logger, &con->con, response, sizeof(response), true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -738,7 +739,7 @@ static int handle_TCP_packet(TCP_Server *tcp_server, uint32_t con_id, const uint
|
||||
|
||||
LOGGER_TRACE(tcp_server->logger, "handling oob send for %d", con_id);
|
||||
|
||||
return handle_TCP_oob_send(tcp_server, con_id, data + 1, data + 1 + CRYPTO_PUBLIC_KEY_SIZE,
|
||||
return handle_tcp_oob_send(tcp_server, con_id, data + 1, data + 1 + CRYPTO_PUBLIC_KEY_SIZE,
|
||||
length - (1 + CRYPTO_PUBLIC_KEY_SIZE));
|
||||
}
|
||||
|
||||
@ -821,7 +822,7 @@ static int handle_TCP_packet(TCP_Server *tcp_server, uint32_t con_id, const uint
|
||||
VLA(uint8_t, new_data, length);
|
||||
memcpy(new_data, data, length);
|
||||
new_data[0] = other_c_id;
|
||||
const int ret = write_packet_TCP_secure_connection(tcp_server->logger,
|
||||
const int ret = write_packet_tcp_secure_connection(tcp_server->logger,
|
||||
&tcp_server->accepted_connection_array[index].con, new_data, length, false);
|
||||
|
||||
if (ret == -1) {
|
||||
@ -837,20 +838,20 @@ static int handle_TCP_packet(TCP_Server *tcp_server, uint32_t con_id, const uint
|
||||
|
||||
|
||||
non_null()
|
||||
static int confirm_TCP_connection(TCP_Server *tcp_server, const Mono_Time *mono_time, TCP_Secure_Connection *con,
|
||||
static int confirm_tcp_connection(TCP_Server *tcp_server, const Mono_Time *mono_time, TCP_Secure_Connection *con,
|
||||
const uint8_t *data, uint16_t length)
|
||||
{
|
||||
const int index = add_accepted(tcp_server, mono_time, con);
|
||||
|
||||
if (index == -1) {
|
||||
LOGGER_DEBUG(tcp_server->logger, "dropping connection %u: not accepted", (unsigned int)con->identifier);
|
||||
kill_TCP_secure_connection(con);
|
||||
kill_tcp_secure_connection(con);
|
||||
return -1;
|
||||
}
|
||||
|
||||
wipe_secure_connection(con);
|
||||
|
||||
if (handle_TCP_packet(tcp_server, index, data, length) == -1) {
|
||||
if (handle_tcp_packet(tcp_server, index, data, length) == -1) {
|
||||
LOGGER_DEBUG(tcp_server->logger, "dropping connection %u: data packet (len=%d) not handled",
|
||||
(unsigned int)con->identifier, length);
|
||||
kill_accepted(tcp_server, index);
|
||||
@ -887,11 +888,12 @@ static int accept_connection(TCP_Server *tcp_server, Socket sock)
|
||||
|
||||
if (conn->status != TCP_STATUS_NO_STATUS) {
|
||||
LOGGER_DEBUG(tcp_server->logger, "connection %d dropped before accepting", index);
|
||||
kill_TCP_secure_connection(conn);
|
||||
kill_tcp_secure_connection(conn);
|
||||
}
|
||||
|
||||
conn->status = TCP_STATUS_CONNECTED;
|
||||
conn->con.ns = tcp_server->ns;
|
||||
conn->con.mem = tcp_server->mem;
|
||||
conn->con.rng = tcp_server->rng;
|
||||
conn->con.sock = sock;
|
||||
conn->next_packet_length = 0;
|
||||
@ -901,7 +903,7 @@ static int accept_connection(TCP_Server *tcp_server, Socket sock)
|
||||
}
|
||||
|
||||
non_null()
|
||||
static Socket new_listening_TCP_socket(const Logger *logger, const Network *ns, Family family, uint16_t port)
|
||||
static Socket new_listening_tcp_socket(const Logger *logger, const Network *ns, Family family, uint16_t port)
|
||||
{
|
||||
const Socket sock = net_socket(ns, family, TOX_SOCK_STREAM, TOX_PROTO_TCP);
|
||||
|
||||
@ -935,7 +937,7 @@ static Socket new_listening_TCP_socket(const Logger *logger, const Network *ns,
|
||||
return sock;
|
||||
}
|
||||
|
||||
TCP_Server *new_TCP_server(const Logger *logger, const Random *rng, const Network *ns,
|
||||
TCP_Server *new_tcp_server(const Logger *logger, const Memory *mem, const Random *rng, const Network *ns,
|
||||
bool ipv6_enabled, uint16_t num_sockets,
|
||||
const uint16_t *ports, const uint8_t *secret_key, Onion *onion, Forwarding *forwarding)
|
||||
{
|
||||
@ -949,7 +951,7 @@ TCP_Server *new_TCP_server(const Logger *logger, const Random *rng, const Networ
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TCP_Server *temp = (TCP_Server *)calloc(1, sizeof(TCP_Server));
|
||||
TCP_Server *temp = (TCP_Server *)mem_alloc(mem, sizeof(TCP_Server));
|
||||
|
||||
if (temp == nullptr) {
|
||||
LOGGER_ERROR(logger, "TCP server allocation failed");
|
||||
@ -957,14 +959,15 @@ TCP_Server *new_TCP_server(const Logger *logger, const Random *rng, const Networ
|
||||
}
|
||||
|
||||
temp->logger = logger;
|
||||
temp->mem = mem;
|
||||
temp->ns = ns;
|
||||
temp->rng = rng;
|
||||
|
||||
temp->socks_listening = (Socket *)calloc(num_sockets, sizeof(Socket));
|
||||
temp->socks_listening = (Socket *)mem_valloc(mem, num_sockets, sizeof(Socket));
|
||||
|
||||
if (temp->socks_listening == nullptr) {
|
||||
LOGGER_ERROR(logger, "socket allocation failed");
|
||||
free(temp);
|
||||
mem_delete(mem, temp);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -973,8 +976,8 @@ TCP_Server *new_TCP_server(const Logger *logger, const Random *rng, const Networ
|
||||
|
||||
if (temp->efd == -1) {
|
||||
LOGGER_ERROR(logger, "epoll initialisation failed");
|
||||
free(temp->socks_listening);
|
||||
free(temp);
|
||||
mem_delete(mem, temp->socks_listening);
|
||||
mem_delete(mem, temp);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -983,7 +986,7 @@ TCP_Server *new_TCP_server(const Logger *logger, const Random *rng, const Networ
|
||||
const Family family = ipv6_enabled ? net_family_ipv6() : net_family_ipv4();
|
||||
|
||||
for (uint32_t i = 0; i < num_sockets; ++i) {
|
||||
const Socket sock = new_listening_TCP_socket(logger, ns, family, ports[i]);
|
||||
const Socket sock = new_listening_tcp_socket(logger, ns, family, ports[i]);
|
||||
|
||||
if (!sock_valid(sock)) {
|
||||
continue;
|
||||
@ -1006,8 +1009,8 @@ TCP_Server *new_TCP_server(const Logger *logger, const Random *rng, const Networ
|
||||
}
|
||||
|
||||
if (temp->num_listening_socks == 0) {
|
||||
free(temp->socks_listening);
|
||||
free(temp);
|
||||
mem_delete(mem, temp->socks_listening);
|
||||
mem_delete(mem, temp);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -1031,7 +1034,7 @@ TCP_Server *new_TCP_server(const Logger *logger, const Random *rng, const Networ
|
||||
|
||||
#ifndef TCP_SERVER_USE_EPOLL
|
||||
non_null()
|
||||
static void do_TCP_accept_new(TCP_Server *tcp_server)
|
||||
static void do_tcp_accept_new(TCP_Server *tcp_server)
|
||||
{
|
||||
for (uint32_t sock_idx = 0; sock_idx < tcp_server->num_listening_socks; ++sock_idx) {
|
||||
|
||||
@ -1061,7 +1064,7 @@ static int do_incoming(TCP_Server *tcp_server, uint32_t i)
|
||||
|
||||
if (ret == -1) {
|
||||
LOGGER_TRACE(tcp_server->logger, "incoming connection %d dropped due to failed handshake", i);
|
||||
kill_TCP_secure_connection(conn);
|
||||
kill_tcp_secure_connection(conn);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1075,7 +1078,7 @@ static int do_incoming(TCP_Server *tcp_server, uint32_t i)
|
||||
|
||||
if (conn_new->status != TCP_STATUS_NO_STATUS) {
|
||||
LOGGER_ERROR(tcp_server->logger, "incoming connection %d would overwrite existing", i);
|
||||
kill_TCP_secure_connection(conn_new);
|
||||
kill_tcp_secure_connection(conn_new);
|
||||
}
|
||||
|
||||
move_secure_connection(conn_new, conn_old);
|
||||
@ -1096,18 +1099,18 @@ static int do_unconfirmed(TCP_Server *tcp_server, const Mono_Time *mono_time, ui
|
||||
LOGGER_TRACE(tcp_server->logger, "handling unconfirmed TCP connection %d", i);
|
||||
|
||||
uint8_t packet[MAX_PACKET_SIZE];
|
||||
const int len = read_packet_TCP_secure_connection(tcp_server->logger, conn->con.ns, conn->con.sock, &conn->next_packet_length, conn->con.shared_key, conn->recv_nonce, packet, sizeof(packet), &conn->con.ip_port);
|
||||
const int len = read_packet_tcp_secure_connection(tcp_server->logger, conn->con.mem, conn->con.ns, conn->con.sock, &conn->next_packet_length, conn->con.shared_key, conn->recv_nonce, packet, sizeof(packet), &conn->con.ip_port);
|
||||
|
||||
if (len == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (len == -1) {
|
||||
kill_TCP_secure_connection(conn);
|
||||
kill_tcp_secure_connection(conn);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return confirm_TCP_connection(tcp_server, mono_time, conn, packet, len);
|
||||
return confirm_tcp_connection(tcp_server, mono_time, conn, packet, len);
|
||||
}
|
||||
|
||||
non_null()
|
||||
@ -1116,7 +1119,7 @@ static bool tcp_process_secure_packet(TCP_Server *tcp_server, uint32_t i)
|
||||
TCP_Secure_Connection *const conn = &tcp_server->accepted_connection_array[i];
|
||||
|
||||
uint8_t packet[MAX_PACKET_SIZE];
|
||||
const int len = read_packet_TCP_secure_connection(tcp_server->logger, conn->con.ns, conn->con.sock, &conn->next_packet_length, conn->con.shared_key, conn->recv_nonce, packet, sizeof(packet), &conn->con.ip_port);
|
||||
const int len = read_packet_tcp_secure_connection(tcp_server->logger, conn->con.mem, conn->con.ns, conn->con.sock, &conn->next_packet_length, conn->con.shared_key, conn->recv_nonce, packet, sizeof(packet), &conn->con.ip_port);
|
||||
LOGGER_TRACE(tcp_server->logger, "processing packet for %d: %d", i, len);
|
||||
|
||||
if (len == 0) {
|
||||
@ -1128,7 +1131,7 @@ static bool tcp_process_secure_packet(TCP_Server *tcp_server, uint32_t i)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (handle_TCP_packet(tcp_server, i, packet, len) == -1) {
|
||||
if (handle_tcp_packet(tcp_server, i, packet, len) == -1) {
|
||||
LOGGER_TRACE(tcp_server->logger, "dropping connection %d: data packet (len=%d) not handled", i, len);
|
||||
kill_accepted(tcp_server, i);
|
||||
return false;
|
||||
@ -1148,7 +1151,7 @@ static void do_confirmed_recv(TCP_Server *tcp_server, uint32_t i)
|
||||
|
||||
#ifndef TCP_SERVER_USE_EPOLL
|
||||
non_null()
|
||||
static void do_TCP_incoming(TCP_Server *tcp_server)
|
||||
static void do_tcp_incoming(TCP_Server *tcp_server)
|
||||
{
|
||||
for (uint32_t i = 0; i < MAX_INCOMING_CONNECTIONS; ++i) {
|
||||
do_incoming(tcp_server, i);
|
||||
@ -1156,7 +1159,7 @@ static void do_TCP_incoming(TCP_Server *tcp_server)
|
||||
}
|
||||
|
||||
non_null()
|
||||
static void do_TCP_unconfirmed(TCP_Server *tcp_server, const Mono_Time *mono_time)
|
||||
static void do_tcp_unconfirmed(TCP_Server *tcp_server, const Mono_Time *mono_time)
|
||||
{
|
||||
for (uint32_t i = 0; i < MAX_INCOMING_CONNECTIONS; ++i) {
|
||||
do_unconfirmed(tcp_server, mono_time, i);
|
||||
@ -1165,7 +1168,7 @@ static void do_TCP_unconfirmed(TCP_Server *tcp_server, const Mono_Time *mono_tim
|
||||
#endif
|
||||
|
||||
non_null()
|
||||
static void do_TCP_confirmed(TCP_Server *tcp_server, const Mono_Time *mono_time)
|
||||
static void do_tcp_confirmed(TCP_Server *tcp_server, const Mono_Time *mono_time)
|
||||
{
|
||||
#ifdef TCP_SERVER_USE_EPOLL
|
||||
|
||||
@ -1193,7 +1196,7 @@ static void do_TCP_confirmed(TCP_Server *tcp_server, const Mono_Time *mono_time)
|
||||
}
|
||||
|
||||
memcpy(ping + 1, &ping_id, sizeof(uint64_t));
|
||||
const int ret = write_packet_TCP_secure_connection(tcp_server->logger, &conn->con, ping, sizeof(ping), true);
|
||||
const int ret = write_packet_tcp_secure_connection(tcp_server->logger, &conn->con, ping, sizeof(ping), true);
|
||||
|
||||
if (ret == 1) {
|
||||
conn->last_pinged = mono_time_get(mono_time);
|
||||
@ -1245,13 +1248,13 @@ static bool tcp_epoll_process(TCP_Server *tcp_server, const Mono_Time *mono_time
|
||||
|
||||
case TCP_SOCKET_INCOMING: {
|
||||
LOGGER_TRACE(tcp_server->logger, "incoming connection %d dropped", index);
|
||||
kill_TCP_secure_connection(&tcp_server->incoming_connection_queue[index]);
|
||||
kill_tcp_secure_connection(&tcp_server->incoming_connection_queue[index]);
|
||||
break;
|
||||
}
|
||||
|
||||
case TCP_SOCKET_UNCONFIRMED: {
|
||||
LOGGER_TRACE(tcp_server->logger, "unconfirmed connection %d dropped", index);
|
||||
kill_TCP_secure_connection(&tcp_server->unconfirmed_connection_queue[index]);
|
||||
kill_tcp_secure_connection(&tcp_server->unconfirmed_connection_queue[index]);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1294,7 +1297,7 @@ static bool tcp_epoll_process(TCP_Server *tcp_server, const Mono_Time *mono_time
|
||||
|
||||
if (epoll_ctl(tcp_server->efd, EPOLL_CTL_ADD, sock_new.sock, &ev) == -1) {
|
||||
LOGGER_DEBUG(tcp_server->logger, "new connection %d was dropped due to epoll error %d", index, net_error());
|
||||
kill_TCP_secure_connection(&tcp_server->incoming_connection_queue[index_new]);
|
||||
kill_tcp_secure_connection(&tcp_server->incoming_connection_queue[index_new]);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -1312,7 +1315,7 @@ static bool tcp_epoll_process(TCP_Server *tcp_server, const Mono_Time *mono_time
|
||||
|
||||
if (epoll_ctl(tcp_server->efd, EPOLL_CTL_MOD, sock.sock, &events[n]) == -1) {
|
||||
LOGGER_DEBUG(tcp_server->logger, "incoming connection %d was dropped due to epoll error %d", index, net_error());
|
||||
kill_TCP_secure_connection(&tcp_server->unconfirmed_connection_queue[index_new]);
|
||||
kill_tcp_secure_connection(&tcp_server->unconfirmed_connection_queue[index_new]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1350,7 +1353,7 @@ static bool tcp_epoll_process(TCP_Server *tcp_server, const Mono_Time *mono_time
|
||||
}
|
||||
|
||||
non_null()
|
||||
static void do_TCP_epoll(TCP_Server *tcp_server, const Mono_Time *mono_time)
|
||||
static void do_tcp_epoll(TCP_Server *tcp_server, const Mono_Time *mono_time)
|
||||
{
|
||||
while (tcp_epoll_process(tcp_server, mono_time)) {
|
||||
// Keep processing packets until there are no more FDs ready for reading.
|
||||
@ -1359,21 +1362,21 @@ static void do_TCP_epoll(TCP_Server *tcp_server, const Mono_Time *mono_time)
|
||||
}
|
||||
#endif
|
||||
|
||||
void do_TCP_server(TCP_Server *tcp_server, const Mono_Time *mono_time)
|
||||
void do_tcp_server(TCP_Server *tcp_server, const Mono_Time *mono_time)
|
||||
{
|
||||
#ifdef TCP_SERVER_USE_EPOLL
|
||||
do_TCP_epoll(tcp_server, mono_time);
|
||||
do_tcp_epoll(tcp_server, mono_time);
|
||||
|
||||
#else
|
||||
do_TCP_accept_new(tcp_server);
|
||||
do_TCP_incoming(tcp_server);
|
||||
do_TCP_unconfirmed(tcp_server, mono_time);
|
||||
do_tcp_accept_new(tcp_server);
|
||||
do_tcp_incoming(tcp_server);
|
||||
do_tcp_unconfirmed(tcp_server, mono_time);
|
||||
#endif
|
||||
|
||||
do_TCP_confirmed(tcp_server, mono_time);
|
||||
do_tcp_confirmed(tcp_server, mono_time);
|
||||
}
|
||||
|
||||
void kill_TCP_server(TCP_Server *tcp_server)
|
||||
void kill_tcp_server(TCP_Server *tcp_server)
|
||||
{
|
||||
if (tcp_server == nullptr) {
|
||||
return;
|
||||
@ -1406,6 +1409,6 @@ void kill_TCP_server(TCP_Server *tcp_server)
|
||||
|
||||
crypto_memzero(tcp_server->secret_key, sizeof(tcp_server->secret_key));
|
||||
|
||||
free(tcp_server->socks_listening);
|
||||
free(tcp_server);
|
||||
mem_delete(tcp_server->mem, tcp_server->socks_listening);
|
||||
mem_delete(tcp_server->mem, tcp_server);
|
||||
}
|
||||
|
@ -34,18 +34,18 @@ non_null()
|
||||
size_t tcp_server_listen_count(const TCP_Server *tcp_server);
|
||||
|
||||
/** Create new TCP server instance. */
|
||||
non_null(1, 2, 3, 6, 7) nullable(8, 9)
|
||||
TCP_Server *new_TCP_server(const Logger *logger, const Random *rng, const Network *ns,
|
||||
non_null(1, 2, 3, 4, 7, 8) nullable(9, 10)
|
||||
TCP_Server *new_tcp_server(const Logger *logger, const Memory *mem, const Random *rng, const Network *ns,
|
||||
bool ipv6_enabled, uint16_t num_sockets, const uint16_t *ports,
|
||||
const uint8_t *secret_key, Onion *onion, Forwarding *forwarding);
|
||||
|
||||
/** Run the TCP_server */
|
||||
non_null()
|
||||
void do_TCP_server(TCP_Server *tcp_server, const Mono_Time *mono_time);
|
||||
void do_tcp_server(TCP_Server *tcp_server, const Mono_Time *mono_time);
|
||||
|
||||
/** Kill the TCP server */
|
||||
nullable(1)
|
||||
void kill_TCP_server(TCP_Server *tcp_server);
|
||||
void kill_tcp_server(TCP_Server *tcp_server);
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -50,6 +50,7 @@ typedef struct Announce_Entry {
|
||||
|
||||
struct Announcements {
|
||||
const Logger *log;
|
||||
const Memory *mem;
|
||||
const Random *rng;
|
||||
Forwarding *forwarding;
|
||||
const Mono_Time *mono_time;
|
||||
@ -593,8 +594,8 @@ static int create_reply(Announcements *announce, const IP_Port *source,
|
||||
|
||||
const uint8_t response_type = announce_response_of_request_type(data[0]);
|
||||
|
||||
return dht_create_packet(announce->rng, announce->public_key, shared_key, response_type,
|
||||
plain_reply, plain_reply_len, reply, reply_max_length);
|
||||
return dht_create_packet(announce->mem, announce->rng, announce->public_key, shared_key,
|
||||
response_type, plain_reply, plain_reply_len, reply, reply_max_length);
|
||||
}
|
||||
|
||||
non_null(1, 2, 3, 5) nullable(7)
|
||||
@ -636,7 +637,7 @@ static int handle_dht_announce_request(void *object, const IP_Port *source,
|
||||
return sendpacket(announce->net, source, reply, len) == len ? 0 : -1;
|
||||
}
|
||||
|
||||
Announcements *new_announcements(const Logger *log, const Random *rng, const Mono_Time *mono_time,
|
||||
Announcements *new_announcements(const Logger *log, const Memory *mem, const Random *rng, const Mono_Time *mono_time,
|
||||
Forwarding *forwarding)
|
||||
{
|
||||
if (log == nullptr || mono_time == nullptr || forwarding == nullptr) {
|
||||
@ -650,6 +651,7 @@ Announcements *new_announcements(const Logger *log, const Random *rng, const Mon
|
||||
}
|
||||
|
||||
announce->log = log;
|
||||
announce->mem = mem;
|
||||
announce->rng = rng;
|
||||
announce->forwarding = forwarding;
|
||||
announce->mono_time = mono_time;
|
||||
@ -658,7 +660,7 @@ Announcements *new_announcements(const Logger *log, const Random *rng, const Mon
|
||||
announce->public_key = dht_get_self_public_key(announce->dht);
|
||||
announce->secret_key = dht_get_self_secret_key(announce->dht);
|
||||
new_hmac_key(announce->rng, announce->hmac_key);
|
||||
announce->shared_keys = shared_key_cache_new(mono_time, announce->secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT);
|
||||
announce->shared_keys = shared_key_cache_new(mono_time, mem, announce->secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT);
|
||||
if (announce->shared_keys == nullptr) {
|
||||
free(announce);
|
||||
return nullptr;
|
||||
|
@ -16,7 +16,8 @@ uint8_t announce_response_of_request_type(uint8_t request_type);
|
||||
typedef struct Announcements Announcements;
|
||||
|
||||
non_null()
|
||||
Announcements *new_announcements(const Logger *log, const Random *rng, const Mono_Time *mono_time, Forwarding *forwarding);
|
||||
Announcements *new_announcements(const Logger *log, const Memory *mem, const Random *rng, const Mono_Time *mono_time,
|
||||
Forwarding *forwarding);
|
||||
|
||||
/**
|
||||
* @brief If data is stored, run `on_retrieve_callback` on it.
|
||||
|
@ -358,7 +358,7 @@ int32_t decrypt_data(const uint8_t *public_key, const uint8_t *secret_key, const
|
||||
/**
|
||||
* @brief Fast encrypt/decrypt operations.
|
||||
*
|
||||
* Use if this is not a one-time communication. @ref encrypt_precompute does the
|
||||
* Use if this is not a one-time communication. `encrypt_precompute` does the
|
||||
* shared-key generation once so it does not have to be performed on every
|
||||
* encrypt/decrypt.
|
||||
*/
|
||||
|
@ -12,8 +12,10 @@ void TestSendForwardRequest(Fuzz_Data &input)
|
||||
{
|
||||
const Network *ns = system_network(); // TODO(iphydf): fuzz_network
|
||||
assert(ns != nullptr);
|
||||
const Memory *mem = system_memory(); // TODO(iphydf): fuzz_memory
|
||||
assert(mem != nullptr);
|
||||
|
||||
with<Logger>{} >> with<Networking_Core>{input, ns} >> [&input](Ptr<Networking_Core> net) {
|
||||
with<Logger>{} >> with<Networking_Core>{input, ns, mem} >> [&input](Ptr<Networking_Core> net) {
|
||||
with<IP_Port>{input} >> [net = std::move(net), &input](const IP_Port &forwarder) {
|
||||
CONSUME1_OR_RETURN(const uint16_t chain_length, input);
|
||||
const uint16_t chain_keys_size = chain_length * CRYPTO_PUBLIC_KEY_SIZE;
|
||||
@ -29,8 +31,10 @@ void TestForwardReply(Fuzz_Data &input)
|
||||
{
|
||||
const Network *ns = system_network(); // TODO(iphydf): fuzz_network
|
||||
assert(ns != nullptr);
|
||||
const Memory *mem = system_memory(); // TODO(iphydf): fuzz_memory
|
||||
assert(mem != nullptr);
|
||||
|
||||
with<Logger>{} >> with<Networking_Core>{input, ns} >> [&input](Ptr<Networking_Core> net) {
|
||||
with<Logger>{} >> with<Networking_Core>{input, ns, mem} >> [&input](Ptr<Networking_Core> net) {
|
||||
with<IP_Port>{input} >> [net = std::move(net), &input](const IP_Port &forwarder) {
|
||||
CONSUME1_OR_RETURN(const uint16_t sendback_length, input);
|
||||
CONSUME_OR_RETURN(const uint8_t *sendback, input, sendback_length);
|
||||
|
@ -461,7 +461,7 @@ static void dht_pk_callback(void *object, int32_t number, const uint8_t *dht_pub
|
||||
}
|
||||
|
||||
friend_new_connection(fr_c, number);
|
||||
onion_set_friend_DHT_pubkey(fr_c->onion_c, friend_con->onion_friendnum, dht_public_key);
|
||||
onion_set_friend_dht_pubkey(fr_c->onion_c, friend_con->onion_friendnum, dht_public_key);
|
||||
}
|
||||
|
||||
non_null()
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "group_announce.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
@ -44,9 +45,10 @@ void TestUnpackPublicAnnounce(Fuzz_Data &input)
|
||||
|
||||
void TestDoGca(Fuzz_Data &input)
|
||||
{
|
||||
const Memory *mem = system_memory();
|
||||
std::unique_ptr<Logger, void (*)(Logger *)> logger(logger_new(), logger_kill);
|
||||
std::unique_ptr<Mono_Time, void (*)(Mono_Time *)> mono_time(
|
||||
mono_time_new(nullptr, nullptr), mono_time_free);
|
||||
std::unique_ptr<Mono_Time, std::function<void(Mono_Time *)>> mono_time(
|
||||
mono_time_new(mem, nullptr, nullptr), [mem](Mono_Time *ptr) { mono_time_free(mem, ptr); });
|
||||
assert(mono_time != nullptr);
|
||||
uint64_t clock = 1;
|
||||
mono_time_set_current_time_callback(
|
||||
|
@ -8,6 +8,7 @@ namespace {
|
||||
|
||||
struct Announces : ::testing::Test {
|
||||
protected:
|
||||
const Memory *mem_ = system_memory();
|
||||
uint64_t clock_ = 0;
|
||||
Mono_Time *mono_time_ = nullptr;
|
||||
GC_Announces_List *gca_ = nullptr;
|
||||
@ -16,7 +17,7 @@ protected:
|
||||
|
||||
void SetUp() override
|
||||
{
|
||||
mono_time_ = mono_time_new(nullptr, nullptr);
|
||||
mono_time_ = mono_time_new(mem_, nullptr, nullptr);
|
||||
ASSERT_NE(mono_time_, nullptr);
|
||||
mono_time_set_current_time_callback(
|
||||
mono_time_, [](void *user_data) { return *static_cast<uint64_t *>(user_data); },
|
||||
@ -28,7 +29,7 @@ protected:
|
||||
~Announces() override
|
||||
{
|
||||
kill_gca(gca_);
|
||||
mono_time_free(mono_time_);
|
||||
mono_time_free(mem_, mono_time_);
|
||||
}
|
||||
|
||||
void advance_clock(uint64_t increment)
|
||||
|
@ -5691,13 +5691,13 @@ static int handle_gc_handshake_request(GC_Chat *chat, const IP_Port *ipp, const
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (chat->connection_O_metre >= GC_NEW_PEER_CONNECTION_LIMIT) {
|
||||
if (chat->connection_o_metre >= GC_NEW_PEER_CONNECTION_LIMIT) {
|
||||
chat->block_handshakes = true;
|
||||
LOGGER_DEBUG(chat->log, "Handshake overflow. Blocking handshakes.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
++chat->connection_O_metre;
|
||||
++chat->connection_o_metre;
|
||||
|
||||
const uint8_t *public_sig_key = data + ENC_PUBLIC_KEY_SIZE;
|
||||
|
||||
@ -7015,7 +7015,7 @@ static void do_gc_ping_and_key_rotation(GC_Chat *chat)
|
||||
non_null()
|
||||
static void do_new_connection_cooldown(GC_Chat *chat)
|
||||
{
|
||||
if (chat->connection_O_metre == 0) {
|
||||
if (chat->connection_o_metre == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -7023,9 +7023,9 @@ static void do_new_connection_cooldown(GC_Chat *chat)
|
||||
|
||||
if (chat->connection_cooldown_timer < tm) {
|
||||
chat->connection_cooldown_timer = tm;
|
||||
--chat->connection_O_metre;
|
||||
--chat->connection_o_metre;
|
||||
|
||||
if (chat->connection_O_metre == 0 && chat->block_handshakes) {
|
||||
if (chat->connection_o_metre == 0 && chat->block_handshakes) {
|
||||
chat->block_handshakes = false;
|
||||
LOGGER_DEBUG(chat->log, "Unblocking handshakes");
|
||||
}
|
||||
@ -7250,7 +7250,7 @@ static bool init_gc_tcp_connection(const GC_Session *c, GC_Chat *chat)
|
||||
{
|
||||
const Messenger *m = c->messenger;
|
||||
|
||||
chat->tcp_conn = new_tcp_connections(chat->log, chat->rng, m->ns, chat->mono_time, chat->self_secret_key,
|
||||
chat->tcp_conn = new_tcp_connections(chat->log, chat->mem, chat->rng, m->ns, chat->mono_time, chat->self_secret_key,
|
||||
&m->options.proxy_info);
|
||||
|
||||
if (chat->tcp_conn == nullptr) {
|
||||
@ -7305,6 +7305,7 @@ static void init_gc_moderation(GC_Chat *chat)
|
||||
memcpy(chat->moderation.self_secret_sig_key, get_sig_pk(chat->self_secret_key), SIG_SECRET_KEY_SIZE);
|
||||
chat->moderation.shared_state_version = chat->shared_state.version;
|
||||
chat->moderation.log = chat->log;
|
||||
chat->moderation.mem = chat->mem;
|
||||
}
|
||||
|
||||
non_null()
|
||||
@ -7332,6 +7333,7 @@ static int create_new_group(GC_Session *c, const uint8_t *nick, size_t nick_leng
|
||||
GC_Chat *chat = &c->chats[group_number];
|
||||
|
||||
chat->log = m->log;
|
||||
chat->mem = m->mem;
|
||||
chat->rng = m->rng;
|
||||
|
||||
const uint64_t tm = mono_time_get(m->mono_time);
|
||||
@ -7476,10 +7478,15 @@ int gc_group_load(GC_Session *c, Bin_Unpack *bu)
|
||||
chat->net = m->net;
|
||||
chat->mono_time = m->mono_time;
|
||||
chat->log = m->log;
|
||||
chat->mem = m->mem;
|
||||
chat->rng = m->rng;
|
||||
chat->last_ping_interval = tm;
|
||||
chat->friend_connection_id = -1;
|
||||
|
||||
// Initialise these first, because we may need to log/dealloc things on cleanup.
|
||||
chat->moderation.log = m->log;
|
||||
chat->moderation.mem = m->mem;
|
||||
|
||||
if (!gc_load_unpack_group(chat, bu)) {
|
||||
LOGGER_ERROR(chat->log, "Failed to unpack group");
|
||||
return -1;
|
||||
|
@ -247,6 +247,7 @@ typedef struct GC_TopicInfo {
|
||||
typedef struct GC_Chat {
|
||||
Mono_Time *mono_time;
|
||||
const Logger *log;
|
||||
const Memory *mem;
|
||||
const Random *rng;
|
||||
|
||||
uint32_t connected_tcp_relays;
|
||||
@ -291,7 +292,7 @@ typedef struct GC_Chat {
|
||||
uint64_t last_time_peers_loaded;
|
||||
|
||||
/* keeps track of frequency of new inbound connections */
|
||||
uint8_t connection_O_metre;
|
||||
uint8_t connection_o_metre;
|
||||
uint64_t connection_cooldown_timer;
|
||||
bool block_handshakes;
|
||||
|
||||
|
@ -61,7 +61,7 @@ int mod_list_unpack(Moderation *moderation, const uint8_t *data, uint16_t length
|
||||
tmp_list[i] = (uint8_t *)malloc(sizeof(uint8_t) * MOD_LIST_ENTRY_SIZE);
|
||||
|
||||
if (tmp_list[i] == nullptr) {
|
||||
free_uint8_t_pointer_array(tmp_list, i);
|
||||
free_uint8_t_pointer_array(moderation->mem, tmp_list, i);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -221,7 +221,7 @@ bool mod_list_add_entry(Moderation *moderation, const uint8_t *mod_data)
|
||||
|
||||
void mod_list_cleanup(Moderation *moderation)
|
||||
{
|
||||
free_uint8_t_pointer_array(moderation->mod_list, moderation->num_mods);
|
||||
free_uint8_t_pointer_array(moderation->mem, moderation->mod_list, moderation->num_mods);
|
||||
moderation->num_mods = 0;
|
||||
moderation->mod_list = nullptr;
|
||||
}
|
||||
|
@ -78,6 +78,7 @@ typedef struct Mod_Sanction {
|
||||
} Mod_Sanction;
|
||||
|
||||
typedef struct Moderation {
|
||||
const Memory *mem;
|
||||
const Logger *log;
|
||||
|
||||
Mod_Sanction *sanctions;
|
||||
|
@ -7,7 +7,7 @@ namespace {
|
||||
void TestModListUnpack(Fuzz_Data &input)
|
||||
{
|
||||
CONSUME1_OR_RETURN(const uint16_t num_mods, input);
|
||||
Moderation mods{};
|
||||
Moderation mods{system_memory()};
|
||||
mod_list_unpack(&mods, input.data, input.size, num_mods);
|
||||
mod_list_cleanup(&mods);
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ using ModerationHash = std::array<uint8_t, MOD_MODERATION_HASH_SIZE>;
|
||||
|
||||
TEST(ModList, PackedSizeOfEmptyModListIsZero)
|
||||
{
|
||||
Moderation mods{};
|
||||
Moderation mods{system_memory()};
|
||||
EXPECT_EQ(mod_list_packed_size(&mods), 0);
|
||||
|
||||
uint8_t byte = 1;
|
||||
@ -28,14 +28,14 @@ TEST(ModList, PackedSizeOfEmptyModListIsZero)
|
||||
|
||||
TEST(ModList, UnpackingZeroSizeArrayIsNoop)
|
||||
{
|
||||
Moderation mods{};
|
||||
Moderation mods{system_memory()};
|
||||
const uint8_t byte = 1;
|
||||
EXPECT_EQ(mod_list_unpack(&mods, &byte, 0, 0), 0);
|
||||
}
|
||||
|
||||
TEST(ModList, AddRemoveMultipleMods)
|
||||
{
|
||||
Moderation mods{};
|
||||
Moderation mods{system_memory()};
|
||||
uint8_t sig_pk1[32] = {1};
|
||||
uint8_t sig_pk2[32] = {2};
|
||||
EXPECT_TRUE(mod_list_add_entry(&mods, sig_pk1));
|
||||
@ -47,7 +47,7 @@ TEST(ModList, AddRemoveMultipleMods)
|
||||
TEST(ModList, PackingAndUnpackingList)
|
||||
{
|
||||
using ModListEntry = std::array<uint8_t, MOD_LIST_ENTRY_SIZE>;
|
||||
Moderation mods{};
|
||||
Moderation mods{system_memory()};
|
||||
EXPECT_TRUE(mod_list_add_entry(&mods, ModListEntry{}.data()));
|
||||
|
||||
std::vector<uint8_t> packed(mod_list_packed_size(&mods));
|
||||
@ -55,7 +55,7 @@ TEST(ModList, PackingAndUnpackingList)
|
||||
|
||||
EXPECT_TRUE(mod_list_remove_entry(&mods, ModListEntry{}.data()));
|
||||
|
||||
Moderation mods2{};
|
||||
Moderation mods2{system_memory()};
|
||||
EXPECT_EQ(mod_list_unpack(&mods2, packed.data(), packed.size(), 1), packed.size());
|
||||
EXPECT_TRUE(mod_list_remove_entry(&mods2, ModListEntry{}.data()));
|
||||
}
|
||||
@ -63,13 +63,13 @@ TEST(ModList, PackingAndUnpackingList)
|
||||
TEST(ModList, UnpackingTooManyModsFails)
|
||||
{
|
||||
using ModListEntry = std::array<uint8_t, MOD_LIST_ENTRY_SIZE>;
|
||||
Moderation mods{};
|
||||
Moderation mods{system_memory()};
|
||||
EXPECT_TRUE(mod_list_add_entry(&mods, ModListEntry{}.data()));
|
||||
|
||||
std::vector<uint8_t> packed(mod_list_packed_size(&mods));
|
||||
mod_list_pack(&mods, packed.data());
|
||||
|
||||
Moderation mods2{};
|
||||
Moderation mods2{system_memory()};
|
||||
EXPECT_EQ(mod_list_unpack(&mods2, packed.data(), packed.size(), 2), -1);
|
||||
EXPECT_TRUE(mod_list_remove_entry(&mods, ModListEntry{}.data()));
|
||||
}
|
||||
@ -78,7 +78,7 @@ TEST(ModList, UnpackingFromEmptyBufferFails)
|
||||
{
|
||||
std::vector<uint8_t> packed(1);
|
||||
|
||||
Moderation mods{};
|
||||
Moderation mods{system_memory()};
|
||||
EXPECT_EQ(mod_list_unpack(&mods, packed.end().base(), 0, 1), -1);
|
||||
}
|
||||
|
||||
@ -87,7 +87,7 @@ TEST(ModList, HashOfEmptyModListZeroesOutBuffer)
|
||||
const Random *rng = system_random();
|
||||
ASSERT_NE(rng, nullptr);
|
||||
|
||||
Moderation mods{};
|
||||
Moderation mods{system_memory()};
|
||||
|
||||
// Fill with random data, check that it's zeroed.
|
||||
ModerationHash hash;
|
||||
@ -98,21 +98,21 @@ TEST(ModList, HashOfEmptyModListZeroesOutBuffer)
|
||||
|
||||
TEST(ModList, RemoveIndexFromEmptyModListFails)
|
||||
{
|
||||
Moderation mods{};
|
||||
Moderation mods{system_memory()};
|
||||
EXPECT_FALSE(mod_list_remove_index(&mods, 0));
|
||||
EXPECT_FALSE(mod_list_remove_index(&mods, UINT16_MAX));
|
||||
}
|
||||
|
||||
TEST(ModList, RemoveEntryFromEmptyModListFails)
|
||||
{
|
||||
Moderation mods{};
|
||||
Moderation mods{system_memory()};
|
||||
uint8_t sig_pk[32] = {0};
|
||||
EXPECT_FALSE(mod_list_remove_entry(&mods, sig_pk));
|
||||
}
|
||||
|
||||
TEST(ModList, ModListRemoveIndex)
|
||||
{
|
||||
Moderation mods{};
|
||||
Moderation mods{system_memory()};
|
||||
uint8_t sig_pk[32] = {1};
|
||||
EXPECT_TRUE(mod_list_add_entry(&mods, sig_pk));
|
||||
EXPECT_TRUE(mod_list_remove_index(&mods, 0));
|
||||
@ -120,20 +120,20 @@ TEST(ModList, ModListRemoveIndex)
|
||||
|
||||
TEST(ModList, CleanupOnEmptyModsIsNoop)
|
||||
{
|
||||
Moderation mods{};
|
||||
Moderation mods{system_memory()};
|
||||
mod_list_cleanup(&mods);
|
||||
}
|
||||
|
||||
TEST(ModList, EmptyModListCannotVerifyAnySigPk)
|
||||
{
|
||||
Moderation mods{};
|
||||
Moderation mods{system_memory()};
|
||||
uint8_t sig_pk[32] = {1};
|
||||
EXPECT_FALSE(mod_list_verify_sig_pk(&mods, sig_pk));
|
||||
}
|
||||
|
||||
TEST(ModList, ModListAddVerifyRemoveSigPK)
|
||||
{
|
||||
Moderation mods{};
|
||||
Moderation mods{system_memory()};
|
||||
uint8_t sig_pk[32] = {1};
|
||||
EXPECT_TRUE(mod_list_add_entry(&mods, sig_pk));
|
||||
EXPECT_TRUE(mod_list_verify_sig_pk(&mods, sig_pk));
|
||||
@ -143,7 +143,7 @@ TEST(ModList, ModListAddVerifyRemoveSigPK)
|
||||
|
||||
TEST(ModList, ModListHashCheck)
|
||||
{
|
||||
Moderation mods1{};
|
||||
Moderation mods1{system_memory()};
|
||||
uint8_t sig_pk1[32] = {1};
|
||||
std::array<uint8_t, MOD_MODERATION_HASH_SIZE> hash1;
|
||||
|
||||
@ -165,7 +165,7 @@ TEST(SanctionsList, PackingIntoUndersizedBufferFails)
|
||||
|
||||
TEST(SanctionsList, PackUnpackSanctionsCreds)
|
||||
{
|
||||
Moderation mod{};
|
||||
Moderation mod{system_memory()};
|
||||
std::array<uint8_t, MOD_SANCTIONS_CREDS_SIZE> packed;
|
||||
EXPECT_EQ(sanctions_creds_pack(&mod.sanctions_creds, packed.data()), MOD_SANCTIONS_CREDS_SIZE);
|
||||
EXPECT_EQ(
|
||||
@ -177,7 +177,7 @@ protected:
|
||||
ExtPublicKey pk;
|
||||
ExtSecretKey sk;
|
||||
Logger *log = logger_new();
|
||||
Moderation mod{};
|
||||
Moderation mod{system_memory()};
|
||||
|
||||
Mod_Sanction sanctions[2] = {};
|
||||
const uint8_t sanctioned_pk1[32] = {1};
|
||||
|
88
toxcore/mem.c
Normal file
88
toxcore/mem.c
Normal file
@ -0,0 +1,88 @@
|
||||
/* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* Copyright © 2016-2018 The TokTok team.
|
||||
* Copyright © 2013 Tox project.
|
||||
*/
|
||||
|
||||
#include "mem.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "ccompat.h"
|
||||
|
||||
nullable(1)
|
||||
static void *sys_malloc(void *obj, uint32_t size)
|
||||
{
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
nullable(1)
|
||||
static void *sys_calloc(void *obj, uint32_t nmemb, uint32_t size)
|
||||
{
|
||||
return calloc(nmemb, size);
|
||||
}
|
||||
|
||||
nullable(1, 2)
|
||||
static void *sys_realloc(void *obj, void *ptr, uint32_t size)
|
||||
{
|
||||
return realloc(ptr, size);
|
||||
}
|
||||
|
||||
nullable(1, 2)
|
||||
static void sys_free(void *obj, void *ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
static const Memory_Funcs system_memory_funcs = {
|
||||
sys_malloc,
|
||||
sys_calloc,
|
||||
sys_realloc,
|
||||
sys_free,
|
||||
};
|
||||
static const Memory system_memory_obj = {&system_memory_funcs};
|
||||
|
||||
const Memory *system_memory(void)
|
||||
{
|
||||
return &system_memory_obj;
|
||||
}
|
||||
|
||||
void *mem_balloc(const Memory *mem, uint32_t size)
|
||||
{
|
||||
void *const ptr = mem->funcs->malloc(mem->obj, size);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void *mem_alloc(const Memory *mem, uint32_t size)
|
||||
{
|
||||
void *const ptr = mem->funcs->calloc(mem->obj, 1, size);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void *mem_valloc(const Memory *mem, uint32_t nmemb, uint32_t size)
|
||||
{
|
||||
const uint32_t bytes = nmemb * size;
|
||||
|
||||
if (size != 0 && bytes / size != nmemb) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void *const ptr = mem->funcs->calloc(mem->obj, nmemb, size);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void *mem_vrealloc(const Memory *mem, void *ptr, uint32_t nmemb, uint32_t size)
|
||||
{
|
||||
const uint32_t bytes = nmemb * size;
|
||||
|
||||
if (size != 0 && bytes / size != nmemb) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void *const new_ptr = mem->funcs->realloc(mem->obj, ptr, bytes);
|
||||
return new_ptr;
|
||||
}
|
||||
|
||||
void mem_delete(const Memory *mem, void *ptr)
|
||||
{
|
||||
mem->funcs->free(mem->obj, ptr);
|
||||
}
|
86
toxcore/mem.h
Normal file
86
toxcore/mem.h
Normal file
@ -0,0 +1,86 @@
|
||||
/* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* Copyright © 2016-2018 The TokTok team.
|
||||
* Copyright © 2013 Tox project.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Memory allocation and deallocation functions.
|
||||
*/
|
||||
#ifndef C_TOXCORE_TOXCORE_MEM_H
|
||||
#define C_TOXCORE_TOXCORE_MEM_H
|
||||
|
||||
#include <stdint.h> // uint*_t
|
||||
|
||||
#include "attributes.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void *mem_malloc_cb(void *obj, uint32_t size);
|
||||
typedef void *mem_calloc_cb(void *obj, uint32_t nmemb, uint32_t size);
|
||||
typedef void *mem_realloc_cb(void *obj, void *ptr, uint32_t size);
|
||||
typedef void mem_free_cb(void *obj, void *ptr);
|
||||
|
||||
/** @brief Functions wrapping standard C memory allocation functions. */
|
||||
typedef struct Memory_Funcs {
|
||||
mem_malloc_cb *malloc;
|
||||
mem_calloc_cb *calloc;
|
||||
mem_realloc_cb *realloc;
|
||||
mem_free_cb *free;
|
||||
} Memory_Funcs;
|
||||
|
||||
typedef struct Memory {
|
||||
const Memory_Funcs *funcs;
|
||||
void *obj;
|
||||
} Memory;
|
||||
|
||||
const Memory *system_memory(void);
|
||||
|
||||
/**
|
||||
* @brief Allocate an array of a given size for built-in types.
|
||||
*
|
||||
* The array will not be initialised. Supported built-in types are
|
||||
* `uint8_t`, `int8_t`, and `int16_t`.
|
||||
*/
|
||||
non_null() void *mem_balloc(const Memory *mem, uint32_t size);
|
||||
|
||||
/**
|
||||
* @brief Allocate a single object.
|
||||
*
|
||||
* Always use as `(T *)mem_alloc(mem, sizeof(T))`.
|
||||
*/
|
||||
non_null() void *mem_alloc(const Memory *mem, uint32_t size);
|
||||
|
||||
/**
|
||||
* @brief Allocate a vector (array) of objects.
|
||||
*
|
||||
* Always use as `(T *)mem_valloc(mem, N, sizeof(T))`.
|
||||
*/
|
||||
non_null() void *mem_valloc(const Memory *mem, uint32_t nmemb, uint32_t size);
|
||||
|
||||
/**
|
||||
* @brief Resize an object vector.
|
||||
*
|
||||
* Changes the size of (and possibly moves) the memory block pointed to by
|
||||
* @p ptr to be large enough for an array of @p nmemb elements, each of which
|
||||
* is @p size bytes. It is similar to the call
|
||||
*
|
||||
* @code
|
||||
* realloc(ptr, nmemb * size);
|
||||
* @endcode
|
||||
*
|
||||
* However, unlike that `realloc()` call, `mem_vrealloc()` fails safely in the
|
||||
* case where the multiplication would overflow. If such an overflow occurs,
|
||||
* `mem_vrealloc()` returns `nullptr`.
|
||||
*/
|
||||
non_null(1) nullable(2) void *mem_vrealloc(const Memory *mem, void *ptr, uint32_t nmemb, uint32_t size);
|
||||
|
||||
/** @brief Free an array, object, or object vector. */
|
||||
non_null(1) nullable(2) void mem_delete(const Memory *mem, void *ptr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif
|
40
toxcore/mem_test.cc
Normal file
40
toxcore/mem_test.cc
Normal file
@ -0,0 +1,40 @@
|
||||
#include "mem.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace {
|
||||
|
||||
TEST(Mem, AllocLarge)
|
||||
{
|
||||
// Mebi prefix: https://en.wikipedia.org/wiki/Binary_prefix.
|
||||
constexpr uint32_t MI = 1024 * 1024;
|
||||
|
||||
const Memory *mem = system_memory();
|
||||
|
||||
void *ptr = mem_valloc(mem, 4, MI);
|
||||
EXPECT_NE(ptr, nullptr);
|
||||
|
||||
mem_delete(mem, ptr);
|
||||
}
|
||||
|
||||
TEST(Mem, AllocOverflow)
|
||||
{
|
||||
// Gibi prefix.
|
||||
constexpr uint32_t GI = 1024 * 1024 * 1024;
|
||||
|
||||
const Memory *mem = system_memory();
|
||||
|
||||
// 1 gibi-elements of 100 bytes each.
|
||||
void *ptr = mem_valloc(mem, GI, 100);
|
||||
EXPECT_EQ(ptr, nullptr);
|
||||
|
||||
// 100 elements of 1 gibibyte each.
|
||||
ptr = mem_valloc(mem, 100, GI);
|
||||
EXPECT_EQ(ptr, nullptr);
|
||||
|
||||
// 128 (a multiple of 2) elements of 1 gibibyte each.
|
||||
ptr = mem_valloc(mem, 128, GI);
|
||||
EXPECT_EQ(ptr, nullptr);
|
||||
}
|
||||
|
||||
} // namespace
|
@ -122,25 +122,25 @@ static uint64_t current_time_monotonic_default(void *user_data)
|
||||
#endif // !OS_WIN32
|
||||
|
||||
|
||||
Mono_Time *mono_time_new(mono_time_current_time_cb *current_time_callback, void *user_data)
|
||||
Mono_Time *mono_time_new(const Memory *mem, mono_time_current_time_cb *current_time_callback, void *user_data)
|
||||
{
|
||||
Mono_Time *mono_time = (Mono_Time *)calloc(1, sizeof(Mono_Time));
|
||||
Mono_Time *mono_time = (Mono_Time *)mem_alloc(mem, sizeof(Mono_Time));
|
||||
|
||||
if (mono_time == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#ifndef ESP_PLATFORM
|
||||
mono_time->time_update_lock = (pthread_rwlock_t *)calloc(1, sizeof(pthread_rwlock_t));
|
||||
mono_time->time_update_lock = (pthread_rwlock_t *)mem_alloc(mem, sizeof(pthread_rwlock_t));
|
||||
|
||||
if (mono_time->time_update_lock == nullptr) {
|
||||
free(mono_time);
|
||||
mem_delete(mem, mono_time);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (pthread_rwlock_init(mono_time->time_update_lock, nullptr) < 0) {
|
||||
free(mono_time->time_update_lock);
|
||||
free(mono_time);
|
||||
if (pthread_rwlock_init(mono_time->time_update_lock, nullptr) != 0) {
|
||||
mem_delete(mem, mono_time->time_update_lock);
|
||||
mem_delete(mem, mono_time);
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
@ -153,8 +153,8 @@ Mono_Time *mono_time_new(mono_time_current_time_cb *current_time_callback, void
|
||||
mono_time->last_clock_update = false;
|
||||
|
||||
if (pthread_mutex_init(&mono_time->last_clock_lock, nullptr) < 0) {
|
||||
free(mono_time->time_update_lock);
|
||||
free(mono_time);
|
||||
mem_delete(mem, mono_time->time_update_lock);
|
||||
mem_delete(mem, mono_time);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -173,7 +173,7 @@ Mono_Time *mono_time_new(mono_time_current_time_cb *current_time_callback, void
|
||||
return mono_time;
|
||||
}
|
||||
|
||||
void mono_time_free(Mono_Time *mono_time)
|
||||
void mono_time_free(const Memory *mem, Mono_Time *mono_time)
|
||||
{
|
||||
if (mono_time == nullptr) {
|
||||
return;
|
||||
@ -183,9 +183,9 @@ void mono_time_free(Mono_Time *mono_time)
|
||||
#endif
|
||||
#ifndef ESP_PLATFORM
|
||||
pthread_rwlock_destroy(mono_time->time_update_lock);
|
||||
free(mono_time->time_update_lock);
|
||||
mem_delete(mem, mono_time->time_update_lock);
|
||||
#endif
|
||||
free(mono_time);
|
||||
mem_delete(mem, mono_time);
|
||||
}
|
||||
|
||||
void mono_time_update(Mono_Time *mono_time)
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "attributes.h"
|
||||
#include "mem.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -47,11 +48,11 @@ typedef struct Mono_Time Mono_Time;
|
||||
|
||||
typedef uint64_t mono_time_current_time_cb(void *user_data);
|
||||
|
||||
nullable(1, 2)
|
||||
Mono_Time *mono_time_new(mono_time_current_time_cb *current_time_callback, void *user_data);
|
||||
non_null(1) nullable(2, 3)
|
||||
Mono_Time *mono_time_new(const Memory *mem, mono_time_current_time_cb *current_time_callback, void *user_data);
|
||||
|
||||
nullable(1)
|
||||
void mono_time_free(Mono_Time *mono_time);
|
||||
non_null(1) nullable(2)
|
||||
void mono_time_free(const Memory *mem, Mono_Time *mono_time);
|
||||
|
||||
/**
|
||||
* Update mono_time; subsequent calls to mono_time_get or mono_time_is_timeout
|
||||
|
@ -6,7 +6,8 @@ namespace {
|
||||
|
||||
TEST(MonoTime, UnixTimeIncreasesOverTime)
|
||||
{
|
||||
Mono_Time *mono_time = mono_time_new(nullptr, nullptr);
|
||||
const Memory *mem = system_memory();
|
||||
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
|
||||
ASSERT_NE(mono_time, nullptr);
|
||||
|
||||
mono_time_update(mono_time);
|
||||
@ -19,12 +20,13 @@ TEST(MonoTime, UnixTimeIncreasesOverTime)
|
||||
uint64_t const end = mono_time_get(mono_time);
|
||||
EXPECT_GT(end, start);
|
||||
|
||||
mono_time_free(mono_time);
|
||||
mono_time_free(mem, mono_time);
|
||||
}
|
||||
|
||||
TEST(MonoTime, IsTimeout)
|
||||
{
|
||||
Mono_Time *mono_time = mono_time_new(nullptr, nullptr);
|
||||
const Memory *mem = system_memory();
|
||||
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
|
||||
ASSERT_NE(mono_time, nullptr);
|
||||
|
||||
uint64_t const start = mono_time_get(mono_time);
|
||||
@ -36,12 +38,13 @@ TEST(MonoTime, IsTimeout)
|
||||
|
||||
EXPECT_TRUE(mono_time_is_timeout(mono_time, start, 1));
|
||||
|
||||
mono_time_free(mono_time);
|
||||
mono_time_free(mem, mono_time);
|
||||
}
|
||||
|
||||
TEST(MonoTime, CustomTime)
|
||||
{
|
||||
Mono_Time *mono_time = mono_time_new(nullptr, nullptr);
|
||||
const Memory *mem = system_memory();
|
||||
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
|
||||
ASSERT_NE(mono_time, nullptr);
|
||||
|
||||
uint64_t test_time = current_time_monotonic(mono_time) + 42137;
|
||||
@ -61,7 +64,7 @@ TEST(MonoTime, CustomTime)
|
||||
|
||||
EXPECT_EQ(current_time_monotonic(mono_time), test_time);
|
||||
|
||||
mono_time_free(mono_time);
|
||||
mono_time_free(mem, mono_time);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
@ -127,6 +127,7 @@ static const Crypto_Connection empty_crypto_connection = {{0}};
|
||||
|
||||
struct Net_Crypto {
|
||||
const Logger *log;
|
||||
const Memory *mem;
|
||||
const Random *rng;
|
||||
Mono_Time *mono_time;
|
||||
const Network *ns;
|
||||
@ -758,7 +759,7 @@ static uint32_t num_packets_array(const Packets_Array *array)
|
||||
* @retval 0 on success.
|
||||
*/
|
||||
non_null()
|
||||
static int add_data_to_buffer(Packets_Array *array, uint32_t number, const Packet_Data *data)
|
||||
static int add_data_to_buffer(const Memory *mem, Packets_Array *array, uint32_t number, const Packet_Data *data)
|
||||
{
|
||||
if (number - array->buffer_start >= CRYPTO_PACKET_BUFFER_SIZE) {
|
||||
return -1;
|
||||
@ -770,7 +771,7 @@ static int add_data_to_buffer(Packets_Array *array, uint32_t number, const Packe
|
||||
return -1;
|
||||
}
|
||||
|
||||
Packet_Data *new_d = (Packet_Data *)calloc(1, sizeof(Packet_Data));
|
||||
Packet_Data *new_d = (Packet_Data *)mem_alloc(mem, sizeof(Packet_Data));
|
||||
|
||||
if (new_d == nullptr) {
|
||||
return -1;
|
||||
@ -817,7 +818,7 @@ static int get_data_pointer(const Packets_Array *array, Packet_Data **data, uint
|
||||
* @return packet number on success.
|
||||
*/
|
||||
non_null()
|
||||
static int64_t add_data_end_of_buffer(const Logger *logger, Packets_Array *array, const Packet_Data *data)
|
||||
static int64_t add_data_end_of_buffer(const Logger *logger, const Memory *mem, Packets_Array *array, const Packet_Data *data)
|
||||
{
|
||||
const uint32_t num_spots = num_packets_array(array);
|
||||
|
||||
@ -826,7 +827,7 @@ static int64_t add_data_end_of_buffer(const Logger *logger, Packets_Array *array
|
||||
return -1;
|
||||
}
|
||||
|
||||
Packet_Data *new_d = (Packet_Data *)calloc(1, sizeof(Packet_Data));
|
||||
Packet_Data *new_d = (Packet_Data *)mem_alloc(mem, sizeof(Packet_Data));
|
||||
|
||||
if (new_d == nullptr) {
|
||||
LOGGER_ERROR(logger, "packet data allocation failed");
|
||||
@ -846,7 +847,7 @@ static int64_t add_data_end_of_buffer(const Logger *logger, Packets_Array *array
|
||||
* @return packet number on success.
|
||||
*/
|
||||
non_null()
|
||||
static int64_t read_data_beg_buffer(Packets_Array *array, Packet_Data *data)
|
||||
static int64_t read_data_beg_buffer(const Memory *mem, Packets_Array *array, Packet_Data *data)
|
||||
{
|
||||
if (array->buffer_end == array->buffer_start) {
|
||||
return -1;
|
||||
@ -861,7 +862,7 @@ static int64_t read_data_beg_buffer(Packets_Array *array, Packet_Data *data)
|
||||
*data = *array->buffer[num];
|
||||
const uint32_t id = array->buffer_start;
|
||||
++array->buffer_start;
|
||||
free(array->buffer[num]);
|
||||
mem_delete(mem, array->buffer[num]);
|
||||
array->buffer[num] = nullptr;
|
||||
return id;
|
||||
}
|
||||
@ -872,7 +873,7 @@ static int64_t read_data_beg_buffer(Packets_Array *array, Packet_Data *data)
|
||||
* @retval 0 on success
|
||||
*/
|
||||
non_null()
|
||||
static int clear_buffer_until(Packets_Array *array, uint32_t number)
|
||||
static int clear_buffer_until(const Memory *mem, Packets_Array *array, uint32_t number)
|
||||
{
|
||||
const uint32_t num_spots = num_packets_array(array);
|
||||
|
||||
@ -886,7 +887,7 @@ static int clear_buffer_until(Packets_Array *array, uint32_t number)
|
||||
const uint32_t num = i % CRYPTO_PACKET_BUFFER_SIZE;
|
||||
|
||||
if (array->buffer[num] != nullptr) {
|
||||
free(array->buffer[num]);
|
||||
mem_delete(mem, array->buffer[num]);
|
||||
array->buffer[num] = nullptr;
|
||||
}
|
||||
}
|
||||
@ -896,7 +897,7 @@ static int clear_buffer_until(Packets_Array *array, uint32_t number)
|
||||
}
|
||||
|
||||
non_null()
|
||||
static int clear_buffer(Packets_Array *array)
|
||||
static int clear_buffer(const Memory *mem, Packets_Array *array)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
@ -904,7 +905,7 @@ static int clear_buffer(Packets_Array *array)
|
||||
const uint32_t num = i % CRYPTO_PACKET_BUFFER_SIZE;
|
||||
|
||||
if (array->buffer[num] != nullptr) {
|
||||
free(array->buffer[num]);
|
||||
mem_delete(mem, array->buffer[num]);
|
||||
array->buffer[num] = nullptr;
|
||||
}
|
||||
}
|
||||
@ -995,7 +996,7 @@ static int generate_request_packet(uint8_t *data, uint16_t length, const Packets
|
||||
* @return number of requested packets on success.
|
||||
*/
|
||||
non_null()
|
||||
static int handle_request_packet(Mono_Time *mono_time, Packets_Array *send_array,
|
||||
static int handle_request_packet(const Memory *mem, Mono_Time *mono_time, Packets_Array *send_array,
|
||||
const uint8_t *data, uint16_t length,
|
||||
uint64_t *latest_send_time, uint64_t rtt_time)
|
||||
{
|
||||
@ -1044,7 +1045,7 @@ static int handle_request_packet(Mono_Time *mono_time, Packets_Array *send_array
|
||||
if (send_array->buffer[num] != nullptr) {
|
||||
l_sent_time = max_u64(l_sent_time, send_array->buffer[num]->sent_time);
|
||||
|
||||
free(send_array->buffer[num]);
|
||||
mem_delete(mem, send_array->buffer[num]);
|
||||
send_array->buffer[num] = nullptr;
|
||||
}
|
||||
}
|
||||
@ -1204,7 +1205,7 @@ static int64_t send_lossless_packet(Net_Crypto *c, int crypt_connection_id, cons
|
||||
dt.length = length;
|
||||
memcpy(dt.data, data, length);
|
||||
pthread_mutex_lock(conn->mutex);
|
||||
const int64_t packet_num = add_data_end_of_buffer(c->log, &conn->send_array, &dt);
|
||||
const int64_t packet_num = add_data_end_of_buffer(c->log, c->mem, &conn->send_array, &dt);
|
||||
pthread_mutex_unlock(conn->mutex);
|
||||
|
||||
if (packet_num == -1) {
|
||||
@ -1384,14 +1385,14 @@ static int new_temp_packet(const Net_Crypto *c, int crypt_connection_id, const u
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t *temp_packet = (uint8_t *)malloc(length);
|
||||
uint8_t *temp_packet = (uint8_t *)mem_balloc(c->mem, length);
|
||||
|
||||
if (temp_packet == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (conn->temp_packet != nullptr) {
|
||||
free(conn->temp_packet);
|
||||
mem_delete(c->mem, conn->temp_packet);
|
||||
}
|
||||
|
||||
memcpy(temp_packet, packet, length);
|
||||
@ -1417,7 +1418,7 @@ static int clear_temp_packet(const Net_Crypto *c, int crypt_connection_id)
|
||||
}
|
||||
|
||||
if (conn->temp_packet != nullptr) {
|
||||
free(conn->temp_packet);
|
||||
mem_delete(c->mem, conn->temp_packet);
|
||||
}
|
||||
|
||||
conn->temp_packet = nullptr;
|
||||
@ -1575,7 +1576,7 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const
|
||||
rtt_calc_time = packet_time->sent_time;
|
||||
}
|
||||
|
||||
if (clear_buffer_until(&conn->send_array, buffer_start) != 0) {
|
||||
if (clear_buffer_until(c->mem, &conn->send_array, buffer_start) != 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -1616,9 +1617,7 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const
|
||||
rtt_time = DEFAULT_TCP_PING_CONNECTION;
|
||||
}
|
||||
|
||||
const int requested = handle_request_packet(c->mono_time, &conn->send_array,
|
||||
real_data, real_length,
|
||||
&rtt_calc_time, rtt_time);
|
||||
const int requested = handle_request_packet(c->mem, c->mono_time, &conn->send_array, real_data, real_length, &rtt_calc_time, rtt_time);
|
||||
|
||||
if (requested == -1) {
|
||||
return -1;
|
||||
@ -1630,13 +1629,13 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const
|
||||
dt.length = real_length;
|
||||
memcpy(dt.data, real_data, real_length);
|
||||
|
||||
if (add_data_to_buffer(&conn->recv_array, num, &dt) != 0) {
|
||||
if (add_data_to_buffer(c->mem, &conn->recv_array, num, &dt) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
pthread_mutex_lock(conn->mutex);
|
||||
const int ret = read_data_beg_buffer(&conn->recv_array, &dt);
|
||||
const int ret = read_data_beg_buffer(c->mem, &conn->recv_array, &dt);
|
||||
pthread_mutex_unlock(conn->mutex);
|
||||
|
||||
if (ret == -1) {
|
||||
@ -1804,20 +1803,20 @@ static int handle_packet_connection(Net_Crypto *c, int crypt_connection_id, cons
|
||||
|
||||
/** @brief Set the size of the friend list to numfriends.
|
||||
*
|
||||
* @retval -1 if realloc fails.
|
||||
* @retval -1 if mem_vrealloc fails.
|
||||
* @retval 0 if it succeeds.
|
||||
*/
|
||||
non_null()
|
||||
static int realloc_cryptoconnection(Net_Crypto *c, uint32_t num)
|
||||
{
|
||||
if (num == 0) {
|
||||
free(c->crypto_connections);
|
||||
mem_delete(c->mem, c->crypto_connections);
|
||||
c->crypto_connections = nullptr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Crypto_Connection *newcrypto_connections = (Crypto_Connection *)realloc(c->crypto_connections,
|
||||
num * sizeof(Crypto_Connection));
|
||||
Crypto_Connection *newcrypto_connections = (Crypto_Connection *)mem_vrealloc(
|
||||
c->mem, c->crypto_connections, num, sizeof(Crypto_Connection));
|
||||
|
||||
if (newcrypto_connections == nullptr) {
|
||||
return -1;
|
||||
@ -1870,7 +1869,7 @@ static int create_crypto_connection(Net_Crypto *c)
|
||||
c->crypto_connections[id].last_packets_left_rem = 0;
|
||||
c->crypto_connections[id].packet_send_rate_requested = 0;
|
||||
c->crypto_connections[id].last_packets_left_requested_rem = 0;
|
||||
c->crypto_connections[id].mutex = (pthread_mutex_t *)calloc(1, sizeof(pthread_mutex_t));
|
||||
c->crypto_connections[id].mutex = (pthread_mutex_t *)mem_alloc(c->mem, sizeof(pthread_mutex_t));
|
||||
|
||||
if (c->crypto_connections[id].mutex == nullptr) {
|
||||
pthread_mutex_unlock(&c->connections_mutex);
|
||||
@ -1878,7 +1877,7 @@ static int create_crypto_connection(Net_Crypto *c)
|
||||
}
|
||||
|
||||
if (pthread_mutex_init(c->crypto_connections[id].mutex, nullptr) != 0) {
|
||||
free(c->crypto_connections[id].mutex);
|
||||
mem_delete(c->mem, c->crypto_connections[id].mutex);
|
||||
pthread_mutex_unlock(&c->connections_mutex);
|
||||
return -1;
|
||||
}
|
||||
@ -1915,7 +1914,7 @@ static int wipe_crypto_connection(Net_Crypto *c, int crypt_connection_id)
|
||||
uint32_t i;
|
||||
|
||||
pthread_mutex_destroy(c->crypto_connections[crypt_connection_id].mutex);
|
||||
free(c->crypto_connections[crypt_connection_id].mutex);
|
||||
mem_delete(c->mem, c->crypto_connections[crypt_connection_id].mutex);
|
||||
crypto_memzero(&c->crypto_connections[crypt_connection_id], sizeof(Crypto_Connection));
|
||||
|
||||
/* check if we can resize the connections array */
|
||||
@ -2019,7 +2018,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source,
|
||||
void *userdata)
|
||||
{
|
||||
New_Connection n_c;
|
||||
n_c.cookie = (uint8_t *)malloc(COOKIE_LENGTH);
|
||||
n_c.cookie = (uint8_t *)mem_balloc(c->mem, COOKIE_LENGTH);
|
||||
|
||||
if (n_c.cookie == nullptr) {
|
||||
return -1;
|
||||
@ -2030,7 +2029,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source,
|
||||
|
||||
if (!handle_crypto_handshake(c, n_c.recv_nonce, n_c.peersessionpublic_key, n_c.public_key, n_c.dht_public_key,
|
||||
n_c.cookie, data, length, nullptr)) {
|
||||
free(n_c.cookie);
|
||||
mem_delete(c->mem, n_c.cookie);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -2047,7 +2046,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source,
|
||||
connection_kill(c, crypt_connection_id, userdata);
|
||||
} else {
|
||||
if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING && conn->status != CRYPTO_CONN_HANDSHAKE_SENT) {
|
||||
free(n_c.cookie);
|
||||
mem_delete(c->mem, n_c.cookie);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -2058,18 +2057,18 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source,
|
||||
crypto_connection_add_source(c, crypt_connection_id, source);
|
||||
|
||||
if (create_send_handshake(c, crypt_connection_id, n_c.cookie, n_c.dht_public_key) != 0) {
|
||||
free(n_c.cookie);
|
||||
mem_delete(c->mem, n_c.cookie);
|
||||
return -1;
|
||||
}
|
||||
|
||||
conn->status = CRYPTO_CONN_NOT_CONFIRMED;
|
||||
free(n_c.cookie);
|
||||
mem_delete(c->mem, n_c.cookie);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
const int ret = c->new_connection_callback(c->new_connection_callback_object, &n_c);
|
||||
free(n_c.cookie);
|
||||
mem_delete(c->mem, n_c.cookie);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -3045,8 +3044,8 @@ int crypto_kill(Net_Crypto *c, int crypt_connection_id)
|
||||
bs_list_remove(&c->ip_port_list, (uint8_t *)&conn->ip_portv4, crypt_connection_id);
|
||||
bs_list_remove(&c->ip_port_list, (uint8_t *)&conn->ip_portv6, crypt_connection_id);
|
||||
clear_temp_packet(c, crypt_connection_id);
|
||||
clear_buffer(&conn->send_array);
|
||||
clear_buffer(&conn->recv_array);
|
||||
clear_buffer(c->mem, &conn->send_array);
|
||||
clear_buffer(c->mem, &conn->recv_array);
|
||||
ret = wipe_crypto_connection(c, crypt_connection_id);
|
||||
}
|
||||
|
||||
@ -3067,9 +3066,8 @@ bool crypto_connection_status(const Net_Crypto *c, int crypt_connection_id, bool
|
||||
|
||||
const uint64_t current_time = mono_time_get(c->mono_time);
|
||||
|
||||
if ((UDP_DIRECT_TIMEOUT + conn->direct_lastrecv_timev4) > current_time) {
|
||||
*direct_connected = true;
|
||||
} else if ((UDP_DIRECT_TIMEOUT + conn->direct_lastrecv_timev6) > current_time) {
|
||||
if ((UDP_DIRECT_TIMEOUT + conn->direct_lastrecv_timev4) > current_time ||
|
||||
(UDP_DIRECT_TIMEOUT + conn->direct_lastrecv_timev6) > current_time) {
|
||||
*direct_connected = true;
|
||||
}
|
||||
}
|
||||
@ -3109,27 +3107,29 @@ void load_secret_key(Net_Crypto *c, const uint8_t *sk)
|
||||
/** @brief Create new instance of Net_Crypto.
|
||||
* Sets all the global connection variables to their default values.
|
||||
*/
|
||||
Net_Crypto *new_net_crypto(const Logger *log, const Random *rng, const Network *ns, Mono_Time *mono_time, DHT *dht, const TCP_Proxy_Info *proxy_info)
|
||||
Net_Crypto *new_net_crypto(const Logger *log, const Memory *mem, const Random *rng, const Network *ns,
|
||||
Mono_Time *mono_time, DHT *dht, const TCP_Proxy_Info *proxy_info)
|
||||
{
|
||||
if (dht == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Net_Crypto *temp = (Net_Crypto *)calloc(1, sizeof(Net_Crypto));
|
||||
Net_Crypto *temp = (Net_Crypto *)mem_alloc(mem, sizeof(Net_Crypto));
|
||||
|
||||
if (temp == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
temp->log = log;
|
||||
temp->mem = mem;
|
||||
temp->rng = rng;
|
||||
temp->mono_time = mono_time;
|
||||
temp->ns = ns;
|
||||
|
||||
temp->tcp_c = new_tcp_connections(log, rng, ns, mono_time, dht_get_self_secret_key(dht), proxy_info);
|
||||
temp->tcp_c = new_tcp_connections(log, mem, rng, ns, mono_time, dht_get_self_secret_key(dht), proxy_info);
|
||||
|
||||
if (temp->tcp_c == nullptr) {
|
||||
free(temp);
|
||||
mem_delete(mem, temp);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -3139,7 +3139,7 @@ Net_Crypto *new_net_crypto(const Logger *log, const Random *rng, const Network *
|
||||
if (create_recursive_mutex(&temp->tcp_mutex) != 0 ||
|
||||
pthread_mutex_init(&temp->connections_mutex, nullptr) != 0) {
|
||||
kill_tcp_connections(temp->tcp_c);
|
||||
free(temp);
|
||||
mem_delete(mem, temp);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -3210,6 +3210,8 @@ void kill_net_crypto(Net_Crypto *c)
|
||||
return;
|
||||
}
|
||||
|
||||
const Memory *mem = c->mem;
|
||||
|
||||
for (uint32_t i = 0; i < c->crypto_connections_length; ++i) {
|
||||
crypto_kill(c, i);
|
||||
}
|
||||
@ -3224,5 +3226,5 @@ void kill_net_crypto(Net_Crypto *c)
|
||||
networking_registerhandler(dht_get_net(c->dht), NET_PACKET_CRYPTO_HS, nullptr, nullptr);
|
||||
networking_registerhandler(dht_get_net(c->dht), NET_PACKET_CRYPTO_DATA, nullptr, nullptr);
|
||||
crypto_memzero(c, sizeof(Net_Crypto));
|
||||
free(c);
|
||||
mem_delete(mem, c);
|
||||
}
|
||||
|
@ -398,7 +398,8 @@ void load_secret_key(Net_Crypto *c, const uint8_t *sk);
|
||||
* Sets all the global connection variables to their default values.
|
||||
*/
|
||||
non_null()
|
||||
Net_Crypto *new_net_crypto(const Logger *log, const Random *rng, const Network *ns, Mono_Time *mono_time, DHT *dht, const TCP_Proxy_Info *proxy_info);
|
||||
Net_Crypto *new_net_crypto(const Logger *log, const Memory *mem, const Random *rng, const Network *ns,
|
||||
Mono_Time *mono_time, DHT *dht, const TCP_Proxy_Info *proxy_info);
|
||||
|
||||
/** return the optimal interval in ms for running do_net_crypto. */
|
||||
non_null()
|
||||
|
@ -139,15 +139,15 @@ static const char *inet_ntop6(const struct in6_addr *addr, char *buf, size_t buf
|
||||
}
|
||||
|
||||
non_null()
|
||||
static int inet_pton4(const char *addrString, struct in_addr *addrbuf)
|
||||
static int inet_pton4(const char *addr_string, struct in_addr *addrbuf)
|
||||
{
|
||||
return inet_pton(AF_INET, addrString, addrbuf);
|
||||
return inet_pton(AF_INET, addr_string, addrbuf);
|
||||
}
|
||||
|
||||
non_null()
|
||||
static int inet_pton6(const char *addrString, struct in6_addr *addrbuf)
|
||||
static int inet_pton6(const char *addr_string, struct in6_addr *addrbuf)
|
||||
{
|
||||
return inet_pton(AF_INET6, addrString, addrbuf);
|
||||
return inet_pton(AF_INET6, addr_string, addrbuf);
|
||||
}
|
||||
|
||||
#else
|
||||
@ -377,47 +377,47 @@ IP6 get_ip6_loopback(void)
|
||||
|
||||
const Socket net_invalid_socket = { (int)INVALID_SOCKET };
|
||||
|
||||
Family net_family_unspec()
|
||||
Family net_family_unspec(void)
|
||||
{
|
||||
return family_unspec;
|
||||
}
|
||||
|
||||
Family net_family_ipv4()
|
||||
Family net_family_ipv4(void)
|
||||
{
|
||||
return family_ipv4;
|
||||
}
|
||||
|
||||
Family net_family_ipv6()
|
||||
Family net_family_ipv6(void)
|
||||
{
|
||||
return family_ipv6;
|
||||
}
|
||||
|
||||
Family net_family_tcp_server()
|
||||
Family net_family_tcp_server(void)
|
||||
{
|
||||
return family_tcp_server;
|
||||
}
|
||||
|
||||
Family net_family_tcp_client()
|
||||
Family net_family_tcp_client(void)
|
||||
{
|
||||
return family_tcp_client;
|
||||
}
|
||||
|
||||
Family net_family_tcp_ipv4()
|
||||
Family net_family_tcp_ipv4(void)
|
||||
{
|
||||
return family_tcp_ipv4;
|
||||
}
|
||||
|
||||
Family net_family_tcp_ipv6()
|
||||
Family net_family_tcp_ipv6(void)
|
||||
{
|
||||
return family_tcp_ipv6;
|
||||
}
|
||||
|
||||
Family net_family_tox_tcp_ipv4()
|
||||
Family net_family_tox_tcp_ipv4(void)
|
||||
{
|
||||
return family_tox_tcp_ipv4;
|
||||
}
|
||||
|
||||
Family net_family_tox_tcp_ipv6()
|
||||
Family net_family_tox_tcp_ipv6(void)
|
||||
{
|
||||
return family_tox_tcp_ipv6;
|
||||
}
|
||||
@ -898,6 +898,7 @@ typedef struct Packet_Handler {
|
||||
|
||||
struct Networking_Core {
|
||||
const Logger *log;
|
||||
const Memory *mem;
|
||||
Packet_Handler packethandlers[256];
|
||||
const Network *ns;
|
||||
|
||||
@ -1009,7 +1010,7 @@ int sendpacket(const Networking_Core *net, const IP_Port *ip_port, const uint8_t
|
||||
* Packet length is put into length.
|
||||
*/
|
||||
non_null()
|
||||
static int receivepacket(const Network *ns, const Logger *log, Socket sock, IP_Port *ip_port, uint8_t *data, uint32_t *length)
|
||||
static int receivepacket(const Network *ns, const Memory *mem, const Logger *log, Socket sock, IP_Port *ip_port, uint8_t *data, uint32_t *length)
|
||||
{
|
||||
memset(ip_port, 0, sizeof(IP_Port));
|
||||
Network_Addr addr = {{0}};
|
||||
@ -1088,7 +1089,7 @@ void networking_poll(const Networking_Core *net, void *userdata)
|
||||
uint8_t data[MAX_UDP_PACKET_SIZE];
|
||||
uint32_t length;
|
||||
|
||||
while (receivepacket(net->ns, net->log, net->sock, &ip_port, data, &length) != -1) {
|
||||
while (receivepacket(net->ns, net->mem, net->log, net->sock, &ip_port, data, &length) != -1) {
|
||||
if (length < 1) {
|
||||
continue;
|
||||
}
|
||||
@ -1117,7 +1118,7 @@ void networking_poll(const Networking_Core *net, void *userdata)
|
||||
* If error is non NULL it is set to 0 if no issues, 1 if socket related error, 2 if other.
|
||||
*/
|
||||
Networking_Core *new_networking_ex(
|
||||
const Logger *log, const Network *ns, const IP *ip,
|
||||
const Logger *log, const Memory *mem, const Network *ns, const IP *ip,
|
||||
uint16_t port_from, uint16_t port_to, unsigned int *error)
|
||||
{
|
||||
/* If both from and to are 0, use default port range
|
||||
@ -1147,7 +1148,7 @@ Networking_Core *new_networking_ex(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Networking_Core *temp = (Networking_Core *)calloc(1, sizeof(Networking_Core));
|
||||
Networking_Core *temp = (Networking_Core *)mem_alloc(mem, sizeof(Networking_Core));
|
||||
|
||||
if (temp == nullptr) {
|
||||
return nullptr;
|
||||
@ -1155,6 +1156,7 @@ Networking_Core *new_networking_ex(
|
||||
|
||||
temp->ns = ns;
|
||||
temp->log = log;
|
||||
temp->mem = mem;
|
||||
temp->family = ip->family;
|
||||
temp->port = 0;
|
||||
|
||||
@ -1168,7 +1170,7 @@ Networking_Core *new_networking_ex(
|
||||
char *strerror = net_new_strerror(neterror);
|
||||
LOGGER_ERROR(log, "failed to get a socket?! %d, %s", neterror, strerror);
|
||||
net_kill_strerror(strerror);
|
||||
free(temp);
|
||||
mem_delete(mem, temp);
|
||||
|
||||
if (error != nullptr) {
|
||||
*error = 1;
|
||||
@ -1246,7 +1248,7 @@ Networking_Core *new_networking_ex(
|
||||
|
||||
portptr = &addr6->sin6_port;
|
||||
} else {
|
||||
free(temp);
|
||||
mem_delete(mem, temp);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -1350,10 +1352,10 @@ Networking_Core *new_networking_ex(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Networking_Core *new_networking_no_udp(const Logger *log, const Network *ns)
|
||||
Networking_Core *new_networking_no_udp(const Logger *log, const Memory *mem, const Network *ns)
|
||||
{
|
||||
/* this is the easiest way to completely disable UDP without changing too much code. */
|
||||
Networking_Core *net = (Networking_Core *)calloc(1, sizeof(Networking_Core));
|
||||
Networking_Core *net = (Networking_Core *)mem_alloc(mem, sizeof(Networking_Core));
|
||||
|
||||
if (net == nullptr) {
|
||||
return nullptr;
|
||||
@ -1361,6 +1363,7 @@ Networking_Core *new_networking_no_udp(const Logger *log, const Network *ns)
|
||||
|
||||
net->ns = ns;
|
||||
net->log = log;
|
||||
net->mem = mem;
|
||||
|
||||
return net;
|
||||
}
|
||||
@ -1377,7 +1380,7 @@ void kill_networking(Networking_Core *net)
|
||||
kill_sock(net->ns, net->sock);
|
||||
}
|
||||
|
||||
free(net);
|
||||
mem_delete(net->mem, net);
|
||||
}
|
||||
|
||||
|
||||
@ -1712,7 +1715,7 @@ bool addr_resolve_or_parse_ip(const Network *ns, const char *address, IP *to, IP
|
||||
return true;
|
||||
}
|
||||
|
||||
bool net_connect(const Logger *log, Socket sock, const IP_Port *ip_port)
|
||||
bool net_connect(const Memory *mem, const Logger *log, Socket sock, const IP_Port *ip_port)
|
||||
{
|
||||
struct sockaddr_storage addr = {0};
|
||||
size_t addrsize;
|
||||
@ -1765,13 +1768,16 @@ bool net_connect(const Logger *log, Socket sock, const IP_Port *ip_port)
|
||||
return true;
|
||||
}
|
||||
|
||||
int32_t net_getipport(const char *node, IP_Port **res, int tox_type)
|
||||
int32_t net_getipport(const Memory *mem, const char *node, IP_Port **res, int tox_type)
|
||||
{
|
||||
// Try parsing as IP address first.
|
||||
IP_Port parsed = {{{0}}};
|
||||
// Initialise to nullptr. In error paths, at least we initialise the out
|
||||
// parameter.
|
||||
*res = nullptr;
|
||||
|
||||
if (addr_parse_ip(node, &parsed.ip)) {
|
||||
IP_Port *tmp = (IP_Port *)calloc(1, sizeof(IP_Port));
|
||||
IP_Port *tmp = (IP_Port *)mem_alloc(mem, sizeof(IP_Port));
|
||||
|
||||
if (tmp == nullptr) {
|
||||
return -1;
|
||||
@ -1784,7 +1790,7 @@ int32_t net_getipport(const char *node, IP_Port **res, int tox_type)
|
||||
|
||||
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
||||
if ((true)) {
|
||||
*res = (IP_Port *)calloc(1, sizeof(IP_Port));
|
||||
*res = (IP_Port *)mem_alloc(mem, sizeof(IP_Port));
|
||||
assert(*res != nullptr);
|
||||
IP_Port *ip_port = *res;
|
||||
ip_port->ip.ip.v4.uint32 = net_htonl(0x7F000003); // 127.0.0.3
|
||||
@ -1797,7 +1803,6 @@ int32_t net_getipport(const char *node, IP_Port **res, int tox_type)
|
||||
// It's not an IP address, so now we try doing a DNS lookup.
|
||||
struct addrinfo *infos;
|
||||
const int ret = getaddrinfo(node, nullptr, nullptr, &infos);
|
||||
*res = nullptr;
|
||||
|
||||
if (ret != 0) {
|
||||
return -1;
|
||||
@ -1827,7 +1832,7 @@ int32_t net_getipport(const char *node, IP_Port **res, int tox_type)
|
||||
return 0;
|
||||
}
|
||||
|
||||
*res = (IP_Port *)calloc(count, sizeof(IP_Port));
|
||||
*res = (IP_Port *)mem_valloc(mem, count, sizeof(IP_Port));
|
||||
|
||||
if (*res == nullptr) {
|
||||
freeaddrinfo(infos);
|
||||
@ -1869,9 +1874,9 @@ int32_t net_getipport(const char *node, IP_Port **res, int tox_type)
|
||||
return count;
|
||||
}
|
||||
|
||||
void net_freeipport(IP_Port *ip_ports)
|
||||
void net_freeipport(const Memory *mem, IP_Port *ip_ports)
|
||||
{
|
||||
free(ip_ports);
|
||||
mem_delete(mem, ip_ports);
|
||||
}
|
||||
|
||||
bool bind_to_port(const Network *ns, Socket sock, Family family, uint16_t port)
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <stdint.h> // uint*_t
|
||||
|
||||
#include "logger.h"
|
||||
#include "mem.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -533,7 +534,7 @@ void networking_poll(const Networking_Core *net, void *userdata);
|
||||
* Return false on failure.
|
||||
*/
|
||||
non_null()
|
||||
bool net_connect(const Logger *log, Socket sock, const IP_Port *ip_port);
|
||||
bool net_connect(const Memory *mem, const Logger *log, Socket sock, const IP_Port *ip_port);
|
||||
|
||||
/** @brief High-level getaddrinfo implementation.
|
||||
*
|
||||
@ -549,11 +550,11 @@ bool net_connect(const Logger *log, Socket sock, const IP_Port *ip_port);
|
||||
* @retval -1 on error.
|
||||
*/
|
||||
non_null()
|
||||
int32_t net_getipport(const char *node, IP_Port **res, int tox_type);
|
||||
int32_t net_getipport(const Memory *mem, const char *node, IP_Port **res, int tox_type);
|
||||
|
||||
/** Deallocates memory allocated by net_getipport */
|
||||
nullable(1)
|
||||
void net_freeipport(IP_Port *ip_ports);
|
||||
non_null(1) nullable(2)
|
||||
void net_freeipport(const Memory *mem, IP_Port *ip_ports);
|
||||
|
||||
/**
|
||||
* @return true on success, false on failure.
|
||||
@ -600,13 +601,13 @@ void net_kill_strerror(char *strerror);
|
||||
*
|
||||
* If error is non NULL it is set to 0 if no issues, 1 if socket related error, 2 if other.
|
||||
*/
|
||||
non_null(1, 2, 3) nullable(6)
|
||||
non_null(1, 2, 3, 4) nullable(7)
|
||||
Networking_Core *new_networking_ex(
|
||||
const Logger *log, const Network *ns, const IP *ip,
|
||||
const Logger *log, const Memory *mem, const Network *ns, const IP *ip,
|
||||
uint16_t port_from, uint16_t port_to, unsigned int *error);
|
||||
|
||||
non_null()
|
||||
Networking_Core *new_networking_no_udp(const Logger *log, const Network *ns);
|
||||
Networking_Core *new_networking_no_udp(const Logger *log, const Memory *mem, const Network *ns);
|
||||
|
||||
/** Function to cleanup networking stuff (doesn't do much right now). */
|
||||
nullable(1)
|
||||
|
@ -668,13 +668,13 @@ void set_callback_handle_recv_1(Onion *onion, onion_recv_1_cb *function, void *o
|
||||
onion->callback_object = object;
|
||||
}
|
||||
|
||||
Onion *new_onion(const Logger *log, const Mono_Time *mono_time, const Random *rng, DHT *dht)
|
||||
Onion *new_onion(const Logger *log, const Memory *mem, const Mono_Time *mono_time, const Random *rng, DHT *dht)
|
||||
{
|
||||
if (dht == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Onion *onion = (Onion *)calloc(1, sizeof(Onion));
|
||||
Onion *onion = (Onion *)mem_alloc(mem, sizeof(Onion));
|
||||
|
||||
if (onion == nullptr) {
|
||||
return nullptr;
|
||||
@ -685,13 +685,14 @@ Onion *new_onion(const Logger *log, const Mono_Time *mono_time, const Random *rn
|
||||
onion->net = dht_get_net(dht);
|
||||
onion->mono_time = mono_time;
|
||||
onion->rng = rng;
|
||||
onion->mem = mem;
|
||||
new_symmetric_key(rng, onion->secret_symmetric_key);
|
||||
onion->timestamp = mono_time_get(onion->mono_time);
|
||||
|
||||
const uint8_t *secret_key = dht_get_self_secret_key(dht);
|
||||
onion->shared_keys_1 = shared_key_cache_new(mono_time, secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT);
|
||||
onion->shared_keys_2 = shared_key_cache_new(mono_time, secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT);
|
||||
onion->shared_keys_3 = shared_key_cache_new(mono_time, secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT);
|
||||
onion->shared_keys_1 = shared_key_cache_new(mono_time, mem, secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT);
|
||||
onion->shared_keys_2 = shared_key_cache_new(mono_time, mem, secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT);
|
||||
onion->shared_keys_3 = shared_key_cache_new(mono_time, mem, secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT);
|
||||
|
||||
if (onion->shared_keys_1 == nullptr ||
|
||||
onion->shared_keys_2 == nullptr ||
|
||||
@ -732,5 +733,5 @@ void kill_onion(Onion *onion)
|
||||
shared_key_cache_free(onion->shared_keys_2);
|
||||
shared_key_cache_free(onion->shared_keys_3);
|
||||
|
||||
free(onion);
|
||||
mem_delete(onion->mem, onion);
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ typedef struct Onion {
|
||||
const Logger *log;
|
||||
const Mono_Time *mono_time;
|
||||
const Random *rng;
|
||||
const Memory *mem;
|
||||
DHT *dht;
|
||||
Networking_Core *net;
|
||||
uint8_t secret_symmetric_key[CRYPTO_SYMMETRIC_KEY_SIZE];
|
||||
@ -147,7 +148,7 @@ non_null(1) nullable(2, 3)
|
||||
void set_callback_handle_recv_1(Onion *onion, onion_recv_1_cb *function, void *object);
|
||||
|
||||
non_null()
|
||||
Onion *new_onion(const Logger *log, const Mono_Time *mono_time, const Random *rng, DHT *dht);
|
||||
Onion *new_onion(const Logger *log, const Memory *mem, const Mono_Time *mono_time, const Random *rng, DHT *dht);
|
||||
|
||||
nullable(1)
|
||||
void kill_onion(Onion *onion);
|
||||
|
@ -51,6 +51,7 @@ struct Onion_Announce {
|
||||
const Logger *log;
|
||||
const Mono_Time *mono_time;
|
||||
const Random *rng;
|
||||
const Memory *mem;
|
||||
DHT *dht;
|
||||
Networking_Core *net;
|
||||
Onion_Announce_Entry entries[ONION_ANNOUNCE_MAX_ENTRIES];
|
||||
@ -316,12 +317,13 @@ static int cmp_entry(const void *a, const void *b)
|
||||
}
|
||||
|
||||
non_null()
|
||||
static void sort_onion_announce_list(Onion_Announce_Entry *list, unsigned int length, const Mono_Time *mono_time,
|
||||
static void sort_onion_announce_list(const Memory *mem, const Mono_Time *mono_time,
|
||||
Onion_Announce_Entry *list, 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.
|
||||
Cmp_Data *cmp_list = (Cmp_Data *)calloc(length, sizeof(Cmp_Data));
|
||||
Cmp_Data *cmp_list = (Cmp_Data *)mem_valloc(mem, length, sizeof(Cmp_Data));
|
||||
|
||||
if (cmp_list == nullptr) {
|
||||
return;
|
||||
@ -339,7 +341,7 @@ static void sort_onion_announce_list(Onion_Announce_Entry *list, unsigned int le
|
||||
list[i] = cmp_list[i].entry;
|
||||
}
|
||||
|
||||
free(cmp_list);
|
||||
mem_delete(mem, cmp_list);
|
||||
}
|
||||
|
||||
/** @brief add entry to entries list
|
||||
@ -377,7 +379,8 @@ static int add_to_entries(Onion_Announce *onion_a, const IP_Port *ret_ip_port, c
|
||||
memcpy(onion_a->entries[pos].data_public_key, data_public_key, CRYPTO_PUBLIC_KEY_SIZE);
|
||||
onion_a->entries[pos].announce_time = mono_time_get(onion_a->mono_time);
|
||||
|
||||
sort_onion_announce_list(onion_a->entries, ONION_ANNOUNCE_MAX_ENTRIES, onion_a->mono_time,
|
||||
sort_onion_announce_list(onion_a->mem, onion_a->mono_time,
|
||||
onion_a->entries, ONION_ANNOUNCE_MAX_ENTRIES,
|
||||
dht_get_self_public_key(onion_a->dht));
|
||||
return in_entries(onion_a, public_key);
|
||||
}
|
||||
@ -438,7 +441,7 @@ static int handle_announce_request_common(
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t *plain = (uint8_t *)malloc(plain_size);
|
||||
uint8_t *plain = (uint8_t *)mem_balloc(onion_a->mem, plain_size);
|
||||
|
||||
if (plain == nullptr) {
|
||||
return 1;
|
||||
@ -448,7 +451,7 @@ static int handle_announce_request_common(
|
||||
packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE, plain_size + CRYPTO_MAC_SIZE, plain);
|
||||
|
||||
if ((uint32_t)decrypted_len != plain_size) {
|
||||
free(plain);
|
||||
mem_delete(onion_a->mem, plain);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -483,10 +486,10 @@ static int handle_announce_request_common(
|
||||
const uint16_t response_size = nodes_offset
|
||||
+ MAX_SENT_NODES * PACKED_NODE_SIZE_IP6
|
||||
+ max_extra_size;
|
||||
uint8_t *response = (uint8_t *)malloc(response_size);
|
||||
uint8_t *response = (uint8_t *)mem_balloc(onion_a->mem, response_size);
|
||||
|
||||
if (response == nullptr) {
|
||||
free(plain);
|
||||
mem_delete(onion_a->mem, plain);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -504,8 +507,8 @@ static int handle_announce_request_common(
|
||||
|
||||
if (nodes_length <= 0) {
|
||||
LOGGER_WARNING(onion_a->log, "Failed to pack nodes");
|
||||
free(response);
|
||||
free(plain);
|
||||
mem_delete(onion_a->mem, response);
|
||||
mem_delete(onion_a->mem, plain);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@ -523,8 +526,8 @@ static int handle_announce_request_common(
|
||||
response, response_size, offset);
|
||||
|
||||
if (extra_size == -1) {
|
||||
free(response);
|
||||
free(plain);
|
||||
mem_delete(onion_a->mem, response);
|
||||
mem_delete(onion_a->mem, plain);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -536,8 +539,8 @@ static int handle_announce_request_common(
|
||||
|
||||
if (len != offset + CRYPTO_MAC_SIZE) {
|
||||
LOGGER_ERROR(onion_a->log, "Failed to encrypt announce response");
|
||||
free(response);
|
||||
free(plain);
|
||||
mem_delete(onion_a->mem, response);
|
||||
mem_delete(onion_a->mem, plain);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -549,13 +552,13 @@ static int handle_announce_request_common(
|
||||
if (send_onion_response(onion_a->net, source, data,
|
||||
1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE + len,
|
||||
packet + (length - ONION_RETURN_3)) == -1) {
|
||||
free(response);
|
||||
free(plain);
|
||||
mem_delete(onion_a->mem, response);
|
||||
mem_delete(onion_a->mem, plain);
|
||||
return 1;
|
||||
}
|
||||
|
||||
free(response);
|
||||
free(plain);
|
||||
mem_delete(onion_a->mem, response);
|
||||
mem_delete(onion_a->mem, plain);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -639,13 +642,13 @@ static int handle_data_request(void *object, const IP_Port *source, const uint8_
|
||||
return 0;
|
||||
}
|
||||
|
||||
Onion_Announce *new_onion_announce(const Logger *log, const Random *rng, const Mono_Time *mono_time, DHT *dht)
|
||||
Onion_Announce *new_onion_announce(const Logger *log, const Memory *mem, const Random *rng, const Mono_Time *mono_time, DHT *dht)
|
||||
{
|
||||
if (dht == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Onion_Announce *onion_a = (Onion_Announce *)calloc(1, sizeof(Onion_Announce));
|
||||
Onion_Announce *onion_a = (Onion_Announce *)mem_alloc(mem, sizeof(Onion_Announce));
|
||||
|
||||
if (onion_a == nullptr) {
|
||||
return nullptr;
|
||||
@ -653,6 +656,7 @@ Onion_Announce *new_onion_announce(const Logger *log, const Random *rng, const M
|
||||
|
||||
onion_a->log = log;
|
||||
onion_a->rng = rng;
|
||||
onion_a->mem = mem;
|
||||
onion_a->mono_time = mono_time;
|
||||
onion_a->dht = dht;
|
||||
onion_a->net = dht_get_net(dht);
|
||||
@ -661,7 +665,7 @@ Onion_Announce *new_onion_announce(const Logger *log, const Random *rng, const M
|
||||
onion_a->extra_data_object = nullptr;
|
||||
new_hmac_key(rng, onion_a->hmac_key);
|
||||
|
||||
onion_a->shared_keys_recv = shared_key_cache_new(mono_time, dht_get_self_secret_key(dht), KEYS_TIMEOUT, MAX_KEYS_PER_SLOT);
|
||||
onion_a->shared_keys_recv = shared_key_cache_new(mono_time, mem, dht_get_self_secret_key(dht), KEYS_TIMEOUT, MAX_KEYS_PER_SLOT);
|
||||
if (onion_a->shared_keys_recv == nullptr) {
|
||||
kill_onion_announce(onion_a);
|
||||
return nullptr;
|
||||
@ -687,5 +691,5 @@ void kill_onion_announce(Onion_Announce *onion_a)
|
||||
crypto_memzero(onion_a->hmac_key, CRYPTO_HMAC_KEY_SIZE);
|
||||
shared_key_cache_free(onion_a->shared_keys_recv);
|
||||
|
||||
free(onion_a);
|
||||
mem_delete(onion_a->mem, onion_a);
|
||||
}
|
||||
|
@ -131,7 +131,7 @@ void onion_announce_extra_data_callback(Onion_Announce *onion_a, uint16_t extra_
|
||||
pack_extra_data_cb *extra_data_callback, void *extra_data_object);
|
||||
|
||||
non_null()
|
||||
Onion_Announce *new_onion_announce(const Logger *log, const Random *rng, const Mono_Time *mono_time, DHT *dht);
|
||||
Onion_Announce *new_onion_announce(const Logger *log, const Memory *mem, const Random *rng, const Mono_Time *mono_time, DHT *dht);
|
||||
|
||||
nullable(1)
|
||||
void kill_onion_announce(Onion_Announce *onion_a);
|
||||
|
@ -106,6 +106,7 @@ struct Onion_Client {
|
||||
const Mono_Time *mono_time;
|
||||
const Logger *logger;
|
||||
const Random *rng;
|
||||
const Memory *mem;
|
||||
|
||||
DHT *dht;
|
||||
Net_Crypto *c;
|
||||
@ -731,12 +732,12 @@ static int onion_client_cmp_entry(const void *a, const void *b)
|
||||
}
|
||||
|
||||
non_null()
|
||||
static void sort_onion_node_list(Onion_Node *list, unsigned int length, const Mono_Time *mono_time,
|
||||
const uint8_t *comp_public_key)
|
||||
static void sort_onion_node_list(const Memory *mem, const Mono_Time *mono_time,
|
||||
Onion_Node *list, 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.
|
||||
Onion_Client_Cmp_Data *cmp_list = (Onion_Client_Cmp_Data *)calloc(length, sizeof(Onion_Client_Cmp_Data));
|
||||
Onion_Client_Cmp_Data *cmp_list = (Onion_Client_Cmp_Data *)mem_valloc(mem, length, sizeof(Onion_Client_Cmp_Data));
|
||||
|
||||
if (cmp_list == nullptr) {
|
||||
return;
|
||||
@ -754,7 +755,7 @@ static void sort_onion_node_list(Onion_Node *list, unsigned int length, const Mo
|
||||
list[i] = cmp_list[i].entry;
|
||||
}
|
||||
|
||||
free(cmp_list);
|
||||
mem_delete(mem, cmp_list);
|
||||
}
|
||||
|
||||
non_null()
|
||||
@ -787,7 +788,7 @@ 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(node_list, list_length, onion_c->mono_time, reference_id);
|
||||
sort_onion_node_list(onion_c->mem, onion_c->mono_time, node_list, list_length, reference_id);
|
||||
|
||||
int index = -1;
|
||||
bool stored = false;
|
||||
@ -1161,7 +1162,7 @@ static int handle_dhtpk_announce(void *object, const uint8_t *source_pubkey, con
|
||||
onion_c->friends_list[friend_num].dht_pk_callback_number, data + 1 + sizeof(uint64_t), userdata);
|
||||
}
|
||||
|
||||
onion_set_friend_DHT_pubkey(onion_c, friend_num, data + 1 + sizeof(uint64_t));
|
||||
onion_set_friend_dht_pubkey(onion_c, friend_num, data + 1 + sizeof(uint64_t));
|
||||
|
||||
const uint16_t len_nodes = length - DHTPK_DATA_MIN_LENGTH;
|
||||
|
||||
@ -1457,19 +1458,19 @@ int onion_friend_num(const Onion_Client *onion_c, const uint8_t *public_key)
|
||||
|
||||
/** @brief Set the size of the friend list to num.
|
||||
*
|
||||
* @retval -1 if realloc fails.
|
||||
* @retval -1 if mem_vrealloc fails.
|
||||
* @retval 0 if it succeeds.
|
||||
*/
|
||||
non_null()
|
||||
static int realloc_onion_friends(Onion_Client *onion_c, uint32_t num)
|
||||
{
|
||||
if (num == 0) {
|
||||
free(onion_c->friends_list);
|
||||
mem_delete(onion_c->mem, onion_c->friends_list);
|
||||
onion_c->friends_list = nullptr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Onion_Friend *newonion_friends = (Onion_Friend *)realloc(onion_c->friends_list, num * sizeof(Onion_Friend));
|
||||
Onion_Friend *newonion_friends = (Onion_Friend *)mem_vrealloc(onion_c->mem, onion_c->friends_list, num, sizeof(Onion_Friend));
|
||||
|
||||
if (newonion_friends == nullptr) {
|
||||
return -1;
|
||||
@ -1601,7 +1602,7 @@ int onion_dht_pk_callback(Onion_Client *onion_c, int friend_num,
|
||||
* return -1 on failure.
|
||||
* return 0 on success.
|
||||
*/
|
||||
int onion_set_friend_DHT_pubkey(Onion_Client *onion_c, int friend_num, const uint8_t *dht_key)
|
||||
int onion_set_friend_dht_pubkey(Onion_Client *onion_c, int friend_num, const uint8_t *dht_key)
|
||||
{
|
||||
if ((uint32_t)friend_num >= onion_c->num_friends) {
|
||||
return -1;
|
||||
@ -1628,7 +1629,7 @@ int onion_set_friend_DHT_pubkey(Onion_Client *onion_c, int friend_num, const uin
|
||||
* return 0 on failure (no key copied).
|
||||
* return 1 on success (key copied).
|
||||
*/
|
||||
unsigned int onion_getfriend_DHT_pubkey(const Onion_Client *onion_c, int friend_num, uint8_t *dht_key)
|
||||
unsigned int onion_getfriend_dht_pubkey(const Onion_Client *onion_c, int friend_num, uint8_t *dht_key)
|
||||
{
|
||||
if ((uint32_t)friend_num >= onion_c->num_friends) {
|
||||
return 0;
|
||||
@ -1656,7 +1657,7 @@ int onion_getfriendip(const Onion_Client *onion_c, int friend_num, IP_Port *ip_p
|
||||
{
|
||||
uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE];
|
||||
|
||||
if (onion_getfriend_DHT_pubkey(onion_c, friend_num, dht_public_key) == 0) {
|
||||
if (onion_getfriend_dht_pubkey(onion_c, friend_num, dht_public_key) == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -2074,28 +2075,29 @@ void do_onion_client(Onion_Client *onion_c)
|
||||
onion_c->last_run = mono_time_get(onion_c->mono_time);
|
||||
}
|
||||
|
||||
Onion_Client *new_onion_client(const Logger *logger, const Random *rng, const Mono_Time *mono_time, Net_Crypto *c)
|
||||
Onion_Client *new_onion_client(const Logger *logger, const Memory *mem, const Random *rng, const Mono_Time *mono_time, Net_Crypto *c)
|
||||
{
|
||||
if (c == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Onion_Client *onion_c = (Onion_Client *)calloc(1, sizeof(Onion_Client));
|
||||
Onion_Client *onion_c = (Onion_Client *)mem_alloc(mem, sizeof(Onion_Client));
|
||||
|
||||
if (onion_c == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
onion_c->announce_ping_array = ping_array_new(ANNOUNCE_ARRAY_SIZE, ANNOUNCE_TIMEOUT);
|
||||
onion_c->announce_ping_array = ping_array_new(mem, ANNOUNCE_ARRAY_SIZE, ANNOUNCE_TIMEOUT);
|
||||
|
||||
if (onion_c->announce_ping_array == nullptr) {
|
||||
free(onion_c);
|
||||
mem_delete(mem, onion_c);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
onion_c->mono_time = mono_time;
|
||||
onion_c->logger = logger;
|
||||
onion_c->rng = rng;
|
||||
onion_c->mem = mem;
|
||||
onion_c->dht = nc_get_dht(c);
|
||||
onion_c->net = dht_get_net(onion_c->dht);
|
||||
onion_c->c = c;
|
||||
@ -2117,6 +2119,8 @@ void kill_onion_client(Onion_Client *onion_c)
|
||||
return;
|
||||
}
|
||||
|
||||
const Memory *mem = onion_c->mem;
|
||||
|
||||
ping_array_kill(onion_c->announce_ping_array);
|
||||
realloc_onion_friends(onion_c, 0);
|
||||
networking_registerhandler(onion_c->net, NET_PACKET_ANNOUNCE_RESPONSE, nullptr, nullptr);
|
||||
@ -2126,5 +2130,5 @@ void kill_onion_client(Onion_Client *onion_c)
|
||||
cryptopacket_registerhandler(onion_c->dht, CRYPTO_PACKET_DHTPK, nullptr, nullptr);
|
||||
set_onion_packet_tcp_connection_callback(nc_get_tcp_c(onion_c->c), nullptr, nullptr);
|
||||
crypto_memzero(onion_c, sizeof(Onion_Client));
|
||||
free(onion_c);
|
||||
mem_delete(mem, onion_c);
|
||||
}
|
||||
|
@ -165,7 +165,7 @@ int onion_dht_pk_callback(Onion_Client *onion_c, int friend_num, onion_dht_pk_cb
|
||||
* return 0 on success.
|
||||
*/
|
||||
non_null()
|
||||
int onion_set_friend_DHT_pubkey(Onion_Client *onion_c, int friend_num, const uint8_t *dht_key);
|
||||
int onion_set_friend_dht_pubkey(Onion_Client *onion_c, int friend_num, const uint8_t *dht_key);
|
||||
|
||||
/** @brief Copy friends DHT public key into dht_key.
|
||||
*
|
||||
@ -173,7 +173,7 @@ int onion_set_friend_DHT_pubkey(Onion_Client *onion_c, int friend_num, const uin
|
||||
* return 1 on success (key copied).
|
||||
*/
|
||||
non_null()
|
||||
unsigned int onion_getfriend_DHT_pubkey(const Onion_Client *onion_c, int friend_num, uint8_t *dht_key);
|
||||
unsigned int onion_getfriend_dht_pubkey(const Onion_Client *onion_c, int friend_num, uint8_t *dht_key);
|
||||
|
||||
#define ONION_DATA_IN_RESPONSE_MIN_SIZE (CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE)
|
||||
#define ONION_CLIENT_MAX_DATA_SIZE (MAX_DATA_REQUEST_SIZE - ONION_DATA_IN_RESPONSE_MIN_SIZE)
|
||||
@ -208,7 +208,7 @@ non_null()
|
||||
void do_onion_client(Onion_Client *onion_c);
|
||||
|
||||
non_null()
|
||||
Onion_Client *new_onion_client(const Logger *logger, const Random *rng, const Mono_Time *mono_time, Net_Crypto *c);
|
||||
Onion_Client *new_onion_client(const Logger *logger, const Memory *mem, const Random *rng, const Mono_Time *mono_time, Net_Crypto *c);
|
||||
|
||||
nullable(1)
|
||||
void kill_onion_client(Onion_Client *onion_c);
|
||||
|
@ -336,18 +336,18 @@ void ping_iterate(Ping *ping)
|
||||
}
|
||||
|
||||
|
||||
Ping *ping_new(const Mono_Time *mono_time, const Random *rng, DHT *dht)
|
||||
Ping *ping_new(const Memory *mem, const Mono_Time *mono_time, const Random *rng, DHT *dht)
|
||||
{
|
||||
Ping *ping = (Ping *)calloc(1, sizeof(Ping));
|
||||
Ping *ping = (Ping *)mem_alloc(mem, sizeof(Ping));
|
||||
|
||||
if (ping == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ping->ping_array = ping_array_new(PING_NUM_MAX, PING_TIMEOUT);
|
||||
ping->ping_array = ping_array_new(mem, PING_NUM_MAX, PING_TIMEOUT);
|
||||
|
||||
if (ping->ping_array == nullptr) {
|
||||
free(ping);
|
||||
mem_delete(mem, ping);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -360,7 +360,7 @@ Ping *ping_new(const Mono_Time *mono_time, const Random *rng, DHT *dht)
|
||||
return ping;
|
||||
}
|
||||
|
||||
void ping_kill(Ping *ping)
|
||||
void ping_kill(const Memory *mem, Ping *ping)
|
||||
{
|
||||
if (ping == nullptr) {
|
||||
return;
|
||||
@ -370,5 +370,5 @@ void ping_kill(Ping *ping)
|
||||
networking_registerhandler(dht_get_net(ping->dht), NET_PACKET_PING_RESPONSE, nullptr, nullptr);
|
||||
ping_array_kill(ping->ping_array);
|
||||
|
||||
free(ping);
|
||||
mem_delete(mem, ping);
|
||||
}
|
||||
|
@ -18,10 +18,10 @@
|
||||
typedef struct Ping Ping;
|
||||
|
||||
non_null()
|
||||
Ping *ping_new(const Mono_Time *mono_time, const Random *rng, DHT *dht);
|
||||
Ping *ping_new(const Memory *mem, const Mono_Time *mono_time, const Random *rng, DHT *dht);
|
||||
|
||||
nullable(1)
|
||||
void ping_kill(Ping *ping);
|
||||
non_null(1) nullable(2)
|
||||
void ping_kill(const Memory *mem, Ping *ping);
|
||||
|
||||
/** @brief Add nodes to the to_ping list.
|
||||
* All nodes in this list are pinged every TIME_TO_PING seconds
|
||||
|
@ -24,6 +24,7 @@ typedef struct Ping_Array_Entry {
|
||||
} Ping_Array_Entry;
|
||||
|
||||
struct Ping_Array {
|
||||
const Memory *mem;
|
||||
Ping_Array_Entry *entries;
|
||||
|
||||
uint32_t last_deleted; /* number representing the next entry to be deleted. */
|
||||
@ -32,7 +33,7 @@ struct Ping_Array {
|
||||
uint32_t timeout; /* The timeout after which entries are cleared. */
|
||||
};
|
||||
|
||||
Ping_Array *ping_array_new(uint32_t size, uint32_t timeout)
|
||||
Ping_Array *ping_array_new(const Memory *mem, uint32_t size, uint32_t timeout)
|
||||
{
|
||||
if (size == 0 || timeout == 0) {
|
||||
return nullptr;
|
||||
@ -43,16 +44,17 @@ Ping_Array *ping_array_new(uint32_t size, uint32_t timeout)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Ping_Array *const empty_array = (Ping_Array *)calloc(1, sizeof(Ping_Array));
|
||||
Ping_Array *const empty_array = (Ping_Array *)mem_alloc(mem, sizeof(Ping_Array));
|
||||
|
||||
if (empty_array == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
empty_array->entries = (Ping_Array_Entry *)calloc(size, sizeof(Ping_Array_Entry));
|
||||
empty_array->mem = mem;
|
||||
empty_array->entries = (Ping_Array_Entry *)mem_valloc(mem, size, sizeof(Ping_Array_Entry));
|
||||
|
||||
if (empty_array->entries == nullptr) {
|
||||
free(empty_array);
|
||||
mem_delete(mem, empty_array);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -67,7 +69,7 @@ non_null()
|
||||
static void clear_entry(Ping_Array *array, uint32_t index)
|
||||
{
|
||||
const Ping_Array_Entry empty = {nullptr};
|
||||
free(array->entries[index].data);
|
||||
mem_delete(array->mem, array->entries[index].data);
|
||||
array->entries[index] = empty;
|
||||
}
|
||||
|
||||
@ -83,8 +85,8 @@ void ping_array_kill(Ping_Array *array)
|
||||
++array->last_deleted;
|
||||
}
|
||||
|
||||
free(array->entries);
|
||||
free(array);
|
||||
mem_delete(array->mem, array->entries);
|
||||
mem_delete(array->mem, array);
|
||||
}
|
||||
|
||||
/** Clear timed out entries. */
|
||||
@ -114,7 +116,7 @@ uint64_t ping_array_add(Ping_Array *array, const Mono_Time *mono_time, const Ran
|
||||
clear_entry(array, index);
|
||||
}
|
||||
|
||||
array->entries[index].data = (uint8_t *)malloc(length);
|
||||
array->entries[index].data = (uint8_t *)mem_balloc(array->mem, length);
|
||||
|
||||
if (array->entries[index].data == nullptr) {
|
||||
return 0;
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "crypto_core.h"
|
||||
#include "mem.h"
|
||||
#include "mono_time.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -29,7 +30,8 @@ typedef struct Ping_Array Ping_Array;
|
||||
*
|
||||
* @return pointer to allocated Ping_Array on success, nullptr on failure.
|
||||
*/
|
||||
struct Ping_Array *ping_array_new(uint32_t size, uint32_t timeout);
|
||||
non_null()
|
||||
struct Ping_Array *ping_array_new(const Memory *mem, uint32_t size, uint32_t timeout);
|
||||
|
||||
/**
|
||||
* @brief Free all the allocated memory in a @ref Ping_Array.
|
||||
|
@ -15,41 +15,54 @@ struct Ping_Array_Deleter {
|
||||
using Ping_Array_Ptr = std::unique_ptr<Ping_Array, Ping_Array_Deleter>;
|
||||
|
||||
struct Mono_Time_Deleter {
|
||||
void operator()(Mono_Time *arr) { mono_time_free(arr); }
|
||||
Mono_Time_Deleter(const Memory *mem)
|
||||
: mem_(mem)
|
||||
{
|
||||
}
|
||||
void operator()(Mono_Time *arr) { mono_time_free(mem_, arr); }
|
||||
|
||||
private:
|
||||
const Memory *mem_;
|
||||
};
|
||||
|
||||
using Mono_Time_Ptr = std::unique_ptr<Mono_Time, Mono_Time_Deleter>;
|
||||
|
||||
TEST(PingArray, MinimumTimeoutIsOne)
|
||||
{
|
||||
EXPECT_EQ(ping_array_new(1, 0), nullptr);
|
||||
EXPECT_NE(Ping_Array_Ptr(ping_array_new(1, 1)), nullptr);
|
||||
const Memory *mem = system_memory();
|
||||
EXPECT_EQ(ping_array_new(mem, 1, 0), nullptr);
|
||||
EXPECT_NE(Ping_Array_Ptr(ping_array_new(mem, 1, 1)), nullptr);
|
||||
}
|
||||
|
||||
TEST(PingArray, MinimumArraySizeIsOne)
|
||||
{
|
||||
EXPECT_EQ(ping_array_new(0, 1), nullptr);
|
||||
EXPECT_NE(Ping_Array_Ptr(ping_array_new(1, 1)), nullptr);
|
||||
const Memory *mem = system_memory();
|
||||
EXPECT_EQ(ping_array_new(mem, 0, 1), nullptr);
|
||||
EXPECT_NE(Ping_Array_Ptr(ping_array_new(mem, 1, 1)), nullptr);
|
||||
}
|
||||
|
||||
TEST(PingArray, ArraySizeMustBePowerOfTwo)
|
||||
{
|
||||
const Memory *mem = system_memory();
|
||||
|
||||
Ping_Array_Ptr arr;
|
||||
arr.reset(ping_array_new(2, 1));
|
||||
arr.reset(ping_array_new(mem, 2, 1));
|
||||
EXPECT_NE(arr, nullptr);
|
||||
arr.reset(ping_array_new(4, 1));
|
||||
arr.reset(ping_array_new(mem, 4, 1));
|
||||
EXPECT_NE(arr, nullptr);
|
||||
arr.reset(ping_array_new(1024, 1));
|
||||
arr.reset(ping_array_new(mem, 1024, 1));
|
||||
EXPECT_NE(arr, nullptr);
|
||||
|
||||
EXPECT_EQ(ping_array_new(1023, 1), nullptr);
|
||||
EXPECT_EQ(ping_array_new(1234, 1), nullptr);
|
||||
EXPECT_EQ(ping_array_new(mem, 1023, 1), nullptr);
|
||||
EXPECT_EQ(ping_array_new(mem, 1234, 1), nullptr);
|
||||
}
|
||||
|
||||
TEST(PingArray, StoredDataCanBeRetrieved)
|
||||
{
|
||||
Ping_Array_Ptr const arr(ping_array_new(2, 1));
|
||||
Mono_Time_Ptr const mono_time(mono_time_new(nullptr, nullptr));
|
||||
const Memory *mem = system_memory();
|
||||
|
||||
Ping_Array_Ptr const arr(ping_array_new(mem, 2, 1));
|
||||
Mono_Time_Ptr const mono_time(mono_time_new(mem, nullptr, nullptr), mem);
|
||||
ASSERT_NE(mono_time, nullptr);
|
||||
const Random *rng = system_random();
|
||||
ASSERT_NE(rng, nullptr);
|
||||
@ -65,8 +78,10 @@ TEST(PingArray, StoredDataCanBeRetrieved)
|
||||
|
||||
TEST(PingArray, RetrievingDataWithTooSmallOutputBufferHasNoEffect)
|
||||
{
|
||||
Ping_Array_Ptr const arr(ping_array_new(2, 1));
|
||||
Mono_Time_Ptr const mono_time(mono_time_new(nullptr, nullptr));
|
||||
const Memory *mem = system_memory();
|
||||
|
||||
Ping_Array_Ptr const arr(ping_array_new(mem, 2, 1));
|
||||
Mono_Time_Ptr const mono_time(mono_time_new(mem, nullptr, nullptr), mem);
|
||||
ASSERT_NE(mono_time, nullptr);
|
||||
const Random *rng = system_random();
|
||||
ASSERT_NE(rng, nullptr);
|
||||
@ -86,8 +101,10 @@ TEST(PingArray, RetrievingDataWithTooSmallOutputBufferHasNoEffect)
|
||||
|
||||
TEST(PingArray, ZeroLengthDataCanBeAdded)
|
||||
{
|
||||
Ping_Array_Ptr const arr(ping_array_new(2, 1));
|
||||
Mono_Time_Ptr const mono_time(mono_time_new(nullptr, nullptr));
|
||||
const Memory *mem = system_memory();
|
||||
|
||||
Ping_Array_Ptr const arr(ping_array_new(mem, 2, 1));
|
||||
Mono_Time_Ptr const mono_time(mono_time_new(mem, nullptr, nullptr), mem);
|
||||
ASSERT_NE(mono_time, nullptr);
|
||||
const Random *rng = system_random();
|
||||
ASSERT_NE(rng, nullptr);
|
||||
@ -101,8 +118,10 @@ TEST(PingArray, ZeroLengthDataCanBeAdded)
|
||||
|
||||
TEST(PingArray, PingId0IsInvalid)
|
||||
{
|
||||
Ping_Array_Ptr const arr(ping_array_new(2, 1));
|
||||
Mono_Time_Ptr const mono_time(mono_time_new(nullptr, nullptr));
|
||||
const Memory *mem = system_memory();
|
||||
|
||||
Ping_Array_Ptr const arr(ping_array_new(mem, 2, 1));
|
||||
Mono_Time_Ptr const mono_time(mono_time_new(mem, nullptr, nullptr), mem);
|
||||
ASSERT_NE(mono_time, nullptr);
|
||||
|
||||
uint8_t c = 0;
|
||||
@ -112,8 +131,10 @@ TEST(PingArray, PingId0IsInvalid)
|
||||
// Protection against replay attacks.
|
||||
TEST(PingArray, DataCanOnlyBeRetrievedOnce)
|
||||
{
|
||||
Ping_Array_Ptr const arr(ping_array_new(2, 1));
|
||||
Mono_Time_Ptr const mono_time(mono_time_new(nullptr, nullptr));
|
||||
const Memory *mem = system_memory();
|
||||
|
||||
Ping_Array_Ptr const arr(ping_array_new(mem, 2, 1));
|
||||
Mono_Time_Ptr const mono_time(mono_time_new(mem, nullptr, nullptr), mem);
|
||||
ASSERT_NE(mono_time, nullptr);
|
||||
const Random *rng = system_random();
|
||||
ASSERT_NE(rng, nullptr);
|
||||
@ -128,8 +149,10 @@ TEST(PingArray, DataCanOnlyBeRetrievedOnce)
|
||||
|
||||
TEST(PingArray, PingIdMustMatchOnCheck)
|
||||
{
|
||||
Ping_Array_Ptr const arr(ping_array_new(1, 1));
|
||||
Mono_Time_Ptr const mono_time(mono_time_new(nullptr, nullptr));
|
||||
const Memory *mem = system_memory();
|
||||
|
||||
Ping_Array_Ptr const arr(ping_array_new(mem, 1, 1));
|
||||
Mono_Time_Ptr const mono_time(mono_time_new(mem, nullptr, nullptr), mem);
|
||||
ASSERT_NE(mono_time, nullptr);
|
||||
const Random *rng = system_random();
|
||||
ASSERT_NE(rng, nullptr);
|
||||
|
@ -6,7 +6,6 @@
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h> // calloc(...)
|
||||
#include <string.h> // memcpy(...)
|
||||
|
||||
#include "ccompat.h"
|
||||
@ -23,7 +22,8 @@ struct Shared_Key_Cache {
|
||||
Shared_Key *keys;
|
||||
const uint8_t* self_secret_key;
|
||||
uint64_t timeout; /** After this time (in seconds), a key is erased on the next housekeeping cycle */
|
||||
const Mono_Time *time;
|
||||
const Mono_Time *mono_time;
|
||||
const Memory *mem;
|
||||
uint8_t keys_per_slot;
|
||||
};
|
||||
|
||||
@ -43,37 +43,38 @@ static void shared_key_set_empty(Shared_Key *k) {
|
||||
assert(shared_key_is_empty(k));
|
||||
}
|
||||
|
||||
Shared_Key_Cache *shared_key_cache_new(const Mono_Time *time, const uint8_t *self_secret_key, uint64_t timeout, uint8_t keys_per_slot)
|
||||
Shared_Key_Cache *shared_key_cache_new(const Mono_Time *mono_time, const Memory *mem, const uint8_t *self_secret_key, uint64_t timeout, uint8_t keys_per_slot)
|
||||
{
|
||||
if (time == nullptr || self_secret_key == nullptr || timeout == 0 || keys_per_slot == 0) {
|
||||
if (mono_time == nullptr || self_secret_key == nullptr || timeout == 0 || keys_per_slot == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Time must not be zero, since we use that as special value for empty slots
|
||||
if (mono_time_get(time) == 0) {
|
||||
if (mono_time_get(mono_time) == 0) {
|
||||
// Fail loudly in debug environments
|
||||
assert(false);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Shared_Key_Cache *res = (Shared_Key_Cache *)calloc(1, sizeof (Shared_Key_Cache));
|
||||
Shared_Key_Cache *res = (Shared_Key_Cache *)mem_alloc(mem, sizeof(Shared_Key_Cache));
|
||||
if (res == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
res->self_secret_key = self_secret_key;
|
||||
res->time = time;
|
||||
res->mono_time = mono_time;
|
||||
res->mem = mem;
|
||||
res->keys_per_slot = keys_per_slot;
|
||||
// We take one byte from the public key for each bucket and store keys_per_slot elements there
|
||||
const size_t cache_size = 256 * keys_per_slot;
|
||||
res->keys = (Shared_Key *)calloc(cache_size, sizeof (Shared_Key));
|
||||
res->keys = (Shared_Key *)mem_valloc(mem, cache_size, sizeof(Shared_Key));
|
||||
|
||||
if (res->keys == nullptr) {
|
||||
free(res);
|
||||
mem_delete(mem, res);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
crypto_memlock(res->keys, cache_size * sizeof (Shared_Key));
|
||||
crypto_memlock(res->keys, cache_size * sizeof(Shared_Key));
|
||||
|
||||
return res;
|
||||
}
|
||||
@ -88,15 +89,15 @@ void shared_key_cache_free(Shared_Key_Cache *cache)
|
||||
// Don't leave key material in memory
|
||||
crypto_memzero(cache->keys, cache_size * sizeof (Shared_Key));
|
||||
crypto_memunlock(cache->keys, cache_size * sizeof (Shared_Key));
|
||||
free(cache->keys);
|
||||
free(cache);
|
||||
mem_delete(cache->mem, cache->keys);
|
||||
mem_delete(cache->mem, cache);
|
||||
}
|
||||
|
||||
/* NOTE: On each lookup housekeeping is performed to evict keys that did timeout. */
|
||||
const uint8_t *shared_key_cache_lookup(Shared_Key_Cache *cache, const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE])
|
||||
{
|
||||
// caching the time is not necessary, but calls to mono_time_get(...) are not free
|
||||
const uint64_t cur_time = mono_time_get(cache->time);
|
||||
const uint64_t cur_time = mono_time_get(cache->mono_time);
|
||||
// We can't use the first and last bytes because they are masked in curve25519. Selected 8 for good alignment.
|
||||
const uint8_t bucket_idx = public_key[8];
|
||||
Shared_Key* bucket_start = &cache->keys[bucket_idx*cache->keys_per_slot];
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <stdint.h> // uint*_t
|
||||
|
||||
#include "crypto_core.h"
|
||||
#include "mem.h"
|
||||
#include "mono_time.h"
|
||||
|
||||
/**
|
||||
@ -18,7 +19,7 @@ typedef struct Shared_Key_Cache Shared_Key_Cache;
|
||||
|
||||
/**
|
||||
* @brief Initializes a new shared key cache.
|
||||
* @param time Time object for retrieving current time.
|
||||
* @param mono_time Time object for retrieving current time.
|
||||
* @param self_secret_key Our own secret key of length CRYPTO_SECRET_KEY_SIZE,
|
||||
* it must not change during the lifetime of the cache.
|
||||
* @param timeout Number of milliseconds, after which a key should be evicted.
|
||||
@ -26,7 +27,7 @@ typedef struct Shared_Key_Cache Shared_Key_Cache;
|
||||
* @return nullptr on error.
|
||||
*/
|
||||
non_null()
|
||||
Shared_Key_Cache *shared_key_cache_new(const Mono_Time *time,
|
||||
Shared_Key_Cache *shared_key_cache_new(const Mono_Time *mono_time, const Memory *mem,
|
||||
const uint8_t *self_secret_key,
|
||||
uint64_t timeout, uint8_t keys_per_slot);
|
||||
|
||||
|
131
toxcore/tox.c
131
toxcore/tox.c
@ -22,6 +22,7 @@
|
||||
#include "group_chats.h"
|
||||
#include "group_moderation.h"
|
||||
#include "logger.h"
|
||||
#include "mem.h"
|
||||
#include "mono_time.h"
|
||||
#include "network.h"
|
||||
#include "tox_private.h"
|
||||
@ -626,18 +627,6 @@ static int tox_load(Tox *tox, const uint8_t *data, uint32_t length)
|
||||
|
||||
Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error)
|
||||
{
|
||||
Tox *tox = (Tox *)calloc(1, sizeof(Tox));
|
||||
|
||||
if (tox == nullptr) {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Messenger_Options m_options = {0};
|
||||
|
||||
bool load_savedata_sk = false;
|
||||
bool load_savedata_tox = false;
|
||||
|
||||
struct Tox_Options *default_options = nullptr;
|
||||
|
||||
if (options == nullptr) {
|
||||
@ -651,7 +640,6 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error)
|
||||
|
||||
case TOX_ERR_OPTIONS_NEW_MALLOC: {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC);
|
||||
free(tox);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
@ -660,11 +648,28 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error)
|
||||
const struct Tox_Options *const opts = options != nullptr ? options : default_options;
|
||||
assert(opts != nullptr);
|
||||
|
||||
const Tox_System *sys = tox_options_get_operating_system(opts);
|
||||
const Tox_System default_system = tox_default_system();
|
||||
|
||||
if (sys == nullptr) {
|
||||
sys = &default_system;
|
||||
}
|
||||
|
||||
if (sys->rng == nullptr || sys->ns == nullptr || sys->mem == nullptr) {
|
||||
// TODO(iphydf): Not quite right, but similar.
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Messenger_Options m_options = {0};
|
||||
|
||||
bool load_savedata_sk = false;
|
||||
bool load_savedata_tox = false;
|
||||
|
||||
if (tox_options_get_savedata_type(opts) != TOX_SAVEDATA_TYPE_NONE) {
|
||||
if (tox_options_get_savedata_data(opts) == nullptr || tox_options_get_savedata_length(opts) == 0) {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_LOAD_BAD_FORMAT);
|
||||
tox_options_free(default_options);
|
||||
free(tox);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
@ -673,7 +678,6 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error)
|
||||
if (tox_options_get_savedata_length(opts) != TOX_SECRET_KEY_SIZE) {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_LOAD_BAD_FORMAT);
|
||||
tox_options_free(default_options);
|
||||
free(tox);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -682,14 +686,12 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error)
|
||||
if (tox_options_get_savedata_length(opts) < TOX_ENC_SAVE_MAGIC_LENGTH) {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_LOAD_BAD_FORMAT);
|
||||
tox_options_free(default_options);
|
||||
free(tox);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (memcmp(tox_options_get_savedata_data(opts), TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) == 0) {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_LOAD_ENCRYPTED);
|
||||
tox_options_free(default_options);
|
||||
free(tox);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -709,6 +711,13 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error)
|
||||
m_options.local_discovery_enabled = false;
|
||||
}
|
||||
|
||||
Tox *tox = (Tox *)mem_alloc(sys->mem, sizeof(Tox));
|
||||
|
||||
if (tox == nullptr) {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
tox->log_callback = tox_options_get_log_callback(opts);
|
||||
m_options.log_callback = tox_log_handler;
|
||||
m_options.log_context = tox;
|
||||
@ -733,34 +742,18 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error)
|
||||
default: {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_PROXY_BAD_TYPE);
|
||||
tox_options_free(default_options);
|
||||
free(tox);
|
||||
mem_delete(sys->mem, tox);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
const Tox_System *sys = tox_options_get_operating_system(opts);
|
||||
const Tox_System default_system = tox_default_system();
|
||||
|
||||
if (sys == nullptr) {
|
||||
sys = &default_system;
|
||||
}
|
||||
|
||||
if (sys->rng == nullptr || sys->ns == nullptr) {
|
||||
// TODO(iphydf): Not quite right, but similar.
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC);
|
||||
tox_options_free(default_options);
|
||||
free(tox);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
tox->rng = *sys->rng;
|
||||
tox->ns = *sys->ns;
|
||||
tox->sys = *sys;
|
||||
|
||||
if (m_options.proxy_info.proxy_type != TCP_PROXY_NONE) {
|
||||
if (tox_options_get_proxy_port(opts) == 0) {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_PROXY_BAD_PORT);
|
||||
tox_options_free(default_options);
|
||||
free(tox);
|
||||
mem_delete(sys->mem, tox);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -773,33 +766,33 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error)
|
||||
const char *const proxy_host = tox_options_get_proxy_host(opts);
|
||||
|
||||
if (proxy_host == nullptr
|
||||
|| !addr_resolve_or_parse_ip(&tox->ns, proxy_host, &m_options.proxy_info.ip_port.ip, nullptr)) {
|
||||
|| !addr_resolve_or_parse_ip(tox->sys.ns, proxy_host, &m_options.proxy_info.ip_port.ip, nullptr)) {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_PROXY_BAD_HOST);
|
||||
// TODO(irungentoo): TOX_ERR_NEW_PROXY_NOT_FOUND if domain.
|
||||
tox_options_free(default_options);
|
||||
free(tox);
|
||||
mem_delete(sys->mem, tox);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
m_options.proxy_info.ip_port.port = net_htons(tox_options_get_proxy_port(opts));
|
||||
}
|
||||
|
||||
tox->mono_time = mono_time_new(sys->mono_time_callback, sys->mono_time_user_data);
|
||||
tox->mono_time = mono_time_new(tox->sys.mem, sys->mono_time_callback, sys->mono_time_user_data);
|
||||
|
||||
if (tox->mono_time == nullptr) {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC);
|
||||
tox_options_free(default_options);
|
||||
free(tox);
|
||||
mem_delete(sys->mem, tox);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (tox_options_get_experimental_thread_safety(opts)) {
|
||||
tox->mutex = (pthread_mutex_t *)calloc(1, sizeof(pthread_mutex_t));
|
||||
tox->mutex = (pthread_mutex_t *)mem_alloc(sys->mem, sizeof(pthread_mutex_t));
|
||||
|
||||
if (tox->mutex == nullptr) {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC);
|
||||
tox_options_free(default_options);
|
||||
free(tox);
|
||||
mem_delete(sys->mem, tox);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -816,18 +809,23 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error)
|
||||
tox_lock(tox);
|
||||
|
||||
Messenger_Error m_error;
|
||||
tox->m = new_messenger(tox->mono_time, &tox->rng, &tox->ns, &m_options, &m_error);
|
||||
tox->m = new_messenger(tox->mono_time, tox->sys.mem, tox->sys.rng, tox->sys.ns, &m_options, &m_error);
|
||||
|
||||
if (tox->m == nullptr) {
|
||||
if (m_error == MESSENGER_ERROR_PORT) {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_PORT_ALLOC);
|
||||
} else if (m_error == MESSENGER_ERROR_TCP_SERVER) {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_PORT_ALLOC);
|
||||
} else {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC);
|
||||
switch (m_error) {
|
||||
case MESSENGER_ERROR_PORT:
|
||||
case MESSENGER_ERROR_TCP_SERVER: {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_PORT_ALLOC);
|
||||
break;
|
||||
}
|
||||
case MESSENGER_ERROR_OTHER:
|
||||
case MESSENGER_ERROR_NONE: {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mono_time_free(tox->mono_time);
|
||||
mono_time_free(tox->sys.mem, tox->mono_time);
|
||||
tox_options_free(default_options);
|
||||
tox_unlock(tox);
|
||||
|
||||
@ -835,15 +833,15 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error)
|
||||
pthread_mutex_destroy(tox->mutex);
|
||||
}
|
||||
|
||||
free(tox->mutex);
|
||||
free(tox);
|
||||
mem_delete(sys->mem, tox->mutex);
|
||||
mem_delete(sys->mem, tox);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (new_groupchats(tox->mono_time, tox->m) == nullptr) {
|
||||
kill_messenger(tox->m);
|
||||
|
||||
mono_time_free(tox->mono_time);
|
||||
mono_time_free(tox->sys.mem, tox->mono_time);
|
||||
tox_options_free(default_options);
|
||||
tox_unlock(tox);
|
||||
|
||||
@ -851,8 +849,8 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error)
|
||||
pthread_mutex_destroy(tox->mutex);
|
||||
}
|
||||
|
||||
free(tox->mutex);
|
||||
free(tox);
|
||||
mem_delete(sys->mem, tox->mutex);
|
||||
mem_delete(sys->mem, tox);
|
||||
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC);
|
||||
return nullptr;
|
||||
@ -928,15 +926,15 @@ void tox_kill(Tox *tox)
|
||||
LOGGER_ASSERT(tox->m->log, tox->m->msi_packet == nullptr, "Attempted to kill tox while toxav is still alive");
|
||||
kill_groupchats(tox->m->conferences_object);
|
||||
kill_messenger(tox->m);
|
||||
mono_time_free(tox->mono_time);
|
||||
mono_time_free(tox->sys.mem, tox->mono_time);
|
||||
tox_unlock(tox);
|
||||
|
||||
if (tox->mutex != nullptr) {
|
||||
pthread_mutex_destroy(tox->mutex);
|
||||
free(tox->mutex);
|
||||
mem_delete(tox->sys.mem, tox->mutex);
|
||||
}
|
||||
|
||||
free(tox);
|
||||
mem_delete(tox->sys.mem, tox);
|
||||
}
|
||||
|
||||
static uint32_t end_size(void)
|
||||
@ -1006,11 +1004,11 @@ static int32_t resolve_bootstrap_node(Tox *tox, const char *host, uint16_t port,
|
||||
return -1;
|
||||
}
|
||||
|
||||
const int32_t count = net_getipport(host, root, TOX_SOCK_DGRAM);
|
||||
const int32_t count = net_getipport(tox->sys.mem, host, root, TOX_SOCK_DGRAM);
|
||||
|
||||
if (count < 1) {
|
||||
LOGGER_DEBUG(tox->m->log, "could not resolve bootstrap node '%s'", host);
|
||||
net_freeipport(*root);
|
||||
net_freeipport(tox->sys.mem, *root);
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_BAD_HOST);
|
||||
return -1;
|
||||
}
|
||||
@ -1054,7 +1052,7 @@ bool tox_bootstrap(Tox *tox, const char *host, uint16_t port, const uint8_t *pub
|
||||
|
||||
tox_unlock(tox);
|
||||
|
||||
net_freeipport(root);
|
||||
net_freeipport(tox->sys.mem, root);
|
||||
|
||||
if (count == 0 || !onion_success || !udp_success) {
|
||||
LOGGER_DEBUG(tox->m->log, "bootstrap node '%s' resolved to %d IP_Ports%s (onion: %s, UDP: %s)",
|
||||
@ -1091,7 +1089,7 @@ bool tox_add_tcp_relay(Tox *tox, const char *host, uint16_t port, const uint8_t
|
||||
|
||||
tox_unlock(tox);
|
||||
|
||||
net_freeipport(root);
|
||||
net_freeipport(tox->sys.mem, root);
|
||||
|
||||
if (count == 0) {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_BAD_HOST);
|
||||
@ -1944,7 +1942,7 @@ uint32_t tox_file_send(Tox *tox, uint32_t friend_number, uint32_t kind, uint64_t
|
||||
|
||||
if (file_id == nullptr) {
|
||||
/* Tox keys are 32 bytes like FILE_ID_LENGTH. */
|
||||
new_symmetric_key(&tox->rng, f_id);
|
||||
new_symmetric_key(tox->sys.rng, f_id);
|
||||
file_id = f_id;
|
||||
}
|
||||
|
||||
@ -2099,7 +2097,7 @@ uint32_t tox_conference_new(Tox *tox, Tox_Err_Conference_New *error)
|
||||
{
|
||||
assert(tox != nullptr);
|
||||
tox_lock(tox);
|
||||
const int ret = add_groupchat(tox->m->conferences_object, &tox->rng, GROUPCHAT_TYPE_TEXT);
|
||||
const int ret = add_groupchat(tox->m->conferences_object, tox->sys.rng, GROUPCHAT_TYPE_TEXT);
|
||||
tox_unlock(tox);
|
||||
|
||||
if (ret == -1) {
|
||||
@ -4580,3 +4578,8 @@ bool tox_group_mod_kick_peer(const Tox *tox, uint32_t group_number, uint32_t pee
|
||||
|
||||
#endif /* VANILLA_NACL */
|
||||
|
||||
const Tox_System *tox_get_system(Tox *tox)
|
||||
{
|
||||
assert(tox != nullptr);
|
||||
return &tox->sys;
|
||||
}
|
||||
|
@ -684,8 +684,8 @@ struct Tox_Options {
|
||||
bool experimental_thread_safety;
|
||||
|
||||
/**
|
||||
* Low level operating system functionality such as send/recv and random
|
||||
* number generation.
|
||||
* Low level operating system functionality such as send/recv, random
|
||||
* number generation, and memory allocation.
|
||||
*/
|
||||
const Tox_System *operating_system;
|
||||
|
||||
@ -911,6 +911,8 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error);
|
||||
*/
|
||||
void tox_kill(Tox *tox);
|
||||
|
||||
const Tox_System *tox_get_system(Tox *tox);
|
||||
|
||||
/**
|
||||
* @brief Calculates the number of bytes required to store the tox instance with
|
||||
* tox_get_savedata.
|
||||
@ -3303,16 +3305,22 @@ uint32_t tox_group_max_part_length(void);
|
||||
*/
|
||||
#define TOX_GROUP_MAX_MESSAGE_LENGTH 1372
|
||||
|
||||
uint32_t tox_group_max_message_length(void);
|
||||
|
||||
/**
|
||||
* Maximum length of a group custom lossy packet.
|
||||
*/
|
||||
#define TOX_GROUP_MAX_CUSTOM_LOSSY_PACKET_LENGTH 500
|
||||
|
||||
uint32_t tox_group_max_custom_lossy_packet_length(void);
|
||||
|
||||
/**
|
||||
* Maximum length of a group custom lossless packet.
|
||||
*/
|
||||
#define TOX_GROUP_MAX_CUSTOM_LOSSLESS_PACKET_LENGTH 1373
|
||||
|
||||
uint32_t tox_group_max_custom_lossless_packet_length(void);
|
||||
|
||||
/**
|
||||
* Maximum length of a group name.
|
||||
*/
|
||||
@ -3973,8 +3981,8 @@ Tox_Connection tox_group_peer_get_connection_status(const Tox *tox, uint32_t gro
|
||||
/**
|
||||
* Write the group public key with the designated peer_id for the designated group number to public_key.
|
||||
*
|
||||
* This key will be permanently tied to a particular peer until they explicitly leave the group or
|
||||
* get kicked, and is the only way to reliably identify the same peer across client restarts.
|
||||
* This key will be permanently tied to a particular peer until they explicitly leave the group and is
|
||||
* the only way to reliably identify the same peer across client restarts.
|
||||
*
|
||||
* `public_key` should have room for at least TOX_GROUP_PEER_PUBLIC_KEY_SIZE bytes. If `public_key` is null
|
||||
* this function has no effect.
|
||||
|
@ -88,6 +88,42 @@ uint32_t tox_max_hostname_length(void)
|
||||
{
|
||||
return TOX_MAX_HOSTNAME_LENGTH;
|
||||
}
|
||||
uint32_t tox_group_max_topic_length(void)
|
||||
{
|
||||
return TOX_GROUP_MAX_TOPIC_LENGTH;
|
||||
}
|
||||
uint32_t tox_group_max_part_length(void)
|
||||
{
|
||||
return TOX_GROUP_MAX_PART_LENGTH;
|
||||
}
|
||||
uint32_t tox_group_max_message_length(void)
|
||||
{
|
||||
return TOX_GROUP_MAX_MESSAGE_LENGTH;
|
||||
}
|
||||
uint32_t tox_group_max_custom_lossy_packet_length(void)
|
||||
{
|
||||
return TOX_GROUP_MAX_CUSTOM_LOSSY_PACKET_LENGTH;
|
||||
}
|
||||
uint32_t tox_group_max_custom_lossless_packet_length(void)
|
||||
{
|
||||
return TOX_GROUP_MAX_CUSTOM_LOSSLESS_PACKET_LENGTH;
|
||||
}
|
||||
uint32_t tox_group_max_group_name_length(void)
|
||||
{
|
||||
return TOX_GROUP_MAX_GROUP_NAME_LENGTH;
|
||||
}
|
||||
uint32_t tox_group_max_password_size(void)
|
||||
{
|
||||
return TOX_GROUP_MAX_PASSWORD_SIZE;
|
||||
}
|
||||
uint32_t tox_group_chat_id_size(void)
|
||||
{
|
||||
return TOX_GROUP_CHAT_ID_SIZE;
|
||||
}
|
||||
uint32_t tox_group_peer_public_key_size(void)
|
||||
{
|
||||
return TOX_GROUP_PEER_PUBLIC_KEY_SIZE;
|
||||
}
|
||||
uint32_t tox_dht_node_ip_string_size(void)
|
||||
{
|
||||
return TOX_DHT_NODE_IP_STRING_SIZE;
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "tox_events.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -11,7 +12,9 @@
|
||||
#include "bin_unpack.h"
|
||||
#include "ccompat.h"
|
||||
#include "events/events_alloc.h"
|
||||
#include "mem.h"
|
||||
#include "tox.h"
|
||||
#include "tox_private.h"
|
||||
|
||||
|
||||
/*****************************************************
|
||||
@ -339,7 +342,7 @@ void tox_events_get_bytes(const Tox_Events *events, uint8_t *bytes)
|
||||
bin_pack_obj(tox_events_bin_pack_handler, events, bytes, UINT32_MAX);
|
||||
}
|
||||
|
||||
Tox_Events *tox_events_load(const uint8_t *bytes, uint32_t bytes_size)
|
||||
Tox_Events *tox_events_load(const Tox_System *sys, const uint8_t *bytes, uint32_t bytes_size)
|
||||
{
|
||||
Bin_Unpack *bu = bin_unpack_new(bytes, bytes_size);
|
||||
|
||||
@ -347,7 +350,7 @@ Tox_Events *tox_events_load(const uint8_t *bytes, uint32_t bytes_size)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Tox_Events *events = (Tox_Events *)calloc(1, sizeof(Tox_Events));
|
||||
Tox_Events *events = (Tox_Events *)mem_alloc(sys->mem, sizeof(Tox_Events));
|
||||
|
||||
if (events == nullptr) {
|
||||
bin_unpack_free(bu);
|
||||
@ -368,8 +371,11 @@ Tox_Events *tox_events_load(const uint8_t *bytes, uint32_t bytes_size)
|
||||
return events;
|
||||
}
|
||||
|
||||
bool tox_events_equal(const Tox_Events *a, const Tox_Events *b)
|
||||
bool tox_events_equal(const Tox_System *sys, const Tox_Events *a, const Tox_Events *b)
|
||||
{
|
||||
assert(sys != nullptr);
|
||||
assert(sys->mem != nullptr);
|
||||
|
||||
const uint32_t a_size = tox_events_bytes_size(a);
|
||||
const uint32_t b_size = tox_events_bytes_size(b);
|
||||
|
||||
@ -377,12 +383,12 @@ bool tox_events_equal(const Tox_Events *a, const Tox_Events *b)
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t *a_bytes = (uint8_t *)malloc(a_size);
|
||||
uint8_t *b_bytes = (uint8_t *)malloc(b_size);
|
||||
uint8_t *a_bytes = (uint8_t *)mem_balloc(sys->mem, a_size);
|
||||
uint8_t *b_bytes = (uint8_t *)mem_balloc(sys->mem, b_size);
|
||||
|
||||
if (a_bytes == nullptr || b_bytes == nullptr) {
|
||||
free(b_bytes);
|
||||
free(a_bytes);
|
||||
mem_delete(sys->mem, b_bytes);
|
||||
mem_delete(sys->mem, a_bytes);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -391,8 +397,8 @@ bool tox_events_equal(const Tox_Events *a, const Tox_Events *b)
|
||||
|
||||
const bool ret = memcmp(a_bytes, b_bytes, a_size) == 0;
|
||||
|
||||
free(b_bytes);
|
||||
free(a_bytes);
|
||||
mem_delete(sys->mem, b_bytes);
|
||||
mem_delete(sys->mem, a_bytes);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -575,9 +575,9 @@ void tox_events_free(Tox_Events *events);
|
||||
uint32_t tox_events_bytes_size(const Tox_Events *events);
|
||||
void tox_events_get_bytes(const Tox_Events *events, uint8_t *bytes);
|
||||
|
||||
Tox_Events *tox_events_load(const uint8_t *bytes, uint32_t bytes_size);
|
||||
Tox_Events *tox_events_load(const Tox_System *sys, const uint8_t *bytes, uint32_t bytes_size);
|
||||
|
||||
bool tox_events_equal(const Tox_Events *a, const Tox_Events *b);
|
||||
bool tox_events_equal(const Tox_System *sys, const Tox_Events *a, const Tox_Events *b);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -1,13 +1,33 @@
|
||||
#include "tox_events.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
|
||||
#include "../testing/fuzzing/fuzz_support.h"
|
||||
|
||||
namespace {
|
||||
|
||||
void TestUnpack(const uint8_t *data, size_t size)
|
||||
void TestUnpack(Fuzz_Data data)
|
||||
{
|
||||
Tox_Events *events = tox_events_load(data, size);
|
||||
// 2 bytes: size of the events data
|
||||
CONSUME_OR_RETURN(const uint8_t *events_size_bytes, data, sizeof(uint16_t));
|
||||
uint16_t events_size;
|
||||
std::memcpy(&events_size, events_size_bytes, sizeof(uint16_t));
|
||||
|
||||
// events_size bytes: events data (max 64K)
|
||||
CONSUME_OR_RETURN(const uint8_t *events_data, data, events_size);
|
||||
|
||||
if (data.size == 0) {
|
||||
// If there's no more input, no malloc failure paths can possibly be
|
||||
// tested, so we ignore this input.
|
||||
return;
|
||||
}
|
||||
|
||||
// rest of the fuzz data is input for malloc
|
||||
Fuzz_System sys{data};
|
||||
|
||||
Tox_Events *events = tox_events_load(sys.sys.get(), events_data, events_size);
|
||||
if (events) {
|
||||
std::vector<uint8_t> packed(tox_events_bytes_size(events));
|
||||
tox_events_get_bytes(events, packed.data());
|
||||
@ -20,6 +40,6 @@ void TestUnpack(const uint8_t *data, size_t size)
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
{
|
||||
TestUnpack(data, size);
|
||||
TestUnpack(Fuzz_Data(data, size));
|
||||
return 0;
|
||||
}
|
||||
|
@ -6,29 +6,32 @@
|
||||
#include <vector>
|
||||
|
||||
#include "crypto_core.h"
|
||||
#include "tox_private.h"
|
||||
|
||||
namespace {
|
||||
|
||||
TEST(ToxEvents, UnpackRandomDataDoesntCrash)
|
||||
{
|
||||
const Random *rng = system_random();
|
||||
ASSERT_NE(rng, nullptr);
|
||||
const Tox_System sys = tox_default_system();
|
||||
ASSERT_NE(sys.rng, nullptr);
|
||||
std::array<uint8_t, 128> data;
|
||||
random_bytes(rng, data.data(), data.size());
|
||||
tox_events_free(tox_events_load(data.data(), data.size()));
|
||||
random_bytes(sys.rng, data.data(), data.size());
|
||||
tox_events_free(tox_events_load(&sys, data.data(), data.size()));
|
||||
}
|
||||
|
||||
TEST(ToxEvents, UnpackEmptyDataFails)
|
||||
{
|
||||
const Tox_System sys = tox_default_system();
|
||||
std::array<uint8_t, 1> data;
|
||||
Tox_Events *events = tox_events_load(data.end(), 0);
|
||||
Tox_Events *events = tox_events_load(&sys, data.end(), 0);
|
||||
EXPECT_EQ(events, nullptr);
|
||||
}
|
||||
|
||||
TEST(ToxEvents, UnpackEmptyArrayCreatesEmptyEvents)
|
||||
{
|
||||
const Tox_System sys = tox_default_system();
|
||||
std::array<uint8_t, 1> data{0x90}; // empty msgpack array
|
||||
Tox_Events *events = tox_events_load(data.data(), data.size());
|
||||
Tox_Events *events = tox_events_load(&sys, data.data(), data.size());
|
||||
ASSERT_NE(events, nullptr);
|
||||
EXPECT_EQ(tox_events_get_conference_connected_size(events), 0);
|
||||
tox_events_free(events);
|
||||
@ -44,9 +47,10 @@ TEST(ToxEvents, NullEventsPacksToEmptyArray)
|
||||
|
||||
TEST(ToxEvents, PackedEventsCanBeUnpacked)
|
||||
{
|
||||
const Tox_System sys = tox_default_system();
|
||||
// [[0, 1]] == Tox_Self_Connection_Status { .connection_status = TOX_CONNECTION_TCP }
|
||||
std::array<uint8_t, 6> packed{0x91, 0x92, 0xcc, 0x00, 0xcc, 0x01};
|
||||
Tox_Events *events = tox_events_load(packed.data(), packed.size());
|
||||
Tox_Events *events = tox_events_load(&sys, packed.data(), packed.size());
|
||||
ASSERT_NE(events, nullptr);
|
||||
std::array<uint8_t, 4> bytes;
|
||||
ASSERT_EQ(tox_events_bytes_size(events), bytes.size());
|
||||
@ -57,8 +61,9 @@ TEST(ToxEvents, PackedEventsCanBeUnpacked)
|
||||
|
||||
TEST(ToxEvents, DealsWithHugeMsgpackArrays)
|
||||
{
|
||||
const Tox_System sys = tox_default_system();
|
||||
std::vector<uint8_t> data{0xdd, 0xff, 0xff, 0xff, 0xff};
|
||||
EXPECT_EQ(tox_events_load(data.data(), data.size()), nullptr);
|
||||
EXPECT_EQ(tox_events_load(&sys, data.data(), data.size()), nullptr);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <assert.h>
|
||||
|
||||
#include "ccompat.h"
|
||||
#include "mem.h"
|
||||
#include "network.h"
|
||||
#include "tox_struct.h"
|
||||
|
||||
@ -28,6 +29,7 @@ Tox_System tox_default_system(void)
|
||||
nullptr, // mono_time_user_data
|
||||
system_random(),
|
||||
system_network(),
|
||||
system_memory(),
|
||||
};
|
||||
return sys;
|
||||
}
|
||||
@ -115,11 +117,11 @@ bool tox_dht_get_nodes(const Tox *tox, const uint8_t *public_key, const char *ip
|
||||
|
||||
IP_Port *root;
|
||||
|
||||
const int32_t count = net_getipport(ip, &root, TOX_SOCK_DGRAM);
|
||||
const int32_t count = net_getipport(tox->sys.mem, ip, &root, TOX_SOCK_DGRAM);
|
||||
|
||||
if (count < 1) {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_DHT_GET_NODES_BAD_IP);
|
||||
net_freeipport(root);
|
||||
net_freeipport(tox->sys.mem, root);
|
||||
tox_unlock(tox);
|
||||
return false;
|
||||
}
|
||||
@ -136,7 +138,7 @@ bool tox_dht_get_nodes(const Tox *tox, const uint8_t *public_key, const char *ip
|
||||
|
||||
tox_unlock(tox);
|
||||
|
||||
net_freeipport(root);
|
||||
net_freeipport(tox->sys.mem, root);
|
||||
|
||||
if (!success) {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_DHT_GET_NODES_FAIL);
|
||||
|
@ -23,6 +23,7 @@ struct Tox_System {
|
||||
void *mono_time_user_data;
|
||||
const struct Random *rng;
|
||||
const struct Network *ns;
|
||||
const struct Memory *mem;
|
||||
};
|
||||
|
||||
Tox_System tox_default_system(void);
|
||||
|
@ -7,6 +7,7 @@
|
||||
#define C_TOXCORE_TOXCORE_TOX_STRUCT_H
|
||||
|
||||
#include "Messenger.h"
|
||||
#include "mem.h"
|
||||
#include "tox.h"
|
||||
#include "tox_private.h"
|
||||
|
||||
@ -17,8 +18,7 @@ extern "C" {
|
||||
struct Tox {
|
||||
Messenger *m;
|
||||
Mono_Time *mono_time;
|
||||
Random rng;
|
||||
Network ns;
|
||||
Tox_System sys;
|
||||
pthread_mutex_t *mutex;
|
||||
|
||||
tox_log_cb *log_callback;
|
||||
|
@ -48,6 +48,15 @@ TEST(Tox, ConstantsAreNonZero)
|
||||
EXPECT_GT(tox_file_id_length(), 0);
|
||||
EXPECT_GT(tox_max_filename_length(), 0);
|
||||
EXPECT_GT(tox_max_hostname_length(), 0);
|
||||
EXPECT_GT(tox_group_max_topic_length(), 0);
|
||||
EXPECT_GT(tox_group_max_part_length(), 0);
|
||||
EXPECT_GT(tox_group_max_message_length(), 0);
|
||||
EXPECT_GT(tox_group_max_custom_lossy_packet_length(), 0);
|
||||
EXPECT_GT(tox_group_max_custom_lossless_packet_length(), 0);
|
||||
EXPECT_GT(tox_group_max_group_name_length(), 0);
|
||||
EXPECT_GT(tox_group_max_password_size(), 0);
|
||||
EXPECT_GT(tox_group_chat_id_size(), 0);
|
||||
EXPECT_GT(tox_group_peer_public_key_size(), 0);
|
||||
EXPECT_GT(tox_dht_node_ip_string_size(), 0);
|
||||
EXPECT_GT(tox_dht_node_public_key_size(), 0);
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ bool is_power_of_2(uint64_t x)
|
||||
return x != 0 && (x & (~x + 1)) == x;
|
||||
}
|
||||
|
||||
void free_uint8_t_pointer_array(uint8_t **ary, size_t n_items)
|
||||
void free_uint8_t_pointer_array(const Memory *mem, uint8_t **ary, size_t n_items)
|
||||
{
|
||||
if (ary == nullptr) {
|
||||
return;
|
||||
@ -32,11 +32,11 @@ void free_uint8_t_pointer_array(uint8_t **ary, size_t n_items)
|
||||
|
||||
for (size_t i = 0; i < n_items; ++i) {
|
||||
if (ary[i] != nullptr) {
|
||||
free(ary[i]);
|
||||
mem_delete(mem, ary[i]);
|
||||
}
|
||||
}
|
||||
|
||||
free(ary);
|
||||
mem_delete(mem, ary);
|
||||
}
|
||||
|
||||
uint16_t data_checksum(const uint8_t *data, uint32_t length)
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "attributes.h"
|
||||
#include "mem.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -24,8 +25,8 @@ extern "C" {
|
||||
bool is_power_of_2(uint64_t x);
|
||||
|
||||
/** @brief Frees all pointers in a uint8_t pointer array, as well as the array itself. */
|
||||
nullable(1)
|
||||
void free_uint8_t_pointer_array(uint8_t **ary, size_t n_items);
|
||||
non_null(1) nullable(2)
|
||||
void free_uint8_t_pointer_array(const Memory *mem, uint8_t **ary, size_t n_items);
|
||||
|
||||
/** Returns -1 if failed or 0 if success */
|
||||
non_null() int create_recursive_mutex(pthread_mutex_t *mutex);
|
||||
|
Reference in New Issue
Block a user