refactor: Add mem module to allow tests to override allocators.

This will allow us to do more interesting things with memory allocation
within toxcore, and allow fuzzers to explore various allocation failure
paths.
This commit is contained in:
iphydf 2023-08-23 10:26:11 +00:00
parent 6133fb1531
commit a549807df7
No known key found for this signature in database
GPG Key ID: 3855DBA2D74403C9
86 changed files with 1148 additions and 623 deletions

View File

@ -9,7 +9,7 @@ sudo apt-get install -y --no-install-recommends \
libopus-dev \ libopus-dev \
libsodium-dev \ libsodium-dev \
libvpx-dev \ libvpx-dev \
llvm-11 \ llvm-14 \
ninja-build ninja-build
git clone --depth=1 https://github.com/ralight/mallocfail /tmp/mallocfail git clone --depth=1 https://github.com/ralight/mallocfail /tmp/mallocfail
cd /tmp/mallocfail # pushd cd /tmp/mallocfail # pushd
@ -21,7 +21,7 @@ export CC=clang
export CXX=clang++ export CXX=clang++
sudo install other/docker/coverage/run_mallocfail /usr/local/bin/run_mallocfail sudo install other/docker/coverage/run_mallocfail /usr/local/bin/run_mallocfail
(cd other/proxy && go build) (cd other/proxy && go get && go build)
other/proxy/proxy & other/proxy/proxy &
. ".github/scripts/flags-coverage.sh" . ".github/scripts/flags-coverage.sh"
@ -58,4 +58,4 @@ cd - # popd
# --exclude testing \ # --exclude testing \
# --gcov-options '\-lp' # --gcov-options '\-lp'
bash <(curl -s https://codecov.io/bash) -x "llvm-cov-11 gcov" bash <(curl -s https://codecov.io/bash) -x "llvm-cov-14 gcov"

View File

@ -268,6 +268,8 @@ set(toxcore_SOURCES
toxcore/logger.h toxcore/logger.h
toxcore/Messenger.c toxcore/Messenger.c
toxcore/Messenger.h toxcore/Messenger.h
toxcore/mem.c
toxcore/mem.h
toxcore/mono_time.c toxcore/mono_time.c
toxcore/mono_time.h toxcore/mono_time.h
toxcore/net_crypto.c toxcore/net_crypto.c
@ -434,6 +436,7 @@ unit_test(toxcore bin_pack)
unit_test(toxcore crypto_core) unit_test(toxcore crypto_core)
unit_test(toxcore group_announce) unit_test(toxcore group_announce)
unit_test(toxcore group_moderation) unit_test(toxcore group_moderation)
unit_test(toxcore mem)
unit_test(toxcore mono_time) unit_test(toxcore mono_time)
unit_test(toxcore ping_array) unit_test(toxcore ping_array)
unit_test(toxcore tox) unit_test(toxcore tox)

View File

@ -45,9 +45,14 @@ static uint16_t ports[NUM_PORTS] = {13215, 33445, 25643};
static void test_basic(void) static void test_basic(void)
{ {
Mono_Time *mono_time = mono_time_new(nullptr, nullptr);
const Random *rng = system_random(); const Random *rng = system_random();
ck_assert(rng != nullptr); ck_assert(rng != nullptr);
const Network *ns = system_network();
ck_assert(ns != nullptr);
const Memory *mem = system_memory();
ck_assert(mem != nullptr);
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
Logger *logger = logger_new(); Logger *logger = logger_new();
logger_callback_log(logger, print_debug_logger, nullptr, nullptr); logger_callback_log(logger, print_debug_logger, nullptr, nullptr);
@ -55,8 +60,7 @@ static void test_basic(void)
uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE];
uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE]; uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE];
crypto_new_keypair(rng, self_public_key, self_secret_key); crypto_new_keypair(rng, self_public_key, self_secret_key);
const Network *ns = system_network(); TCP_Server *tcp_s = new_TCP_server(logger, mem, rng, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr, nullptr);
TCP_Server *tcp_s = new_TCP_server(logger, rng, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr, nullptr);
ck_assert_msg(tcp_s != nullptr, "Failed to create a TCP relay server."); ck_assert_msg(tcp_s != nullptr, "Failed to create a TCP relay server.");
ck_assert_msg(tcp_server_listen_count(tcp_s) == NUM_PORTS, ck_assert_msg(tcp_server_listen_count(tcp_s) == NUM_PORTS,
"Failed to bind a TCP relay server to all %d attempted ports.", NUM_PORTS); "Failed to bind a TCP relay server to all %d attempted ports.", NUM_PORTS);
@ -70,7 +74,7 @@ static void test_basic(void)
for (uint8_t i = 0; i < NUM_PORTS; i++) { for (uint8_t i = 0; i < NUM_PORTS; i++) {
sock = net_socket(ns, net_family_ipv6(), TOX_SOCK_STREAM, TOX_PROTO_TCP); sock = net_socket(ns, net_family_ipv6(), TOX_SOCK_STREAM, TOX_PROTO_TCP);
localhost.port = net_htons(ports[i]); localhost.port = net_htons(ports[i]);
bool ret = net_connect(logger, sock, &localhost); bool ret = net_connect(mem, logger, sock, &localhost);
ck_assert_msg(ret, "Failed to connect to created TCP relay server on port %d (%d).", ports[i], errno); ck_assert_msg(ret, "Failed to connect to created TCP relay server on port %d (%d).", ports[i], errno);
// Leave open one connection for the next test. // Leave open one connection for the next test.
@ -184,30 +188,32 @@ static void test_basic(void)
kill_TCP_server(tcp_s); kill_TCP_server(tcp_s);
logger_kill(logger); logger_kill(logger);
mono_time_free(mono_time); mono_time_free(mem, mono_time);
} }
struct sec_TCP_con { struct sec_TCP_con {
Socket sock; Socket sock;
const Network *ns; const Network *ns;
const Memory *mem;
uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE];
uint8_t recv_nonce[CRYPTO_NONCE_SIZE]; uint8_t recv_nonce[CRYPTO_NONCE_SIZE];
uint8_t sent_nonce[CRYPTO_NONCE_SIZE]; uint8_t sent_nonce[CRYPTO_NONCE_SIZE];
uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE]; uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE];
}; };
static struct sec_TCP_con *new_TCP_con(const Logger *logger, const Random *rng, const Network *ns, TCP_Server *tcp_s, Mono_Time *mono_time) static struct sec_TCP_con *new_TCP_con(const Logger *logger, const Memory *mem, const Random *rng, const Network *ns, TCP_Server *tcp_s, Mono_Time *mono_time)
{ {
struct sec_TCP_con *sec_c = (struct sec_TCP_con *)malloc(sizeof(struct sec_TCP_con)); struct sec_TCP_con *sec_c = (struct sec_TCP_con *)malloc(sizeof(struct sec_TCP_con));
ck_assert(sec_c != nullptr); ck_assert(sec_c != nullptr);
sec_c->ns = ns; sec_c->ns = ns;
sec_c->mem = mem;
Socket sock = net_socket(ns, net_family_ipv6(), TOX_SOCK_STREAM, TOX_PROTO_TCP); Socket sock = net_socket(ns, net_family_ipv6(), TOX_SOCK_STREAM, TOX_PROTO_TCP);
IP_Port localhost; IP_Port localhost;
localhost.ip = get_loopback(); localhost.ip = get_loopback();
localhost.port = net_htons(ports[random_u32(rng) % NUM_PORTS]); localhost.port = net_htons(ports[random_u32(rng) % NUM_PORTS]);
bool ok = net_connect(logger, sock, &localhost); bool ok = net_connect(mem, logger, sock, &localhost);
ck_assert_msg(ok, "Failed to connect to the test TCP relay server."); ck_assert_msg(ok, "Failed to connect to the test TCP relay server.");
uint8_t f_secret_key[CRYPTO_SECRET_KEY_SIZE]; uint8_t f_secret_key[CRYPTO_SECRET_KEY_SIZE];
@ -297,22 +303,26 @@ static int read_packet_sec_TCP(const Logger *logger, struct sec_TCP_con *con, ui
static void test_some(void) static void test_some(void)
{ {
Mono_Time *mono_time = mono_time_new(nullptr, nullptr);
const Random *rng = system_random(); const Random *rng = system_random();
ck_assert(rng != nullptr); ck_assert(rng != nullptr);
Logger *logger = logger_new();
const Network *ns = system_network(); const Network *ns = system_network();
ck_assert(ns != nullptr);
const Memory *mem = system_memory();
ck_assert(mem != nullptr);
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
Logger *logger = logger_new();
uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE];
uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE]; uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE];
crypto_new_keypair(rng, self_public_key, self_secret_key); crypto_new_keypair(rng, self_public_key, self_secret_key);
TCP_Server *tcp_s = new_TCP_server(logger, rng, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr, nullptr); TCP_Server *tcp_s = new_TCP_server(logger, mem, rng, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr, nullptr);
ck_assert_msg(tcp_s != nullptr, "Failed to create TCP relay server"); ck_assert_msg(tcp_s != nullptr, "Failed to create TCP relay server");
ck_assert_msg(tcp_server_listen_count(tcp_s) == NUM_PORTS, "Failed to bind to all ports."); ck_assert_msg(tcp_server_listen_count(tcp_s) == NUM_PORTS, "Failed to bind to all ports.");
struct sec_TCP_con *con1 = new_TCP_con(logger, rng, ns, tcp_s, mono_time); struct sec_TCP_con *con1 = new_TCP_con(logger, mem, rng, ns, tcp_s, mono_time);
struct sec_TCP_con *con2 = new_TCP_con(logger, rng, ns, tcp_s, mono_time); struct sec_TCP_con *con2 = new_TCP_con(logger, mem, rng, ns, tcp_s, mono_time);
struct sec_TCP_con *con3 = new_TCP_con(logger, rng, ns, tcp_s, mono_time); struct sec_TCP_con *con3 = new_TCP_con(logger, mem, rng, ns, tcp_s, mono_time);
uint8_t requ_p[1 + CRYPTO_PUBLIC_KEY_SIZE]; uint8_t requ_p[1 + CRYPTO_PUBLIC_KEY_SIZE];
requ_p[0] = TCP_PACKET_ROUTING_REQUEST; requ_p[0] = TCP_PACKET_ROUTING_REQUEST;
@ -402,7 +412,7 @@ static void test_some(void)
kill_TCP_con(con3); kill_TCP_con(con3);
logger_kill(logger); logger_kill(logger);
mono_time_free(mono_time); mono_time_free(mem, mono_time);
} }
static int response_callback_good; static int response_callback_good;
@ -488,16 +498,20 @@ static int oob_data_callback(void *object, const uint8_t *public_key, const uint
static void test_client(void) static void test_client(void)
{ {
Mono_Time *mono_time = mono_time_new(nullptr, nullptr);
const Random *rng = system_random(); const Random *rng = system_random();
ck_assert(rng != nullptr); ck_assert(rng != nullptr);
const Network *ns = system_network();
ck_assert(ns != nullptr);
const Memory *mem = system_memory();
ck_assert(mem != nullptr);
Logger *logger = logger_new(); Logger *logger = logger_new();
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE];
uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE]; uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE];
crypto_new_keypair(rng, self_public_key, self_secret_key); crypto_new_keypair(rng, self_public_key, self_secret_key);
const Network *ns = system_network(); TCP_Server *tcp_s = new_TCP_server(logger, mem, rng, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr, nullptr);
TCP_Server *tcp_s = new_TCP_server(logger, rng, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr, nullptr);
ck_assert_msg(tcp_s != nullptr, "Failed to create a TCP relay server."); ck_assert_msg(tcp_s != nullptr, "Failed to create a TCP relay server.");
ck_assert_msg(tcp_server_listen_count(tcp_s) == NUM_PORTS, "Failed to bind the relay server to all ports."); ck_assert_msg(tcp_server_listen_count(tcp_s) == NUM_PORTS, "Failed to bind the relay server to all ports.");
@ -509,8 +523,7 @@ static void test_client(void)
ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]); ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]);
ip_port_tcp_s.ip = get_loopback(); ip_port_tcp_s.ip = get_loopback();
TCP_Client_Connection *conn = new_TCP_connection(logger, mono_time, rng, ns, &ip_port_tcp_s, self_public_key, f_public_key, TCP_Client_Connection *conn = new_TCP_connection(logger, mem, mono_time, rng, ns, &ip_port_tcp_s, self_public_key, f_public_key, f_secret_key, nullptr);
f_secret_key, nullptr);
do_TCP_connection(logger, mono_time, conn, nullptr); do_TCP_connection(logger, mono_time, conn, nullptr);
c_sleep(50); c_sleep(50);
@ -544,7 +557,7 @@ static void test_client(void)
uint8_t f2_secret_key[CRYPTO_SECRET_KEY_SIZE]; uint8_t f2_secret_key[CRYPTO_SECRET_KEY_SIZE];
crypto_new_keypair(rng, f2_public_key, f2_secret_key); crypto_new_keypair(rng, f2_public_key, f2_secret_key);
ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]); ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]);
TCP_Client_Connection *conn2 = new_TCP_connection(logger, mono_time, rng, ns, &ip_port_tcp_s, self_public_key, f2_public_key, TCP_Client_Connection *conn2 = new_TCP_connection(logger, mem, mono_time, rng, ns, &ip_port_tcp_s, self_public_key, f2_public_key,
f2_secret_key, nullptr); f2_secret_key, nullptr);
// The client should call this function (defined earlier) during the routing process. // The client should call this function (defined earlier) during the routing process.
@ -613,17 +626,21 @@ static void test_client(void)
kill_TCP_connection(conn2); kill_TCP_connection(conn2);
logger_kill(logger); logger_kill(logger);
mono_time_free(mono_time); mono_time_free(mem, mono_time);
} }
// Test how the client handles servers that don't respond. // Test how the client handles servers that don't respond.
static void test_client_invalid(void) static void test_client_invalid(void)
{ {
Mono_Time *mono_time = mono_time_new(nullptr, nullptr);
const Random *rng = system_random(); const Random *rng = system_random();
ck_assert(rng != nullptr); ck_assert(rng != nullptr);
Logger *logger = logger_new();
const Network *ns = system_network(); const Network *ns = system_network();
ck_assert(ns != nullptr);
const Memory *mem = system_memory();
ck_assert(mem != nullptr);
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
Logger *logger = logger_new();
uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE];
uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE]; uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE];
@ -636,7 +653,7 @@ static void test_client_invalid(void)
ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]); ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]);
ip_port_tcp_s.ip = get_loopback(); ip_port_tcp_s.ip = get_loopback();
TCP_Client_Connection *conn = new_TCP_connection(logger, mono_time, rng, ns, &ip_port_tcp_s, TCP_Client_Connection *conn = new_TCP_connection(logger, mem, mono_time, rng, ns, &ip_port_tcp_s,
self_public_key, f_public_key, f_secret_key, nullptr); self_public_key, f_public_key, f_secret_key, nullptr);
// Run the client's main loop but not the server. // Run the client's main loop but not the server.
@ -663,7 +680,7 @@ static void test_client_invalid(void)
kill_TCP_connection(conn); kill_TCP_connection(conn);
logger_kill(logger); logger_kill(logger);
mono_time_free(mono_time); mono_time_free(mem, mono_time);
} }
#include "../toxcore/TCP_connection.h" #include "../toxcore/TCP_connection.h"
@ -694,27 +711,31 @@ static int tcp_data_callback(void *object, int id, const uint8_t *data, uint16_t
static void test_tcp_connection(void) static void test_tcp_connection(void)
{ {
Mono_Time *mono_time = mono_time_new(nullptr, nullptr);
Logger *logger = logger_new();
const Random *rng = system_random(); const Random *rng = system_random();
ck_assert(rng != nullptr); ck_assert(rng != nullptr);
const Network *ns = system_network(); const Network *ns = system_network();
ck_assert(ns != nullptr);
const Memory *mem = system_memory();
ck_assert(mem != nullptr);
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
Logger *logger = logger_new();
tcp_data_callback_called = 0; tcp_data_callback_called = 0;
uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE];
uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE]; uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE];
crypto_new_keypair(rng, self_public_key, self_secret_key); crypto_new_keypair(rng, self_public_key, self_secret_key);
TCP_Server *tcp_s = new_TCP_server(logger, rng, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr, nullptr); TCP_Server *tcp_s = new_TCP_server(logger, mem, rng, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr, nullptr);
ck_assert_msg(pk_equal(tcp_server_public_key(tcp_s), self_public_key), "Wrong public key"); ck_assert_msg(pk_equal(tcp_server_public_key(tcp_s), self_public_key), "Wrong public key");
TCP_Proxy_Info proxy_info; TCP_Proxy_Info proxy_info;
proxy_info.proxy_type = TCP_PROXY_NONE; proxy_info.proxy_type = TCP_PROXY_NONE;
crypto_new_keypair(rng, self_public_key, self_secret_key); crypto_new_keypair(rng, self_public_key, self_secret_key);
TCP_Connections *tc_1 = new_tcp_connections(logger, rng, ns, mono_time, self_secret_key, &proxy_info); TCP_Connections *tc_1 = new_tcp_connections(logger, mem, rng, ns, mono_time, self_secret_key, &proxy_info);
ck_assert_msg(pk_equal(tcp_connections_public_key(tc_1), self_public_key), "Wrong public key"); ck_assert_msg(pk_equal(tcp_connections_public_key(tc_1), self_public_key), "Wrong public key");
crypto_new_keypair(rng, self_public_key, self_secret_key); crypto_new_keypair(rng, self_public_key, self_secret_key);
TCP_Connections *tc_2 = new_tcp_connections(logger, rng, ns, mono_time, self_secret_key, &proxy_info); TCP_Connections *tc_2 = new_tcp_connections(logger, mem, rng, ns, mono_time, self_secret_key, &proxy_info);
ck_assert_msg(pk_equal(tcp_connections_public_key(tc_2), self_public_key), "Wrong public key"); ck_assert_msg(pk_equal(tcp_connections_public_key(tc_2), self_public_key), "Wrong public key");
IP_Port ip_port_tcp_s; IP_Port ip_port_tcp_s;
@ -777,7 +798,7 @@ static void test_tcp_connection(void)
kill_tcp_connections(tc_2); kill_tcp_connections(tc_2);
logger_kill(logger); logger_kill(logger);
mono_time_free(mono_time); mono_time_free(mem, mono_time);
} }
static bool tcp_oobdata_callback_called; static bool tcp_oobdata_callback_called;
@ -803,11 +824,15 @@ static int tcp_oobdata_callback(void *object, const uint8_t *public_key, unsigne
static void test_tcp_connection2(void) static void test_tcp_connection2(void)
{ {
Mono_Time *mono_time = mono_time_new(nullptr, nullptr);
Logger *logger = logger_new();
const Random *rng = system_random(); const Random *rng = system_random();
ck_assert(rng != nullptr); ck_assert(rng != nullptr);
const Network *ns = system_network(); const Network *ns = system_network();
ck_assert(ns != nullptr);
const Memory *mem = system_memory();
ck_assert(mem != nullptr);
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
Logger *logger = logger_new();
tcp_oobdata_callback_called = 0; tcp_oobdata_callback_called = 0;
tcp_data_callback_called = 0; tcp_data_callback_called = 0;
@ -815,17 +840,17 @@ static void test_tcp_connection2(void)
uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE];
uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE]; uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE];
crypto_new_keypair(rng, self_public_key, self_secret_key); crypto_new_keypair(rng, self_public_key, self_secret_key);
TCP_Server *tcp_s = new_TCP_server(logger, rng, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr, nullptr); TCP_Server *tcp_s = new_TCP_server(logger, mem, rng, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr, nullptr);
ck_assert_msg(pk_equal(tcp_server_public_key(tcp_s), self_public_key), "Wrong public key"); ck_assert_msg(pk_equal(tcp_server_public_key(tcp_s), self_public_key), "Wrong public key");
TCP_Proxy_Info proxy_info; TCP_Proxy_Info proxy_info;
proxy_info.proxy_type = TCP_PROXY_NONE; proxy_info.proxy_type = TCP_PROXY_NONE;
crypto_new_keypair(rng, self_public_key, self_secret_key); crypto_new_keypair(rng, self_public_key, self_secret_key);
TCP_Connections *tc_1 = new_tcp_connections(logger, rng, ns, mono_time, self_secret_key, &proxy_info); TCP_Connections *tc_1 = new_tcp_connections(logger, mem, rng, ns, mono_time, self_secret_key, &proxy_info);
ck_assert_msg(pk_equal(tcp_connections_public_key(tc_1), self_public_key), "Wrong public key"); ck_assert_msg(pk_equal(tcp_connections_public_key(tc_1), self_public_key), "Wrong public key");
crypto_new_keypair(rng, self_public_key, self_secret_key); crypto_new_keypair(rng, self_public_key, self_secret_key);
TCP_Connections *tc_2 = new_tcp_connections(logger, rng, ns, mono_time, self_secret_key, &proxy_info); TCP_Connections *tc_2 = new_tcp_connections(logger, mem, rng, ns, mono_time, self_secret_key, &proxy_info);
ck_assert_msg(pk_equal(tcp_connections_public_key(tc_2), self_public_key), "Wrong public key"); ck_assert_msg(pk_equal(tcp_connections_public_key(tc_2), self_public_key), "Wrong public key");
IP_Port ip_port_tcp_s; IP_Port ip_port_tcp_s;
@ -881,7 +906,7 @@ static void test_tcp_connection2(void)
kill_tcp_connections(tc_2); kill_tcp_connections(tc_2);
logger_kill(logger); logger_kill(logger);
mono_time_free(mono_time); mono_time_free(mem, mono_time);
} }
static void TCP_suite(void) static void TCP_suite(void)

View File

@ -54,14 +54,17 @@ static void test_store_data(void)
ck_assert(rng != nullptr); ck_assert(rng != nullptr);
const Network *ns = system_network(); const Network *ns = system_network();
ck_assert(ns != nullptr); ck_assert(ns != nullptr);
const Memory *mem = system_memory();
ck_assert(mem != nullptr);
Logger *log = logger_new(); Logger *log = logger_new();
ck_assert(log != nullptr); ck_assert(log != nullptr);
logger_callback_log(log, print_debug_logger, nullptr, nullptr); logger_callback_log(log, print_debug_logger, nullptr, nullptr);
Mono_Time *mono_time = mono_time_new(nullptr, nullptr); Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
Networking_Core *net = new_networking_no_udp(log, ns); Networking_Core *net = new_networking_no_udp(log, mem, ns);
DHT *dht = new_dht(log, rng, ns, mono_time, net, true, true); DHT *dht = new_dht(log, mem, rng, ns, mono_time, net, true, true);
Forwarding *forwarding = new_forwarding(log, rng, mono_time, dht); Forwarding *forwarding = new_forwarding(log, rng, mono_time, dht);
Announcements *announce = new_announcements(log, rng, mono_time, forwarding); Announcements *announce = new_announcements(log, mem, rng, mono_time, forwarding);
ck_assert(announce != nullptr); ck_assert(announce != nullptr);
/* Just to prevent CI from complaining that set_synch_offset is unused: */ /* Just to prevent CI from complaining that set_synch_offset is unused: */
@ -103,7 +106,7 @@ static void test_store_data(void)
kill_forwarding(forwarding); kill_forwarding(forwarding);
kill_dht(dht); kill_dht(dht);
kill_networking(net); kill_networking(net);
mono_time_free(mono_time); mono_time_free(mem, mono_time);
logger_kill(log); logger_kill(log);
} }

View File

@ -102,56 +102,58 @@ typedef struct Forwarding_Subtox {
Announcements *announce; Announcements *announce;
} Forwarding_Subtox; } Forwarding_Subtox;
static Forwarding_Subtox *new_forwarding_subtox(bool no_udp, uint32_t *index, uint16_t port) static Forwarding_Subtox *new_forwarding_subtox(const Memory *mem, bool no_udp, uint32_t *index, uint16_t port)
{ {
const Random *rng = system_random();
ck_assert(rng != nullptr);
const Network *ns = system_network();
ck_assert(ns != nullptr);
Forwarding_Subtox *subtox = (Forwarding_Subtox *)calloc(1, sizeof(Forwarding_Subtox)); Forwarding_Subtox *subtox = (Forwarding_Subtox *)calloc(1, sizeof(Forwarding_Subtox));
ck_assert(subtox != nullptr); ck_assert(subtox != nullptr);
subtox->log = logger_new(); subtox->log = logger_new();
ck_assert(subtox->log != nullptr); ck_assert(subtox->log != nullptr);
logger_callback_log(subtox->log, print_debug_logger, nullptr, index); logger_callback_log(subtox->log, print_debug_logger, nullptr, index);
subtox->mono_time = mono_time_new(nullptr, nullptr); subtox->mono_time = mono_time_new(mem, nullptr, nullptr);
const Random *rng= system_random();
ck_assert(rng != nullptr);
const Network *ns = system_network();
ck_assert(ns != nullptr);
if (no_udp) { if (no_udp) {
subtox->net = new_networking_no_udp(subtox->log, ns); subtox->net = new_networking_no_udp(subtox->log, mem, ns);
} else { } else {
const IP ip = get_loopback(); const IP ip = get_loopback();
subtox->net = new_networking_ex(subtox->log, ns, &ip, port, port, nullptr); subtox->net = new_networking_ex(subtox->log, mem, ns, &ip, port, port, nullptr);
} }
subtox->dht = new_dht(subtox->log, rng, ns, subtox->mono_time, subtox->net, true, true); subtox->dht = new_dht(subtox->log, mem, rng, ns, subtox->mono_time, subtox->net, true, true);
const TCP_Proxy_Info inf = {{{{0}}}}; const TCP_Proxy_Info inf = {{{{0}}}};
subtox->c = new_net_crypto(subtox->log, rng, ns, subtox->mono_time, subtox->dht, &inf); subtox->c = new_net_crypto(subtox->log, mem, rng, ns, subtox->mono_time, subtox->dht, &inf);
subtox->forwarding = new_forwarding(subtox->log, rng, subtox->mono_time, subtox->dht); subtox->forwarding = new_forwarding(subtox->log, rng, subtox->mono_time, subtox->dht);
ck_assert(subtox->forwarding != nullptr); ck_assert(subtox->forwarding != nullptr);
subtox->announce = new_announcements(subtox->log, rng, subtox->mono_time, subtox->forwarding); subtox->announce = new_announcements(subtox->log, mem, rng, subtox->mono_time, subtox->forwarding);
ck_assert(subtox->announce != nullptr); ck_assert(subtox->announce != nullptr);
return subtox; return subtox;
} }
static void kill_forwarding_subtox(Forwarding_Subtox *subtox) static void kill_forwarding_subtox(const Memory *mem, Forwarding_Subtox *subtox)
{ {
kill_announcements(subtox->announce); kill_announcements(subtox->announce);
kill_forwarding(subtox->forwarding); kill_forwarding(subtox->forwarding);
kill_net_crypto(subtox->c); kill_net_crypto(subtox->c);
kill_dht(subtox->dht); kill_dht(subtox->dht);
kill_networking(subtox->net); kill_networking(subtox->net);
mono_time_free(subtox->mono_time); mono_time_free(mem, subtox->mono_time);
logger_kill(subtox->log); logger_kill(subtox->log);
free(subtox); free(subtox);
} }
static void test_forwarding(void) static void test_forwarding(void)
{ {
const Memory *mem = system_memory();
ck_assert(mem != nullptr);
const Random *rng = system_random(); const Random *rng = system_random();
ck_assert(rng != nullptr); ck_assert(rng != nullptr);
const Network *ns = system_network(); const Network *ns = system_network();
@ -165,7 +167,7 @@ static void test_forwarding(void)
for (uint32_t i = 0; i < NUM_FORWARDER; ++i) { for (uint32_t i = 0; i < NUM_FORWARDER; ++i) {
index[i] = i + 1; index[i] = i + 1;
subtoxes[i] = new_forwarding_subtox(i < NUM_FORWARDER_TCP, &index[i], FORWARDING_BASE_PORT + i); subtoxes[i] = new_forwarding_subtox(mem, i < NUM_FORWARDER_TCP, &index[i], FORWARDING_BASE_PORT + i);
test_data[i].net = subtoxes[i]->net; test_data[i].net = subtoxes[i]->net;
test_data[i].send_back = 0; test_data[i].send_back = 0;
@ -317,7 +319,7 @@ static void test_forwarding(void)
for (uint32_t i = 0; i < NUM_FORWARDER; ++i) { for (uint32_t i = 0; i < NUM_FORWARDER; ++i) {
kill_forwarding_subtox(subtoxes[i]); kill_forwarding_subtox(mem, subtoxes[i]);
} }
tox_kill(relay); tox_kill(relay);

View File

@ -215,29 +215,32 @@ static void send_onion_packet(const Networking_Core *net, const Random *rng, con
/** Initialize networking. /** Initialize networking.
* Added for reverse compatibility with old new_networking calls. * Added for reverse compatibility with old new_networking calls.
*/ */
static Networking_Core *new_networking(const Logger *log, const Network *ns, const IP *ip, uint16_t port) static Networking_Core *new_networking(const Logger *log, const Memory *mem, const Network *ns, const IP *ip, uint16_t port)
{ {
return new_networking_ex(log, ns, ip, port, port + (TOX_PORTRANGE_TO - TOX_PORTRANGE_FROM), nullptr); return new_networking_ex(log, mem, ns, ip, port, port + (TOX_PORTRANGE_TO - TOX_PORTRANGE_FROM), nullptr);
} }
static void test_basic(void) static void test_basic(void)
{ {
uint32_t index[] = { 1, 2, 3 }; uint32_t index[] = { 1, 2, 3 };
const Network *ns = system_network(); const Network *ns = system_network();
ck_assert(ns != nullptr);
const Memory *mem = system_memory();
ck_assert(mem != nullptr);
const Random *rng = system_random();
ck_assert(rng != nullptr);
Logger *log1 = logger_new(); Logger *log1 = logger_new();
logger_callback_log(log1, print_debug_logger, nullptr, &index[0]); logger_callback_log(log1, print_debug_logger, nullptr, &index[0]);
Logger *log2 = logger_new(); Logger *log2 = logger_new();
logger_callback_log(log2, print_debug_logger, nullptr, &index[1]); logger_callback_log(log2, print_debug_logger, nullptr, &index[1]);
const Random *rng = system_random(); Mono_Time *mono_time1 = mono_time_new(mem, nullptr, nullptr);
ck_assert(rng != nullptr); Mono_Time *mono_time2 = mono_time_new(mem, nullptr, nullptr);
Mono_Time *mono_time1 = mono_time_new(nullptr, nullptr);
Mono_Time *mono_time2 = mono_time_new(nullptr, nullptr);
IP ip = get_loopback(); IP ip = get_loopback();
Onion *onion1 = new_onion(log1, mono_time1, rng, new_dht(log1, rng, ns, mono_time1, new_networking(log1, ns, &ip, 36567), true, false)); Onion *onion1 = new_onion(log1, mem, mono_time1, rng, new_dht(log1, mem, rng, ns, mono_time1, new_networking(log1, mem, ns, &ip, 36567), true, false));
Onion *onion2 = new_onion(log2, mono_time2, rng, new_dht(log2, rng, ns, mono_time2, new_networking(log2, ns, &ip, 36568), true, false)); Onion *onion2 = new_onion(log2, mem, mono_time2, rng, new_dht(log2, mem, rng, ns, mono_time2, new_networking(log2, mem, ns, &ip, 36568), true, false));
ck_assert_msg((onion1 != nullptr) && (onion2 != nullptr), "Onion failed initializing."); ck_assert_msg((onion1 != nullptr) && (onion2 != nullptr), "Onion failed initializing.");
networking_registerhandler(onion2->net, NET_PACKET_ANNOUNCE_REQUEST, &handle_test_1, onion2); networking_registerhandler(onion2->net, NET_PACKET_ANNOUNCE_REQUEST, &handle_test_1, onion2);
@ -280,8 +283,8 @@ static void test_basic(void)
do_onion(mono_time2, onion2); do_onion(mono_time2, onion2);
} while (handled_test_2 == 0); } while (handled_test_2 == 0);
Onion_Announce *onion1_a = new_onion_announce(log1, rng, mono_time1, onion1->dht); Onion_Announce *onion1_a = new_onion_announce(log1, mem, rng, mono_time1, onion1->dht);
Onion_Announce *onion2_a = new_onion_announce(log2, rng, mono_time2, onion2->dht); Onion_Announce *onion2_a = new_onion_announce(log2, mem, rng, mono_time2, onion2->dht);
networking_registerhandler(onion1->net, NET_PACKET_ANNOUNCE_RESPONSE, &handle_test_3, onion1); networking_registerhandler(onion1->net, NET_PACKET_ANNOUNCE_RESPONSE, &handle_test_3, onion1);
networking_registerhandler(onion1->net, NET_PACKET_ANNOUNCE_RESPONSE_OLD, &handle_test_3_old, onion1); networking_registerhandler(onion1->net, NET_PACKET_ANNOUNCE_RESPONSE_OLD, &handle_test_3_old, onion1);
ck_assert_msg((onion1_a != nullptr) && (onion2_a != nullptr), "Onion_Announce failed initializing."); ck_assert_msg((onion1_a != nullptr) && (onion2_a != nullptr), "Onion_Announce failed initializing.");
@ -331,9 +334,9 @@ static void test_basic(void)
Logger *log3 = logger_new(); Logger *log3 = logger_new();
logger_callback_log(log3, print_debug_logger, nullptr, &index[2]); logger_callback_log(log3, print_debug_logger, nullptr, &index[2]);
Mono_Time *mono_time3 = mono_time_new(nullptr, nullptr); Mono_Time *mono_time3 = mono_time_new(mem, nullptr, nullptr);
Onion *onion3 = new_onion(log3, mono_time3, rng, new_dht(log3, rng, ns, mono_time3, new_networking(log3, ns, &ip, 36569), true, false)); Onion *onion3 = new_onion(log3, mem, mono_time3, rng, new_dht(log3, mem, rng, ns, mono_time3, new_networking(log3, mem, ns, &ip, 36569), true, false));
ck_assert_msg((onion3 != nullptr), "Onion failed initializing."); ck_assert_msg((onion3 != nullptr), "Onion failed initializing.");
random_nonce(rng, nonce); random_nonce(rng, nonce);
@ -363,7 +366,7 @@ static void test_basic(void)
kill_onion(onion); kill_onion(onion);
kill_dht(dht); kill_dht(dht);
kill_networking(net); kill_networking(net);
mono_time_free(mono_time3); mono_time_free(mem, mono_time3);
logger_kill(log3); logger_kill(log3);
} }
@ -375,7 +378,7 @@ static void test_basic(void)
kill_onion(onion); kill_onion(onion);
kill_dht(dht); kill_dht(dht);
kill_networking(net); kill_networking(net);
mono_time_free(mono_time2); mono_time_free(mem, mono_time2);
logger_kill(log2); logger_kill(log2);
} }
@ -387,7 +390,7 @@ static void test_basic(void)
kill_onion(onion); kill_onion(onion);
kill_dht(dht); kill_dht(dht);
kill_networking(net); kill_networking(net);
mono_time_free(mono_time1); mono_time_free(mem, mono_time1);
logger_kill(log1); logger_kill(log1);
} }
} }
@ -400,7 +403,7 @@ typedef struct {
Onion_Client *onion_c; Onion_Client *onion_c;
} Onions; } Onions;
static Onions *new_onions(const Random *rng, uint16_t port, uint32_t *index) static Onions *new_onions(const Memory *mem, const Random *rng, uint16_t port, uint32_t *index)
{ {
IP ip = get_loopback(); IP ip = get_loopback();
ip.ip.v6.uint8[15] = 1; ip.ip.v6.uint8[15] = 1;
@ -420,7 +423,7 @@ static Onions *new_onions(const Random *rng, uint16_t port, uint32_t *index)
logger_callback_log(on->log, print_debug_logger, nullptr, index); logger_callback_log(on->log, print_debug_logger, nullptr, index);
on->mono_time = mono_time_new(nullptr, nullptr); on->mono_time = mono_time_new(mem, nullptr, nullptr);
if (!on->mono_time) { if (!on->mono_time) {
logger_kill(on->log); logger_kill(on->log);
@ -428,57 +431,57 @@ static Onions *new_onions(const Random *rng, uint16_t port, uint32_t *index)
return nullptr; return nullptr;
} }
Networking_Core *net = new_networking(on->log, ns, &ip, port); Networking_Core *net = new_networking(on->log, mem, ns, &ip, port);
if (!net) { if (!net) {
mono_time_free(on->mono_time); mono_time_free(mem, on->mono_time);
logger_kill(on->log); logger_kill(on->log);
free(on); free(on);
return nullptr; return nullptr;
} }
DHT *dht = new_dht(on->log, rng, ns, on->mono_time, net, true, false); DHT *dht = new_dht(on->log, mem, rng, ns, on->mono_time, net, true, false);
if (!dht) { if (!dht) {
kill_networking(net); kill_networking(net);
mono_time_free(on->mono_time); mono_time_free(mem, on->mono_time);
logger_kill(on->log); logger_kill(on->log);
free(on); free(on);
return nullptr; return nullptr;
} }
on->onion = new_onion(on->log, on->mono_time, rng, dht); on->onion = new_onion(on->log, mem, on->mono_time, rng, dht);
if (!on->onion) { if (!on->onion) {
kill_dht(dht); kill_dht(dht);
kill_networking(net); kill_networking(net);
mono_time_free(on->mono_time); mono_time_free(mem, on->mono_time);
logger_kill(on->log); logger_kill(on->log);
free(on); free(on);
return nullptr; return nullptr;
} }
on->onion_a = new_onion_announce(on->log, rng, on->mono_time, dht); on->onion_a = new_onion_announce(on->log, mem, rng, on->mono_time, dht);
if (!on->onion_a) { if (!on->onion_a) {
kill_onion(on->onion); kill_onion(on->onion);
kill_dht(dht); kill_dht(dht);
kill_networking(net); kill_networking(net);
mono_time_free(on->mono_time); mono_time_free(mem, on->mono_time);
logger_kill(on->log); logger_kill(on->log);
free(on); free(on);
return nullptr; return nullptr;
} }
TCP_Proxy_Info inf = {{{{0}}}}; TCP_Proxy_Info inf = {{{{0}}}};
on->onion_c = new_onion_client(on->log, rng, on->mono_time, new_net_crypto(on->log, rng, ns, on->mono_time, dht, &inf)); on->onion_c = new_onion_client(on->log, mem, rng, on->mono_time, new_net_crypto(on->log, mem, rng, ns, on->mono_time, dht, &inf));
if (!on->onion_c) { if (!on->onion_c) {
kill_onion_announce(on->onion_a); kill_onion_announce(on->onion_a);
kill_onion(on->onion); kill_onion(on->onion);
kill_dht(dht); kill_dht(dht);
kill_networking(net); kill_networking(net);
mono_time_free(on->mono_time); mono_time_free(mem, on->mono_time);
logger_kill(on->log); logger_kill(on->log);
free(on); free(on);
return nullptr; return nullptr;
@ -496,7 +499,7 @@ static void do_onions(Onions *on)
do_onion_client(on->onion_c); do_onion_client(on->onion_c);
} }
static void kill_onions(Onions *on) static void kill_onions(const Memory *mem, Onions *on)
{ {
Networking_Core *net = dht_get_net(on->onion->dht); Networking_Core *net = dht_get_net(on->onion->dht);
DHT *dht = on->onion->dht; DHT *dht = on->onion->dht;
@ -507,7 +510,7 @@ static void kill_onions(Onions *on)
kill_net_crypto(c); kill_net_crypto(c);
kill_dht(dht); kill_dht(dht);
kill_networking(net); kill_networking(net);
mono_time_free(on->mono_time); mono_time_free(mem, on->mono_time);
logger_kill(on->log); logger_kill(on->log);
free(on); free(on);
} }
@ -576,10 +579,12 @@ static void test_announce(void)
Onions *onions[NUM_ONIONS]; Onions *onions[NUM_ONIONS];
const Random *rng = system_random(); const Random *rng = system_random();
ck_assert(rng != nullptr); ck_assert(rng != nullptr);
const Memory *mem = system_memory();
ck_assert(mem != nullptr);
for (i = 0; i < NUM_ONIONS; ++i) { for (i = 0; i < NUM_ONIONS; ++i) {
index[i] = i + 1; index[i] = i + 1;
onions[i] = new_onions(rng, i + 36655, &index[i]); onions[i] = new_onions(mem, rng, i + 36655, &index[i]);
ck_assert_msg(onions[i] != nullptr, "Failed to create onions. %u", i); ck_assert_msg(onions[i] != nullptr, "Failed to create onions. %u", i);
} }
@ -653,7 +658,7 @@ static void test_announce(void)
ck_assert_msg(ip_port.port == net_port(onions[NUM_FIRST]->onion->net), "Port in returned ip not correct."); ck_assert_msg(ip_port.port == net_port(onions[NUM_FIRST]->onion->net), "Port in returned ip not correct.");
for (i = 0; i < NUM_ONIONS; ++i) { for (i = 0; i < NUM_ONIONS; ++i) {
kill_onions(onions[i]); kill_onions(mem, onions[i]);
} }
} }

View File

@ -43,7 +43,7 @@ static void dump_events(const char *path, const Tox_Events *events)
} }
} }
static void print_events(Tox_Events *events) static void print_events(const Tox_System *sys, Tox_Events *events)
{ {
const uint32_t size = tox_events_bytes_size(events); const uint32_t size = tox_events_bytes_size(events);
@ -52,11 +52,11 @@ static void print_events(Tox_Events *events)
tox_events_get_bytes(events, bytes); tox_events_get_bytes(events, bytes);
Tox_Events *events_copy = tox_events_load(bytes, size); Tox_Events *events_copy = tox_events_load(sys, bytes, size);
ck_assert(events_copy != nullptr); ck_assert(events_copy != nullptr);
free(bytes); free(bytes);
ck_assert(tox_events_equal(events, events_copy)); ck_assert(tox_events_equal(sys, events, events_copy));
tox_events_free(events_copy); tox_events_free(events_copy);
tox_events_free(events); tox_events_free(events);
@ -64,9 +64,11 @@ static void print_events(Tox_Events *events)
static bool await_message(Tox **toxes, const Tox_Dispatch *dispatch) static bool await_message(Tox **toxes, const Tox_Dispatch *dispatch)
{ {
const Tox_System *sys = tox_get_system(toxes[0]);
for (uint32_t i = 0; i < 100; ++i) { for (uint32_t i = 0; i < 100; ++i) {
// Ignore events on tox 1. // Ignore events on tox 1.
print_events(tox_events_iterate(toxes[0], false, nullptr)); print_events(sys, tox_events_iterate(toxes[0], false, nullptr));
// Check if tox 2 got the message from tox 1. // Check if tox 2 got the message from tox 1.
Tox_Events *events = tox_events_iterate(toxes[1], false, nullptr); Tox_Events *events = tox_events_iterate(toxes[1], false, nullptr);
@ -74,7 +76,7 @@ static bool await_message(Tox **toxes, const Tox_Dispatch *dispatch)
bool success = false; bool success = false;
tox_dispatch_invoke(dispatch, events, toxes[1], &success); tox_dispatch_invoke(dispatch, events, toxes[1], &success);
print_events(events); print_events(sys, events);
if (success) { if (success) {
return true; return true;
@ -101,6 +103,8 @@ static void test_tox_events(void)
ck_assert_msg(toxes[i] != nullptr, "failed to create tox instances %u", i); ck_assert_msg(toxes[i] != nullptr, "failed to create tox instances %u", i);
} }
const Tox_System *sys = tox_get_system(toxes[0]);
Tox_Err_Dispatch_New err_new; Tox_Err_Dispatch_New err_new;
Tox_Dispatch *dispatch = tox_dispatch_new(&err_new); Tox_Dispatch *dispatch = tox_dispatch_new(&err_new);
ck_assert_msg(dispatch != nullptr, "failed to create event dispatcher"); ck_assert_msg(dispatch != nullptr, "failed to create event dispatcher");
@ -123,8 +127,8 @@ static void test_tox_events(void)
while (tox_self_get_connection_status(toxes[0]) == TOX_CONNECTION_NONE || while (tox_self_get_connection_status(toxes[0]) == TOX_CONNECTION_NONE ||
tox_self_get_connection_status(toxes[1]) == TOX_CONNECTION_NONE) { tox_self_get_connection_status(toxes[1]) == TOX_CONNECTION_NONE) {
// Ignore connection events for now. // Ignore connection events for now.
print_events(tox_events_iterate(toxes[0], false, nullptr)); print_events(sys, tox_events_iterate(toxes[0], false, nullptr));
print_events(tox_events_iterate(toxes[1], false, nullptr)); print_events(sys, tox_events_iterate(toxes[1], false, nullptr));
c_sleep(tox_iteration_interval(toxes[0])); c_sleep(tox_iteration_interval(toxes[0]));
} }
@ -134,8 +138,8 @@ static void test_tox_events(void)
while (tox_friend_get_connection_status(toxes[0], 0, nullptr) == TOX_CONNECTION_NONE || while (tox_friend_get_connection_status(toxes[0], 0, nullptr) == TOX_CONNECTION_NONE ||
tox_friend_get_connection_status(toxes[1], 0, nullptr) == TOX_CONNECTION_NONE) { tox_friend_get_connection_status(toxes[1], 0, nullptr) == TOX_CONNECTION_NONE) {
// Ignore connection events for now. // Ignore connection events for now.
print_events(tox_events_iterate(toxes[0], false, nullptr)); print_events(sys, tox_events_iterate(toxes[0], false, nullptr));
print_events(tox_events_iterate(toxes[1], false, nullptr)); print_events(sys, tox_events_iterate(toxes[1], false, nullptr));
c_sleep(tox_iteration_interval(toxes[0])); c_sleep(tox_iteration_interval(toxes[0]));
} }

View File

@ -9,7 +9,7 @@ jobs:
shared: shared:
conan.shared: "True" conan.shared: "True"
steps: steps:
- bash: python -m pip install conan - bash: python -m pip install conan==1.59.0
- bash: git submodule update --init --recursive - bash: git submodule update --init --recursive
- bash: conan install -if _build -o with_tests=True -o shared=$(conan.shared) . - bash: conan install -if _build -o with_tests=True -o shared=$(conan.shared) .
- bash: CONAN_CPU_COUNT=50 CTEST_OUTPUT_ON_FAILURE=1 conan build -bf _build -if _build . - bash: CONAN_CPU_COUNT=50 CTEST_OUTPUT_ON_FAILURE=1 conan build -bf _build -if _build .

View File

@ -11,3 +11,7 @@ coverage:
# because of the above range, but toxcore coverage fluctuates a lot due # because of the above range, but toxcore coverage fluctuates a lot due
# to low coverage of error paths that sometimes happen. # to low coverage of error paths that sometimes happen.
threshold: 2% threshold: 2%
ignore:
- "auto_tests" # ignore tests in coverage analysis
- "other" # we don't test the bootstrap daemon

View File

@ -144,15 +144,17 @@ int main(int argc, char *argv[])
} }
const Random *rng = system_random(); const Random *rng = system_random();
Mono_Time *mono_time = mono_time_new(nullptr, nullptr); const Network *ns = system_network();
const Memory *mem = system_memory();
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
const uint16_t start_port = PORT; const uint16_t start_port = PORT;
const uint16_t end_port = start_port + (TOX_PORTRANGE_TO - TOX_PORTRANGE_FROM); const uint16_t end_port = start_port + (TOX_PORTRANGE_TO - TOX_PORTRANGE_FROM);
const Network *ns = system_network(); DHT *dht = new_dht(logger, mem, rng, ns, mono_time, new_networking_ex(logger, mem, ns, &ip, start_port, end_port, nullptr), true, true);
DHT *dht = new_dht(logger, rng, ns, mono_time, new_networking_ex(logger, ns, &ip, start_port, end_port, nullptr), true, true); Onion *onion = new_onion(logger, mem, mono_time, rng, dht);
Onion *onion = new_onion(logger, mono_time, rng, dht);
Forwarding *forwarding = new_forwarding(logger, rng, mono_time, dht); Forwarding *forwarding = new_forwarding(logger, rng, mono_time, dht);
GC_Announces_List *gc_announces_list = new_gca_list(); GC_Announces_List *gc_announces_list = new_gca_list();
Onion_Announce *onion_a = new_onion_announce(logger, rng, mono_time, dht); Onion_Announce *onion_a = new_onion_announce(logger, mem, rng, mono_time, dht);
#ifdef DHT_NODE_EXTRA_PACKETS #ifdef DHT_NODE_EXTRA_PACKETS
bootstrap_set_callbacks(dht_get_net(dht), DHT_VERSION_NUMBER, DHT_MOTD, sizeof(DHT_MOTD)); bootstrap_set_callbacks(dht_get_net(dht), DHT_VERSION_NUMBER, DHT_MOTD, sizeof(DHT_MOTD));
@ -173,7 +175,7 @@ int main(int argc, char *argv[])
#ifdef TCP_RELAY_ENABLED #ifdef TCP_RELAY_ENABLED
#define NUM_PORTS 3 #define NUM_PORTS 3
uint16_t ports[NUM_PORTS] = {443, 3389, PORT}; uint16_t ports[NUM_PORTS] = {443, 3389, PORT};
TCP_Server *tcp_s = new_TCP_server(logger, rng, ns, ipv6enabled, NUM_PORTS, ports, dht_get_self_secret_key(dht), onion, forwarding); TCP_Server *tcp_s = new_TCP_server(logger, mem, rng, ns, ipv6enabled, NUM_PORTS, ports, dht_get_self_secret_key(dht), onion, forwarding);
if (tcp_s == nullptr) { if (tcp_s == nullptr) {
printf("TCP server failed to initialize.\n"); printf("TCP server failed to initialize.\n");

View File

@ -1 +1 @@
23e142729a72618462018b25c830dbad5b023d0fa3de9ae53d376f43dc46b481 /usr/local/bin/tox-bootstrapd 6f4ec4239de5ea05ae341271bbda4cb78535f943a693321648ee1ab043a203d2 /usr/local/bin/tox-bootstrapd

View File

@ -280,15 +280,17 @@ int main(int argc, char *argv[])
} }
const uint16_t end_port = start_port + (TOX_PORTRANGE_TO - TOX_PORTRANGE_FROM); const uint16_t end_port = start_port + (TOX_PORTRANGE_TO - TOX_PORTRANGE_FROM);
const Memory *mem = system_memory();
const Random *rng = system_random();
const Network *ns = system_network(); const Network *ns = system_network();
Networking_Core *net = new_networking_ex(logger, ns, &ip, start_port, end_port, nullptr); Networking_Core *net = new_networking_ex(logger, mem, ns, &ip, start_port, end_port, nullptr);
if (net == nullptr) { if (net == nullptr) {
if (enable_ipv6 && enable_ipv4_fallback) { if (enable_ipv6 && enable_ipv4_fallback) {
log_write(LOG_LEVEL_WARNING, "Couldn't initialize IPv6 networking. Falling back to using IPv4.\n"); log_write(LOG_LEVEL_WARNING, "Couldn't initialize IPv6 networking. Falling back to using IPv4.\n");
enable_ipv6 = 0; enable_ipv6 = 0;
ip_init(&ip, enable_ipv6); ip_init(&ip, enable_ipv6);
net = new_networking_ex(logger, ns, &ip, start_port, end_port, nullptr); net = new_networking_ex(logger, mem, ns, &ip, start_port, end_port, nullptr);
if (net == nullptr) { if (net == nullptr) {
log_write(LOG_LEVEL_ERROR, "Couldn't fallback to IPv4. Exiting.\n"); log_write(LOG_LEVEL_ERROR, "Couldn't fallback to IPv4. Exiting.\n");
@ -308,7 +310,7 @@ int main(int argc, char *argv[])
} }
} }
Mono_Time *const mono_time = mono_time_new(nullptr, nullptr); Mono_Time *const mono_time = mono_time_new(mem, nullptr, nullptr);
if (mono_time == nullptr) { if (mono_time == nullptr) {
log_write(LOG_LEVEL_ERROR, "Couldn't initialize monotonic timer. Exiting.\n"); log_write(LOG_LEVEL_ERROR, "Couldn't initialize monotonic timer. Exiting.\n");
@ -322,12 +324,11 @@ int main(int argc, char *argv[])
mono_time_update(mono_time); mono_time_update(mono_time);
const Random *rng = system_random(); DHT *const dht = new_dht(logger, mem, rng, ns, mono_time, net, true, enable_lan_discovery);
DHT *const dht = new_dht(logger, rng, ns, mono_time, net, true, enable_lan_discovery);
if (dht == nullptr) { if (dht == nullptr) {
log_write(LOG_LEVEL_ERROR, "Couldn't initialize Tox DHT instance. Exiting.\n"); log_write(LOG_LEVEL_ERROR, "Couldn't initialize Tox DHT instance. Exiting.\n");
mono_time_free(mono_time); mono_time_free(mem, mono_time);
kill_networking(net); kill_networking(net);
logger_kill(logger); logger_kill(logger);
free(motd); free(motd);
@ -341,7 +342,7 @@ int main(int argc, char *argv[])
if (forwarding == nullptr) { if (forwarding == nullptr) {
log_write(LOG_LEVEL_ERROR, "Couldn't initialize forwarding. Exiting.\n"); log_write(LOG_LEVEL_ERROR, "Couldn't initialize forwarding. Exiting.\n");
kill_dht(dht); kill_dht(dht);
mono_time_free(mono_time); mono_time_free(mem, mono_time);
kill_networking(net); kill_networking(net);
logger_kill(logger); logger_kill(logger);
free(motd); free(motd);
@ -350,13 +351,13 @@ int main(int argc, char *argv[])
return 1; return 1;
} }
Announcements *announce = new_announcements(logger, rng, mono_time, forwarding); Announcements *announce = new_announcements(logger, mem, rng, mono_time, forwarding);
if (announce == nullptr) { if (announce == nullptr) {
log_write(LOG_LEVEL_ERROR, "Couldn't initialize DHT announcements. Exiting.\n"); log_write(LOG_LEVEL_ERROR, "Couldn't initialize DHT announcements. Exiting.\n");
kill_forwarding(forwarding); kill_forwarding(forwarding);
kill_dht(dht); kill_dht(dht);
mono_time_free(mono_time); mono_time_free(mem, mono_time);
kill_networking(net); kill_networking(net);
logger_kill(logger); logger_kill(logger);
free(motd); free(motd);
@ -372,7 +373,7 @@ int main(int argc, char *argv[])
kill_announcements(announce); kill_announcements(announce);
kill_forwarding(forwarding); kill_forwarding(forwarding);
kill_dht(dht); kill_dht(dht);
mono_time_free(mono_time); mono_time_free(mem, mono_time);
kill_networking(net); kill_networking(net);
logger_kill(logger); logger_kill(logger);
free(motd); free(motd);
@ -381,14 +382,14 @@ int main(int argc, char *argv[])
return 1; return 1;
} }
Onion *onion = new_onion(logger, mono_time, rng, dht); Onion *onion = new_onion(logger, mem, mono_time, rng, dht);
if (!onion) { if (!onion) {
log_write(LOG_LEVEL_ERROR, "Couldn't initialize Tox Onion. Exiting.\n"); log_write(LOG_LEVEL_ERROR, "Couldn't initialize Tox Onion. Exiting.\n");
kill_announcements(announce); kill_announcements(announce);
kill_forwarding(forwarding); kill_forwarding(forwarding);
kill_dht(dht); kill_dht(dht);
mono_time_free(mono_time); mono_time_free(mem, mono_time);
kill_networking(net); kill_networking(net);
logger_kill(logger); logger_kill(logger);
free(motd); free(motd);
@ -397,7 +398,7 @@ int main(int argc, char *argv[])
return 1; return 1;
} }
Onion_Announce *onion_a = new_onion_announce(logger, rng, mono_time, dht); Onion_Announce *onion_a = new_onion_announce(logger, mem, rng, mono_time, dht);
if (!onion_a) { if (!onion_a) {
log_write(LOG_LEVEL_ERROR, "Couldn't initialize Tox Onion Announce. Exiting.\n"); log_write(LOG_LEVEL_ERROR, "Couldn't initialize Tox Onion Announce. Exiting.\n");
@ -406,7 +407,7 @@ int main(int argc, char *argv[])
kill_announcements(announce); kill_announcements(announce);
kill_forwarding(forwarding); kill_forwarding(forwarding);
kill_dht(dht); kill_dht(dht);
mono_time_free(mono_time); mono_time_free(mem, mono_time);
kill_networking(net); kill_networking(net);
logger_kill(logger); logger_kill(logger);
free(motd); free(motd);
@ -429,7 +430,7 @@ int main(int argc, char *argv[])
kill_announcements(announce); kill_announcements(announce);
kill_forwarding(forwarding); kill_forwarding(forwarding);
kill_dht(dht); kill_dht(dht);
mono_time_free(mono_time); mono_time_free(mem, mono_time);
kill_networking(net); kill_networking(net);
logger_kill(logger); logger_kill(logger);
free(motd); free(motd);
@ -450,7 +451,7 @@ int main(int argc, char *argv[])
kill_announcements(announce); kill_announcements(announce);
kill_forwarding(forwarding); kill_forwarding(forwarding);
kill_dht(dht); kill_dht(dht);
mono_time_free(mono_time); mono_time_free(mem, mono_time);
kill_networking(net); kill_networking(net);
logger_kill(logger); logger_kill(logger);
free(tcp_relay_ports); free(tcp_relay_ports);
@ -469,14 +470,15 @@ int main(int argc, char *argv[])
kill_forwarding(forwarding); kill_forwarding(forwarding);
kill_onion(onion); kill_onion(onion);
kill_dht(dht); kill_dht(dht);
mono_time_free(mono_time); mono_time_free(mem, mono_time);
kill_networking(net); kill_networking(net);
logger_kill(logger); logger_kill(logger);
free(tcp_relay_ports); free(tcp_relay_ports);
return 1; return 1;
} }
tcp_server = new_TCP_server(logger, rng, ns, enable_ipv6, tcp_relay_port_count, tcp_relay_ports, tcp_server = new_TCP_server(logger, mem, rng, ns, enable_ipv6,
tcp_relay_port_count, tcp_relay_ports,
dht_get_self_secret_key(dht), onion, forwarding); dht_get_self_secret_key(dht), onion, forwarding);
free(tcp_relay_ports); free(tcp_relay_ports);
@ -515,7 +517,7 @@ int main(int argc, char *argv[])
kill_announcements(announce); kill_announcements(announce);
kill_forwarding(forwarding); kill_forwarding(forwarding);
kill_dht(dht); kill_dht(dht);
mono_time_free(mono_time); mono_time_free(mem, mono_time);
kill_networking(net); kill_networking(net);
logger_kill(logger); logger_kill(logger);
return 1; return 1;
@ -533,7 +535,7 @@ int main(int argc, char *argv[])
kill_announcements(announce); kill_announcements(announce);
kill_forwarding(forwarding); kill_forwarding(forwarding);
kill_dht(dht); kill_dht(dht);
mono_time_free(mono_time); mono_time_free(mem, mono_time);
kill_networking(net); kill_networking(net);
logger_kill(logger); logger_kill(logger);
return 1; return 1;
@ -616,7 +618,7 @@ int main(int argc, char *argv[])
kill_announcements(announce); kill_announcements(announce);
kill_forwarding(forwarding); kill_forwarding(forwarding);
kill_dht(dht); kill_dht(dht);
mono_time_free(mono_time); mono_time_free(mem, mono_time);
kill_networking(net); kill_networking(net);
logger_kill(logger); logger_kill(logger);

View File

@ -1,5 +1,5 @@
FROM toxchat/c-toxcore:sources AS src FROM toxchat/c-toxcore:sources AS src
FROM ubuntu:20.04 AS build FROM ubuntu:22.04 AS build
RUN apt-get update && \ RUN apt-get update && \
DEBIAN_FRONTEND="noninteractive" apt-get install -y --no-install-recommends \ DEBIAN_FRONTEND="noninteractive" apt-get install -y --no-install-recommends \
@ -31,8 +31,8 @@ SHELL ["/bin/bash", "-c"]
WORKDIR /work WORKDIR /work
COPY --from=src /src/ /work/ COPY --from=src /src/ /work/
RUN source .github/scripts/flags-coverage.sh \ RUN source .github/scripts/flags-coverage.sh \
&& go get github.com/things-go/go-socks5 \ && go version \
&& go build other/proxy/proxy_server.go \ && (cd other/proxy && go get github.com/things-go/go-socks5 && go build proxy_server.go) \
&& cmake -B_build -H. -GNinja \ && cmake -B_build -H. -GNinja \
-DCMAKE_C_FLAGS="$C_FLAGS" \ -DCMAKE_C_FLAGS="$C_FLAGS" \
-DCMAKE_CXX_FLAGS="$CXX_FLAGS" \ -DCMAKE_CXX_FLAGS="$CXX_FLAGS" \
@ -46,6 +46,7 @@ RUN source .github/scripts/flags-coverage.sh \
-DAUTOTEST=ON \ -DAUTOTEST=ON \
-DPROXY_TEST=ON \ -DPROXY_TEST=ON \
-DUSE_IPV6=OFF \ -DUSE_IPV6=OFF \
-DTEST_TIMEOUT_SECONDS=30 \
&& cmake --build _build --parallel 8 --target install && cmake --build _build --parallel 8 --target install
WORKDIR /work/_build WORKDIR /work/_build

View File

@ -1,5 +1,5 @@
module github.com/TokTok/c-toxcore/other/proxy module github.com/TokTok/c-toxcore/other/proxy
go 1.16 go 1.18
require github.com/things-go/go-socks5 v0.0.2 require github.com/things-go/go-socks5 v0.0.3

View File

@ -4,6 +4,8 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/things-go/go-socks5 v0.0.2 h1:dFi5iZ/LqgHRTQ6n3XlipTLDWHAQsejvJ300bH2VFWo= github.com/things-go/go-socks5 v0.0.2 h1:dFi5iZ/LqgHRTQ6n3XlipTLDWHAQsejvJ300bH2VFWo=
github.com/things-go/go-socks5 v0.0.2/go.mod h1:dhnDTBbIg31cbJdROP4/Zz6Iw7JPEpiMvOl2LdHSSjE= github.com/things-go/go-socks5 v0.0.2/go.mod h1:dhnDTBbIg31cbJdROP4/Zz6Iw7JPEpiMvOl2LdHSSjE=
github.com/things-go/go-socks5 v0.0.3 h1:QtlIhkwDuLNCwW3wnt2uTjn1mQzpyjnwct2xdPuqroI=
github.com/things-go/go-socks5 v0.0.3/go.mod h1:f8Zx+n8kfzyT90hXM767cP6sysAud93+t9rV90IgMcg=
golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

View File

@ -92,7 +92,8 @@ int main(int argc, char *argv[])
exit(0); exit(0);
} }
Mono_Time *const mono_time = mono_time_new(nullptr, nullptr); const Memory *mem = system_memory();
Mono_Time *const mono_time = mono_time_new(mem, nullptr, nullptr);
if (mono_time == nullptr) { if (mono_time == nullptr) {
fputs("Failed to allocate monotonic timer datastructure\n", stderr); fputs("Failed to allocate monotonic timer datastructure\n", stderr);
@ -102,7 +103,7 @@ int main(int argc, char *argv[])
Messenger_Options options = {0}; Messenger_Options options = {0};
options.ipv6enabled = ipv6enabled; options.ipv6enabled = ipv6enabled;
Messenger_Error err; Messenger_Error err;
m = new_messenger(mono_time, system_random(), system_network(), &options, &err); m = new_messenger(mono_time, mem, system_random(), system_network(), &options, &err);
if (!m) { if (!m) {
fprintf(stderr, "Failed to allocate messenger datastructure: %d\n", err); fprintf(stderr, "Failed to allocate messenger datastructure: %d\n", err);

View File

@ -28,6 +28,7 @@ cc_library(
cc_fuzz_test( cc_fuzz_test(
name = "bootstrap_fuzz_test", name = "bootstrap_fuzz_test",
#size = "small",
srcs = ["bootstrap_harness.cc"], srcs = ["bootstrap_harness.cc"],
copts = ["-UNDEBUG"], copts = ["-UNDEBUG"],
corpus = ["//tools/toktok-fuzzer/corpus:bootstrap_fuzzer"], corpus = ["//tools/toktok-fuzzer/corpus:bootstrap_fuzzer"],
@ -42,6 +43,7 @@ cc_fuzz_test(
cc_fuzz_test( cc_fuzz_test(
name = "e2e_fuzz_test", name = "e2e_fuzz_test",
#size = "small",
srcs = ["e2e_fuzz_test.cc"], srcs = ["e2e_fuzz_test.cc"],
copts = ["-UNDEBUG"], copts = ["-UNDEBUG"],
corpus = ["//tools/toktok-fuzzer/corpus:e2e_fuzz_test"], corpus = ["//tools/toktok-fuzzer/corpus:e2e_fuzz_test"],
@ -57,6 +59,7 @@ cc_fuzz_test(
cc_fuzz_test( cc_fuzz_test(
name = "toxsave_fuzz_test", name = "toxsave_fuzz_test",
#size = "small",
srcs = ["toxsave_harness.cc"], srcs = ["toxsave_harness.cc"],
copts = ["-UNDEBUG"], copts = ["-UNDEBUG"],
corpus = ["//tools/toktok-fuzzer/corpus:toxsave_fuzzer"], corpus = ["//tools/toktok-fuzzer/corpus:toxsave_fuzzer"],
@ -89,6 +92,7 @@ fuzzing_binary(
cc_fuzz_test( cc_fuzz_test(
name = "protodump_reduce", name = "protodump_reduce",
#size = "small",
srcs = ["protodump_reduce.cc"], srcs = ["protodump_reduce.cc"],
copts = ["-UNDEBUG"], copts = ["-UNDEBUG"],
deps = [ deps = [

View File

@ -169,7 +169,7 @@ void TestBootstrap(Fuzz_Data &input)
while (input.size > 0) { while (input.size > 0) {
Tox_Err_Events_Iterate error_iterate; Tox_Err_Events_Iterate error_iterate;
Tox_Events *events = tox_events_iterate(tox, true, &error_iterate); Tox_Events *events = tox_events_iterate(tox, true, &error_iterate);
assert(tox_events_equal(events, events)); assert(tox_events_equal(sys.sys.get(), events, events));
tox_dispatch_invoke(dispatch, events, tox, nullptr); tox_dispatch_invoke(dispatch, events, tox, nullptr);
tox_events_free(events); tox_events_free(events);
// Move the clock forward a decent amount so all the time-based checks // Move the clock forward a decent amount so all the time-based checks

View File

@ -134,6 +134,8 @@ void setup_callbacks(Tox_Dispatch *dispatch)
void TestEndToEnd(Fuzz_Data &input) void TestEndToEnd(Fuzz_Data &input)
{ {
Fuzz_System sys(input); Fuzz_System sys(input);
// Used for places where we want all allocations to succeed.
Null_System null_sys;
Ptr<Tox_Options> opts(tox_options_new(nullptr), tox_options_free); Ptr<Tox_Options> opts(tox_options_new(nullptr), tox_options_free);
assert(opts != nullptr); assert(opts != nullptr);
@ -170,7 +172,7 @@ void TestEndToEnd(Fuzz_Data &input)
while (input.size > 0) { while (input.size > 0) {
Tox_Err_Events_Iterate error_iterate; Tox_Err_Events_Iterate error_iterate;
Tox_Events *events = tox_events_iterate(tox, true, &error_iterate); Tox_Events *events = tox_events_iterate(tox, true, &error_iterate);
assert(tox_events_equal(events, events)); assert(tox_events_equal(null_sys.sys.get(), events, events));
tox_dispatch_invoke(dispatch, events, tox, nullptr); tox_dispatch_invoke(dispatch, events, tox, nullptr);
tox_events_free(events); tox_events_free(events);
// Move the clock forward a decent amount so all the time-based checks // Move the clock forward a decent amount so all the time-based checks

View File

@ -62,6 +62,33 @@ static int recv_common(Fuzz_Data &input, uint8_t *buf, size_t buf_len)
return res; return res;
} }
template <typename F>
static void *alloc_common(Fuzz_Data &data, F func)
{
CONSUME1_OR_RETURN_VAL(const uint8_t want_alloc, data, func());
if (!want_alloc) {
return nullptr;
}
return func();
}
static constexpr Memory_Funcs fuzz_memory_funcs = {
/* .malloc = */
![](Fuzz_System *self, uint32_t size) {
return alloc_common(self->data, [=]() { return std::malloc(size); });
},
/* .calloc = */
![](Fuzz_System *self, uint32_t nmemb, uint32_t size) {
return alloc_common(self->data, [=]() { return std::calloc(nmemb, size); });
},
/* .realloc = */
![](Fuzz_System *self, void *ptr, uint32_t size) {
return alloc_common(self->data, [=]() { return std::realloc(ptr, size); });
},
/* .free = */
![](Fuzz_System *self, void *ptr) { std::free(ptr); },
};
static constexpr Network_Funcs fuzz_network_funcs = { static constexpr Network_Funcs fuzz_network_funcs = {
/* .close = */ ![](Fuzz_System *self, int sock) { return 0; }, /* .close = */ ![](Fuzz_System *self, int sock) { return 0; },
/* .accept = */ ![](Fuzz_System *self, int sock) { return 1337; }, /* .accept = */ ![](Fuzz_System *self, int sock) { return 1337; },
@ -149,6 +176,7 @@ static constexpr Random_Funcs fuzz_random_funcs = {
Fuzz_System::Fuzz_System(Fuzz_Data &input) Fuzz_System::Fuzz_System(Fuzz_Data &input)
: System{ : System{
std::make_unique<Tox_System>(), std::make_unique<Tox_System>(),
std::make_unique<Memory>(Memory{&fuzz_memory_funcs, this}),
std::make_unique<Network>(Network{&fuzz_network_funcs, this}), std::make_unique<Network>(Network{&fuzz_network_funcs, this}),
std::make_unique<Random>(Random{&fuzz_random_funcs, this}), std::make_unique<Random>(Random{&fuzz_random_funcs, this}),
} }
@ -156,10 +184,22 @@ Fuzz_System::Fuzz_System(Fuzz_Data &input)
{ {
sys->mono_time_callback = ![](Fuzz_System *self) { return self->clock; }; sys->mono_time_callback = ![](Fuzz_System *self) { return self->clock; };
sys->mono_time_user_data = this; sys->mono_time_user_data = this;
sys->mem = mem.get();
sys->ns = ns.get(); sys->ns = ns.get();
sys->rng = rng.get(); sys->rng = rng.get();
} }
static constexpr Memory_Funcs null_memory_funcs = {
/* .malloc = */
![](Null_System *self, uint32_t size) { return std::malloc(size); },
/* .calloc = */
![](Null_System *self, uint32_t nmemb, uint32_t size) { return std::calloc(nmemb, size); },
/* .realloc = */
![](Null_System *self, void *ptr, uint32_t size) { return std::realloc(ptr, size); },
/* .free = */
![](Null_System *self, void *ptr) { std::free(ptr); },
};
static constexpr Network_Funcs null_network_funcs = { static constexpr Network_Funcs null_network_funcs = {
/* .close = */ ![](Null_System *self, int sock) { return 0; }, /* .close = */ ![](Null_System *self, int sock) { return 0; },
/* .accept = */ ![](Null_System *self, int sock) { return 1337; }, /* .accept = */ ![](Null_System *self, int sock) { return 1337; },
@ -224,12 +264,14 @@ static constexpr Random_Funcs null_random_funcs = {
Null_System::Null_System() Null_System::Null_System()
: System{ : System{
std::make_unique<Tox_System>(), std::make_unique<Tox_System>(),
std::make_unique<Memory>(Memory{&null_memory_funcs, this}),
std::make_unique<Network>(Network{&null_network_funcs, this}), std::make_unique<Network>(Network{&null_network_funcs, this}),
std::make_unique<Random>(Random{&null_random_funcs, this}), std::make_unique<Random>(Random{&null_random_funcs, this}),
} }
{ {
sys->mono_time_callback = ![](Fuzz_System *self) { return self->clock; }; sys->mono_time_callback = ![](Fuzz_System *self) { return self->clock; };
sys->mono_time_user_data = this; sys->mono_time_user_data = this;
sys->mem = mem.get();
sys->ns = ns.get(); sys->ns = ns.get();
sys->rng = rng.get(); sys->rng = rng.get();
} }
@ -244,6 +286,8 @@ static uint16_t get_port(const Network_Addr *addr)
} }
} }
static constexpr Memory_Funcs record_memory_funcs = null_memory_funcs;
static constexpr Network_Funcs record_network_funcs = { static constexpr Network_Funcs record_network_funcs = {
/* .close = */ ![](Record_System *self, int sock) { return 0; }, /* .close = */ ![](Record_System *self, int sock) { return 0; },
/* .accept = */ ![](Record_System *self, int sock) { return 2; }, /* .accept = */ ![](Record_System *self, int sock) { return 2; },
@ -348,6 +392,7 @@ static constexpr Random_Funcs record_random_funcs = {
Record_System::Record_System(Global &global, uint64_t seed, const char *name) Record_System::Record_System(Global &global, uint64_t seed, const char *name)
: System{ : System{
std::make_unique<Tox_System>(), std::make_unique<Tox_System>(),
std::make_unique<Memory>(Memory{&record_memory_funcs, this}),
std::make_unique<Network>(Network{&record_network_funcs, this}), std::make_unique<Network>(Network{&record_network_funcs, this}),
std::make_unique<Random>(Random{&record_random_funcs, this}), std::make_unique<Random>(Random{&record_random_funcs, this}),
} }
@ -357,6 +402,7 @@ Record_System::Record_System(Global &global, uint64_t seed, const char *name)
{ {
sys->mono_time_callback = ![](Fuzz_System *self) { return self->clock; }; sys->mono_time_callback = ![](Fuzz_System *self) { return self->clock; };
sys->mono_time_user_data = this; sys->mono_time_user_data = this;
sys->mem = mem.get();
sys->ns = ns.get(); sys->ns = ns.get();
sys->rng = rng.get(); sys->rng = rng.get();
} }

View File

@ -59,6 +59,23 @@ struct Fuzz_Data {
} \ } \
DECL = INPUT.consume1() DECL = INPUT.consume1()
/** @brief Consumes 1 byte of the fuzzer input or returns a value if no data
* available.
*
* This advances the fuzzer input data by 1 byte and consumes that byte in the
* declaration.
*
* @example
* @code
* CONSUME1_OR_RETURN_VAL(const uint8_t one_byte, input, nullptr);
* @endcode
*/
#define CONSUME1_OR_RETURN_VAL(DECL, INPUT, VAL) \
if (INPUT.size < 1) { \
return VAL; \
} \
DECL = INPUT.consume1()
/** @brief Consumes SIZE bytes of the fuzzer input or returns if not enough data available. /** @brief Consumes SIZE bytes of the fuzzer input or returns if not enough data available.
* *
* This advances the fuzzer input data by SIZE byte and consumes those bytes in * This advances the fuzzer input data by SIZE byte and consumes those bytes in
@ -100,11 +117,13 @@ void fuzz_select_target(const uint8_t *data, std::size_t size, Args &&... args)
return fuzz_select_target(selector, input, std::forward<Args>(args)...); return fuzz_select_target(selector, input, std::forward<Args>(args)...);
} }
struct Memory;
struct Network; struct Network;
struct Random; struct Random;
struct System { struct System {
std::unique_ptr<Tox_System> sys; std::unique_ptr<Tox_System> sys;
std::unique_ptr<Memory> mem;
std::unique_ptr<Network> ns; std::unique_ptr<Network> ns;
std::unique_ptr<Random> rng; std::unique_ptr<Random> rng;

View File

@ -62,13 +62,14 @@ struct with<IP_Port> {
/** @brief Construct a Networking_Core object using the Network vtable passed. /** @brief Construct a Networking_Core object using the Network vtable passed.
* *
* Use `with<Logger>{} >> with<Networking_Core>{input, ns} >> ...` to construct * Use `with<Logger>{} >> with<Networking_Core>{input, ns, mem} >> ...` to construct
* a logger and pass it to the Networking_Core constructor function. * a logger and pass it to the Networking_Core constructor function.
*/ */
template <> template <>
struct with<Networking_Core> { struct with<Networking_Core> {
Fuzz_Data &input_; Fuzz_Data &input_;
const Network *ns_; const Network *ns_;
const Memory *mem_;
Ptr<Logger> logger_{nullptr, logger_kill}; Ptr<Logger> logger_{nullptr, logger_kill};
friend with operator>>(with<Logger> f, with self) friend with operator>>(with<Logger> f, with self)
@ -82,7 +83,7 @@ struct with<Networking_Core> {
{ {
with<IP_Port>{input_} >> [&f, this](const IP_Port &ipp) { with<IP_Port>{input_} >> [&f, this](const IP_Port &ipp) {
Ptr<Networking_Core> net( Ptr<Networking_Core> net(
new_networking_ex(logger_.get(), ns_, &ipp.ip, ipp.port, ipp.port + 100, nullptr), new_networking_ex(logger_.get(), mem_, ns_, &ipp.ip, ipp.port, ipp.port + 100, nullptr),
kill_networking); kill_networking);
if (net == nullptr) { if (net == nullptr) {
return; return;

View File

@ -244,12 +244,12 @@ void RecordBootstrap()
Tox_Events *events; Tox_Events *events;
events = tox_events_iterate(tox1, true, &error_iterate); events = tox_events_iterate(tox1, true, &error_iterate);
assert(tox_events_equal(events, events)); assert(tox_events_equal(sys1.sys.get(), events, events));
tox_dispatch_invoke(dispatch, events, tox1, &done1); tox_dispatch_invoke(dispatch, events, tox1, &done1);
tox_events_free(events); tox_events_free(events);
events = tox_events_iterate(tox2, true, &error_iterate); events = tox_events_iterate(tox2, true, &error_iterate);
assert(tox_events_equal(events, events)); assert(tox_events_equal(sys2.sys.get(), events, events));
tox_dispatch_invoke(dispatch, events, tox2, &done2); tox_dispatch_invoke(dispatch, events, tox2, &done2);
tox_events_free(events); tox_events_free(events);

View File

@ -172,7 +172,7 @@ void TestEndToEnd(Fuzz_Data &input)
while (input.size > 0) { while (input.size > 0) {
Tox_Err_Events_Iterate error_iterate; Tox_Err_Events_Iterate error_iterate;
Tox_Events *events = tox_events_iterate(tox, true, &error_iterate); Tox_Events *events = tox_events_iterate(tox, true, &error_iterate);
assert(tox_events_equal(events, events)); assert(tox_events_equal(tox_get_system(tox), events, events));
tox_dispatch_invoke(dispatch, events, tox, nullptr); tox_dispatch_invoke(dispatch, events, tox, nullptr);
tox_events_free(events); tox_events_free(events);
sys.clock += std::max(System::MIN_ITERATION_INTERVAL, random_u08(sys.rng.get())); sys.clock += std::max(System::MIN_ITERATION_INTERVAL, random_u08(sys.rng.get()));

View File

@ -536,7 +536,7 @@ bool groupchat_av_enabled(const Group_Chats *g_c, uint32_t groupnumber)
*/ */
int add_av_groupchat(const Logger *log, Tox *tox, Group_Chats *g_c, audio_data_cb *audio_callback, void *userdata) int add_av_groupchat(const Logger *log, Tox *tox, Group_Chats *g_c, audio_data_cb *audio_callback, void *userdata)
{ {
const int groupnumber = add_groupchat(g_c, &tox->rng, GROUPCHAT_TYPE_AV); const int groupnumber = add_groupchat(g_c, tox->sys.rng, GROUPCHAT_TYPE_AV);
if (groupnumber == -1) { if (groupnumber == -1) {
return -1; return -1;

View File

@ -181,7 +181,7 @@ ToxAV *toxav_new(Tox *tox, Toxav_Err_New *error)
av->tox = tox; av->tox = tox;
av->m = m; av->m = m;
av->toxav_mono_time = mono_time_new(nullptr, nullptr); av->toxav_mono_time = mono_time_new(tox->sys.mem, nullptr, nullptr);
av->msi = msi_new(av->m); av->msi = msi_new(av->m);
if (av->msi == nullptr) { if (av->msi == nullptr) {
@ -239,7 +239,7 @@ void toxav_kill(ToxAV *av)
} }
} }
mono_time_free(av->toxav_mono_time); mono_time_free(av->tox->sys.mem, av->toxav_mono_time);
pthread_mutex_unlock(av->mutex); pthread_mutex_unlock(av->mutex);
pthread_mutex_destroy(av->mutex); pthread_mutex_destroy(av->mutex);

View File

@ -23,6 +23,28 @@ cc_library(
deps = [":attributes"], 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( cc_library(
name = "util", name = "util",
srcs = ["util.c"], srcs = ["util.c"],
@ -37,6 +59,7 @@ cc_library(
deps = [ deps = [
":attributes", ":attributes",
":ccompat", ":ccompat",
":mem",
"@pthread", "@pthread",
], ],
) )
@ -175,6 +198,7 @@ cc_library(
deps = [ deps = [
":attributes", ":attributes",
":ccompat", ":ccompat",
":mem",
"@pthread", "@pthread",
], ],
) )
@ -204,6 +228,7 @@ cc_library(
deps = [ deps = [
":ccompat", ":ccompat",
":crypto_core", ":crypto_core",
":mem",
":mono_time", ":mono_time",
], ],
) )
@ -223,6 +248,7 @@ cc_library(
":ccompat", ":ccompat",
":crypto_core", ":crypto_core",
":logger", ":logger",
":mem",
":mono_time", ":mono_time",
":util", ":util",
"@libsodium", "@libsodium",
@ -260,6 +286,7 @@ cc_library(
deps = [ deps = [
":ccompat", ":ccompat",
":crypto_core", ":crypto_core",
":mem",
":mono_time", ":mono_time",
":util", ":util",
], ],
@ -315,6 +342,7 @@ cc_library(
":ccompat", ":ccompat",
":crypto_core", ":crypto_core",
":logger", ":logger",
":mem",
":mono_time", ":mono_time",
":network", ":network",
":ping_array", ":ping_array",
@ -413,6 +441,7 @@ cc_library(
":attributes", ":attributes",
":ccompat", ":ccompat",
":crypto_core", ":crypto_core",
":mem",
":network", ":network",
], ],
) )
@ -766,6 +795,7 @@ cc_library(
":group", ":group",
":group_moderation", ":group_moderation",
":logger", ":logger",
":mem",
":mono_time", ":mono_time",
":network", ":network",
"//c-toxcore/toxencryptsave:defines", "//c-toxcore/toxencryptsave:defines",
@ -810,6 +840,7 @@ cc_library(
":bin_pack", ":bin_pack",
":bin_unpack", ":bin_unpack",
":ccompat", ":ccompat",
":mem",
":tox", ":tox",
":tox_unpack", ":tox_unpack",
"//c-toxcore/third_party:cmp", "//c-toxcore/third_party:cmp",
@ -822,6 +853,7 @@ cc_test(
srcs = ["tox_events_test.cc"], srcs = ["tox_events_test.cc"],
deps = [ deps = [
":crypto_core", ":crypto_core",
":tox",
":tox_events", ":tox_events",
"@com_google_googletest//:gtest", "@com_google_googletest//:gtest",
"@com_google_googletest//:gtest_main", "@com_google_googletest//:gtest_main",
@ -832,7 +864,10 @@ cc_fuzz_test(
name = "tox_events_fuzz_test", name = "tox_events_fuzz_test",
srcs = ["tox_events_fuzz_test.cc"], srcs = ["tox_events_fuzz_test.cc"],
corpus = ["//tools/toktok-fuzzer/corpus:tox_events_fuzz_test"], corpus = ["//tools/toktok-fuzzer/corpus:tox_events_fuzz_test"],
deps = [":tox_events"], deps = [
":tox_events",
"//c-toxcore/testing/fuzzing:fuzz_support",
],
) )
cc_library( cc_library(

View File

@ -91,6 +91,7 @@ struct DHT {
const Logger *log; const Logger *log;
const Network *ns; const Network *ns;
Mono_Time *mono_time; Mono_Time *mono_time;
const Memory *mem;
const Random *rng; const Random *rng;
Networking_Core *net; Networking_Core *net;
@ -414,12 +415,13 @@ int pack_ip_port(const Logger *logger, uint8_t *data, uint16_t length, const IP_
} }
} }
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 *shared_key, const uint8_t type,
const uint8_t *plain, size_t plain_length, const uint8_t *plain, size_t plain_length,
uint8_t *packet, size_t 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]; uint8_t nonce[CRYPTO_NONCE_SIZE];
if (encrypted == nullptr) { if (encrypted == nullptr) {
@ -431,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); const int encrypted_length = encrypt_data_symmetric(shared_key, nonce, plain, plain_length, encrypted);
if (encrypted_length == -1) { if (encrypted_length == -1) {
free(encrypted); mem_delete(mem, encrypted);
return -1; return -1;
} }
if (length < 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + encrypted_length) { if (length < 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + encrypted_length) {
free(encrypted); mem_delete(mem, encrypted);
return -1; return -1;
} }
@ -445,7 +447,7 @@ 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, nonce, CRYPTO_NONCE_SIZE);
memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, encrypted, encrypted_length); 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; return 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + encrypted_length;
} }
@ -937,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]; 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)) { plain, sizeof(plain), request, sizeof(request)) != sizeof(request)) {
return false; return false;
} }
@ -1008,12 +1011,12 @@ static bool store_node_ok(const Client_data *client, uint64_t cur_time, const ui
} }
non_null() 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) const uint8_t *comp_public_key)
{ {
// Pass comp_public_key to qsort with each Client_data entry, so the // Pass comp_public_key to qsort with each Client_data entry, so the
// comparison function can use it as the base of comparison. // 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) { if (cmp_list == nullptr) {
return; return;
@ -1031,7 +1034,7 @@ static void sort_client_list(Client_data *list, uint64_t cur_time, unsigned int
list[i] = cmp_list[i].entry; list[i] = cmp_list[i].entry;
} }
free(cmp_list); mem_delete(mem, cmp_list);
} }
non_null() non_null()
@ -1092,7 +1095,7 @@ static bool replace_all(const DHT *dht,
return false; 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]; Client_data *const client = &list[0];
pk_copy(client->public_key, public_key); pk_copy(client->public_key, public_key);
@ -1392,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 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, dht->self_public_key, shared_key, NET_PACKET_GET_NODES,
plain, sizeof(plain), data, sizeof(data)); plain, sizeof(plain), data, sizeof(data));
@ -1442,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; 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); 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, dht->self_public_key, shared_encryption_key, NET_PACKET_SEND_NODES_IPV6,
plain, 1 + nodes_length + length, data, SIZEOF_VLA(data)); plain, 1 + nodes_length + length, data, SIZEOF_VLA(data));
@ -1681,7 +1684,7 @@ int dht_addfriend(DHT *dht, const uint8_t *public_key, dht_ip_cb *ip_callback,
return 0; 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) { if (temp == nullptr) {
return -1; return -1;
@ -1726,12 +1729,12 @@ int dht_delfriend(DHT *dht, const uint8_t *public_key, uint32_t lock_token)
} }
if (dht->num_friends == 0) { if (dht->num_friends == 0) {
free(dht->friends_list); mem_delete(dht->mem, dht->friends_list);
dht->friends_list = nullptr; dht->friends_list = nullptr;
return 0; 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) { if (temp == nullptr) {
return -1; return -1;
@ -1784,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); const uint64_t temp_time = mono_time_get(dht->mono_time);
uint32_t num_nodes = 0; uint32_t num_nodes = 0;
Client_data **client_list = (Client_data **)calloc(list_count * 2, sizeof(Client_data *)); Client_data **client_list = (Client_data **)mem_valloc(dht->mem, list_count * 2, sizeof(Client_data *));
IPPTsPng **assoc_list = (IPPTsPng **)calloc(list_count * 2, sizeof(IPPTsPng *)); IPPTsPng **assoc_list = (IPPTsPng **)mem_valloc(dht->mem, list_count * 2, sizeof(IPPTsPng *));
unsigned int sort = 0; unsigned int sort = 0;
bool sort_ok = false; bool sort_ok = false;
if (client_list == nullptr || assoc_list == nullptr) { if (client_list == nullptr || assoc_list == nullptr) {
free(assoc_list); mem_delete(dht->mem, assoc_list);
free(client_list); mem_delete(dht->mem, client_list);
return 0; return 0;
} }
@ -1831,7 +1834,7 @@ static uint8_t do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, co
} }
if (sortable && sort_ok) { 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) if (num_nodes > 0 && (mono_time_is_timeout(dht->mono_time, *lastgetnode, GET_NODE_INTERVAL)
@ -1848,8 +1851,8 @@ static uint8_t do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, co
++*bootstrap_times; ++*bootstrap_times;
} }
free(assoc_list); mem_delete(dht->mem, assoc_list);
free(client_list); mem_delete(dht->mem, client_list);
return not_kill; return not_kill;
} }
@ -2606,14 +2609,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) bool hole_punching_enabled, bool lan_discovery_enabled)
{ {
if (net == nullptr) { if (net == nullptr) {
return nullptr; return nullptr;
} }
DHT *const dht = (DHT *)calloc(1, sizeof(DHT)); DHT *const dht = (DHT *)mem_alloc(mem, sizeof(DHT));
if (dht == nullptr) { if (dht == nullptr) {
return nullptr; return nullptr;
@ -2625,11 +2629,12 @@ DHT *new_dht(const Logger *log, const Random *rng, const Network *ns, Mono_Time
dht->log = log; dht->log = log;
dht->net = net; dht->net = net;
dht->rng = rng; dht->rng = rng;
dht->mem = mem;
dht->hole_punching_enabled = hole_punching_enabled; dht->hole_punching_enabled = hole_punching_enabled;
dht->lan_discovery_enabled = lan_discovery_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) { if (dht->ping == nullptr) {
kill_dht(dht); kill_dht(dht);
@ -2648,8 +2653,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); 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_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, 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) { if (dht->shared_keys_recv == nullptr || dht->shared_keys_sent == nullptr) {
kill_dht(dht); kill_dht(dht);
@ -2657,7 +2662,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) { if (dht->dht_ping_array == nullptr) {
kill_dht(dht); kill_dht(dht);
@ -2722,11 +2727,11 @@ void kill_dht(DHT *dht)
shared_key_cache_free(dht->shared_keys_recv); shared_key_cache_free(dht->shared_keys_recv);
shared_key_cache_free(dht->shared_keys_sent); shared_key_cache_free(dht->shared_keys_sent);
ping_array_kill(dht->dht_ping_array); ping_array_kill(dht->dht_ping_array);
ping_kill(dht->ping); ping_kill(dht->mem, dht->ping);
free(dht->friends_list); mem_delete(dht->mem, dht->friends_list);
free(dht->loaded_nodes_list); mem_delete(dht->mem, dht->loaded_nodes_list);
crypto_memzero(dht->self_secret_key, sizeof(dht->self_secret_key)); 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 */ /* new DHT format for load/save, more robust and forward compatible */
@ -2780,7 +2785,7 @@ void dht_save(const DHT *dht, uint8_t *data)
/* get right offset. we write the actual header later. */ /* get right offset. we write the actual header later. */
data = state_write_section_header(data, DHT_STATE_COOKIE_TYPE, 0, 0); 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) { if (clients == nullptr) {
LOGGER_ERROR(dht->log, "could not allocate %u nodes", MAX_SAVED_DHT_NODES); LOGGER_ERROR(dht->log, "could not allocate %u nodes", MAX_SAVED_DHT_NODES);
@ -2829,7 +2834,7 @@ 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, 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); 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 */ /** Bootstrap from this number of nodes every time `dht_connect_after_load()` is called */
@ -2847,7 +2852,7 @@ int dht_connect_after_load(DHT *dht)
/* DHT is connected, stop. */ /* DHT is connected, stop. */
if (dht_non_lan_connected(dht)) { 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_nodes_list = nullptr;
dht->loaded_num_nodes = 0; dht->loaded_num_nodes = 0;
return 0; return 0;
@ -2873,9 +2878,9 @@ static State_Load_Status dht_load_state_callback(void *outer, const uint8_t *dat
break; break;
} }
free(dht->loaded_nodes_list); mem_delete(dht->mem, dht->loaded_nodes_list);
// Copy to loaded_clients_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) { if (dht->loaded_nodes_list == nullptr) {
LOGGER_ERROR(dht->log, "could not allocate %u nodes", MAX_SAVED_DHT_NODES); LOGGER_ERROR(dht->log, "could not allocate %u nodes", MAX_SAVED_DHT_NODES);

View File

@ -14,6 +14,7 @@
#include "attributes.h" #include "attributes.h"
#include "crypto_core.h" #include "crypto_core.h"
#include "logger.h" #include "logger.h"
#include "mem.h"
#include "mono_time.h" #include "mono_time.h"
#include "network.h" #include "network.h"
#include "ping_array.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. * @retval -1 on failure.
*/ */
non_null() 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 public_key[CRYPTO_PUBLIC_KEY_SIZE],
const uint8_t *shared_key, const uint8_t type, const uint8_t *shared_key, const uint8_t type,
const uint8_t *plain, size_t plain_length, const uint8_t *plain, size_t plain_length,
@ -494,8 +495,8 @@ int dht_load(DHT *dht, const uint8_t *data, uint32_t length);
/** Initialize DHT. */ /** Initialize DHT. */
non_null() non_null()
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,
bool hole_punching_enabled, bool lan_discovery_enabled); Mono_Time *mono_time, Networking_Core *net, bool hole_punching_enabled, bool lan_discovery_enabled);
nullable(1) nullable(1)
void kill_dht(DHT *dht); void kill_dht(DHT *dht);

View File

@ -187,12 +187,14 @@ TEST(Request, CreateAndParse)
TEST(AnnounceNodes, SetAndTest) TEST(AnnounceNodes, SetAndTest)
{ {
Logger *log = logger_new();
Mono_Time *mono_time = mono_time_new(nullptr, nullptr);
const Random *rng = system_random(); const Random *rng = system_random();
const Network *ns = system_network(); const Network *ns = system_network();
Networking_Core *net = new_networking_no_udp(log, ns); const Memory *mem = system_memory();
DHT *dht = new_dht(log, rng, ns, mono_time, net, true, true);
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); ASSERT_NE(dht, nullptr);
uint8_t pk_data[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t pk_data[CRYPTO_PUBLIC_KEY_SIZE];
@ -224,7 +226,7 @@ TEST(AnnounceNodes, SetAndTest)
kill_dht(dht); kill_dht(dht);
kill_networking(net); kill_networking(net);
mono_time_free(mono_time); mono_time_free(mem, mono_time);
logger_kill(log); logger_kill(log);
} }

View File

@ -39,6 +39,8 @@ libtoxcore_la_SOURCES = ../third_party/cmp/cmp.c \
../toxcore/events/self_connection_status.c \ ../toxcore/events/self_connection_status.c \
../toxcore/DHT.h \ ../toxcore/DHT.h \
../toxcore/DHT.c \ ../toxcore/DHT.c \
../toxcore/mem.h \
../toxcore/mem.c \
../toxcore/mono_time.h \ ../toxcore/mono_time.h \
../toxcore/mono_time.c \ ../toxcore/mono_time.c \
../toxcore/network.h \ ../toxcore/network.h \

View File

@ -41,18 +41,18 @@ bool friend_is_valid(const Messenger *m, int32_t friendnumber)
/** @brief Set the size of the friend list to numfriends. /** @brief Set the size of the friend list to numfriends.
* *
* @retval -1 if realloc fails. * @retval -1 if mem_vrealloc fails.
*/ */
non_null() non_null()
static int realloc_friendlist(Messenger *m, uint32_t num) static int realloc_friendlist(Messenger *m, uint32_t num)
{ {
if (num == 0) { if (num == 0) {
free(m->friendlist); mem_delete(m->mem, m->friendlist);
m->friendlist = nullptr; m->friendlist = nullptr;
return 0; 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) { if (newfriendlist == nullptr) {
return -1; return -1;
@ -313,7 +313,7 @@ static int clear_receipts(Messenger *m, int32_t friendnumber)
while (receipts != nullptr) { while (receipts != nullptr) {
struct Receipts *temp_r = receipts->next; struct Receipts *temp_r = receipts->next;
free(receipts); mem_delete(m->mem, receipts);
receipts = temp_r; receipts = temp_r;
} }
@ -329,7 +329,7 @@ static int add_receipt(Messenger *m, int32_t friendnumber, uint32_t packet_num,
return -1; 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) { if (new_receipts == nullptr) {
return -1; return -1;
@ -430,7 +430,7 @@ static int do_receipts(Messenger *m, int32_t friendnumber, void *userdata)
struct Receipts *r_next = receipts->next; struct Receipts *r_next = receipts->next;
free(receipts); mem_delete(m->mem, receipts);
m->friendlist[friendnumber].receipts_start = r_next; m->friendlist[friendnumber].receipts_start = r_next;
@ -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_load_cb *load_callback,
m_state_save_cb *save_callback) m_state_save_cb *save_callback)
{ {
Messenger_State_Plugin *temp = (Messenger_State_Plugin *)realloc(m->options.state_plugins, const uint32_t new_length = m->options.state_plugins_length + 1;
sizeof(Messenger_State_Plugin) * (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) { if (temp == nullptr) {
return false; return false;
} }
m->options.state_plugins = temp; 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; const uint8_t index = m->options.state_plugins_length - 1;
m->options.state_plugins[index].type = type; 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. * 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) { if (options == nullptr) {
return nullptr; return nullptr;
@ -3512,20 +3514,21 @@ Messenger *new_messenger(Mono_Time *mono_time, const Random *rng, const Network
*error = MESSENGER_ERROR_OTHER; *error = MESSENGER_ERROR_OTHER;
} }
Messenger *m = (Messenger *)calloc(1, sizeof(Messenger)); Messenger *m = (Messenger *)mem_alloc(mem, sizeof(Messenger));
if (m == nullptr) { if (m == nullptr) {
return nullptr; return nullptr;
} }
m->mono_time = mono_time; m->mono_time = mono_time;
m->mem = mem;
m->rng = rng; m->rng = rng;
m->ns = ns; m->ns = ns;
m->fr = friendreq_new(); m->fr = friendreq_new();
if (m->fr == nullptr) { if (m->fr == nullptr) {
free(m); mem_delete(mem, m);
return nullptr; return nullptr;
} }
@ -3533,7 +3536,7 @@ Messenger *new_messenger(Mono_Time *mono_time, const Random *rng, const Network
if (m->log == nullptr) { if (m->log == nullptr) {
friendreq_kill(m->fr); friendreq_kill(m->fr);
free(m); mem_delete(mem, m);
return nullptr; return nullptr;
} }
@ -3548,17 +3551,17 @@ Messenger *new_messenger(Mono_Time *mono_time, const Random *rng, const Network
} }
if (options->udp_disabled) { 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 { } else {
IP ip; IP ip;
ip_init(&ip, options->ipv6enabled); 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) { if (m->net == nullptr) {
friendreq_kill(m->fr); friendreq_kill(m->fr);
logger_kill(m->log); logger_kill(m->log);
free(m); mem_delete(mem, m);
if (error != nullptr && net_err == 1) { if (error != nullptr && net_err == 1) {
*error = MESSENGER_ERROR_PORT; *error = MESSENGER_ERROR_PORT;
@ -3567,24 +3570,24 @@ Messenger *new_messenger(Mono_Time *mono_time, const Random *rng, const Network
return nullptr; 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) { if (m->dht == nullptr) {
kill_networking(m->net); kill_networking(m->net);
friendreq_kill(m->fr); friendreq_kill(m->fr);
logger_kill(m->log); logger_kill(m->log);
free(m); mem_delete(mem, m);
return nullptr; 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) { if (m->net_crypto == nullptr) {
kill_dht(m->dht); kill_dht(m->dht);
kill_networking(m->net); kill_networking(m->net);
friendreq_kill(m->fr); friendreq_kill(m->fr);
logger_kill(m->log); logger_kill(m->log);
free(m); mem_delete(mem, m);
return nullptr; return nullptr;
} }
@ -3597,7 +3600,7 @@ Messenger *new_messenger(Mono_Time *mono_time, const Random *rng, const Network
kill_networking(m->net); kill_networking(m->net);
friendreq_kill(m->fr); friendreq_kill(m->fr);
logger_kill(m->log); logger_kill(m->log);
free(m); mem_delete(mem, m);
return nullptr; return nullptr;
} }
@ -3605,15 +3608,15 @@ Messenger *new_messenger(Mono_Time *mono_time, const Random *rng, const Network
if (options->dht_announcements_enabled) { if (options->dht_announcements_enabled) {
m->forwarding = new_forwarding(m->log, m->rng, m->mono_time, m->dht); 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 { } else {
m->forwarding = nullptr; m->forwarding = nullptr;
m->announce = nullptr; m->announce = nullptr;
} }
m->onion = new_onion(m->log, m->mono_time, m->rng, m->dht); m->onion = new_onion(m->log, m->mem, m->mono_time, m->rng, m->dht);
m->onion_a = new_onion_announce(m->log, m->rng, m->mono_time, 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->rng, m->mono_time, m->net_crypto); 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); 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)) || 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); kill_networking(m->net);
friendreq_kill(m->fr); friendreq_kill(m->fr);
logger_kill(m->log); logger_kill(m->log);
free(m); mem_delete(mem, m);
return nullptr; return nullptr;
} }
@ -3654,15 +3657,16 @@ Messenger *new_messenger(Mono_Time *mono_time, const Random *rng, const Network
kill_networking(m->net); kill_networking(m->net);
friendreq_kill(m->fr); friendreq_kill(m->fr);
logger_kill(m->log); logger_kill(m->log);
free(m); mem_delete(mem, m);
return nullptr; return nullptr;
} }
#endif /* VANILLA_NACL */ #endif /* VANILLA_NACL */
if (options->tcp_server_port != 0) { 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, m->tcp_server = new_TCP_server(m->log, m->mem, m->rng, m->ns, options->ipv6enabled, 1,
dht_get_self_secret_key(m->dht), m->onion, m->forwarding); &options->tcp_server_port, dht_get_self_secret_key(m->dht),
m->onion, m->forwarding);
if (m->tcp_server == nullptr) { if (m->tcp_server == nullptr) {
kill_onion(m->onion); kill_onion(m->onion);
@ -3682,7 +3686,7 @@ Messenger *new_messenger(Mono_Time *mono_time, const Random *rng, const Network
kill_networking(m->net); kill_networking(m->net);
friendreq_kill(m->fr); friendreq_kill(m->fr);
logger_kill(m->log); logger_kill(m->log);
free(m); mem_delete(mem, m);
if (error != nullptr) { if (error != nullptr) {
*error = MESSENGER_ERROR_TCP_SERVER; *error = MESSENGER_ERROR_TCP_SERVER;
@ -3745,11 +3749,11 @@ void kill_messenger(Messenger *m)
} }
logger_kill(m->log); logger_kill(m->log);
free(m->friendlist); mem_delete(m->mem, m->friendlist);
friendreq_kill(m->fr); friendreq_kill(m->fr);
free(m->options.state_plugins); mem_delete(m->mem, m->options.state_plugins);
free(m); mem_delete(m->mem, m);
} }
bool m_is_receiving_file(Messenger *m) bool m_is_receiving_file(Messenger *m)

View File

@ -245,6 +245,7 @@ typedef struct Friend {
struct Messenger { struct Messenger {
Logger *log; Logger *log;
Mono_Time *mono_time; Mono_Time *mono_time;
const Memory *mem;
const Random *rng; const Random *rng;
const Network *ns; 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. * if error is not NULL it will be set to one of the values in the enum above.
*/ */
non_null() 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. /** @brief Run this before closing shop.
* *

View File

@ -8,6 +8,7 @@
*/ */
#include "TCP_client.h" #include "TCP_client.h"
#include <assert.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.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 * @retval false on failure
*/ */
non_null() 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) { 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 { } 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"; char success[] = "200";
uint8_t data[16]; // draining works the best if the length is a power of 2 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, const TCP_Connection *con0 = &tcp_conn->con;
&tcp_conn->con.ip_port); const int ret = read_TCP_packet(logger, con0->mem, con0->ns, con0->sock, data, sizeof(data) - 1, &con0->ip_port);
if (ret == -1) { if (ret == -1) {
return 0; return 0;
@ -167,9 +168,10 @@ static int proxy_http_read_connection_response(const Logger *logger, const TCP_C
while (data_left > 0) { while (data_left > 0) {
uint8_t temp_data[16]; uint8_t temp_data[16];
const uint16_t temp_data_size = min_u16(data_left, sizeof(temp_data)); 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, if (read_TCP_packet(logger, con->mem, con->ns, con->sock, temp_data, temp_data_size,
&tcp_conn->con.ip_port) == -1) { &con->ip_port) == -1) {
LOGGER_ERROR(logger, "failed to drain TCP data (but ignoring failure)"); LOGGER_ERROR(logger, "failed to drain TCP data (but ignoring failure)");
return 1; return 1;
} }
@ -212,7 +214,8 @@ non_null()
static int socks5_read_handshake_response(const Logger *logger, const TCP_Client_Connection *tcp_conn) static int socks5_read_handshake_response(const Logger *logger, const TCP_Client_Connection *tcp_conn)
{ {
uint8_t data[2]; 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) { if (ret == -1) {
return 0; 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)) { if (net_family_is_ipv4(tcp_conn->ip_port.ip.family)) {
uint8_t data[4 + sizeof(IP4) + sizeof(uint16_t)]; 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) { if (ret == -1) {
return 0; return 0;
@ -273,7 +277,8 @@ static int proxy_socks5_read_connection_response(const Logger *logger, const TCP
} }
} else { } else {
uint8_t data[4 + sizeof(IP6) + sizeof(uint16_t)]; 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) { if (ret == -1) {
return 0; return 0;
@ -566,10 +571,16 @@ void forwarding_handler(TCP_Client_Connection *con, forwarded_response_cb *forwa
/** Create new TCP connection to ip_port/public_key */ /** Create new TCP connection to ip_port/public_key */
TCP_Client_Connection *new_TCP_connection( 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 Logger *logger, const Memory *mem, const Mono_Time *mono_time, const Random *rng, const Network *ns,
const uint8_t *public_key, const uint8_t *self_public_key, const uint8_t *self_secret_key, 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) 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)) { if (!net_family_is_ipv4(ip_port->ip.family) && !net_family_is_ipv6(ip_port->ip.family)) {
return nullptr; return nullptr;
} }
@ -597,12 +608,12 @@ TCP_Client_Connection *new_TCP_connection(
return nullptr; 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); kill_sock(ns, sock);
return nullptr; 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) { if (temp == nullptr) {
kill_sock(ns, sock); kill_sock(ns, sock);
@ -610,6 +621,7 @@ TCP_Client_Connection *new_TCP_connection(
} }
temp->con.ns = ns; temp->con.ns = ns;
temp->con.mem = mem;
temp->con.rng = rng; temp->con.rng = rng;
temp->con.sock = sock; temp->con.sock = sock;
temp->con.ip_port = *ip_port; temp->con.ip_port = *ip_port;
@ -637,7 +649,7 @@ TCP_Client_Connection *new_TCP_connection(
if (generate_handshake(temp) == -1) { if (generate_handshake(temp) == -1) {
kill_sock(ns, sock); kill_sock(ns, sock);
free(temp); mem_delete(mem, temp);
return nullptr; return 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) static bool tcp_process_packet(const Logger *logger, TCP_Client_Connection *conn, void *userdata)
{ {
uint8_t packet[MAX_PACKET_SIZE]; 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) { if (len == 0) {
return false; return false;
@ -969,7 +981,8 @@ void do_TCP_connection(const Logger *logger, const Mono_Time *mono_time,
if (tcp_connection->status == TCP_CLIENT_UNCONFIRMED) { if (tcp_connection->status == TCP_CLIENT_UNCONFIRMED) {
uint8_t data[TCP_SERVER_HANDSHAKE_SIZE]; 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 (sizeof(data) == len) {
if (handle_handshake(tcp_connection, data) == 0) { if (handle_handshake(tcp_connection, data) == 0) {
@ -998,8 +1011,10 @@ void kill_TCP_connection(TCP_Client_Connection *tcp_connection)
return; 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); kill_sock(tcp_connection->con.ns, tcp_connection->con.sock);
crypto_memzero(tcp_connection, sizeof(TCP_Client_Connection)); crypto_memzero(tcp_connection, sizeof(TCP_Client_Connection));
free(tcp_connection); mem_delete(mem, tcp_connection);
} }

View File

@ -57,10 +57,10 @@ non_null()
void tcp_con_set_custom_uint(TCP_Client_Connection *con, uint32_t value); void tcp_con_set_custom_uint(TCP_Client_Connection *con, uint32_t value);
/** Create new TCP connection to ip_port/public_key */ /** Create new TCP connection to ip_port/public_key */
non_null(1, 2, 3, 4, 5, 6, 7, 8) nullable(9) non_null(1, 2, 3, 4, 5, 6, 7, 8, 9) nullable(10)
TCP_Client_Connection *new_TCP_connection( 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 Logger *logger, const Memory *mem, const Mono_Time *mono_time, const Random *rng, const Network *ns,
const uint8_t *public_key, const uint8_t *self_public_key, const uint8_t *self_secret_key, 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); const TCP_Proxy_Info *proxy_info);
/** Run the TCP connection */ /** Run the TCP connection */

View File

@ -10,13 +10,13 @@
#include "ccompat.h" #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) { while (p != nullptr) {
TCP_Priority_List *pp = p; TCP_Priority_List *pp = p;
p = p->next; p = p->next;
free(pp->data); mem_delete(mem, pp->data);
free(pp); mem_delete(mem, pp);
} }
} }
@ -74,8 +74,8 @@ int send_pending_data(const Logger *logger, TCP_Connection *con)
TCP_Priority_List *pp = p; TCP_Priority_List *pp = p;
p = p->next; p = p->next;
free(pp->data); mem_delete(con->mem, pp->data);
free(pp); mem_delete(con->mem, pp);
} }
con->priority_queue_start = p; 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 * @retval true on success
*/ */
non_null() non_null()
static bool add_priority(TCP_Connection *con, const uint8_t *packet, uint16_t size, uint16_t sent) 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 *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) { if (new_list == nullptr) {
return false; 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->next = nullptr;
new_list->size = size; new_list->size = size;
new_list->sent = sent; 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) { if (new_list->data == nullptr) {
free(new_list); mem_delete(con->mem, new_list);
return false; return false;
} }
@ -195,7 +195,8 @@ int write_packet_TCP_secure_connection(const Logger *logger, TCP_Connection *con
* return length on success * return length on success
* return -1 on failure/no data in buffer. * 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); 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. * return -1 on failure.
*/ */
non_null() 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); const uint16_t count = net_socket_data_recv_buffer(ns, sock);
@ -255,12 +256,13 @@ static uint16_t read_TCP_length(const Logger *logger, const Network *ns, Socket
* @retval -1 on failure (connection must be killed). * @retval -1 on failure (connection must be killed).
*/ */
int read_packet_TCP_secure_connection( int read_packet_TCP_secure_connection(
const Logger *logger, const Network *ns, Socket sock, uint16_t *next_packet_length, 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, const uint8_t *shared_key, uint8_t *recv_nonce, uint8_t *data,
uint16_t max_len, const IP_Port *ip_port) uint16_t max_len, const IP_Port *ip_port)
{ {
if (*next_packet_length == 0) { 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) { if (len == (uint16_t) -1) {
return -1; return -1;
@ -279,7 +281,7 @@ int read_packet_TCP_secure_connection(
} }
VLA(uint8_t, data_encrypted, (int) *next_packet_length); 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) { if (len_packet == -1) {
return 0; return 0;

View File

@ -7,6 +7,7 @@
#define C_TOXCORE_TOXCORE_TCP_COMMON_H #define C_TOXCORE_TOXCORE_TCP_COMMON_H
#include "crypto_core.h" #include "crypto_core.h"
#include "mem.h"
#include "network.h" #include "network.h"
typedef struct TCP_Priority_List TCP_Priority_List; typedef struct TCP_Priority_List TCP_Priority_List;
@ -17,8 +18,8 @@ struct TCP_Priority_List {
uint8_t *data; uint8_t *data;
}; };
nullable(1) non_null(1) nullable(2)
void wipe_priority_list(TCP_Priority_List *p); void wipe_priority_list(const Memory *mem, TCP_Priority_List *p);
#define NUM_RESERVED_PORTS 16 #define NUM_RESERVED_PORTS 16
#define NUM_CLIENT_CONNECTIONS (256 - NUM_RESERVED_PORTS) #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 #define MAX_PACKET_SIZE 2048
typedef struct TCP_Connection { typedef struct TCP_Connection {
const Memory *mem;
const Random *rng; const Random *rng;
const Network *ns; const Network *ns;
Socket sock; Socket sock;
@ -108,7 +110,7 @@ int write_packet_TCP_secure_connection(
*/ */
non_null() non_null()
int read_TCP_packet( int read_TCP_packet(
const Logger *logger, const Network *ns, Socket sock, uint8_t *data, uint16_t length, const IP_Port *ip_port); 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. * @return length of received packet on success.
@ -117,7 +119,8 @@ int read_TCP_packet(
*/ */
non_null() non_null()
int read_packet_TCP_secure_connection( int read_packet_TCP_secure_connection(
const Logger *logger, const Network *ns, Socket sock, uint16_t *next_packet_length, 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, const uint8_t *shared_key, uint8_t *recv_nonce, uint8_t *data,
uint16_t max_len, const IP_Port *ip_port); uint16_t max_len, const IP_Port *ip_port);

View File

@ -19,6 +19,7 @@
struct TCP_Connections { struct TCP_Connections {
const Logger *logger; const Logger *logger;
const Memory *mem;
const Random *rng; const Random *rng;
Mono_Time *mono_time; Mono_Time *mono_time;
const Network *ns; 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. /** @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. * @retval 0 if it succeeds.
*/ */
non_null() 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) { if (num == 0) {
free(*array); mem_delete(mem, *array);
*array = nullptr; *array = nullptr;
return 0; return 0;
} }
TCP_Connection_to *temp_pointer = 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) { if (temp_pointer == nullptr) {
return -1; return -1;
@ -94,15 +95,15 @@ static int realloc_TCP_Connection_to(TCP_Connection_to **array, size_t num)
} }
non_null() 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) { if (num == 0) {
free(*array); mem_delete(mem, *array);
*array = nullptr; *array = nullptr;
return 0; 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) { if (temp_pointer == nullptr) {
return -1; return -1;
@ -164,7 +165,7 @@ static int create_connection(TCP_Connections *tcp_c)
int id = -1; 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; id = tcp_c->connections_length;
++tcp_c->connections_length; ++tcp_c->connections_length;
tcp_c->connections[id] = empty_tcp_connection_to; tcp_c->connections[id] = empty_tcp_connection_to;
@ -189,7 +190,7 @@ static int create_tcp_connection(TCP_Connections *tcp_c)
int id = -1; 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; id = tcp_c->tcp_connections_length;
++tcp_c->tcp_connections_length; ++tcp_c->tcp_connections_length;
tcp_c->tcp_connections[id] = empty_tcp_con; 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) { if (tcp_c->connections_length != i) {
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; 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) { if (tcp_c->tcp_connections_length != i) {
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; return 0;
@ -920,7 +925,7 @@ static int reconnect_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connec
uint8_t relay_pk[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t relay_pk[CRYPTO_PUBLIC_KEY_SIZE];
memcpy(relay_pk, tcp_con_public_key(tcp_con->connection), CRYPTO_PUBLIC_KEY_SIZE); memcpy(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 = 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); 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) { if (tcp_con->connection == nullptr) {
kill_tcp_relay_connection(tcp_c, tcp_connections_number); kill_tcp_relay_connection(tcp_c, tcp_connections_number);
@ -1008,7 +1013,7 @@ static int unsleep_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connecti
} }
tcp_con->connection = new_TCP_connection( tcp_con->connection = new_TCP_connection(
tcp_c->logger, tcp_c->mono_time, tcp_c->rng, tcp_c->ns, &tcp_con->ip_port, 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); tcp_con->relay_pk, tcp_c->self_public_key, tcp_c->self_secret_key, &tcp_c->proxy_info);
if (tcp_con->connection == nullptr) { if (tcp_con->connection == nullptr) {
@ -1304,7 +1309,7 @@ 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 *tcp_con = &tcp_c->tcp_connections[tcp_connections_number];
tcp_con->connection = new_TCP_connection( tcp_con->connection = new_TCP_connection(
tcp_c->logger, tcp_c->mono_time, tcp_c->rng, tcp_c->ns, &ipp_copy, 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); relay_pk, tcp_c->self_public_key, tcp_c->self_secret_key, &tcp_c->proxy_info);
if (tcp_con->connection == nullptr) { if (tcp_con->connection == nullptr) {
@ -1580,21 +1585,27 @@ int set_tcp_onion_status(TCP_Connections *tcp_c, bool status)
* *
* Returns NULL on failure. * Returns NULL on failure.
*/ */
TCP_Connections *new_tcp_connections( TCP_Connections *new_tcp_connections(const Logger *logger, const Memory *mem, const Random *rng, const Network *ns,
const Logger *logger, const Random *rng, const Network *ns, Mono_Time *mono_time, const uint8_t *secret_key, Mono_Time *mono_time, const uint8_t *secret_key, const TCP_Proxy_Info *proxy_info)
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) { if (secret_key == nullptr) {
return 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) { if (temp == nullptr) {
return nullptr; return nullptr;
} }
temp->logger = logger; temp->logger = logger;
temp->mem = mem;
temp->rng = rng; temp->rng = rng;
temp->mono_time = mono_time; temp->mono_time = mono_time;
temp->ns = ns; temp->ns = ns;
@ -1707,7 +1718,7 @@ void kill_tcp_connections(TCP_Connections *tcp_c)
crypto_memzero(tcp_c->self_secret_key, sizeof(tcp_c->self_secret_key)); crypto_memzero(tcp_c->self_secret_key, sizeof(tcp_c->self_secret_key));
free(tcp_c->tcp_connections); mem_delete(tcp_c->mem, tcp_c->tcp_connections);
free(tcp_c->connections); mem_delete(tcp_c->mem, tcp_c->connections);
free(tcp_c); mem_delete(tcp_c->mem, tcp_c);
} }

View File

@ -298,9 +298,8 @@ uint32_t tcp_copy_connected_relays_index(const TCP_Connections *tcp_c, Node_form
* Returns NULL on failure. * Returns NULL on failure.
*/ */
non_null() non_null()
TCP_Connections *new_tcp_connections( TCP_Connections *new_tcp_connections(const Logger *logger, const Memory *mem, const Random *rng, const Network *ns,
const Logger *logger, const Random *rng, const Network *ns, Mono_Time *mono_time, Mono_Time *mono_time, const uint8_t *secret_key, const TCP_Proxy_Info *proxy_info);
const uint8_t *secret_key, const TCP_Proxy_Info *proxy_info);
non_null() non_null()
int kill_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connections_number); int kill_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connections_number);

View File

@ -58,6 +58,7 @@ typedef struct TCP_Secure_Connection {
struct TCP_Server { struct TCP_Server {
const Logger *logger; const Logger *logger;
const Memory *mem;
const Random *rng; const Random *rng;
const Network *ns; const Network *ns;
Onion *onion; Onion *onion;
@ -117,9 +118,9 @@ static int alloc_new_connections(TCP_Server *tcp_server, uint32_t num)
return -1; return -1;
} }
TCP_Secure_Connection *new_connections = (TCP_Secure_Connection *)realloc( TCP_Secure_Connection *new_connections = (TCP_Secure_Connection *)mem_vrealloc(
tcp_server->accepted_connection_array, tcp_server->mem, tcp_server->accepted_connection_array,
new_size * sizeof(TCP_Secure_Connection)); new_size, sizeof(TCP_Secure_Connection));
if (new_connections == nullptr) { if (new_connections == nullptr) {
return -1; return -1;
@ -138,7 +139,7 @@ non_null()
static void wipe_secure_connection(TCP_Secure_Connection *con) static void wipe_secure_connection(TCP_Secure_Connection *con)
{ {
if (con->status != 0) { 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)); 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]); 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->accepted_connection_array = nullptr;
tcp_server->size_accepted_connections = 0; tcp_server->size_accepted_connections = 0;
} }
@ -369,7 +370,7 @@ non_null()
static int read_connection_handshake(const Logger *logger, TCP_Secure_Connection *con, const uint8_t *self_secret_key) 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]; 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) { if (len == -1) {
LOGGER_TRACE(logger, "connection handshake is not ready yet"); LOGGER_TRACE(logger, "connection handshake is not ready yet");
@ -892,6 +893,7 @@ static int accept_connection(TCP_Server *tcp_server, Socket sock)
conn->status = TCP_STATUS_CONNECTED; conn->status = TCP_STATUS_CONNECTED;
conn->con.ns = tcp_server->ns; conn->con.ns = tcp_server->ns;
conn->con.mem = tcp_server->mem;
conn->con.rng = tcp_server->rng; conn->con.rng = tcp_server->rng;
conn->con.sock = sock; conn->con.sock = sock;
conn->next_packet_length = 0; conn->next_packet_length = 0;
@ -935,7 +937,7 @@ static Socket new_listening_TCP_socket(const Logger *logger, const Network *ns,
return sock; 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, bool ipv6_enabled, uint16_t num_sockets,
const uint16_t *ports, const uint8_t *secret_key, Onion *onion, Forwarding *forwarding) 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; 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) { if (temp == nullptr) {
LOGGER_ERROR(logger, "TCP server allocation failed"); 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->logger = logger;
temp->mem = mem;
temp->ns = ns; temp->ns = ns;
temp->rng = rng; 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) { if (temp->socks_listening == nullptr) {
LOGGER_ERROR(logger, "socket allocation failed"); LOGGER_ERROR(logger, "socket allocation failed");
free(temp); mem_delete(mem, temp);
return nullptr; return nullptr;
} }
@ -973,8 +976,8 @@ TCP_Server *new_TCP_server(const Logger *logger, const Random *rng, const Networ
if (temp->efd == -1) { if (temp->efd == -1) {
LOGGER_ERROR(logger, "epoll initialisation failed"); LOGGER_ERROR(logger, "epoll initialisation failed");
free(temp->socks_listening); mem_delete(mem, temp->socks_listening);
free(temp); mem_delete(mem, temp);
return nullptr; return nullptr;
} }
@ -1006,8 +1009,8 @@ TCP_Server *new_TCP_server(const Logger *logger, const Random *rng, const Networ
} }
if (temp->num_listening_socks == 0) { if (temp->num_listening_socks == 0) {
free(temp->socks_listening); mem_delete(mem, temp->socks_listening);
free(temp); mem_delete(mem, temp);
return nullptr; return nullptr;
} }
@ -1096,7 +1099,7 @@ 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); LOGGER_TRACE(tcp_server->logger, "handling unconfirmed TCP connection %d", i);
uint8_t packet[MAX_PACKET_SIZE]; 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) { if (len == 0) {
return -1; return -1;
@ -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]; TCP_Secure_Connection *const conn = &tcp_server->accepted_connection_array[i];
uint8_t packet[MAX_PACKET_SIZE]; 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); LOGGER_TRACE(tcp_server->logger, "processing packet for %d: %d", i, len);
if (len == 0) { if (len == 0) {
@ -1406,6 +1409,6 @@ void kill_TCP_server(TCP_Server *tcp_server)
crypto_memzero(tcp_server->secret_key, sizeof(tcp_server->secret_key)); crypto_memzero(tcp_server->secret_key, sizeof(tcp_server->secret_key));
free(tcp_server->socks_listening); mem_delete(tcp_server->mem, tcp_server->socks_listening);
free(tcp_server); mem_delete(tcp_server->mem, tcp_server);
} }

View File

@ -34,8 +34,8 @@ non_null()
size_t tcp_server_listen_count(const TCP_Server *tcp_server); size_t tcp_server_listen_count(const TCP_Server *tcp_server);
/** Create new TCP server instance. */ /** Create new TCP server instance. */
non_null(1, 2, 3, 6, 7) nullable(8, 9) non_null(1, 2, 3, 4, 7, 8) nullable(9, 10)
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, bool ipv6_enabled, uint16_t num_sockets, const uint16_t *ports,
const uint8_t *secret_key, Onion *onion, Forwarding *forwarding); const uint8_t *secret_key, Onion *onion, Forwarding *forwarding);

View File

@ -50,6 +50,7 @@ typedef struct Announce_Entry {
struct Announcements { struct Announcements {
const Logger *log; const Logger *log;
const Memory *mem;
const Random *rng; const Random *rng;
Forwarding *forwarding; Forwarding *forwarding;
const Mono_Time *mono_time; 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]); 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, return dht_create_packet(announce->mem, announce->rng, announce->public_key, shared_key,
plain_reply, plain_reply_len, reply, reply_max_length); response_type, plain_reply, plain_reply_len, reply, reply_max_length);
} }
non_null(1, 2, 3, 5) nullable(7) 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; 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) Forwarding *forwarding)
{ {
if (log == nullptr || mono_time == nullptr || forwarding == nullptr) { 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->log = log;
announce->mem = mem;
announce->rng = rng; announce->rng = rng;
announce->forwarding = forwarding; announce->forwarding = forwarding;
announce->mono_time = mono_time; 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->public_key = dht_get_self_public_key(announce->dht);
announce->secret_key = dht_get_self_secret_key(announce->dht); announce->secret_key = dht_get_self_secret_key(announce->dht);
new_hmac_key(announce->rng, announce->hmac_key); 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) { if (announce->shared_keys == nullptr) {
free(announce); free(announce);
return nullptr; return nullptr;

View File

@ -16,7 +16,8 @@ uint8_t announce_response_of_request_type(uint8_t request_type);
typedef struct Announcements Announcements; typedef struct Announcements Announcements;
non_null() 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. * @brief If data is stored, run `on_retrieve_callback` on it.

View File

@ -12,8 +12,10 @@ void TestSendForwardRequest(Fuzz_Data &input)
{ {
const Network *ns = system_network(); // TODO(iphydf): fuzz_network const Network *ns = system_network(); // TODO(iphydf): fuzz_network
assert(ns != nullptr); 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) { with<IP_Port>{input} >> [net = std::move(net), &input](const IP_Port &forwarder) {
CONSUME1_OR_RETURN(const uint16_t chain_length, input); CONSUME1_OR_RETURN(const uint16_t chain_length, input);
const uint16_t chain_keys_size = chain_length * CRYPTO_PUBLIC_KEY_SIZE; 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 const Network *ns = system_network(); // TODO(iphydf): fuzz_network
assert(ns != nullptr); 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) { with<IP_Port>{input} >> [net = std::move(net), &input](const IP_Port &forwarder) {
CONSUME1_OR_RETURN(const uint16_t sendback_length, input); CONSUME1_OR_RETURN(const uint16_t sendback_length, input);
CONSUME_OR_RETURN(const uint8_t *sendback, input, sendback_length); CONSUME_OR_RETURN(const uint8_t *sendback, input, sendback_length);

View File

@ -1,6 +1,7 @@
#include "group_announce.h" #include "group_announce.h"
#include <cassert> #include <cassert>
#include <functional>
#include <memory> #include <memory>
#include <vector> #include <vector>
@ -44,9 +45,10 @@ void TestUnpackPublicAnnounce(Fuzz_Data &input)
void TestDoGca(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<Logger, void (*)(Logger *)> logger(logger_new(), logger_kill);
std::unique_ptr<Mono_Time, void (*)(Mono_Time *)> mono_time( std::unique_ptr<Mono_Time, std::function<void(Mono_Time *)>> mono_time(
mono_time_new(nullptr, nullptr), mono_time_free); mono_time_new(mem, nullptr, nullptr), [mem](Mono_Time *ptr) { mono_time_free(mem, ptr); });
assert(mono_time != nullptr); assert(mono_time != nullptr);
uint64_t clock = 1; uint64_t clock = 1;
mono_time_set_current_time_callback( mono_time_set_current_time_callback(

View File

@ -8,6 +8,7 @@ namespace {
struct Announces : ::testing::Test { struct Announces : ::testing::Test {
protected: protected:
const Memory *mem_ = system_memory();
uint64_t clock_ = 0; uint64_t clock_ = 0;
Mono_Time *mono_time_ = nullptr; Mono_Time *mono_time_ = nullptr;
GC_Announces_List *gca_ = nullptr; GC_Announces_List *gca_ = nullptr;
@ -16,7 +17,7 @@ protected:
void SetUp() override void SetUp() override
{ {
mono_time_ = mono_time_new(nullptr, nullptr); mono_time_ = mono_time_new(mem_, nullptr, nullptr);
ASSERT_NE(mono_time_, nullptr); ASSERT_NE(mono_time_, nullptr);
mono_time_set_current_time_callback( mono_time_set_current_time_callback(
mono_time_, [](void *user_data) { return *static_cast<uint64_t *>(user_data); }, mono_time_, [](void *user_data) { return *static_cast<uint64_t *>(user_data); },
@ -28,7 +29,7 @@ protected:
~Announces() override ~Announces() override
{ {
kill_gca(gca_); kill_gca(gca_);
mono_time_free(mono_time_); mono_time_free(mem_, mono_time_);
} }
void advance_clock(uint64_t increment) void advance_clock(uint64_t increment)

View File

@ -7250,7 +7250,7 @@ static bool init_gc_tcp_connection(const GC_Session *c, GC_Chat *chat)
{ {
const Messenger *m = c->messenger; 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); &m->options.proxy_info);
if (chat->tcp_conn == nullptr) { 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); 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.shared_state_version = chat->shared_state.version;
chat->moderation.log = chat->log; chat->moderation.log = chat->log;
chat->moderation.mem = chat->mem;
} }
non_null() 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]; GC_Chat *chat = &c->chats[group_number];
chat->log = m->log; chat->log = m->log;
chat->mem = m->mem;
chat->rng = m->rng; chat->rng = m->rng;
const uint64_t tm = mono_time_get(m->mono_time); const uint64_t tm = mono_time_get(m->mono_time);
@ -7476,6 +7478,7 @@ int gc_group_load(GC_Session *c, Bin_Unpack *bu)
chat->net = m->net; chat->net = m->net;
chat->mono_time = m->mono_time; chat->mono_time = m->mono_time;
chat->log = m->log; chat->log = m->log;
chat->mem = m->mem;
chat->rng = m->rng; chat->rng = m->rng;
chat->last_ping_interval = tm; chat->last_ping_interval = tm;
chat->friend_connection_id = -1; chat->friend_connection_id = -1;

View File

@ -247,6 +247,7 @@ typedef struct GC_TopicInfo {
typedef struct GC_Chat { typedef struct GC_Chat {
Mono_Time *mono_time; Mono_Time *mono_time;
const Logger *log; const Logger *log;
const Memory *mem;
const Random *rng; const Random *rng;
uint32_t connected_tcp_relays; uint32_t connected_tcp_relays;

View File

@ -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); tmp_list[i] = (uint8_t *)malloc(sizeof(uint8_t) * MOD_LIST_ENTRY_SIZE);
if (tmp_list[i] == nullptr) { 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; return -1;
} }
@ -221,7 +221,7 @@ bool mod_list_add_entry(Moderation *moderation, const uint8_t *mod_data)
void mod_list_cleanup(Moderation *moderation) 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->num_mods = 0;
moderation->mod_list = nullptr; moderation->mod_list = nullptr;
} }

View File

@ -78,6 +78,7 @@ typedef struct Mod_Sanction {
} Mod_Sanction; } Mod_Sanction;
typedef struct Moderation { typedef struct Moderation {
const Memory *mem;
const Logger *log; const Logger *log;
Mod_Sanction *sanctions; Mod_Sanction *sanctions;

View File

@ -7,7 +7,7 @@ namespace {
void TestModListUnpack(Fuzz_Data &input) void TestModListUnpack(Fuzz_Data &input)
{ {
CONSUME1_OR_RETURN(const uint16_t num_mods, 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_unpack(&mods, input.data, input.size, num_mods);
mod_list_cleanup(&mods); mod_list_cleanup(&mods);
} }

View File

@ -18,7 +18,7 @@ using ModerationHash = std::array<uint8_t, MOD_MODERATION_HASH_SIZE>;
TEST(ModList, PackedSizeOfEmptyModListIsZero) TEST(ModList, PackedSizeOfEmptyModListIsZero)
{ {
Moderation mods{}; Moderation mods{system_memory()};
EXPECT_EQ(mod_list_packed_size(&mods), 0); EXPECT_EQ(mod_list_packed_size(&mods), 0);
uint8_t byte = 1; uint8_t byte = 1;
@ -28,14 +28,14 @@ TEST(ModList, PackedSizeOfEmptyModListIsZero)
TEST(ModList, UnpackingZeroSizeArrayIsNoop) TEST(ModList, UnpackingZeroSizeArrayIsNoop)
{ {
Moderation mods{}; Moderation mods{system_memory()};
const uint8_t byte = 1; const uint8_t byte = 1;
EXPECT_EQ(mod_list_unpack(&mods, &byte, 0, 0), 0); EXPECT_EQ(mod_list_unpack(&mods, &byte, 0, 0), 0);
} }
TEST(ModList, AddRemoveMultipleMods) TEST(ModList, AddRemoveMultipleMods)
{ {
Moderation mods{}; Moderation mods{system_memory()};
uint8_t sig_pk1[32] = {1}; uint8_t sig_pk1[32] = {1};
uint8_t sig_pk2[32] = {2}; uint8_t sig_pk2[32] = {2};
EXPECT_TRUE(mod_list_add_entry(&mods, sig_pk1)); EXPECT_TRUE(mod_list_add_entry(&mods, sig_pk1));
@ -47,7 +47,7 @@ TEST(ModList, AddRemoveMultipleMods)
TEST(ModList, PackingAndUnpackingList) TEST(ModList, PackingAndUnpackingList)
{ {
using ModListEntry = std::array<uint8_t, MOD_LIST_ENTRY_SIZE>; 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())); EXPECT_TRUE(mod_list_add_entry(&mods, ModListEntry{}.data()));
std::vector<uint8_t> packed(mod_list_packed_size(&mods)); 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())); 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_EQ(mod_list_unpack(&mods2, packed.data(), packed.size(), 1), packed.size());
EXPECT_TRUE(mod_list_remove_entry(&mods2, ModListEntry{}.data())); EXPECT_TRUE(mod_list_remove_entry(&mods2, ModListEntry{}.data()));
} }
@ -63,13 +63,13 @@ TEST(ModList, PackingAndUnpackingList)
TEST(ModList, UnpackingTooManyModsFails) TEST(ModList, UnpackingTooManyModsFails)
{ {
using ModListEntry = std::array<uint8_t, MOD_LIST_ENTRY_SIZE>; 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())); EXPECT_TRUE(mod_list_add_entry(&mods, ModListEntry{}.data()));
std::vector<uint8_t> packed(mod_list_packed_size(&mods)); std::vector<uint8_t> packed(mod_list_packed_size(&mods));
mod_list_pack(&mods, packed.data()); 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_EQ(mod_list_unpack(&mods2, packed.data(), packed.size(), 2), -1);
EXPECT_TRUE(mod_list_remove_entry(&mods, ModListEntry{}.data())); EXPECT_TRUE(mod_list_remove_entry(&mods, ModListEntry{}.data()));
} }
@ -78,7 +78,7 @@ TEST(ModList, UnpackingFromEmptyBufferFails)
{ {
std::vector<uint8_t> packed(1); std::vector<uint8_t> packed(1);
Moderation mods{}; Moderation mods{system_memory()};
EXPECT_EQ(mod_list_unpack(&mods, packed.end().base(), 0, 1), -1); EXPECT_EQ(mod_list_unpack(&mods, packed.end().base(), 0, 1), -1);
} }
@ -87,7 +87,7 @@ TEST(ModList, HashOfEmptyModListZeroesOutBuffer)
const Random *rng = system_random(); const Random *rng = system_random();
ASSERT_NE(rng, nullptr); ASSERT_NE(rng, nullptr);
Moderation mods{}; Moderation mods{system_memory()};
// Fill with random data, check that it's zeroed. // Fill with random data, check that it's zeroed.
ModerationHash hash; ModerationHash hash;
@ -98,21 +98,21 @@ TEST(ModList, HashOfEmptyModListZeroesOutBuffer)
TEST(ModList, RemoveIndexFromEmptyModListFails) TEST(ModList, RemoveIndexFromEmptyModListFails)
{ {
Moderation mods{}; Moderation mods{system_memory()};
EXPECT_FALSE(mod_list_remove_index(&mods, 0)); EXPECT_FALSE(mod_list_remove_index(&mods, 0));
EXPECT_FALSE(mod_list_remove_index(&mods, UINT16_MAX)); EXPECT_FALSE(mod_list_remove_index(&mods, UINT16_MAX));
} }
TEST(ModList, RemoveEntryFromEmptyModListFails) TEST(ModList, RemoveEntryFromEmptyModListFails)
{ {
Moderation mods{}; Moderation mods{system_memory()};
uint8_t sig_pk[32] = {0}; uint8_t sig_pk[32] = {0};
EXPECT_FALSE(mod_list_remove_entry(&mods, sig_pk)); EXPECT_FALSE(mod_list_remove_entry(&mods, sig_pk));
} }
TEST(ModList, ModListRemoveIndex) TEST(ModList, ModListRemoveIndex)
{ {
Moderation mods{}; Moderation mods{system_memory()};
uint8_t sig_pk[32] = {1}; uint8_t sig_pk[32] = {1};
EXPECT_TRUE(mod_list_add_entry(&mods, sig_pk)); EXPECT_TRUE(mod_list_add_entry(&mods, sig_pk));
EXPECT_TRUE(mod_list_remove_index(&mods, 0)); EXPECT_TRUE(mod_list_remove_index(&mods, 0));
@ -120,20 +120,20 @@ TEST(ModList, ModListRemoveIndex)
TEST(ModList, CleanupOnEmptyModsIsNoop) TEST(ModList, CleanupOnEmptyModsIsNoop)
{ {
Moderation mods{}; Moderation mods{system_memory()};
mod_list_cleanup(&mods); mod_list_cleanup(&mods);
} }
TEST(ModList, EmptyModListCannotVerifyAnySigPk) TEST(ModList, EmptyModListCannotVerifyAnySigPk)
{ {
Moderation mods{}; Moderation mods{system_memory()};
uint8_t sig_pk[32] = {1}; uint8_t sig_pk[32] = {1};
EXPECT_FALSE(mod_list_verify_sig_pk(&mods, sig_pk)); EXPECT_FALSE(mod_list_verify_sig_pk(&mods, sig_pk));
} }
TEST(ModList, ModListAddVerifyRemoveSigPK) TEST(ModList, ModListAddVerifyRemoveSigPK)
{ {
Moderation mods{}; Moderation mods{system_memory()};
uint8_t sig_pk[32] = {1}; uint8_t sig_pk[32] = {1};
EXPECT_TRUE(mod_list_add_entry(&mods, sig_pk)); EXPECT_TRUE(mod_list_add_entry(&mods, sig_pk));
EXPECT_TRUE(mod_list_verify_sig_pk(&mods, sig_pk)); EXPECT_TRUE(mod_list_verify_sig_pk(&mods, sig_pk));
@ -143,7 +143,7 @@ TEST(ModList, ModListAddVerifyRemoveSigPK)
TEST(ModList, ModListHashCheck) TEST(ModList, ModListHashCheck)
{ {
Moderation mods1{}; Moderation mods1{system_memory()};
uint8_t sig_pk1[32] = {1}; uint8_t sig_pk1[32] = {1};
std::array<uint8_t, MOD_MODERATION_HASH_SIZE> hash1; std::array<uint8_t, MOD_MODERATION_HASH_SIZE> hash1;
@ -165,7 +165,7 @@ TEST(SanctionsList, PackingIntoUndersizedBufferFails)
TEST(SanctionsList, PackUnpackSanctionsCreds) TEST(SanctionsList, PackUnpackSanctionsCreds)
{ {
Moderation mod{}; Moderation mod{system_memory()};
std::array<uint8_t, MOD_SANCTIONS_CREDS_SIZE> packed; 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(sanctions_creds_pack(&mod.sanctions_creds, packed.data()), MOD_SANCTIONS_CREDS_SIZE);
EXPECT_EQ( EXPECT_EQ(
@ -177,7 +177,7 @@ protected:
ExtPublicKey pk; ExtPublicKey pk;
ExtSecretKey sk; ExtSecretKey sk;
Logger *log = logger_new(); Logger *log = logger_new();
Moderation mod{}; Moderation mod{system_memory()};
Mod_Sanction sanctions[2] = {}; Mod_Sanction sanctions[2] = {};
const uint8_t sanctioned_pk1[32] = {1}; const uint8_t sanctioned_pk1[32] = {1};

88
toxcore/mem.c Normal file
View 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
View 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
View 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

View File

@ -122,25 +122,25 @@ static uint64_t current_time_monotonic_default(void *user_data)
#endif // !OS_WIN32 #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) { if (mono_time == nullptr) {
return nullptr; return nullptr;
} }
#ifndef ESP_PLATFORM #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) { if (mono_time->time_update_lock == nullptr) {
free(mono_time); mem_delete(mem, mono_time);
return nullptr; return nullptr;
} }
if (pthread_rwlock_init(mono_time->time_update_lock, nullptr) < 0) { if (pthread_rwlock_init(mono_time->time_update_lock, nullptr) < 0) {
free(mono_time->time_update_lock); mem_delete(mem, mono_time->time_update_lock);
free(mono_time); mem_delete(mem, mono_time);
return nullptr; return nullptr;
} }
#endif #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; mono_time->last_clock_update = false;
if (pthread_mutex_init(&mono_time->last_clock_lock, nullptr) < 0) { if (pthread_mutex_init(&mono_time->last_clock_lock, nullptr) < 0) {
free(mono_time->time_update_lock); mem_delete(mem, mono_time->time_update_lock);
free(mono_time); mem_delete(mem, mono_time);
return nullptr; return nullptr;
} }
@ -173,7 +173,7 @@ Mono_Time *mono_time_new(mono_time_current_time_cb *current_time_callback, void
return mono_time; 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) { if (mono_time == nullptr) {
return; return;
@ -183,9 +183,9 @@ void mono_time_free(Mono_Time *mono_time)
#endif #endif
#ifndef ESP_PLATFORM #ifndef ESP_PLATFORM
pthread_rwlock_destroy(mono_time->time_update_lock); pthread_rwlock_destroy(mono_time->time_update_lock);
free(mono_time->time_update_lock); mem_delete(mem, mono_time->time_update_lock);
#endif #endif
free(mono_time); mem_delete(mem, mono_time);
} }
void mono_time_update(Mono_Time *mono_time) void mono_time_update(Mono_Time *mono_time)

View File

@ -9,6 +9,7 @@
#include <stdint.h> #include <stdint.h>
#include "attributes.h" #include "attributes.h"
#include "mem.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -47,11 +48,11 @@ typedef struct Mono_Time Mono_Time;
typedef uint64_t mono_time_current_time_cb(void *user_data); typedef uint64_t mono_time_current_time_cb(void *user_data);
nullable(1, 2) non_null(1) nullable(2, 3)
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);
nullable(1) non_null(1) nullable(2)
void mono_time_free(Mono_Time *mono_time); 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 * Update mono_time; subsequent calls to mono_time_get or mono_time_is_timeout

View File

@ -6,7 +6,8 @@ namespace {
TEST(MonoTime, UnixTimeIncreasesOverTime) 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); ASSERT_NE(mono_time, nullptr);
mono_time_update(mono_time); mono_time_update(mono_time);
@ -19,12 +20,13 @@ TEST(MonoTime, UnixTimeIncreasesOverTime)
uint64_t const end = mono_time_get(mono_time); uint64_t const end = mono_time_get(mono_time);
EXPECT_GT(end, start); EXPECT_GT(end, start);
mono_time_free(mono_time); mono_time_free(mem, mono_time);
} }
TEST(MonoTime, IsTimeout) 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); ASSERT_NE(mono_time, nullptr);
uint64_t const start = mono_time_get(mono_time); 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)); EXPECT_TRUE(mono_time_is_timeout(mono_time, start, 1));
mono_time_free(mono_time); mono_time_free(mem, mono_time);
} }
TEST(MonoTime, CustomTime) 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); ASSERT_NE(mono_time, nullptr);
uint64_t test_time = current_time_monotonic(mono_time) + 42137; 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); EXPECT_EQ(current_time_monotonic(mono_time), test_time);
mono_time_free(mono_time); mono_time_free(mem, mono_time);
} }
} // namespace } // namespace

View File

@ -127,6 +127,7 @@ static const Crypto_Connection empty_crypto_connection = {{0}};
struct Net_Crypto { struct Net_Crypto {
const Logger *log; const Logger *log;
const Memory *mem;
const Random *rng; const Random *rng;
Mono_Time *mono_time; Mono_Time *mono_time;
const Network *ns; const Network *ns;
@ -758,7 +759,7 @@ static uint32_t num_packets_array(const Packets_Array *array)
* @retval 0 on success. * @retval 0 on success.
*/ */
non_null() 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) { if (number - array->buffer_start >= CRYPTO_PACKET_BUFFER_SIZE) {
return -1; return -1;
@ -770,7 +771,7 @@ static int add_data_to_buffer(Packets_Array *array, uint32_t number, const Packe
return -1; 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) { if (new_d == nullptr) {
return -1; return -1;
@ -817,7 +818,7 @@ static int get_data_pointer(const Packets_Array *array, Packet_Data **data, uint
* @return packet number on success. * @return packet number on success.
*/ */
non_null() 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); 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; 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) { if (new_d == nullptr) {
LOGGER_ERROR(logger, "packet data allocation failed"); 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. * @return packet number on success.
*/ */
non_null() 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) { if (array->buffer_end == array->buffer_start) {
return -1; return -1;
@ -861,7 +862,7 @@ static int64_t read_data_beg_buffer(Packets_Array *array, Packet_Data *data)
*data = *array->buffer[num]; *data = *array->buffer[num];
const uint32_t id = array->buffer_start; const uint32_t id = array->buffer_start;
++array->buffer_start; ++array->buffer_start;
free(array->buffer[num]); mem_delete(mem, array->buffer[num]);
array->buffer[num] = nullptr; array->buffer[num] = nullptr;
return id; return id;
} }
@ -872,7 +873,7 @@ static int64_t read_data_beg_buffer(Packets_Array *array, Packet_Data *data)
* @retval 0 on success * @retval 0 on success
*/ */
non_null() 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); 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; const uint32_t num = i % CRYPTO_PACKET_BUFFER_SIZE;
if (array->buffer[num] != nullptr) { if (array->buffer[num] != nullptr) {
free(array->buffer[num]); mem_delete(mem, array->buffer[num]);
array->buffer[num] = nullptr; array->buffer[num] = nullptr;
} }
} }
@ -896,7 +897,7 @@ static int clear_buffer_until(Packets_Array *array, uint32_t number)
} }
non_null() non_null()
static int clear_buffer(Packets_Array *array) static int clear_buffer(const Memory *mem, Packets_Array *array)
{ {
uint32_t i; uint32_t i;
@ -904,7 +905,7 @@ static int clear_buffer(Packets_Array *array)
const uint32_t num = i % CRYPTO_PACKET_BUFFER_SIZE; const uint32_t num = i % CRYPTO_PACKET_BUFFER_SIZE;
if (array->buffer[num] != nullptr) { if (array->buffer[num] != nullptr) {
free(array->buffer[num]); mem_delete(mem, array->buffer[num]);
array->buffer[num] = nullptr; 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. * @return number of requested packets on success.
*/ */
non_null() 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, const uint8_t *data, uint16_t length,
uint64_t *latest_send_time, uint64_t rtt_time) 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) { if (send_array->buffer[num] != nullptr) {
l_sent_time = max_u64(l_sent_time, send_array->buffer[num]->sent_time); 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; 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; dt.length = length;
memcpy(dt.data, data, length); memcpy(dt.data, data, length);
pthread_mutex_lock(conn->mutex); 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); pthread_mutex_unlock(conn->mutex);
if (packet_num == -1) { 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; 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) { if (temp_packet == nullptr) {
return -1; return -1;
} }
if (conn->temp_packet != nullptr) { if (conn->temp_packet != nullptr) {
free(conn->temp_packet); mem_delete(c->mem, conn->temp_packet);
} }
memcpy(temp_packet, packet, length); 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) { if (conn->temp_packet != nullptr) {
free(conn->temp_packet); mem_delete(c->mem, conn->temp_packet);
} }
conn->temp_packet = nullptr; 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; 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; 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; rtt_time = DEFAULT_TCP_PING_CONNECTION;
} }
const int requested = handle_request_packet(c->mono_time, &conn->send_array, const int requested = handle_request_packet(c->mem, c->mono_time, &conn->send_array, real_data, real_length, &rtt_calc_time, rtt_time);
real_data, real_length,
&rtt_calc_time, rtt_time);
if (requested == -1) { if (requested == -1) {
return -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; dt.length = real_length;
memcpy(dt.data, real_data, 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; return -1;
} }
while (true) { while (true) {
pthread_mutex_lock(conn->mutex); 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); pthread_mutex_unlock(conn->mutex);
if (ret == -1) { 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. /** @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. * @retval 0 if it succeeds.
*/ */
non_null() non_null()
static int realloc_cryptoconnection(Net_Crypto *c, uint32_t num) static int realloc_cryptoconnection(Net_Crypto *c, uint32_t num)
{ {
if (num == 0) { if (num == 0) {
free(c->crypto_connections); mem_delete(c->mem, c->crypto_connections);
c->crypto_connections = nullptr; c->crypto_connections = nullptr;
return 0; return 0;
} }
Crypto_Connection *newcrypto_connections = (Crypto_Connection *)realloc(c->crypto_connections, Crypto_Connection *newcrypto_connections = (Crypto_Connection *)mem_vrealloc(
num * sizeof(Crypto_Connection)); c->mem, c->crypto_connections, num, sizeof(Crypto_Connection));
if (newcrypto_connections == nullptr) { if (newcrypto_connections == nullptr) {
return -1; 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].last_packets_left_rem = 0;
c->crypto_connections[id].packet_send_rate_requested = 0; c->crypto_connections[id].packet_send_rate_requested = 0;
c->crypto_connections[id].last_packets_left_requested_rem = 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) { if (c->crypto_connections[id].mutex == nullptr) {
pthread_mutex_unlock(&c->connections_mutex); 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) { 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); pthread_mutex_unlock(&c->connections_mutex);
return -1; return -1;
} }
@ -1915,7 +1914,7 @@ static int wipe_crypto_connection(Net_Crypto *c, int crypt_connection_id)
uint32_t i; uint32_t i;
pthread_mutex_destroy(c->crypto_connections[crypt_connection_id].mutex); 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)); crypto_memzero(&c->crypto_connections[crypt_connection_id], sizeof(Crypto_Connection));
/* check if we can resize the connections array */ /* 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) void *userdata)
{ {
New_Connection n_c; 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) { if (n_c.cookie == nullptr) {
return -1; 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, 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)) { n_c.cookie, data, length, nullptr)) {
free(n_c.cookie); mem_delete(c->mem, n_c.cookie);
return -1; 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); connection_kill(c, crypt_connection_id, userdata);
} else { } else {
if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING && conn->status != CRYPTO_CONN_HANDSHAKE_SENT) { 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; 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); 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) { 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; return -1;
} }
conn->status = CRYPTO_CONN_NOT_CONFIRMED; conn->status = CRYPTO_CONN_NOT_CONFIRMED;
free(n_c.cookie); mem_delete(c->mem, n_c.cookie);
return 0; return 0;
} }
} }
const int ret = c->new_connection_callback(c->new_connection_callback_object, &n_c); 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; 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_portv4, crypt_connection_id);
bs_list_remove(&c->ip_port_list, (uint8_t *)&conn->ip_portv6, 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_temp_packet(c, crypt_connection_id);
clear_buffer(&conn->send_array); clear_buffer(c->mem, &conn->send_array);
clear_buffer(&conn->recv_array); clear_buffer(c->mem, &conn->recv_array);
ret = wipe_crypto_connection(c, crypt_connection_id); ret = wipe_crypto_connection(c, crypt_connection_id);
} }
@ -3109,27 +3108,29 @@ void load_secret_key(Net_Crypto *c, const uint8_t *sk)
/** @brief Create new instance of Net_Crypto. /** @brief Create new instance of Net_Crypto.
* Sets all the global connection variables to their default values. * 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) { if (dht == nullptr) {
return 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) { if (temp == nullptr) {
return nullptr; return nullptr;
} }
temp->log = log; temp->log = log;
temp->mem = mem;
temp->rng = rng; temp->rng = rng;
temp->mono_time = mono_time; temp->mono_time = mono_time;
temp->ns = ns; 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) { if (temp->tcp_c == nullptr) {
free(temp); mem_delete(mem, temp);
return nullptr; return nullptr;
} }
@ -3139,7 +3140,7 @@ Net_Crypto *new_net_crypto(const Logger *log, const Random *rng, const Network *
if (create_recursive_mutex(&temp->tcp_mutex) != 0 || if (create_recursive_mutex(&temp->tcp_mutex) != 0 ||
pthread_mutex_init(&temp->connections_mutex, nullptr) != 0) { pthread_mutex_init(&temp->connections_mutex, nullptr) != 0) {
kill_tcp_connections(temp->tcp_c); kill_tcp_connections(temp->tcp_c);
free(temp); mem_delete(mem, temp);
return nullptr; return nullptr;
} }
@ -3210,6 +3211,8 @@ void kill_net_crypto(Net_Crypto *c)
return; return;
} }
const Memory *mem = c->mem;
for (uint32_t i = 0; i < c->crypto_connections_length; ++i) { for (uint32_t i = 0; i < c->crypto_connections_length; ++i) {
crypto_kill(c, i); crypto_kill(c, i);
} }
@ -3224,5 +3227,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_HS, nullptr, nullptr);
networking_registerhandler(dht_get_net(c->dht), NET_PACKET_CRYPTO_DATA, nullptr, nullptr); networking_registerhandler(dht_get_net(c->dht), NET_PACKET_CRYPTO_DATA, nullptr, nullptr);
crypto_memzero(c, sizeof(Net_Crypto)); crypto_memzero(c, sizeof(Net_Crypto));
free(c); mem_delete(mem, c);
} }

View File

@ -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. * Sets all the global connection variables to their default values.
*/ */
non_null() 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. */ /** return the optimal interval in ms for running do_net_crypto. */
non_null() non_null()

View File

@ -898,6 +898,7 @@ typedef struct Packet_Handler {
struct Networking_Core { struct Networking_Core {
const Logger *log; const Logger *log;
const Memory *mem;
Packet_Handler packethandlers[256]; Packet_Handler packethandlers[256];
const Network *ns; 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. * Packet length is put into length.
*/ */
non_null() 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)); memset(ip_port, 0, sizeof(IP_Port));
Network_Addr addr = {{0}}; Network_Addr addr = {{0}};
@ -1088,7 +1089,7 @@ void networking_poll(const Networking_Core *net, void *userdata)
uint8_t data[MAX_UDP_PACKET_SIZE]; uint8_t data[MAX_UDP_PACKET_SIZE];
uint32_t length; 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) { if (length < 1) {
continue; 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. * 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( 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) uint16_t port_from, uint16_t port_to, unsigned int *error)
{ {
/* If both from and to are 0, use default port range /* If both from and to are 0, use default port range
@ -1147,7 +1148,7 @@ Networking_Core *new_networking_ex(
return nullptr; 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) { if (temp == nullptr) {
return nullptr; return nullptr;
@ -1155,6 +1156,7 @@ Networking_Core *new_networking_ex(
temp->ns = ns; temp->ns = ns;
temp->log = log; temp->log = log;
temp->mem = mem;
temp->family = ip->family; temp->family = ip->family;
temp->port = 0; temp->port = 0;
@ -1168,7 +1170,7 @@ Networking_Core *new_networking_ex(
char *strerror = net_new_strerror(neterror); char *strerror = net_new_strerror(neterror);
LOGGER_ERROR(log, "failed to get a socket?! %d, %s", neterror, strerror); LOGGER_ERROR(log, "failed to get a socket?! %d, %s", neterror, strerror);
net_kill_strerror(strerror); net_kill_strerror(strerror);
free(temp); mem_delete(mem, temp);
if (error != nullptr) { if (error != nullptr) {
*error = 1; *error = 1;
@ -1246,7 +1248,7 @@ Networking_Core *new_networking_ex(
portptr = &addr6->sin6_port; portptr = &addr6->sin6_port;
} else { } else {
free(temp); mem_delete(mem, temp);
return nullptr; return nullptr;
} }
@ -1350,10 +1352,10 @@ Networking_Core *new_networking_ex(
return nullptr; 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. */ /* 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) { if (net == nullptr) {
return nullptr; return nullptr;
@ -1361,6 +1363,7 @@ Networking_Core *new_networking_no_udp(const Logger *log, const Network *ns)
net->ns = ns; net->ns = ns;
net->log = log; net->log = log;
net->mem = mem;
return net; return net;
} }
@ -1377,7 +1380,7 @@ void kill_networking(Networking_Core *net)
kill_sock(net->ns, net->sock); 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; 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}; struct sockaddr_storage addr = {0};
size_t addrsize; size_t addrsize;
@ -1765,13 +1768,13 @@ bool net_connect(const Logger *log, Socket sock, const IP_Port *ip_port)
return true; 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. // Try parsing as IP address first.
IP_Port parsed = {{{0}}}; IP_Port parsed = {{{0}}};
if (addr_parse_ip(node, &parsed.ip)) { 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) { if (tmp == nullptr) {
return -1; return -1;
@ -1784,7 +1787,7 @@ int32_t net_getipport(const char *node, IP_Port **res, int tox_type)
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
if ((true)) { if ((true)) {
*res = (IP_Port *)calloc(1, sizeof(IP_Port)); *res = (IP_Port *)mem_alloc(mem, sizeof(IP_Port));
assert(*res != nullptr); assert(*res != nullptr);
IP_Port *ip_port = *res; IP_Port *ip_port = *res;
ip_port->ip.ip.v4.uint32 = net_htonl(0x7F000003); // 127.0.0.3 ip_port->ip.ip.v4.uint32 = net_htonl(0x7F000003); // 127.0.0.3
@ -1827,7 +1830,7 @@ int32_t net_getipport(const char *node, IP_Port **res, int tox_type)
return 0; return 0;
} }
*res = (IP_Port *)calloc(count, sizeof(IP_Port)); *res = (IP_Port *)mem_valloc(mem, count, sizeof(IP_Port));
if (*res == nullptr) { if (*res == nullptr) {
freeaddrinfo(infos); freeaddrinfo(infos);
@ -1869,9 +1872,9 @@ int32_t net_getipport(const char *node, IP_Port **res, int tox_type)
return count; 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) bool bind_to_port(const Network *ns, Socket sock, Family family, uint16_t port)

View File

@ -14,6 +14,7 @@
#include <stdint.h> // uint*_t #include <stdint.h> // uint*_t
#include "logger.h" #include "logger.h"
#include "mem.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -533,7 +534,7 @@ void networking_poll(const Networking_Core *net, void *userdata);
* Return false on failure. * Return false on failure.
*/ */
non_null() 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. /** @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. * @retval -1 on error.
*/ */
non_null() 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 */ /** Deallocates memory allocated by net_getipport */
nullable(1) non_null(1) nullable(2)
void net_freeipport(IP_Port *ip_ports); void net_freeipport(const Memory *mem, IP_Port *ip_ports);
/** /**
* @return true on success, false on failure. * @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. * 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( 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); uint16_t port_from, uint16_t port_to, unsigned int *error);
non_null() 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). */ /** Function to cleanup networking stuff (doesn't do much right now). */
nullable(1) nullable(1)

View File

@ -668,13 +668,13 @@ void set_callback_handle_recv_1(Onion *onion, onion_recv_1_cb *function, void *o
onion->callback_object = object; 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) { if (dht == nullptr) {
return nullptr; return nullptr;
} }
Onion *onion = (Onion *)calloc(1, sizeof(Onion)); Onion *onion = (Onion *)mem_alloc(mem, sizeof(Onion));
if (onion == nullptr) { if (onion == nullptr) {
return 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->net = dht_get_net(dht);
onion->mono_time = mono_time; onion->mono_time = mono_time;
onion->rng = rng; onion->rng = rng;
onion->mem = mem;
new_symmetric_key(rng, onion->secret_symmetric_key); new_symmetric_key(rng, onion->secret_symmetric_key);
onion->timestamp = mono_time_get(onion->mono_time); onion->timestamp = mono_time_get(onion->mono_time);
const uint8_t *secret_key = dht_get_self_secret_key(dht); 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_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, 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, 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 || if (onion->shared_keys_1 == nullptr ||
onion->shared_keys_2 == 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_2);
shared_key_cache_free(onion->shared_keys_3); shared_key_cache_free(onion->shared_keys_3);
free(onion); mem_delete(onion->mem, onion);
} }

View File

@ -20,6 +20,7 @@ typedef struct Onion {
const Logger *log; const Logger *log;
const Mono_Time *mono_time; const Mono_Time *mono_time;
const Random *rng; const Random *rng;
const Memory *mem;
DHT *dht; DHT *dht;
Networking_Core *net; Networking_Core *net;
uint8_t secret_symmetric_key[CRYPTO_SYMMETRIC_KEY_SIZE]; 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); void set_callback_handle_recv_1(Onion *onion, onion_recv_1_cb *function, void *object);
non_null() 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) nullable(1)
void kill_onion(Onion *onion); void kill_onion(Onion *onion);

View File

@ -51,6 +51,7 @@ struct Onion_Announce {
const Logger *log; const Logger *log;
const Mono_Time *mono_time; const Mono_Time *mono_time;
const Random *rng; const Random *rng;
const Memory *mem;
DHT *dht; DHT *dht;
Networking_Core *net; Networking_Core *net;
Onion_Announce_Entry entries[ONION_ANNOUNCE_MAX_ENTRIES]; Onion_Announce_Entry entries[ONION_ANNOUNCE_MAX_ENTRIES];
@ -316,12 +317,13 @@ static int cmp_entry(const void *a, const void *b)
} }
non_null() 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) const uint8_t *comp_public_key)
{ {
// Pass comp_public_key to qsort with each Client_data entry, so the // Pass comp_public_key to qsort with each Client_data entry, so the
// comparison function can use it as the base of comparison. // 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) { if (cmp_list == nullptr) {
return; return;
@ -339,7 +341,7 @@ static void sort_onion_announce_list(Onion_Announce_Entry *list, unsigned int le
list[i] = cmp_list[i].entry; list[i] = cmp_list[i].entry;
} }
free(cmp_list); mem_delete(mem, cmp_list);
} }
/** @brief add entry to entries 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); 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); 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)); dht_get_self_public_key(onion_a->dht));
return in_entries(onion_a, public_key); return in_entries(onion_a, public_key);
} }
@ -438,7 +441,7 @@ static int handle_announce_request_common(
return 1; 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) { if (plain == nullptr) {
return 1; 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); packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE, plain_size + CRYPTO_MAC_SIZE, plain);
if ((uint32_t)decrypted_len != plain_size) { if ((uint32_t)decrypted_len != plain_size) {
free(plain); mem_delete(onion_a->mem, plain);
return 1; return 1;
} }
@ -483,10 +486,10 @@ static int handle_announce_request_common(
const uint16_t response_size = nodes_offset const uint16_t response_size = nodes_offset
+ MAX_SENT_NODES * PACKED_NODE_SIZE_IP6 + MAX_SENT_NODES * PACKED_NODE_SIZE_IP6
+ max_extra_size; + 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) { if (response == nullptr) {
free(plain); mem_delete(onion_a->mem, plain);
return 1; return 1;
} }
@ -504,8 +507,8 @@ static int handle_announce_request_common(
if (nodes_length <= 0) { if (nodes_length <= 0) {
LOGGER_WARNING(onion_a->log, "Failed to pack nodes"); LOGGER_WARNING(onion_a->log, "Failed to pack nodes");
free(response); mem_delete(onion_a->mem, response);
free(plain); mem_delete(onion_a->mem, plain);
return 1; return 1;
} }
} }
@ -523,8 +526,8 @@ static int handle_announce_request_common(
response, response_size, offset); response, response_size, offset);
if (extra_size == -1) { if (extra_size == -1) {
free(response); mem_delete(onion_a->mem, response);
free(plain); mem_delete(onion_a->mem, plain);
return 1; return 1;
} }
@ -536,8 +539,8 @@ static int handle_announce_request_common(
if (len != offset + CRYPTO_MAC_SIZE) { if (len != offset + CRYPTO_MAC_SIZE) {
LOGGER_ERROR(onion_a->log, "Failed to encrypt announce response"); LOGGER_ERROR(onion_a->log, "Failed to encrypt announce response");
free(response); mem_delete(onion_a->mem, response);
free(plain); mem_delete(onion_a->mem, plain);
return 1; return 1;
} }
@ -549,13 +552,13 @@ static int handle_announce_request_common(
if (send_onion_response(onion_a->net, source, data, if (send_onion_response(onion_a->net, source, data,
1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE + len, 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE + len,
packet + (length - ONION_RETURN_3)) == -1) { packet + (length - ONION_RETURN_3)) == -1) {
free(response); mem_delete(onion_a->mem, response);
free(plain); mem_delete(onion_a->mem, plain);
return 1; return 1;
} }
free(response); mem_delete(onion_a->mem, response);
free(plain); mem_delete(onion_a->mem, plain);
return 0; return 0;
} }
@ -639,13 +642,13 @@ static int handle_data_request(void *object, const IP_Port *source, const uint8_
return 0; 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) { if (dht == nullptr) {
return 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) { if (onion_a == nullptr) {
return 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->log = log;
onion_a->rng = rng; onion_a->rng = rng;
onion_a->mem = mem;
onion_a->mono_time = mono_time; onion_a->mono_time = mono_time;
onion_a->dht = dht; onion_a->dht = dht;
onion_a->net = dht_get_net(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; onion_a->extra_data_object = nullptr;
new_hmac_key(rng, onion_a->hmac_key); 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) { if (onion_a->shared_keys_recv == nullptr) {
kill_onion_announce(onion_a); kill_onion_announce(onion_a);
return nullptr; return nullptr;
@ -687,5 +691,5 @@ void kill_onion_announce(Onion_Announce *onion_a)
crypto_memzero(onion_a->hmac_key, CRYPTO_HMAC_KEY_SIZE); crypto_memzero(onion_a->hmac_key, CRYPTO_HMAC_KEY_SIZE);
shared_key_cache_free(onion_a->shared_keys_recv); shared_key_cache_free(onion_a->shared_keys_recv);
free(onion_a); mem_delete(onion_a->mem, onion_a);
} }

View File

@ -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); pack_extra_data_cb *extra_data_callback, void *extra_data_object);
non_null() 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) nullable(1)
void kill_onion_announce(Onion_Announce *onion_a); void kill_onion_announce(Onion_Announce *onion_a);

View File

@ -106,6 +106,7 @@ struct Onion_Client {
const Mono_Time *mono_time; const Mono_Time *mono_time;
const Logger *logger; const Logger *logger;
const Random *rng; const Random *rng;
const Memory *mem;
DHT *dht; DHT *dht;
Net_Crypto *c; Net_Crypto *c;
@ -731,12 +732,12 @@ static int onion_client_cmp_entry(const void *a, const void *b)
} }
non_null() non_null()
static void sort_onion_node_list(Onion_Node *list, unsigned int length, const Mono_Time *mono_time, static void sort_onion_node_list(const Memory *mem, const Mono_Time *mono_time,
const uint8_t *comp_public_key) 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 // Pass comp_public_key to qsort with each Client_data entry, so the
// comparison function can use it as the base of comparison. // 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) { if (cmp_list == nullptr) {
return; 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; list[i] = cmp_list[i].entry;
} }
free(cmp_list); mem_delete(mem, cmp_list);
} }
non_null() 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; 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; int index = -1;
bool stored = false; bool stored = false;
@ -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. /** @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. * @retval 0 if it succeeds.
*/ */
non_null() non_null()
static int realloc_onion_friends(Onion_Client *onion_c, uint32_t num) static int realloc_onion_friends(Onion_Client *onion_c, uint32_t num)
{ {
if (num == 0) { if (num == 0) {
free(onion_c->friends_list); mem_delete(onion_c->mem, onion_c->friends_list);
onion_c->friends_list = nullptr; onion_c->friends_list = nullptr;
return 0; 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) { if (newonion_friends == nullptr) {
return -1; 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_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) { if (c == nullptr) {
return 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) { if (onion_c == nullptr) {
return 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) { if (onion_c->announce_ping_array == nullptr) {
free(onion_c); mem_delete(mem, onion_c);
return nullptr; return nullptr;
} }
onion_c->mono_time = mono_time; onion_c->mono_time = mono_time;
onion_c->logger = logger; onion_c->logger = logger;
onion_c->rng = rng; onion_c->rng = rng;
onion_c->mem = mem;
onion_c->dht = nc_get_dht(c); onion_c->dht = nc_get_dht(c);
onion_c->net = dht_get_net(onion_c->dht); onion_c->net = dht_get_net(onion_c->dht);
onion_c->c = c; onion_c->c = c;
@ -2117,6 +2119,8 @@ void kill_onion_client(Onion_Client *onion_c)
return; return;
} }
const Memory *mem = onion_c->mem;
ping_array_kill(onion_c->announce_ping_array); ping_array_kill(onion_c->announce_ping_array);
realloc_onion_friends(onion_c, 0); realloc_onion_friends(onion_c, 0);
networking_registerhandler(onion_c->net, NET_PACKET_ANNOUNCE_RESPONSE, nullptr, nullptr); 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); 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); set_onion_packet_tcp_connection_callback(nc_get_tcp_c(onion_c->c), nullptr, nullptr);
crypto_memzero(onion_c, sizeof(Onion_Client)); crypto_memzero(onion_c, sizeof(Onion_Client));
free(onion_c); mem_delete(mem, onion_c);
} }

View File

@ -208,7 +208,7 @@ non_null()
void do_onion_client(Onion_Client *onion_c); void do_onion_client(Onion_Client *onion_c);
non_null() 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) nullable(1)
void kill_onion_client(Onion_Client *onion_c); void kill_onion_client(Onion_Client *onion_c);

View File

@ -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) { if (ping == nullptr) {
return 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) { if (ping->ping_array == nullptr) {
free(ping); mem_delete(mem, ping);
return nullptr; return nullptr;
} }
@ -360,7 +360,7 @@ Ping *ping_new(const Mono_Time *mono_time, const Random *rng, DHT *dht)
return ping; return ping;
} }
void ping_kill(Ping *ping) void ping_kill(const Memory *mem, Ping *ping)
{ {
if (ping == nullptr) { if (ping == nullptr) {
return; return;
@ -370,5 +370,5 @@ void ping_kill(Ping *ping)
networking_registerhandler(dht_get_net(ping->dht), NET_PACKET_PING_RESPONSE, nullptr, nullptr); networking_registerhandler(dht_get_net(ping->dht), NET_PACKET_PING_RESPONSE, nullptr, nullptr);
ping_array_kill(ping->ping_array); ping_array_kill(ping->ping_array);
free(ping); mem_delete(mem, ping);
} }

View File

@ -18,10 +18,10 @@
typedef struct Ping Ping; typedef struct Ping Ping;
non_null() 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) non_null(1) nullable(2)
void ping_kill(Ping *ping); void ping_kill(const Memory *mem, Ping *ping);
/** @brief Add nodes to the to_ping list. /** @brief Add nodes to the to_ping list.
* All nodes in this list are pinged every TIME_TO_PING seconds * All nodes in this list are pinged every TIME_TO_PING seconds

View File

@ -24,6 +24,7 @@ typedef struct Ping_Array_Entry {
} Ping_Array_Entry; } Ping_Array_Entry;
struct Ping_Array { struct Ping_Array {
const Memory *mem;
Ping_Array_Entry *entries; Ping_Array_Entry *entries;
uint32_t last_deleted; /* number representing the next entry to be deleted. */ 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. */ 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) { if (size == 0 || timeout == 0) {
return nullptr; return nullptr;
@ -43,16 +44,17 @@ Ping_Array *ping_array_new(uint32_t size, uint32_t timeout)
return nullptr; 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) { if (empty_array == nullptr) {
return 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) { if (empty_array->entries == nullptr) {
free(empty_array); mem_delete(mem, empty_array);
return nullptr; return nullptr;
} }
@ -67,7 +69,7 @@ non_null()
static void clear_entry(Ping_Array *array, uint32_t index) static void clear_entry(Ping_Array *array, uint32_t index)
{ {
const Ping_Array_Entry empty = {nullptr}; const Ping_Array_Entry empty = {nullptr};
free(array->entries[index].data); mem_delete(array->mem, array->entries[index].data);
array->entries[index] = empty; array->entries[index] = empty;
} }
@ -83,8 +85,8 @@ void ping_array_kill(Ping_Array *array)
++array->last_deleted; ++array->last_deleted;
} }
free(array->entries); mem_delete(array->mem, array->entries);
free(array); mem_delete(array->mem, array);
} }
/** Clear timed out entries. */ /** 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); 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) { if (array->entries[index].data == nullptr) {
return 0; return 0;

View File

@ -13,6 +13,7 @@
#include <stdint.h> #include <stdint.h>
#include "crypto_core.h" #include "crypto_core.h"
#include "mem.h"
#include "mono_time.h" #include "mono_time.h"
#ifdef __cplusplus #ifdef __cplusplus
@ -29,7 +30,8 @@ typedef struct Ping_Array Ping_Array;
* *
* @return pointer to allocated Ping_Array on success, nullptr on failure. * @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. * @brief Free all the allocated memory in a @ref Ping_Array.

View File

@ -15,41 +15,54 @@ struct Ping_Array_Deleter {
using Ping_Array_Ptr = std::unique_ptr<Ping_Array, Ping_Array_Deleter>; using Ping_Array_Ptr = std::unique_ptr<Ping_Array, Ping_Array_Deleter>;
struct Mono_Time_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>; using Mono_Time_Ptr = std::unique_ptr<Mono_Time, Mono_Time_Deleter>;
TEST(PingArray, MinimumTimeoutIsOne) TEST(PingArray, MinimumTimeoutIsOne)
{ {
EXPECT_EQ(ping_array_new(1, 0), nullptr); const Memory *mem = system_memory();
EXPECT_NE(Ping_Array_Ptr(ping_array_new(1, 1)), nullptr); EXPECT_EQ(ping_array_new(mem, 1, 0), nullptr);
EXPECT_NE(Ping_Array_Ptr(ping_array_new(mem, 1, 1)), nullptr);
} }
TEST(PingArray, MinimumArraySizeIsOne) TEST(PingArray, MinimumArraySizeIsOne)
{ {
EXPECT_EQ(ping_array_new(0, 1), nullptr); const Memory *mem = system_memory();
EXPECT_NE(Ping_Array_Ptr(ping_array_new(1, 1)), nullptr); EXPECT_EQ(ping_array_new(mem, 0, 1), nullptr);
EXPECT_NE(Ping_Array_Ptr(ping_array_new(mem, 1, 1)), nullptr);
} }
TEST(PingArray, ArraySizeMustBePowerOfTwo) TEST(PingArray, ArraySizeMustBePowerOfTwo)
{ {
const Memory *mem = system_memory();
Ping_Array_Ptr arr; Ping_Array_Ptr arr;
arr.reset(ping_array_new(2, 1)); arr.reset(ping_array_new(mem, 2, 1));
EXPECT_NE(arr, nullptr); EXPECT_NE(arr, nullptr);
arr.reset(ping_array_new(4, 1)); arr.reset(ping_array_new(mem, 4, 1));
EXPECT_NE(arr, nullptr); EXPECT_NE(arr, nullptr);
arr.reset(ping_array_new(1024, 1)); arr.reset(ping_array_new(mem, 1024, 1));
EXPECT_NE(arr, nullptr); EXPECT_NE(arr, nullptr);
EXPECT_EQ(ping_array_new(1023, 1), nullptr); EXPECT_EQ(ping_array_new(mem, 1023, 1), nullptr);
EXPECT_EQ(ping_array_new(1234, 1), nullptr); EXPECT_EQ(ping_array_new(mem, 1234, 1), nullptr);
} }
TEST(PingArray, StoredDataCanBeRetrieved) TEST(PingArray, StoredDataCanBeRetrieved)
{ {
Ping_Array_Ptr const arr(ping_array_new(2, 1)); const Memory *mem = system_memory();
Mono_Time_Ptr const mono_time(mono_time_new(nullptr, nullptr));
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); ASSERT_NE(mono_time, nullptr);
const Random *rng = system_random(); const Random *rng = system_random();
ASSERT_NE(rng, nullptr); ASSERT_NE(rng, nullptr);
@ -65,8 +78,10 @@ TEST(PingArray, StoredDataCanBeRetrieved)
TEST(PingArray, RetrievingDataWithTooSmallOutputBufferHasNoEffect) TEST(PingArray, RetrievingDataWithTooSmallOutputBufferHasNoEffect)
{ {
Ping_Array_Ptr const arr(ping_array_new(2, 1)); const Memory *mem = system_memory();
Mono_Time_Ptr const mono_time(mono_time_new(nullptr, nullptr));
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); ASSERT_NE(mono_time, nullptr);
const Random *rng = system_random(); const Random *rng = system_random();
ASSERT_NE(rng, nullptr); ASSERT_NE(rng, nullptr);
@ -86,8 +101,10 @@ TEST(PingArray, RetrievingDataWithTooSmallOutputBufferHasNoEffect)
TEST(PingArray, ZeroLengthDataCanBeAdded) TEST(PingArray, ZeroLengthDataCanBeAdded)
{ {
Ping_Array_Ptr const arr(ping_array_new(2, 1)); const Memory *mem = system_memory();
Mono_Time_Ptr const mono_time(mono_time_new(nullptr, nullptr));
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); ASSERT_NE(mono_time, nullptr);
const Random *rng = system_random(); const Random *rng = system_random();
ASSERT_NE(rng, nullptr); ASSERT_NE(rng, nullptr);
@ -101,8 +118,10 @@ TEST(PingArray, ZeroLengthDataCanBeAdded)
TEST(PingArray, PingId0IsInvalid) TEST(PingArray, PingId0IsInvalid)
{ {
Ping_Array_Ptr const arr(ping_array_new(2, 1)); const Memory *mem = system_memory();
Mono_Time_Ptr const mono_time(mono_time_new(nullptr, nullptr));
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); ASSERT_NE(mono_time, nullptr);
uint8_t c = 0; uint8_t c = 0;
@ -112,8 +131,10 @@ TEST(PingArray, PingId0IsInvalid)
// Protection against replay attacks. // Protection against replay attacks.
TEST(PingArray, DataCanOnlyBeRetrievedOnce) TEST(PingArray, DataCanOnlyBeRetrievedOnce)
{ {
Ping_Array_Ptr const arr(ping_array_new(2, 1)); const Memory *mem = system_memory();
Mono_Time_Ptr const mono_time(mono_time_new(nullptr, nullptr));
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); ASSERT_NE(mono_time, nullptr);
const Random *rng = system_random(); const Random *rng = system_random();
ASSERT_NE(rng, nullptr); ASSERT_NE(rng, nullptr);
@ -128,8 +149,10 @@ TEST(PingArray, DataCanOnlyBeRetrievedOnce)
TEST(PingArray, PingIdMustMatchOnCheck) TEST(PingArray, PingIdMustMatchOnCheck)
{ {
Ping_Array_Ptr const arr(ping_array_new(1, 1)); const Memory *mem = system_memory();
Mono_Time_Ptr const mono_time(mono_time_new(nullptr, nullptr));
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); ASSERT_NE(mono_time, nullptr);
const Random *rng = system_random(); const Random *rng = system_random();
ASSERT_NE(rng, nullptr); ASSERT_NE(rng, nullptr);

View File

@ -6,7 +6,6 @@
#include <assert.h> #include <assert.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> // calloc(...)
#include <string.h> // memcpy(...) #include <string.h> // memcpy(...)
#include "ccompat.h" #include "ccompat.h"
@ -23,7 +22,8 @@ struct Shared_Key_Cache {
Shared_Key *keys; Shared_Key *keys;
const uint8_t* self_secret_key; const uint8_t* self_secret_key;
uint64_t timeout; /** After this time (in seconds), a key is erased on the next housekeeping cycle */ 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; uint8_t keys_per_slot;
}; };
@ -43,37 +43,38 @@ static void shared_key_set_empty(Shared_Key *k) {
assert(shared_key_is_empty(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; return nullptr;
} }
// Time must not be zero, since we use that as special value for empty slots // 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 // Fail loudly in debug environments
assert(false); assert(false);
return nullptr; 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) { if (res == nullptr) {
return nullptr; return nullptr;
} }
res->self_secret_key = self_secret_key; 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; 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 // 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; 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) { if (res->keys == nullptr) {
free(res); mem_delete(mem, res);
return nullptr; return nullptr;
} }
crypto_memlock(res->keys, cache_size * sizeof (Shared_Key)); crypto_memlock(res->keys, cache_size * sizeof(Shared_Key));
return res; return res;
} }
@ -88,15 +89,15 @@ void shared_key_cache_free(Shared_Key_Cache *cache)
// Don't leave key material in memory // Don't leave key material in memory
crypto_memzero(cache->keys, cache_size * sizeof (Shared_Key)); crypto_memzero(cache->keys, cache_size * sizeof (Shared_Key));
crypto_memunlock(cache->keys, cache_size * sizeof (Shared_Key)); crypto_memunlock(cache->keys, cache_size * sizeof (Shared_Key));
free(cache->keys); mem_delete(cache->mem, cache->keys);
free(cache); mem_delete(cache->mem, cache);
} }
/* NOTE: On each lookup housekeeping is performed to evict keys that did timeout. */ /* 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]) 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 // 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. // 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]; const uint8_t bucket_idx = public_key[8];
Shared_Key* bucket_start = &cache->keys[bucket_idx*cache->keys_per_slot]; Shared_Key* bucket_start = &cache->keys[bucket_idx*cache->keys_per_slot];

View File

@ -8,6 +8,7 @@
#include <stdint.h> // uint*_t #include <stdint.h> // uint*_t
#include "crypto_core.h" #include "crypto_core.h"
#include "mem.h"
#include "mono_time.h" #include "mono_time.h"
/** /**
@ -18,7 +19,7 @@ typedef struct Shared_Key_Cache Shared_Key_Cache;
/** /**
* @brief Initializes a new 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, * @param self_secret_key Our own secret key of length CRYPTO_SECRET_KEY_SIZE,
* it must not change during the lifetime of the cache. * it must not change during the lifetime of the cache.
* @param timeout Number of milliseconds, after which a key should be evicted. * @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. * @return nullptr on error.
*/ */
non_null() 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, const uint8_t *self_secret_key,
uint64_t timeout, uint8_t keys_per_slot); uint64_t timeout, uint8_t keys_per_slot);

View File

@ -22,6 +22,7 @@
#include "group_chats.h" #include "group_chats.h"
#include "group_moderation.h" #include "group_moderation.h"
#include "logger.h" #include "logger.h"
#include "mem.h"
#include "mono_time.h" #include "mono_time.h"
#include "network.h" #include "network.h"
#include "tox_private.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_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; struct Tox_Options *default_options = nullptr;
if (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: { case TOX_ERR_OPTIONS_NEW_MALLOC: {
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC); SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC);
free(tox);
return nullptr; 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; const struct Tox_Options *const opts = options != nullptr ? options : default_options;
assert(opts != nullptr); 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_type(opts) != TOX_SAVEDATA_TYPE_NONE) {
if (tox_options_get_savedata_data(opts) == nullptr || tox_options_get_savedata_length(opts) == 0) { 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); SET_ERROR_PARAMETER(error, TOX_ERR_NEW_LOAD_BAD_FORMAT);
tox_options_free(default_options); tox_options_free(default_options);
free(tox);
return nullptr; 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) { if (tox_options_get_savedata_length(opts) != TOX_SECRET_KEY_SIZE) {
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_LOAD_BAD_FORMAT); SET_ERROR_PARAMETER(error, TOX_ERR_NEW_LOAD_BAD_FORMAT);
tox_options_free(default_options); tox_options_free(default_options);
free(tox);
return nullptr; 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) { if (tox_options_get_savedata_length(opts) < TOX_ENC_SAVE_MAGIC_LENGTH) {
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_LOAD_BAD_FORMAT); SET_ERROR_PARAMETER(error, TOX_ERR_NEW_LOAD_BAD_FORMAT);
tox_options_free(default_options); tox_options_free(default_options);
free(tox);
return nullptr; return nullptr;
} }
if (memcmp(tox_options_get_savedata_data(opts), TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) == 0) { if (memcmp(tox_options_get_savedata_data(opts), TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) == 0) {
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_LOAD_ENCRYPTED); SET_ERROR_PARAMETER(error, TOX_ERR_NEW_LOAD_ENCRYPTED);
tox_options_free(default_options); tox_options_free(default_options);
free(tox);
return nullptr; return nullptr;
} }
@ -709,6 +711,13 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error)
m_options.local_discovery_enabled = false; 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); tox->log_callback = tox_options_get_log_callback(opts);
m_options.log_callback = tox_log_handler; m_options.log_callback = tox_log_handler;
m_options.log_context = tox; m_options.log_context = tox;
@ -733,34 +742,18 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error)
default: { default: {
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_PROXY_BAD_TYPE); SET_ERROR_PARAMETER(error, TOX_ERR_NEW_PROXY_BAD_TYPE);
tox_options_free(default_options); tox_options_free(default_options);
free(tox); mem_delete(sys->mem, tox);
return nullptr; return nullptr;
} }
} }
const Tox_System *sys = tox_options_get_operating_system(opts); tox->sys = *sys;
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;
if (m_options.proxy_info.proxy_type != TCP_PROXY_NONE) { if (m_options.proxy_info.proxy_type != TCP_PROXY_NONE) {
if (tox_options_get_proxy_port(opts) == 0) { if (tox_options_get_proxy_port(opts) == 0) {
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_PROXY_BAD_PORT); SET_ERROR_PARAMETER(error, TOX_ERR_NEW_PROXY_BAD_PORT);
tox_options_free(default_options); tox_options_free(default_options);
free(tox); mem_delete(sys->mem, tox);
return nullptr; 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); const char *const proxy_host = tox_options_get_proxy_host(opts);
if (proxy_host == nullptr 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); SET_ERROR_PARAMETER(error, TOX_ERR_NEW_PROXY_BAD_HOST);
// TODO(irungentoo): TOX_ERR_NEW_PROXY_NOT_FOUND if domain. // TODO(irungentoo): TOX_ERR_NEW_PROXY_NOT_FOUND if domain.
tox_options_free(default_options); tox_options_free(default_options);
free(tox); mem_delete(sys->mem, tox);
return nullptr; return nullptr;
} }
m_options.proxy_info.ip_port.port = net_htons(tox_options_get_proxy_port(opts)); 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) { if (tox->mono_time == nullptr) {
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC); SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC);
tox_options_free(default_options); tox_options_free(default_options);
free(tox); mem_delete(sys->mem, tox);
return nullptr; return nullptr;
} }
if (tox_options_get_experimental_thread_safety(opts)) { 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) { if (tox->mutex == nullptr) {
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC); SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC);
tox_options_free(default_options); tox_options_free(default_options);
free(tox); mem_delete(sys->mem, tox);
return nullptr; return nullptr;
} }
@ -816,7 +809,7 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error)
tox_lock(tox); tox_lock(tox);
Messenger_Error m_error; 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 (tox->m == nullptr) {
if (m_error == MESSENGER_ERROR_PORT) { if (m_error == MESSENGER_ERROR_PORT) {
@ -827,7 +820,7 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error)
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC); SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC);
} }
mono_time_free(tox->mono_time); mono_time_free(tox->sys.mem, tox->mono_time);
tox_options_free(default_options); tox_options_free(default_options);
tox_unlock(tox); tox_unlock(tox);
@ -835,15 +828,15 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error)
pthread_mutex_destroy(tox->mutex); pthread_mutex_destroy(tox->mutex);
} }
free(tox->mutex); mem_delete(sys->mem, tox->mutex);
free(tox); mem_delete(sys->mem, tox);
return nullptr; return nullptr;
} }
if (new_groupchats(tox->mono_time, tox->m) == nullptr) { if (new_groupchats(tox->mono_time, tox->m) == nullptr) {
kill_messenger(tox->m); 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_options_free(default_options);
tox_unlock(tox); tox_unlock(tox);
@ -851,8 +844,8 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error)
pthread_mutex_destroy(tox->mutex); pthread_mutex_destroy(tox->mutex);
} }
free(tox->mutex); mem_delete(sys->mem, tox->mutex);
free(tox); mem_delete(sys->mem, tox);
SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC); SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC);
return nullptr; return nullptr;
@ -928,15 +921,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"); 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_groupchats(tox->m->conferences_object);
kill_messenger(tox->m); kill_messenger(tox->m);
mono_time_free(tox->mono_time); mono_time_free(tox->sys.mem, tox->mono_time);
tox_unlock(tox); tox_unlock(tox);
if (tox->mutex != nullptr) { if (tox->mutex != nullptr) {
pthread_mutex_destroy(tox->mutex); 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) static uint32_t end_size(void)
@ -1006,11 +999,11 @@ static int32_t resolve_bootstrap_node(Tox *tox, const char *host, uint16_t port,
return -1; 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) { if (count < 1) {
LOGGER_DEBUG(tox->m->log, "could not resolve bootstrap node '%s'", host); 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); SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_BAD_HOST);
return -1; return -1;
} }
@ -1054,7 +1047,7 @@ bool tox_bootstrap(Tox *tox, const char *host, uint16_t port, const uint8_t *pub
tox_unlock(tox); tox_unlock(tox);
net_freeipport(root); net_freeipport(tox->sys.mem, root);
if (count == 0 || !onion_success || !udp_success) { 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)", LOGGER_DEBUG(tox->m->log, "bootstrap node '%s' resolved to %d IP_Ports%s (onion: %s, UDP: %s)",
@ -1091,7 +1084,7 @@ bool tox_add_tcp_relay(Tox *tox, const char *host, uint16_t port, const uint8_t
tox_unlock(tox); tox_unlock(tox);
net_freeipport(root); net_freeipport(tox->sys.mem, root);
if (count == 0) { if (count == 0) {
SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_BAD_HOST); SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_BAD_HOST);
@ -1944,7 +1937,7 @@ uint32_t tox_file_send(Tox *tox, uint32_t friend_number, uint32_t kind, uint64_t
if (file_id == nullptr) { if (file_id == nullptr) {
/* Tox keys are 32 bytes like FILE_ID_LENGTH. */ /* 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; file_id = f_id;
} }
@ -2099,7 +2092,7 @@ uint32_t tox_conference_new(Tox *tox, Tox_Err_Conference_New *error)
{ {
assert(tox != nullptr); assert(tox != nullptr);
tox_lock(tox); 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); tox_unlock(tox);
if (ret == -1) { if (ret == -1) {
@ -4580,3 +4573,8 @@ bool tox_group_mod_kick_peer(const Tox *tox, uint32_t group_number, uint32_t pee
#endif /* VANILLA_NACL */ #endif /* VANILLA_NACL */
const Tox_System *tox_get_system(Tox *tox)
{
assert(tox != nullptr);
return &tox->sys;
}

View File

@ -684,8 +684,8 @@ struct Tox_Options {
bool experimental_thread_safety; bool experimental_thread_safety;
/** /**
* Low level operating system functionality such as send/recv and random * Low level operating system functionality such as send/recv, random
* number generation. * number generation, and memory allocation.
*/ */
const Tox_System *operating_system; 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); 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 * @brief Calculates the number of bytes required to store the tox instance with
* tox_get_savedata. * tox_get_savedata.

View File

@ -4,6 +4,7 @@
#include "tox_events.h" #include "tox_events.h"
#include <assert.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -11,7 +12,9 @@
#include "bin_unpack.h" #include "bin_unpack.h"
#include "ccompat.h" #include "ccompat.h"
#include "events/events_alloc.h" #include "events/events_alloc.h"
#include "mem.h"
#include "tox.h" #include "tox.h"
#include "tox_private.h"
/***************************************************** /*****************************************************
@ -231,7 +234,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); 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); Bin_Unpack *bu = bin_unpack_new(bytes, bytes_size);
@ -239,7 +242,7 @@ Tox_Events *tox_events_load(const uint8_t *bytes, uint32_t bytes_size)
return nullptr; 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) { if (events == nullptr) {
bin_unpack_free(bu); bin_unpack_free(bu);
@ -260,8 +263,11 @@ Tox_Events *tox_events_load(const uint8_t *bytes, uint32_t bytes_size)
return events; 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 a_size = tox_events_bytes_size(a);
const uint32_t b_size = tox_events_bytes_size(b); const uint32_t b_size = tox_events_bytes_size(b);
@ -269,12 +275,12 @@ bool tox_events_equal(const Tox_Events *a, const Tox_Events *b)
return false; return false;
} }
uint8_t *a_bytes = (uint8_t *)malloc(a_size); uint8_t *a_bytes = (uint8_t *)mem_balloc(sys->mem, a_size);
uint8_t *b_bytes = (uint8_t *)malloc(b_size); uint8_t *b_bytes = (uint8_t *)mem_balloc(sys->mem, b_size);
if (a_bytes == nullptr || b_bytes == nullptr) { if (a_bytes == nullptr || b_bytes == nullptr) {
free(b_bytes); mem_delete(sys->mem, b_bytes);
free(a_bytes); mem_delete(sys->mem, a_bytes);
return false; return false;
} }
@ -283,8 +289,8 @@ bool tox_events_equal(const Tox_Events *a, const Tox_Events *b)
const bool ret = memcmp(a_bytes, b_bytes, a_size) == 0; const bool ret = memcmp(a_bytes, b_bytes, a_size) == 0;
free(b_bytes); mem_delete(sys->mem, b_bytes);
free(a_bytes); mem_delete(sys->mem, a_bytes);
return ret; return ret;
} }

View File

@ -343,9 +343,9 @@ void tox_events_free(Tox_Events *events);
uint32_t tox_events_bytes_size(const 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); 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 #ifdef __cplusplus
} }

View File

@ -1,13 +1,33 @@
#include "tox_events.h" #include "tox_events.h"
#include <cstdint> #include <cstdint>
#include <cstring>
#include <vector> #include <vector>
#include "../testing/fuzzing/fuzz_support.h"
namespace { 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) { if (events) {
std::vector<uint8_t> packed(tox_events_bytes_size(events)); std::vector<uint8_t> packed(tox_events_bytes_size(events));
tox_events_get_bytes(events, packed.data()); 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);
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; return 0;
} }

View File

@ -6,29 +6,32 @@
#include <vector> #include <vector>
#include "crypto_core.h" #include "crypto_core.h"
#include "tox_private.h"
namespace { namespace {
TEST(ToxEvents, UnpackRandomDataDoesntCrash) TEST(ToxEvents, UnpackRandomDataDoesntCrash)
{ {
const Random *rng = system_random(); const Tox_System sys = tox_default_system();
ASSERT_NE(rng, nullptr); ASSERT_NE(sys.rng, nullptr);
std::array<uint8_t, 128> data; std::array<uint8_t, 128> data;
random_bytes(rng, data.data(), data.size()); random_bytes(sys.rng, data.data(), data.size());
tox_events_free(tox_events_load(data.data(), data.size())); tox_events_free(tox_events_load(&sys, data.data(), data.size()));
} }
TEST(ToxEvents, UnpackEmptyDataFails) TEST(ToxEvents, UnpackEmptyDataFails)
{ {
const Tox_System sys = tox_default_system();
std::array<uint8_t, 1> data; 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); EXPECT_EQ(events, nullptr);
} }
TEST(ToxEvents, UnpackEmptyArrayCreatesEmptyEvents) TEST(ToxEvents, UnpackEmptyArrayCreatesEmptyEvents)
{ {
const Tox_System sys = tox_default_system();
std::array<uint8_t, 1> data{0x90}; // empty msgpack array 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); ASSERT_NE(events, nullptr);
EXPECT_EQ(tox_events_get_conference_connected_size(events), 0); EXPECT_EQ(tox_events_get_conference_connected_size(events), 0);
tox_events_free(events); tox_events_free(events);
@ -44,9 +47,10 @@ TEST(ToxEvents, NullEventsPacksToEmptyArray)
TEST(ToxEvents, PackedEventsCanBeUnpacked) TEST(ToxEvents, PackedEventsCanBeUnpacked)
{ {
const Tox_System sys = tox_default_system();
// [[0, 1]] == Tox_Self_Connection_Status { .connection_status = TOX_CONNECTION_TCP } // [[0, 1]] == Tox_Self_Connection_Status { .connection_status = TOX_CONNECTION_TCP }
std::array<uint8_t, 6> packed{0x91, 0x92, 0xcc, 0x00, 0xcc, 0x01}; 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); ASSERT_NE(events, nullptr);
std::array<uint8_t, 4> bytes; std::array<uint8_t, 4> bytes;
ASSERT_EQ(tox_events_bytes_size(events), bytes.size()); ASSERT_EQ(tox_events_bytes_size(events), bytes.size());
@ -57,8 +61,9 @@ TEST(ToxEvents, PackedEventsCanBeUnpacked)
TEST(ToxEvents, DealsWithHugeMsgpackArrays) TEST(ToxEvents, DealsWithHugeMsgpackArrays)
{ {
const Tox_System sys = tox_default_system();
std::vector<uint8_t> data{0xdd, 0xff, 0xff, 0xff, 0xff}; 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 } // namespace

View File

@ -11,6 +11,7 @@
#include <assert.h> #include <assert.h>
#include "ccompat.h" #include "ccompat.h"
#include "mem.h"
#include "network.h" #include "network.h"
#include "tox_struct.h" #include "tox_struct.h"
@ -28,6 +29,7 @@ Tox_System tox_default_system(void)
nullptr, // mono_time_user_data nullptr, // mono_time_user_data
system_random(), system_random(),
system_network(), system_network(),
system_memory(),
}; };
return sys; 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; 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) { if (count < 1) {
SET_ERROR_PARAMETER(error, TOX_ERR_DHT_GET_NODES_BAD_IP); SET_ERROR_PARAMETER(error, TOX_ERR_DHT_GET_NODES_BAD_IP);
net_freeipport(root); net_freeipport(tox->sys.mem, root);
tox_unlock(tox); tox_unlock(tox);
return false; 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); tox_unlock(tox);
net_freeipport(root); net_freeipport(tox->sys.mem, root);
if (!success) { if (!success) {
SET_ERROR_PARAMETER(error, TOX_ERR_DHT_GET_NODES_FAIL); SET_ERROR_PARAMETER(error, TOX_ERR_DHT_GET_NODES_FAIL);

View File

@ -23,6 +23,7 @@ struct Tox_System {
void *mono_time_user_data; void *mono_time_user_data;
const struct Random *rng; const struct Random *rng;
const struct Network *ns; const struct Network *ns;
const struct Memory *mem;
}; };
Tox_System tox_default_system(void); Tox_System tox_default_system(void);

View File

@ -7,6 +7,7 @@
#define C_TOXCORE_TOXCORE_TOX_STRUCT_H #define C_TOXCORE_TOXCORE_TOX_STRUCT_H
#include "Messenger.h" #include "Messenger.h"
#include "mem.h"
#include "tox.h" #include "tox.h"
#include "tox_private.h" #include "tox_private.h"
@ -17,8 +18,7 @@ extern "C" {
struct Tox { struct Tox {
Messenger *m; Messenger *m;
Mono_Time *mono_time; Mono_Time *mono_time;
Random rng; Tox_System sys;
Network ns;
pthread_mutex_t *mutex; pthread_mutex_t *mutex;
tox_log_cb *log_callback; tox_log_cb *log_callback;

View File

@ -24,7 +24,7 @@ bool is_power_of_2(uint64_t x)
return x != 0 && (x & (~x + 1)) == 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) { if (ary == nullptr) {
return; 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) { for (size_t i = 0; i < n_items; ++i) {
if (ary[i] != nullptr) { 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) uint16_t data_checksum(const uint8_t *data, uint32_t length)

View File

@ -16,6 +16,7 @@
#include <stdint.h> #include <stdint.h>
#include "attributes.h" #include "attributes.h"
#include "mem.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -24,8 +25,8 @@ extern "C" {
bool is_power_of_2(uint64_t x); bool is_power_of_2(uint64_t x);
/** @brief Frees all pointers in a uint8_t pointer array, as well as the array itself. */ /** @brief Frees all pointers in a uint8_t pointer array, as well as the array itself. */
nullable(1) non_null(1) nullable(2)
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);
/** Returns -1 if failed or 0 if success */ /** Returns -1 if failed or 0 if success */
non_null() int create_recursive_mutex(pthread_mutex_t *mutex); non_null() int create_recursive_mutex(pthread_mutex_t *mutex);