diff --git a/BUILD.bazel b/BUILD.bazel index db5f5693df..723a400dc0 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -3,32 +3,75 @@ load("//tools/project:build_defs.bzl", "project") project(license = "gpl3-https") +genrule( + name = "toxcore_headers", + srcs = ["//c-toxcore/toxcore:public"], + outs = [ + "tox/toxcore/os_log.h", + "tox/toxcore/os_memory.h", + "tox/toxcore/os_network.h", + "tox/toxcore/os_random.h", + "tox/toxcore/os_system.h", + "tox/toxcore/tox.h", + "tox/toxcore/tox_attributes.h", + "tox/toxcore/tox_dispatch.h", + "tox/toxcore/tox_events.h", + "tox/toxcore/tox_log.h", + "tox/toxcore/tox_log_impl.h", + "tox/toxcore/tox_memory.h", + "tox/toxcore/tox_memory_impl.h", + "tox/toxcore/tox_network.h", + "tox/toxcore/tox_network_impl.h", + "tox/toxcore/tox_options.h", + "tox/toxcore/tox_random.h", + "tox/toxcore/tox_random_impl.h", + "tox/toxcore/tox_system.h", + "tox/toxcore/tox_system_impl.h", + "tox/toxcore/tox_time.h", + "tox/toxcore/tox_time_impl.h", + ], + cmd = "cp $(locations //c-toxcore/toxcore:public) $(GENDIR)/c-toxcore/tox/toxcore/", + visibility = ["//visibility:public"], +) + genrule( name = "public_headers", srcs = [ + "tox.h", + "toxav.h", + "toxencryptsave.h", "//c-toxcore/toxav:toxav.h", - "//c-toxcore/toxcore:tox.h", - "//c-toxcore/toxcore:tox_private.h", "//c-toxcore/toxencryptsave:toxencryptsave.h", ], outs = [ - "tox/toxav.h", "tox/tox.h", - "tox/tox_private.h", + "tox/toxav.h", + "tox/toxav/toxav.h", "tox/toxencryptsave.h", + "tox/toxencryptsave/toxencryptsave.h", ], cmd = """ - cp $(location //c-toxcore/toxav:toxav.h) $(GENDIR)/c-toxcore/tox/toxav.h - cp $(location //c-toxcore/toxcore:tox.h) $(GENDIR)/c-toxcore/tox/tox.h - cp $(location //c-toxcore/toxcore:tox_private.h) $(GENDIR)/c-toxcore/tox/tox_private.h - cp $(location //c-toxcore/toxencryptsave:toxencryptsave.h) $(GENDIR)/c-toxcore/tox/toxencryptsave.h + cp $(location toxav.h) $(GENDIR)/c-toxcore/tox/toxav.h + cp $(location tox.h) $(GENDIR)/c-toxcore/tox/tox.h + cp $(location toxencryptsave.h) $(GENDIR)/c-toxcore/tox/toxencryptsave.h + cp $(location //c-toxcore/toxav:toxav.h) $(GENDIR)/c-toxcore/tox/toxav/toxav.h + cp $(location //c-toxcore/toxencryptsave:toxencryptsave.h) $(GENDIR)/c-toxcore/tox/toxencryptsave/toxencryptsave.h """, visibility = ["//visibility:public"], ) +filegroup( + name = "public", + srcs = [ + ":public_headers", + ":toxcore_headers", + ], + visibility = ["//visibility:public"], +) + cc_library( name = "c-toxcore", - hdrs = [":public_headers"], + hdrs = [":public"], includes = ["."], visibility = ["//visibility:public"], deps = [ diff --git a/CMakeLists.txt b/CMakeLists.txt index f211207794..feaea22f69 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,6 +30,7 @@ endif() set_source_files_properties( toxcore/mono_time.c toxcore/network.c + toxcore/os_time.c toxcore/tox.c toxcore/util.c PROPERTIES SKIP_UNITY_BUILD_INCLUSION TRUE) @@ -317,6 +318,19 @@ set(toxcore_SOURCES toxcore/onion_client.c toxcore/onion_client.h toxcore/onion.h + toxcore/os_log.c + toxcore/os_log.h + toxcore/os_memory.c + toxcore/os_memory.h + toxcore/os_network.c + toxcore/os_network.h + toxcore/os_network_impl.h + toxcore/os_random.c + toxcore/os_random.h + toxcore/os_system.c + toxcore/os_system.h + toxcore/os_time.c + toxcore/os_time.h toxcore/ping_array.c toxcore/ping_array.h toxcore/ping.c @@ -337,13 +351,33 @@ set(toxcore_SOURCES toxcore/timed_auth.h toxcore/tox_api.c toxcore/tox.c + toxcore/tox.h toxcore/tox_dispatch.c toxcore/tox_dispatch.h toxcore/tox_event.c toxcore/tox_event.h toxcore/tox_events.c toxcore/tox_events.h - toxcore/tox.h + toxcore/tox_log.c + toxcore/tox_log.h + toxcore/tox_log_impl.h + toxcore/tox_memory.c + toxcore/tox_memory.h + toxcore/tox_memory_impl.h + toxcore/tox_network.c + toxcore/tox_network.h + toxcore/tox_network_impl.h + toxcore/tox_options.c + toxcore/tox_options.h + toxcore/tox_random.c + toxcore/tox_random.h + toxcore/tox_random_impl.h + toxcore/tox_system.c + toxcore/tox_system.h + toxcore/tox_system_impl.h + toxcore/tox_time.c + toxcore/tox_time.h + toxcore/tox_time_impl.h toxcore/tox_private.c toxcore/tox_private.h toxcore/tox_pack.c @@ -362,13 +396,24 @@ else() endif() set(toxcore_PKGCONFIG_REQUIRES ${toxcore_PKGCONFIG_REQUIRES} libsodium) set(toxcore_API_HEADERS + ${toxcore_SOURCE_DIR}/tox.h^tox + ${toxcore_SOURCE_DIR}/toxcore/os_log.h^os + ${toxcore_SOURCE_DIR}/toxcore/os_memory.h^os + ${toxcore_SOURCE_DIR}/toxcore/os_network.h^os + ${toxcore_SOURCE_DIR}/toxcore/os_random.h^os + ${toxcore_SOURCE_DIR}/toxcore/os_system.h^os ${toxcore_SOURCE_DIR}/toxcore/tox.h^tox + ${toxcore_SOURCE_DIR}/toxcore/tox_attributes.h^tox + ${toxcore_SOURCE_DIR}/toxcore/tox_dispatch.h^tox ${toxcore_SOURCE_DIR}/toxcore/tox_events.h^tox - ${toxcore_SOURCE_DIR}/toxcore/tox_dispatch.h^tox) -if(EXPERIMENTAL_API) - set(toxcore_API_HEADERS ${toxcore_API_HEADERS} - ${toxcore_SOURCE_DIR}/toxcore/tox_private.h^tox) -endif() + ${toxcore_SOURCE_DIR}/toxcore/tox_log.h^tox + ${toxcore_SOURCE_DIR}/toxcore/tox_memory.h^tox + ${toxcore_SOURCE_DIR}/toxcore/tox_network.h^tox + ${toxcore_SOURCE_DIR}/toxcore/tox_options.h^tox + ${toxcore_SOURCE_DIR}/toxcore/tox_random.h^tox + ${toxcore_SOURCE_DIR}/toxcore/tox_system.h^tox + ${toxcore_SOURCE_DIR}/toxcore/tox_system_impl.h^tox + ${toxcore_SOURCE_DIR}/toxcore/tox_time.h^tox) ################################################################################ # @@ -397,6 +442,7 @@ if(BUILD_TOXAV) toxav/video.c toxav/video.h) set(toxcore_API_HEADERS ${toxcore_API_HEADERS} + ${toxcore_SOURCE_DIR}/toxav.h^toxav ${toxcore_SOURCE_DIR}/toxav/toxav.h^toxav) if(MSVC) @@ -420,6 +466,7 @@ set(toxcore_SOURCES ${toxcore_SOURCES} toxencryptsave/toxencryptsave.c toxencryptsave/toxencryptsave.h) set(toxcore_API_HEADERS ${toxcore_API_HEADERS} + ${toxcore_SOURCE_DIR}/toxencryptsave.h^tox ${toxcore_SOURCE_DIR}/toxencryptsave/toxencryptsave.h^tox) ################################################################################ diff --git a/auto_tests/BUILD.bazel b/auto_tests/BUILD.bazel index 17606cafe5..7ef0d3dc8d 100644 --- a/auto_tests/BUILD.bazel +++ b/auto_tests/BUILD.bazel @@ -19,6 +19,7 @@ cc_library( "//c-toxcore/toxcore:tox", "//c-toxcore/toxcore:tox_dispatch", "//c-toxcore/toxcore:tox_events", + "//c-toxcore/toxcore:tox_time", ], ) @@ -75,9 +76,13 @@ extra_data = { "//c-toxcore/toxcore:onion", "//c-toxcore/toxcore:onion_announce", "//c-toxcore/toxcore:onion_client", + "//c-toxcore/toxcore:os_memory", + "//c-toxcore/toxcore:os_network", + "//c-toxcore/toxcore:os_random", "//c-toxcore/toxcore:tox", "//c-toxcore/toxcore:tox_dispatch", "//c-toxcore/toxcore:tox_events", + "//c-toxcore/toxcore:tox_time", "//c-toxcore/toxcore:util", "//c-toxcore/toxencryptsave", "@libsodium", diff --git a/auto_tests/TCP_test.c b/auto_tests/TCP_test.c index 3c5b88e959..e8e6b6e08c 100644 --- a/auto_tests/TCP_test.c +++ b/auto_tests/TCP_test.c @@ -8,6 +8,9 @@ #include "../toxcore/TCP_server.h" #include "../toxcore/crypto_core.h" #include "../toxcore/mono_time.h" +#include "../toxcore/os_random.h" +#include "../toxcore/os_network.h" +#include "../toxcore/os_memory.h" #include "../toxcore/util.h" #include "auto_test_support.h" @@ -52,7 +55,7 @@ static void test_basic(void) const Memory *mem = os_memory(); ck_assert(mem != nullptr); - Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); + Mono_Time *mono_time = mono_time_new(mem, nullptr); Logger *logger = logger_new(mem); logger_callback_log(logger, print_debug_logger, nullptr, nullptr); @@ -103,7 +106,7 @@ static void test_basic(void) // Encrypting handshake int ret = encrypt_data(self_public_key, f_secret_key, handshake + CRYPTO_PUBLIC_KEY_SIZE, handshake_plain, - TCP_HANDSHAKE_PLAIN_SIZE, handshake + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE); + TCP_HANDSHAKE_PLAIN_SIZE, handshake + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, mem); ck_assert_msg(ret == TCP_CLIENT_HANDSHAKE_SIZE - (CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE), "encrypt_data() call failed."); @@ -129,7 +132,7 @@ static void test_basic(void) ck_assert_msg(net_recv(ns, logger, sock, response, TCP_SERVER_HANDSHAKE_SIZE, &localhost) == TCP_SERVER_HANDSHAKE_SIZE, "Could/did not receive a server response to the initial handshake."); ret = decrypt_data(self_public_key, f_secret_key, response, response + CRYPTO_NONCE_SIZE, - TCP_SERVER_HANDSHAKE_SIZE - CRYPTO_NONCE_SIZE, response_plain); + TCP_SERVER_HANDSHAKE_SIZE - CRYPTO_NONCE_SIZE, response_plain, mem); ck_assert_msg(ret == TCP_HANDSHAKE_PLAIN_SIZE, "Failed to decrypt handshake response."); uint8_t f_nonce_r[CRYPTO_NONCE_SIZE]; uint8_t f_shared_key[CRYPTO_SHARED_KEY_SIZE]; @@ -143,7 +146,7 @@ static void test_basic(void) uint8_t r_req[2 + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE]; uint16_t size = 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE; size = net_htons(size); - encrypt_data_symmetric(f_shared_key, f_nonce, r_req_p, 1 + CRYPTO_PUBLIC_KEY_SIZE, r_req + 2); + encrypt_data_symmetric(f_shared_key, f_nonce, r_req_p, 1 + CRYPTO_PUBLIC_KEY_SIZE, r_req + 2, mem); increment_nonce(f_nonce); memcpy(r_req, &size, 2); @@ -174,7 +177,7 @@ static void test_basic(void) "Wrong packet size for request response."); uint8_t packet_resp_plain[4096]; - ret = decrypt_data_symmetric(f_shared_key, f_nonce_r, packet_resp + 2, recv_data_len - 2, packet_resp_plain); + ret = decrypt_data_symmetric(f_shared_key, f_nonce_r, packet_resp + 2, recv_data_len - 2, packet_resp_plain, mem); ck_assert_msg(ret != -1, "Failed to decrypt the TCP server's response."); increment_nonce(f_nonce_r); @@ -229,7 +232,7 @@ static struct sec_TCP_con *new_tcp_con(const Logger *logger, const Memory *mem, random_nonce(rng, handshake + CRYPTO_PUBLIC_KEY_SIZE); int ret = encrypt_data(tcp_server_public_key(tcp_s), f_secret_key, handshake + CRYPTO_PUBLIC_KEY_SIZE, handshake_plain, - TCP_HANDSHAKE_PLAIN_SIZE, handshake + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE); + TCP_HANDSHAKE_PLAIN_SIZE, handshake + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, mem); ck_assert_msg(ret == TCP_CLIENT_HANDSHAKE_SIZE - (CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE), "Failed to encrypt the outgoing handshake."); @@ -249,7 +252,7 @@ static struct sec_TCP_con *new_tcp_con(const Logger *logger, const Memory *mem, ck_assert_msg(net_recv(sec_c->ns, logger, sock, response, TCP_SERVER_HANDSHAKE_SIZE, &localhost) == TCP_SERVER_HANDSHAKE_SIZE, "Failed to receive server handshake response."); ret = decrypt_data(tcp_server_public_key(tcp_s), f_secret_key, response, response + CRYPTO_NONCE_SIZE, - TCP_SERVER_HANDSHAKE_SIZE - CRYPTO_NONCE_SIZE, response_plain); + TCP_SERVER_HANDSHAKE_SIZE - CRYPTO_NONCE_SIZE, response_plain, mem); ck_assert_msg(ret == TCP_HANDSHAKE_PLAIN_SIZE, "Failed to decrypt server handshake response."); encrypt_precompute(response_plain, t_secret_key, sec_c->shared_key); memcpy(sec_c->recv_nonce, response_plain + CRYPTO_SHARED_KEY_SIZE, CRYPTO_NONCE_SIZE); @@ -271,7 +274,7 @@ static int write_packet_tcp_test_connection(const Logger *logger, struct sec_TCP uint16_t c_length = net_htons(length + CRYPTO_MAC_SIZE); memcpy(packet, &c_length, sizeof(uint16_t)); - int len = encrypt_data_symmetric(con->shared_key, con->sent_nonce, data, length, packet + sizeof(uint16_t)); + int len = encrypt_data_symmetric(con->shared_key, con->sent_nonce, data, length, packet + sizeof(uint16_t), con->mem); if ((unsigned int)len != (packet_size - sizeof(uint16_t))) { return -1; @@ -296,7 +299,7 @@ static int read_packet_sec_tcp(const Logger *logger, struct sec_TCP_con *con, ui int rlen = net_recv(con->ns, logger, con->sock, data, length, &localhost); ck_assert_msg(rlen == length, "Did not receive packet of correct length. Wanted %i, instead got %i", length, rlen); - rlen = decrypt_data_symmetric(con->shared_key, con->recv_nonce, data + 2, length - 2, data); + rlen = decrypt_data_symmetric(con->shared_key, con->recv_nonce, data + 2, length - 2, data, con->mem); ck_assert_msg(rlen != -1, "Failed to decrypt a received packet from the Relay server."); increment_nonce(con->recv_nonce); return rlen; @@ -311,7 +314,7 @@ static void test_some(void) const Memory *mem = os_memory(); ck_assert(mem != nullptr); - Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); + Mono_Time *mono_time = mono_time_new(mem, nullptr); Logger *logger = logger_new(mem); uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; @@ -507,7 +510,7 @@ static void test_client(void) ck_assert(mem != nullptr); Logger *logger = logger_new(mem); - Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); + Mono_Time *mono_time = mono_time_new(mem, nullptr); uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE]; @@ -642,7 +645,7 @@ static void test_client_invalid(void) const Memory *mem = os_memory(); ck_assert(mem != nullptr); - Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); + Mono_Time *mono_time = mono_time_new(mem, nullptr); Logger *logger = logger_new(mem); uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; @@ -720,7 +723,7 @@ static void test_tcp_connection(void) const Memory *mem = os_memory(); ck_assert(mem != nullptr); - Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); + Mono_Time *mono_time = mono_time_new(mem, nullptr); Logger *logger = logger_new(mem); tcp_data_callback_called = 0; @@ -833,7 +836,7 @@ static void test_tcp_connection2(void) const Memory *mem = os_memory(); ck_assert(mem != nullptr); - Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); + Mono_Time *mono_time = mono_time_new(mem, nullptr); Logger *logger = logger_new(mem); tcp_oobdata_callback_called = 0; diff --git a/auto_tests/announce_test.c b/auto_tests/announce_test.c index ef93095b1b..dfb950d726 100644 --- a/auto_tests/announce_test.c +++ b/auto_tests/announce_test.c @@ -7,6 +7,9 @@ #include "../toxcore/mono_time.h" #include "../toxcore/forwarding.h" #include "../toxcore/net_crypto.h" +#include "../toxcore/os_memory.h" +#include "../toxcore/os_network.h" +#include "../toxcore/os_random.h" #include "../toxcore/util.h" #include "auto_test_support.h" #include "check_compat.h" @@ -60,13 +63,13 @@ static void test_store_data(void) Logger *log = logger_new(mem); ck_assert(log != nullptr); logger_callback_log(log, print_debug_logger, nullptr, nullptr); - Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); + Mono_Time *mono_time = mono_time_new(mem, nullptr); ck_assert(mono_time != nullptr); Networking_Core *net = new_networking_no_udp(log, mem, ns); ck_assert(net != nullptr); DHT *dht = new_dht(log, mem, rng, ns, mono_time, net, true, true); ck_assert(dht != nullptr); - Forwarding *forwarding = new_forwarding(log, rng, mono_time, dht); + Forwarding *forwarding = new_forwarding(log, mem, rng, mono_time, dht); ck_assert(forwarding != nullptr); Announcements *announce = new_announcements(log, mem, rng, mono_time, forwarding); ck_assert(announce != nullptr); diff --git a/auto_tests/auto_test_support.c b/auto_tests/auto_test_support.c index 213e70570c..5cc63b0cf6 100644 --- a/auto_tests/auto_test_support.c +++ b/auto_tests/auto_test_support.c @@ -7,7 +7,8 @@ #include "../toxcore/mono_time.h" #include "../toxcore/tox_dispatch.h" #include "../toxcore/tox_events.h" -#include "../toxcore/tox_struct.h" +#include "../toxcore/tox_impl.h" +#include "../toxcore/tox_time_impl.h" #include "auto_test_support.h" @@ -157,17 +158,25 @@ static uint64_t get_state_clock_callback(void *user_data) return *clock; } +static const Tox_Time_Funcs autotox_time_funcs = { + get_state_clock_callback, +}; + void set_mono_time_callback(AutoTox *autotox) { ck_assert(autotox != nullptr); + if (autotox->tm == nullptr) { + autotox->tm = tox_time_new(&autotox_time_funcs, &autotox->clock, autotox->tox->sys.mem); + } + Mono_Time *mono_time = autotox->tox->mono_time; + mono_time_set_current_time_callback(mono_time, nullptr); // set to default first autotox->clock = current_time_monotonic(mono_time); ck_assert_msg(autotox->clock >= 1000, "clock is too low (not initialised?): %lu", (unsigned long)autotox->clock); - mono_time_set_current_time_callback(mono_time, nullptr, nullptr); // set to default first - mono_time_set_current_time_callback(mono_time, get_state_clock_callback, &autotox->clock); + mono_time_set_current_time_callback(mono_time, autotox->tm); } void save_autotox(AutoTox *autotox) @@ -194,6 +203,8 @@ void kill_autotox(AutoTox *autotox) autotox->alive = false; tox_dispatch_free(autotox->dispatch); tox_kill(autotox->tox); + tox_time_free(autotox->tm); + autotox->tm = nullptr; } void reload(AutoTox *autotox) @@ -399,6 +410,7 @@ void run_auto_test(struct Tox_Options *options, uint32_t tox_count, autotox_test for (uint32_t i = 0; i < tox_count; ++i) { tox_dispatch_free(autotoxes[i].dispatch); tox_kill(autotoxes[i].tox); + tox_time_free(autotoxes[i].tm); free(autotoxes[i].state); free(autotoxes[i].save_state); } diff --git a/auto_tests/auto_test_support.h b/auto_tests/auto_test_support.h index b9132e16bc..0e9bf913fc 100644 --- a/auto_tests/auto_test_support.h +++ b/auto_tests/auto_test_support.h @@ -12,6 +12,7 @@ typedef struct AutoTox { Tox *tox; Tox_Dispatch *dispatch; + Tox_Time *tm; uint32_t index; uint64_t clock; diff --git a/auto_tests/conference_av_test.c b/auto_tests/conference_av_test.c index 28a2a3a1e3..c070e9ed11 100644 --- a/auto_tests/conference_av_test.c +++ b/auto_tests/conference_av_test.c @@ -7,6 +7,7 @@ #include #include "../toxav/toxav.h" +#include "../toxcore/os_random.h" #include "check_compat.h" #define NUM_AV_GROUP_TOX 16 diff --git a/auto_tests/conference_test.c b/auto_tests/conference_test.c index af1cd288f8..8426cccf30 100644 --- a/auto_tests/conference_test.c +++ b/auto_tests/conference_test.c @@ -6,6 +6,7 @@ #include #include +#include "../toxcore/os_random.h" #include "../toxcore/util.h" #include "check_compat.h" diff --git a/auto_tests/crypto_test.c b/auto_tests/crypto_test.c index 83f8c525a6..fa847d0e00 100644 --- a/auto_tests/crypto_test.c +++ b/auto_tests/crypto_test.c @@ -4,6 +4,8 @@ #include "../testing/misc_tools.h" #include "../toxcore/crypto_core.h" +#include "../toxcore/os_memory.h" +#include "../toxcore/os_random.h" #include "../toxcore/net_crypto.h" #include "check_compat.h" @@ -80,6 +82,9 @@ static const uint8_t test_c[147] = { static void test_known(void) { + const Memory *mem = os_memory(); + ck_assert(mem != nullptr); + uint8_t c[147]; uint8_t m[131]; @@ -88,12 +93,12 @@ static void test_known(void) ck_assert_msg(sizeof(test_c) == sizeof(c), "sanity check failed"); ck_assert_msg(sizeof(test_m) == sizeof(m), "sanity check failed"); - const uint16_t clen = encrypt_data(bobpk, alicesk, test_nonce, test_m, sizeof(test_m) / sizeof(uint8_t), c); + const uint16_t clen = encrypt_data(bobpk, alicesk, test_nonce, test_m, sizeof(test_m) / sizeof(uint8_t), c, mem); ck_assert_msg(memcmp(test_c, c, sizeof(c)) == 0, "cyphertext doesn't match test vector"); ck_assert_msg(clen == sizeof(c) / sizeof(uint8_t), "wrong ciphertext length"); - const uint16_t mlen = decrypt_data(bobpk, alicesk, test_nonce, test_c, sizeof(test_c) / sizeof(uint8_t), m); + const uint16_t mlen = decrypt_data(bobpk, alicesk, test_nonce, test_c, sizeof(test_c) / sizeof(uint8_t), m, mem); ck_assert_msg(memcmp(test_m, m, sizeof(m)) == 0, "decrypted text doesn't match test vector"); ck_assert_msg(mlen == sizeof(m) / sizeof(uint8_t), "wrong plaintext length"); @@ -101,6 +106,9 @@ static void test_known(void) static void test_fast_known(void) { + const Memory *mem = os_memory(); + ck_assert(mem != nullptr); + uint8_t k[CRYPTO_SHARED_KEY_SIZE]; uint8_t c[147]; uint8_t m[131]; @@ -112,12 +120,12 @@ static void test_fast_known(void) ck_assert_msg(sizeof(test_c) == sizeof(c), "sanity check failed"); ck_assert_msg(sizeof(test_m) == sizeof(m), "sanity check failed"); - const uint16_t clen = encrypt_data_symmetric(k, test_nonce, test_m, sizeof(test_m) / sizeof(uint8_t), c); + const uint16_t clen = encrypt_data_symmetric(k, test_nonce, test_m, sizeof(test_m) / sizeof(uint8_t), c, mem); ck_assert_msg(memcmp(test_c, c, sizeof(c)) == 0, "cyphertext doesn't match test vector"); ck_assert_msg(clen == sizeof(c) / sizeof(uint8_t), "wrong ciphertext length"); - const uint16_t mlen = decrypt_data_symmetric(k, test_nonce, test_c, sizeof(test_c) / sizeof(uint8_t), m); + const uint16_t mlen = decrypt_data_symmetric(k, test_nonce, test_c, sizeof(test_c) / sizeof(uint8_t), m, mem); ck_assert_msg(memcmp(test_m, m, sizeof(m)) == 0, "decrypted text doesn't match test vector"); ck_assert_msg(mlen == sizeof(m) / sizeof(uint8_t), "wrong plaintext length"); @@ -125,6 +133,8 @@ static void test_fast_known(void) static void test_endtoend(void) { + const Memory *mem = os_memory(); + ck_assert(mem != nullptr); const Random *rng = os_random(); ck_assert(rng != nullptr); @@ -166,10 +176,10 @@ static void test_endtoend(void) ck_assert_msg(memcmp(k1, k2, CRYPTO_SHARED_KEY_SIZE) == 0, "encrypt_precompute: bad"); //Encrypt all four ways - const uint16_t c1len = encrypt_data(pk2, sk1, n, m, mlen, c1); - const uint16_t c2len = encrypt_data(pk1, sk2, n, m, mlen, c2); - const uint16_t c3len = encrypt_data_symmetric(k1, n, m, mlen, c3); - const uint16_t c4len = encrypt_data_symmetric(k2, n, m, mlen, c4); + const uint16_t c1len = encrypt_data(pk2, sk1, n, m, mlen, c1, mem); + const uint16_t c2len = encrypt_data(pk1, sk2, n, m, mlen, c2, mem); + const uint16_t c3len = encrypt_data_symmetric(k1, n, m, mlen, c3, mem); + const uint16_t c4len = encrypt_data_symmetric(k2, n, m, mlen, c4, mem); ck_assert_msg(c1len == c2len && c1len == c3len && c1len == c4len, "cyphertext lengths differ"); ck_assert_msg(c1len == mlen + (uint16_t)CRYPTO_MAC_SIZE, "wrong cyphertext length"); @@ -177,10 +187,10 @@ static void test_endtoend(void) && memcmp(c1, c4, c1len) == 0, "crypertexts differ"); //Decrypt all four ways - const uint16_t m1len = decrypt_data(pk2, sk1, n, c1, c1len, m1); - const uint16_t m2len = decrypt_data(pk1, sk2, n, c1, c1len, m2); - const uint16_t m3len = decrypt_data_symmetric(k1, n, c1, c1len, m3); - const uint16_t m4len = decrypt_data_symmetric(k2, n, c1, c1len, m4); + const uint16_t m1len = decrypt_data(pk2, sk1, n, c1, c1len, m1, mem); + const uint16_t m2len = decrypt_data(pk1, sk2, n, c1, c1len, m2, mem); + const uint16_t m3len = decrypt_data_symmetric(k1, n, c1, c1len, m3, mem); + const uint16_t m4len = decrypt_data_symmetric(k2, n, c1, c1len, m4, mem); ck_assert_msg(m1len == m2len && m1len == m3len && m1len == m4len, "decrypted text lengths differ"); ck_assert_msg(m1len == mlen, "wrong decrypted text length"); @@ -192,6 +202,8 @@ static void test_endtoend(void) static void test_large_data(void) { + const Memory *mem = os_memory(); + ck_assert(mem != nullptr); const Random *rng = os_random(); ck_assert(rng != nullptr); uint8_t k[CRYPTO_SHARED_KEY_SIZE]; @@ -216,13 +228,13 @@ static void test_large_data(void) //Generate key rand_bytes(rng, k, CRYPTO_SHARED_KEY_SIZE); - const uint16_t c1len = encrypt_data_symmetric(k, n, m1, m1_size, c1); - const uint16_t c2len = encrypt_data_symmetric(k, n, m2, m2_size, c2); + const uint16_t c1len = encrypt_data_symmetric(k, n, m1, m1_size, c1, mem); + const uint16_t c2len = encrypt_data_symmetric(k, n, m2, m2_size, c2, mem); ck_assert_msg(c1len == m1_size + CRYPTO_MAC_SIZE, "could not encrypt"); ck_assert_msg(c2len == m2_size + CRYPTO_MAC_SIZE, "could not encrypt"); - const uint16_t m1plen = decrypt_data_symmetric(k, n, c1, c1len, m1prime); + const uint16_t m1plen = decrypt_data_symmetric(k, n, c1, c1len, m1prime, mem); ck_assert_msg(m1plen == m1_size, "decrypted text lengths differ"); ck_assert_msg(memcmp(m1prime, m1, m1_size) == 0, "decrypted texts differ"); @@ -236,8 +248,11 @@ static void test_large_data(void) static void test_large_data_symmetric(void) { + const Memory *mem = os_memory(); + ck_assert(mem != nullptr); const Random *rng = os_random(); ck_assert(rng != nullptr); + uint8_t k[CRYPTO_SYMMETRIC_KEY_SIZE]; uint8_t n[CRYPTO_NONCE_SIZE]; @@ -256,10 +271,10 @@ static void test_large_data_symmetric(void) //Generate key new_symmetric_key(rng, k); - const uint16_t c1len = encrypt_data_symmetric(k, n, m1, m1_size, c1); + const uint16_t c1len = encrypt_data_symmetric(k, n, m1, m1_size, c1, mem); ck_assert_msg(c1len == m1_size + CRYPTO_MAC_SIZE, "could not encrypt data"); - const uint16_t m1plen = decrypt_data_symmetric(k, n, c1, c1len, m1prime); + const uint16_t m1plen = decrypt_data_symmetric(k, n, c1, c1len, m1prime, mem); ck_assert_msg(m1plen == m1_size, "decrypted text lengths differ"); ck_assert_msg(memcmp(m1prime, m1, m1_size) == 0, "decrypted texts differ"); @@ -271,6 +286,8 @@ static void test_large_data_symmetric(void) static void test_very_large_data(void) { + const Memory *mem = os_memory(); + ck_assert(mem != nullptr); const Random *rng = os_random(); ck_assert(rng != nullptr); @@ -287,7 +304,7 @@ static void test_very_large_data(void) ck_assert(plain != nullptr); ck_assert(encrypted != nullptr); - encrypt_data(pk, sk, nonce, plain, plain_size, encrypted); + encrypt_data(pk, sk, nonce, plain, plain_size, encrypted, mem); free(encrypted); free(plain); diff --git a/auto_tests/encryptsave_test.c b/auto_tests/encryptsave_test.c index e433e410a8..0d40dcc8d3 100644 --- a/auto_tests/encryptsave_test.c +++ b/auto_tests/encryptsave_test.c @@ -8,6 +8,7 @@ #include "../testing/misc_tools.h" #include "../toxcore/ccompat.h" #include "../toxcore/crypto_core.h" +#include "../toxcore/os_random.h" #include "../toxcore/tox.h" #include "../toxencryptsave/toxencryptsave.h" #include "auto_test_support.h" diff --git a/auto_tests/forwarding_test.c b/auto_tests/forwarding_test.c index 3ba85ed151..97f4949de8 100644 --- a/auto_tests/forwarding_test.c +++ b/auto_tests/forwarding_test.c @@ -8,6 +8,9 @@ #include "../toxcore/mono_time.h" #include "../toxcore/forwarding.h" #include "../toxcore/net_crypto.h" +#include "../toxcore/os_memory.h" +#include "../toxcore/os_network.h" +#include "../toxcore/os_random.h" #include "../toxcore/util.h" #include "auto_test_support.h" #include "check_compat.h" @@ -115,7 +118,7 @@ static Forwarding_Subtox *new_forwarding_subtox(const Memory *mem, bool no_udp, subtox->log = logger_new(mem); ck_assert(subtox->log != nullptr); logger_callback_log(subtox->log, print_debug_logger, nullptr, index); - subtox->mono_time = mono_time_new(mem, nullptr, nullptr); + subtox->mono_time = mono_time_new(mem, nullptr); if (no_udp) { subtox->net = new_networking_no_udp(subtox->log, mem, ns); @@ -129,7 +132,7 @@ static Forwarding_Subtox *new_forwarding_subtox(const Memory *mem, bool no_udp, const TCP_Proxy_Info inf = {{{{0}}}}; 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, mem, rng, subtox->mono_time, subtox->dht); ck_assert(subtox->forwarding != nullptr); subtox->announce = new_announcements(subtox->log, mem, rng, subtox->mono_time, subtox->forwarding); diff --git a/auto_tests/group_message_test.c b/auto_tests/group_message_test.c index 380a994b56..7ebe8cba6c 100644 --- a/auto_tests/group_message_test.c +++ b/auto_tests/group_message_test.c @@ -12,6 +12,7 @@ #include "auto_test_support.h" #include "check_compat.h" +#include "../toxcore/os_random.h" #include "../toxcore/util.h" typedef struct State { diff --git a/auto_tests/group_sync_test.c b/auto_tests/group_sync_test.c index 146c2258dd..f8d2997f9b 100644 --- a/auto_tests/group_sync_test.c +++ b/auto_tests/group_sync_test.c @@ -10,6 +10,7 @@ #include "auto_test_support.h" +#include "../toxcore/os_random.h" #include "../toxcore/tox.h" #include "../toxcore/util.h" diff --git a/auto_tests/group_topic_test.c b/auto_tests/group_topic_test.c index c8d84cb7e0..81f18fc9e1 100644 --- a/auto_tests/group_topic_test.c +++ b/auto_tests/group_topic_test.c @@ -11,8 +11,9 @@ #include "auto_test_support.h" #include "check_compat.h" -#include "../toxcore/tox.h" #include "../toxcore/group_chats.h" +#include "../toxcore/os_random.h" +#include "../toxcore/tox.h" #define NUM_GROUP_TOXES 3 diff --git a/auto_tests/lan_discovery_test.c b/auto_tests/lan_discovery_test.c index d7bf594b2b..847d883dbb 100644 --- a/auto_tests/lan_discovery_test.c +++ b/auto_tests/lan_discovery_test.c @@ -3,7 +3,9 @@ #include "../testing/misc_tools.h" #include "../toxcore/ccompat.h" -#include "../toxcore/tox_struct.h" +#include "../toxcore/os_memory.h" +#include "../toxcore/tox_time_impl.h" +#include "../toxcore/tox_impl.h" #include "auto_test_support.h" static uint64_t get_state_clock_callback(void *user_data) @@ -12,6 +14,10 @@ static uint64_t get_state_clock_callback(void *user_data) return *clock; } +static const Tox_Time_Funcs mock_time_funcs = { + get_state_clock_callback, +}; + int main(void) { setvbuf(stdout, nullptr, _IONBF, 0); @@ -21,14 +27,18 @@ int main(void) ck_assert(tox1 != nullptr); ck_assert(tox2 != nullptr); + const Memory *mem = os_memory(); + uint64_t clock = current_time_monotonic(tox1->mono_time); + Tox_Time *tm = tox_time_new(&mock_time_funcs, &clock, mem); + Mono_Time *mono_time; mono_time = tox1->mono_time; - mono_time_set_current_time_callback(mono_time, get_state_clock_callback, &clock); + mono_time_set_current_time_callback(mono_time, tm); mono_time = tox2->mono_time; - mono_time_set_current_time_callback(mono_time, get_state_clock_callback, &clock); + mono_time_set_current_time_callback(mono_time, tm); printf("Waiting for LAN discovery. This loop will attempt to run until successful."); @@ -49,5 +59,7 @@ int main(void) tox_kill(tox2); tox_kill(tox1); + + tox_time_free(tm); return 0; } diff --git a/auto_tests/network_test.c b/auto_tests/network_test.c index 76cb94a17f..f96618385e 100644 --- a/auto_tests/network_test.c +++ b/auto_tests/network_test.c @@ -3,6 +3,7 @@ #include "../testing/misc_tools.h" #include "../toxcore/network.h" +#include "../toxcore/os_network.h" #include "check_compat.h" #ifndef USE_IPV6 diff --git a/auto_tests/onion_test.c b/auto_tests/onion_test.c index 7a323066ba..c9d415fa6c 100644 --- a/auto_tests/onion_test.c +++ b/auto_tests/onion_test.c @@ -6,6 +6,9 @@ #include "../toxcore/onion.h" #include "../toxcore/onion_announce.h" #include "../toxcore/onion_client.h" +#include "../toxcore/os_memory.h" +#include "../toxcore/os_network.h" +#include "../toxcore/os_random.h" #include "../toxcore/util.h" #include "auto_test_support.h" #include "check_compat.h" @@ -112,7 +115,7 @@ static int handle_test_3(void *object, const IP_Port *source, const uint8_t *pac int len = decrypt_data(test_3_pub_key, dht_get_self_secret_key(onion->dht), packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH, packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE, - 2 + CRYPTO_SHA256_SIZE + CRYPTO_MAC_SIZE, plain); + 2 + CRYPTO_SHA256_SIZE + CRYPTO_MAC_SIZE, plain, onion->mem); if (len == -1) { return 1; @@ -147,7 +150,7 @@ static int handle_test_3_old(void *object, const IP_Port *source, const uint8_t int len = decrypt_data(test_3_pub_key, dht_get_self_secret_key(onion->dht), packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH, packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE, - 1 + CRYPTO_SHA256_SIZE + CRYPTO_MAC_SIZE, plain); + 1 + CRYPTO_SHA256_SIZE + CRYPTO_MAC_SIZE, plain, onion->mem); if (len == -1) { return 1; @@ -183,7 +186,7 @@ static int handle_test_4(void *object, const IP_Port *source, const uint8_t *pac } int len = decrypt_data(packet + 1 + CRYPTO_NONCE_SIZE, dht_get_self_secret_key(onion->dht), packet + 1, - packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE, sizeof("Install gentoo") + CRYPTO_MAC_SIZE, plain); + packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE, sizeof("Install gentoo") + CRYPTO_MAC_SIZE, plain, onion->mem); if (len == -1) { return 1; @@ -202,10 +205,10 @@ static int handle_test_4(void *object, const IP_Port *source, const uint8_t *pac * Use Onion_Path path to send data of length to dest. * Maximum length of data is ONION_MAX_DATA_SIZE. */ -static void send_onion_packet(const Networking_Core *net, const Random *rng, const Onion_Path *path, const IP_Port *dest, const uint8_t *data, uint16_t length) +static void send_onion_packet(const Networking_Core *net, const Memory *mem, const Random *rng, const Onion_Path *path, const IP_Port *dest, const uint8_t *data, uint16_t length) { uint8_t packet[ONION_MAX_PACKET_SIZE]; - const int len = create_onion_packet(rng, packet, sizeof(packet), path, dest, data, length); + const int len = create_onion_packet(rng, packet, sizeof(packet), path, dest, data, length, mem); ck_assert_msg(len != -1, "failed to create onion packet"); ck_assert_msg(sendpacket(net, &path->ip_port1, packet, len) == len, "failed to send onion packet"); } @@ -233,8 +236,8 @@ static void test_basic(void) Logger *log2 = logger_new(mem); logger_callback_log(log2, print_debug_logger, nullptr, &index[1]); - Mono_Time *mono_time1 = mono_time_new(mem, nullptr, nullptr); - Mono_Time *mono_time2 = mono_time_new(mem, nullptr, nullptr); + Mono_Time *mono_time1 = mono_time_new(mem, nullptr); + Mono_Time *mono_time2 = mono_time_new(mem, nullptr); IP ip = get_loopback(); 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)); @@ -264,7 +267,7 @@ static void test_basic(void) nodes[3] = n2; Onion_Path path; create_onion_path(rng, onion1->dht, &path, nodes); - send_onion_packet(onion1->net, rng, &path, &nodes[3].ip_port, req_packet, sizeof(req_packet)); + send_onion_packet(onion1->net, mem, rng, &path, &nodes[3].ip_port, req_packet, sizeof(req_packet)); handled_test_1 = 0; @@ -291,7 +294,7 @@ static void test_basic(void) uint64_t s; memcpy(&s, sb_data, sizeof(uint64_t)); memcpy(test_3_pub_key, nodes[3].public_key, CRYPTO_PUBLIC_KEY_SIZE); - int ret = send_announce_request(log1, onion1->net, rng, &path, &nodes[3], + int ret = send_announce_request(log1, onion1->net, rng, mem, &path, &nodes[3], dht_get_self_public_key(onion1->dht), dht_get_self_secret_key(onion1->dht), zeroes, @@ -313,7 +316,7 @@ static void test_basic(void) memcpy(onion_announce_entry_public_key(onion2_a, 1), dht_get_self_public_key(onion2->dht), CRYPTO_PUBLIC_KEY_SIZE); onion_announce_entry_set_time(onion2_a, 1, mono_time_get(mono_time2)); networking_registerhandler(onion1->net, NET_PACKET_ONION_DATA_RESPONSE, &handle_test_4, onion1); - send_announce_request(log1, onion1->net, rng, &path, &nodes[3], + send_announce_request(log1, onion1->net, rng, mem, &path, &nodes[3], dht_get_self_public_key(onion1->dht), dht_get_self_secret_key(onion1->dht), test_3_ping_id, @@ -332,13 +335,13 @@ static void test_basic(void) Logger *log3 = logger_new(mem); logger_callback_log(log3, print_debug_logger, nullptr, &index[2]); - Mono_Time *mono_time3 = mono_time_new(mem, nullptr, nullptr); + Mono_Time *mono_time3 = mono_time_new(mem, nullptr); 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."); random_nonce(rng, nonce); - ret = send_data_request(log3, onion3->net, rng, &path, &nodes[3].ip_port, + ret = send_data_request(log3, onion3->net, rng, mem, &path, &nodes[3].ip_port, dht_get_self_public_key(onion1->dht), dht_get_self_public_key(onion1->dht), nonce, (const uint8_t *)"Install gentoo", sizeof("Install gentoo")); @@ -421,7 +424,7 @@ static Onions *new_onions(const Memory *mem, const Random *rng, uint16_t port, u logger_callback_log(on->log, print_debug_logger, nullptr, index); - on->mono_time = mono_time_new(mem, nullptr, nullptr); + on->mono_time = mono_time_new(mem, nullptr); if (!on->mono_time) { logger_kill(on->log); diff --git a/auto_tests/proxy_test.c b/auto_tests/proxy_test.c index d20c14f237..0e30009f67 100644 --- a/auto_tests/proxy_test.c +++ b/auto_tests/proxy_test.c @@ -1,6 +1,7 @@ /* Tests that we can send messages to friends. */ +#include #include #include #include diff --git a/auto_tests/reconnect_test.c b/auto_tests/reconnect_test.c index 8a4b31c495..ffb99799f9 100644 --- a/auto_tests/reconnect_test.c +++ b/auto_tests/reconnect_test.c @@ -11,6 +11,7 @@ #include "../testing/misc_tools.h" #include "../toxcore/friend_connection.h" +#include "../toxcore/os_random.h" #include "../toxcore/tox.h" #include "../toxcore/util.h" #include "check_compat.h" diff --git a/auto_tests/save_friend_test.c b/auto_tests/save_friend_test.c index 339690f2b8..5b82c63470 100644 --- a/auto_tests/save_friend_test.c +++ b/auto_tests/save_friend_test.c @@ -8,6 +8,7 @@ #include "../testing/misc_tools.h" #include "../toxcore/ccompat.h" #include "../toxcore/crypto_core.h" +#include "../toxcore/os_random.h" #include "../toxcore/tox.h" #include "auto_test_support.h" #include "check_compat.h" diff --git a/auto_tests/save_load_test.c b/auto_tests/save_load_test.c index f4158856de..cad6caafde 100644 --- a/auto_tests/save_load_test.c +++ b/auto_tests/save_load_test.c @@ -8,8 +8,10 @@ #include "../testing/misc_tools.h" #include "../toxcore/ccompat.h" +#include "../toxcore/os_memory.h" #include "../toxcore/tox.h" -#include "../toxcore/tox_struct.h" +#include "../toxcore/tox_impl.h" +#include "../toxcore/tox_time_impl.h" #include "../toxcore/util.h" #include "auto_test_support.h" #include "check_compat.h" @@ -130,6 +132,10 @@ static uint64_t get_state_clock_callback(void *user_data) return clock; } +static const Tox_Time_Funcs mock_time_funcs = { + get_state_clock_callback, +}; + static void increment_clock(Time_Data *time_data, uint64_t count) { pthread_mutex_lock(&time_data->lock); @@ -137,10 +143,10 @@ static void increment_clock(Time_Data *time_data, uint64_t count) pthread_mutex_unlock(&time_data->lock); } -static void set_current_time_callback(Tox *tox, Time_Data *time_data) +static void set_current_time_callback(Tox *tox, Tox_Time *tm) { Mono_Time *mono_time = tox->mono_time; - mono_time_set_current_time_callback(mono_time, get_state_clock_callback, time_data); + mono_time_set_current_time_callback(mono_time, tm); } static void test_few_clients(void) @@ -180,9 +186,12 @@ static void test_few_clients(void) Time_Data time_data; ck_assert_msg(pthread_mutex_init(&time_data.lock, nullptr) == 0, "Failed to init time_data mutex"); time_data.clock = current_time_monotonic(tox1->mono_time); - set_current_time_callback(tox1, &time_data); - set_current_time_callback(tox2, &time_data); - set_current_time_callback(tox3, &time_data); + + const Memory *mem = os_memory(); + Tox_Time *tm = tox_time_new(&mock_time_funcs, &time_data, mem); + set_current_time_callback(tox1, tm); + set_current_time_callback(tox2, tm); + set_current_time_callback(tox3, tm); uint8_t dht_key[TOX_PUBLIC_KEY_SIZE]; tox_self_get_dht_id(tox1, dht_key); @@ -304,6 +313,8 @@ static void test_few_clients(void) tox_options_free(opts2); tox_options_free(opts3); + + tox_time_free(tm); } int main(void) diff --git a/auto_tests/tox_dispatch_test.c b/auto_tests/tox_dispatch_test.c index 6a57ed4a02..4fd1668be4 100644 --- a/auto_tests/tox_dispatch_test.c +++ b/auto_tests/tox_dispatch_test.c @@ -43,7 +43,7 @@ static void dump_events(const char *path, const Tox_Events *events) fclose(fh); } -static void print_events(const Tox_System *sys, Tox_Events *events) +static void print_events(const struct Tox_System *sys, Tox_Events *events) { const uint32_t size = tox_events_bytes_size(events); @@ -71,7 +71,7 @@ static void print_events(const Tox_System *sys, Tox_Events *events) static bool await_message(Tox **toxes, const Tox_Dispatch *dispatch) { - const Tox_System *sys = tox_get_system(toxes[0]); + const struct Tox_System *sys = tox_get_system(toxes[0]); for (uint32_t i = 0; i < 100; ++i) { // Ignore events on tox 1. @@ -112,7 +112,7 @@ static void test_tox_events(void) ck_assert_msg(toxes[i] != nullptr, "failed to create tox instances %u", i); } - const Tox_System *sys = tox_get_system(toxes[0]); + const struct Tox_System *sys = tox_get_system(toxes[0]); Tox_Err_Dispatch_New err_new; Tox_Dispatch *dispatch = tox_dispatch_new(&err_new); diff --git a/auto_tests/tox_events_test.c b/auto_tests/tox_events_test.c index 1b7cb729aa..bd7e0f24c0 100644 --- a/auto_tests/tox_events_test.c +++ b/auto_tests/tox_events_test.c @@ -7,9 +7,11 @@ #include #include "../testing/misc_tools.h" +#include "../toxcore/os_memory.h" #include "../toxcore/tox.h" #include "../toxcore/tox_events.h" -#include "../toxcore/tox_struct.h" +#include "../toxcore/tox_impl.h" +#include "../toxcore/tox_time_impl.h" #include "auto_test_support.h" #include "check_compat.h" @@ -54,6 +56,9 @@ static uint64_t get_state_clock_callback(void *user_data) const uint64_t *clock = (const uint64_t *)user_data; return *clock; } +static const Tox_Time_Funcs mock_time_funcs = { + get_state_clock_callback, +}; static void test_tox_events(void) { @@ -70,13 +75,17 @@ static void test_tox_events(void) ck_assert_msg(toxes[i] != nullptr, "failed to create tox instances %u", i); } + const Memory *mem = os_memory(); + uint64_t clock = current_time_monotonic(toxes[0]->mono_time); + Tox_Time *tm = tox_time_new(&mock_time_funcs, &clock, mem); + Mono_Time *mono_time; mono_time = toxes[0]->mono_time; - mono_time_set_current_time_callback(mono_time, get_state_clock_callback, &clock); + mono_time_set_current_time_callback(mono_time, tm); mono_time = toxes[1]->mono_time; - mono_time_set_current_time_callback(mono_time, get_state_clock_callback, &clock); + mono_time_set_current_time_callback(mono_time, tm); uint8_t pk[TOX_PUBLIC_KEY_SIZE]; tox_self_get_dht_id(toxes[0], pk); @@ -124,6 +133,8 @@ static void test_tox_events(void) for (uint32_t i = 0; i < 2; ++i) { tox_kill(toxes[i]); } + + tox_time_free(tm); } int main(void) diff --git a/auto_tests/tox_many_tcp_test.c b/auto_tests/tox_many_tcp_test.c index 0f88300562..fcb035ca99 100644 --- a/auto_tests/tox_many_tcp_test.c +++ b/auto_tests/tox_many_tcp_test.c @@ -8,6 +8,7 @@ #include "../testing/misc_tools.h" #include "../toxcore/crypto_core.h" +#include "../toxcore/os_random.h" #include "../toxcore/tox.h" #include "../toxcore/util.h" #include "auto_test_support.h" diff --git a/auto_tests/tox_many_test.c b/auto_tests/tox_many_test.c index 7a53191d40..56f839b33b 100644 --- a/auto_tests/tox_many_test.c +++ b/auto_tests/tox_many_test.c @@ -8,6 +8,7 @@ #include "../testing/misc_tools.h" #include "../toxcore/crypto_core.h" +#include "../toxcore/os_random.h" #include "../toxcore/tox.h" #include "../toxcore/util.h" #include "auto_test_support.h" diff --git a/auto_tests/toxav_many_test.c b/auto_tests/toxav_many_test.c index fe1a1033c6..801d9929c3 100644 --- a/auto_tests/toxav_many_test.c +++ b/auto_tests/toxav_many_test.c @@ -15,8 +15,10 @@ #include "../toxav/toxav.h" #include "../toxcore/crypto_core.h" #include "../toxcore/logger.h" +#include "../toxcore/os_memory.h" #include "../toxcore/tox.h" -#include "../toxcore/tox_struct.h" +#include "../toxcore/tox_impl.h" +#include "../toxcore/tox_time_impl.h" #include "../toxcore/util.h" #include "auto_test_support.h" #include "check_compat.h" @@ -143,6 +145,10 @@ static uint64_t get_state_clock_callback(void *user_data) return clock; } +static const Tox_Time_Funcs mock_time_funcs = { + get_state_clock_callback, +}; + static void increment_clock(Time_Data *time_data, uint64_t count) { pthread_mutex_lock(&time_data->lock); @@ -150,10 +156,10 @@ static void increment_clock(Time_Data *time_data, uint64_t count) pthread_mutex_unlock(&time_data->lock); } -static void set_current_time_callback(Tox *tox, Time_Data *time_data) +static void set_current_time_callback(Tox *tox, Tox_Time *tm) { Mono_Time *mono_time = tox->mono_time; - mono_time_set_current_time_callback(mono_time, get_state_clock_callback, time_data); + mono_time_set_current_time_callback(mono_time, tm); } static void test_av_three_calls(void) @@ -167,6 +173,10 @@ static void test_av_three_calls(void) Time_Data time_data; pthread_mutex_init(&time_data.lock, nullptr); + + const Memory *mem = os_memory(); + Tox_Time *tm = tox_time_new(&mock_time_funcs, &time_data, mem); + { Tox_Options *opts = tox_options_new(nullptr); ck_assert(opts != nullptr); @@ -177,23 +187,23 @@ static void test_av_three_calls(void) ck_assert(error == TOX_ERR_NEW_OK); time_data.clock = current_time_monotonic(bootstrap->mono_time); - set_current_time_callback(bootstrap, &time_data); + set_current_time_callback(bootstrap, tm); alice = tox_new_log(opts, &error, &index[1]); ck_assert(error == TOX_ERR_NEW_OK); - set_current_time_callback(alice, &time_data); + set_current_time_callback(alice, tm); bobs[0] = tox_new_log(opts, &error, &index[2]); ck_assert(error == TOX_ERR_NEW_OK); - set_current_time_callback(bobs[0], &time_data); + set_current_time_callback(bobs[0], tm); bobs[1] = tox_new_log(opts, &error, &index[3]); ck_assert(error == TOX_ERR_NEW_OK); - set_current_time_callback(bobs[1], &time_data); + set_current_time_callback(bobs[1], tm); bobs[2] = tox_new_log(opts, &error, &index[4]); ck_assert(error == TOX_ERR_NEW_OK); - set_current_time_callback(bobs[2], &time_data); + set_current_time_callback(bobs[2], tm); tox_options_free(opts); } @@ -369,6 +379,8 @@ static void test_av_three_calls(void) tox_kill(alice); tox_kill(bootstrap); + tox_time_free(tm); + pthread_mutex_destroy(&time_data.lock); printf("\nTest successful!\n"); diff --git a/cmake/ModulePackage.cmake b/cmake/ModulePackage.cmake index c20a80a1f7..35ca8b9127 100644 --- a/cmake/ModulePackage.cmake +++ b/cmake/ModulePackage.cmake @@ -20,6 +20,7 @@ if(FULLY_STATIC) endif() function(install_module lib) + cmake_parse_arguments(INSTALL_MODULE "" "DESTINATION" "" ${ARGN}) if(TARGET ${lib}_shared) set_target_properties(${lib}_shared PROPERTIES VERSION ${SOVERSION} @@ -59,7 +60,10 @@ function(install_module lib) foreach(sublib ${${lib}_API_HEADERS}) string(REPLACE "^" ";" sublib ${sublib}) list(GET sublib 0 header) + string(REPLACE "${${lib}_SOURCE_DIR}/" "" target_header ${header}) + get_filename_component(target_path ${target_header} DIRECTORY) - install(FILES ${header} ${ARGN}) + install(FILES ${header} DESTINATION + "${INSTALL_MODULE_DESTINATION}/${target_path}") endforeach() endfunction() diff --git a/cmake/StrictAbi.cmake b/cmake/StrictAbi.cmake index ec5792199b..75af030c89 100644 --- a/cmake/StrictAbi.cmake +++ b/cmake/StrictAbi.cmake @@ -32,7 +32,7 @@ function(_make_version_script target) COMMAND ${SHELL} -c "egrep '^\\w' ${header} | grep '${ns}_[a-z0-9_]*(' | grep -v '^typedef' | grep -o '${ns}_[a-z0-9_]*(' | egrep -o '[a-z0-9_]+' | sort -u" OUTPUT_VARIABLE sublib_SYMS OUTPUT_STRIP_TRAILING_WHITESPACE) - string(REPLACE "\n" ";" sublib_SYMS ${sublib_SYMS}) + string(REPLACE "\n" ";" sublib_SYMS "${sublib_SYMS}") foreach(sym ${sublib_SYMS}) file(APPEND ${${target}_VERSION_SCRIPT} diff --git a/other/BUILD.bazel b/other/BUILD.bazel index 50693bda43..dfb240916e 100644 --- a/other/BUILD.bazel +++ b/other/BUILD.bazel @@ -26,6 +26,9 @@ cc_binary( "//c-toxcore/toxcore:mono_time", "//c-toxcore/toxcore:network", "//c-toxcore/toxcore:onion_announce", + "//c-toxcore/toxcore:os_memory", + "//c-toxcore/toxcore:os_network", + "//c-toxcore/toxcore:os_random", "//c-toxcore/toxcore:tox", ], ) diff --git a/other/DHT_bootstrap.c b/other/DHT_bootstrap.c index 3b22ad688c..e0ad15f754 100644 --- a/other/DHT_bootstrap.c +++ b/other/DHT_bootstrap.c @@ -26,6 +26,9 @@ #include "../toxcore/network.h" #include "../toxcore/onion.h" #include "../toxcore/onion_announce.h" +#include "../toxcore/os_memory.h" +#include "../toxcore/os_network.h" +#include "../toxcore/os_random.h" #include "../toxcore/tox.h" #define TCP_RELAY_ENABLED @@ -154,13 +157,13 @@ int main(int argc, char *argv[]) logger_callback_log(logger, print_log, nullptr, nullptr); } - Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); + Mono_Time *mono_time = mono_time_new(mem, nullptr); const uint16_t start_port = PORT; const uint16_t end_port = start_port + (TOX_PORTRANGE_TO - TOX_PORTRANGE_FROM); DHT *dht = new_dht(logger, mem, rng, ns, mono_time, new_networking_ex(logger, mem, ns, &ip, start_port, end_port, nullptr), true, true); Onion *onion = new_onion(logger, mem, mono_time, rng, dht); - Forwarding *forwarding = new_forwarding(logger, rng, mono_time, dht); - GC_Announces_List *gc_announces_list = new_gca_list(); + Forwarding *forwarding = new_forwarding(logger, mem, rng, mono_time, dht); + GC_Announces_List *gc_announces_list = new_gca_list(mem); Onion_Announce *onion_a = new_onion_announce(logger, mem, rng, mono_time, dht); #ifdef DHT_NODE_EXTRA_PACKETS @@ -242,7 +245,7 @@ int main(int argc, char *argv[]) bool is_waiting_for_dht_connection = true; uint64_t last_lan_discovery = 0; - const Broadcast_Info *broadcast = lan_discovery_init(ns); + const Broadcast_Info *broadcast = lan_discovery_init(mem, ns); while (true) { mono_time_update(mono_time); diff --git a/other/analysis/run-clang-tidy b/other/analysis/run-clang-tidy index bcdb78f5b8..e6e78bcc58 100755 --- a/other/analysis/run-clang-tidy +++ b/other/analysis/run-clang-tidy @@ -79,6 +79,15 @@ CHECKS="$CHECKS,-clang-diagnostic-tautological-pointer-compare" # [unreadVariable] CHECKS="$CHECKS,-cppcoreguidelines-init-variables" +# False positive on initialising one global using a pointer to another. +# E.g.: +# int a; +# int *p = &a; +# The warning says: +# initializing non-local variable with non-const expression depending on +# uninitialized non-local variable +CHECKS="$CHECKS,-cppcoreguidelines-interfaces-global-init" + # Short variable names are used quite a lot, and we don't consider them a # readability issue. CHECKS="$CHECKS,-readability-identifier-length" diff --git a/other/analysis/run-cppcheck b/other/analysis/run-cppcheck index 03c597d709..d9d24e91e9 100755 --- a/other/analysis/run-cppcheck +++ b/other/analysis/run-cppcheck @@ -20,6 +20,8 @@ CPPCHECK+=("--suppress=knownConditionTrueFalse") CPPCHECK+=("--suppress=missingIncludeSystem") # TODO(iphydf): Maybe fix? CPPCHECK+=("--suppress=signConversion") +# We have suppressions in the code for the misra extension. +CPPCHECK+=("--suppress=unmatchedSuppression") # We use this for VLAs. CPPCHECK_CXX+=("--suppress=allocaCalled") diff --git a/other/bootstrap_daemon/BUILD.bazel b/other/bootstrap_daemon/BUILD.bazel index 6d4b157b17..35b901fb41 100644 --- a/other/bootstrap_daemon/BUILD.bazel +++ b/other/bootstrap_daemon/BUILD.bazel @@ -12,11 +12,15 @@ cc_binary( "//c-toxcore/toxcore:LAN_discovery", "//c-toxcore/toxcore:TCP_server", "//c-toxcore/toxcore:announce", + "//c-toxcore/toxcore:attributes", "//c-toxcore/toxcore:ccompat", "//c-toxcore/toxcore:group_onion_announce", "//c-toxcore/toxcore:logger", "//c-toxcore/toxcore:mono_time", "//c-toxcore/toxcore:onion_announce", + "//c-toxcore/toxcore:os_memory", + "//c-toxcore/toxcore:os_network", + "//c-toxcore/toxcore:os_random", "//c-toxcore/toxcore:tox", "@libconfig", ], diff --git a/other/bootstrap_daemon/docker/Dockerfile b/other/bootstrap_daemon/docker/Dockerfile index 3d150e02f6..b18f3346ad 100644 --- a/other/bootstrap_daemon/docker/Dockerfile +++ b/other/bootstrap_daemon/docker/Dockerfile @@ -27,7 +27,9 @@ COPY other/DHT_bootstrap.c other/ COPY other/pkgconfig other/pkgconfig COPY other/rpm other/rpm COPY testing/misc_tools.[ch] testing/ +COPY tox.h ./ COPY toxcore toxcore +COPY toxencryptsave.h ./ COPY toxencryptsave toxencryptsave COPY third_party third_party COPY CMakeLists.txt so.version ./ diff --git a/other/bootstrap_daemon/src/log_backend_stdout.h b/other/bootstrap_daemon/src/log_backend_stdout.h index 131d48da05..48bac9c0b1 100644 --- a/other/bootstrap_daemon/src/log_backend_stdout.h +++ b/other/bootstrap_daemon/src/log_backend_stdout.h @@ -12,7 +12,7 @@ #include -#include "../../../toxcore/attributes.h" +#include "../../../toxcore/tox_attributes.h" #include "log.h" void log_backend_stdout_write(LOG_LEVEL level, const char *format, va_list args) GNU_PRINTF(2, 0); diff --git a/other/bootstrap_daemon/src/log_backend_syslog.h b/other/bootstrap_daemon/src/log_backend_syslog.h index 8e919f03af..dc9b31ce19 100644 --- a/other/bootstrap_daemon/src/log_backend_syslog.h +++ b/other/bootstrap_daemon/src/log_backend_syslog.h @@ -12,7 +12,7 @@ #include -#include "../../../toxcore/attributes.h" +#include "../../../toxcore/tox_attributes.h" #include "log.h" void log_backend_syslog_open(void); diff --git a/other/bootstrap_daemon/src/tox-bootstrapd.c b/other/bootstrap_daemon/src/tox-bootstrapd.c index e29afe5c2b..b441c5613f 100644 --- a/other/bootstrap_daemon/src/tox-bootstrapd.c +++ b/other/bootstrap_daemon/src/tox-bootstrapd.c @@ -41,6 +41,9 @@ #include "../../../toxcore/network.h" #include "../../../toxcore/onion.h" #include "../../../toxcore/onion_announce.h" +#include "../../../toxcore/os_memory.h" +#include "../../../toxcore/os_network.h" +#include "../../../toxcore/os_random.h" // misc #include "../../bootstrap_node_packets.h" @@ -321,7 +324,7 @@ int main(int argc, char *argv[]) } } - Mono_Time *const mono_time = mono_time_new(mem, nullptr, nullptr); + Mono_Time *const mono_time = mono_time_new(mem, nullptr); if (mono_time == nullptr) { log_write(LOG_LEVEL_ERROR, "Couldn't initialize monotonic timer. Exiting.\n"); @@ -348,7 +351,7 @@ int main(int argc, char *argv[]) return 1; } - Forwarding *forwarding = new_forwarding(logger, rng, mono_time, dht); + Forwarding *forwarding = new_forwarding(logger, mem, rng, mono_time, dht); if (forwarding == nullptr) { log_write(LOG_LEVEL_ERROR, "Couldn't initialize forwarding. Exiting.\n"); @@ -377,7 +380,7 @@ int main(int argc, char *argv[]) return 1; } - GC_Announces_List *group_announce = new_gca_list(); + GC_Announces_List *group_announce = new_gca_list(mem); if (group_announce == nullptr) { log_write(LOG_LEVEL_ERROR, "Couldn't initialize group announces. Exiting.\n"); @@ -563,7 +566,7 @@ int main(int argc, char *argv[]) Broadcast_Info *broadcast = nullptr; if (enable_lan_discovery) { - broadcast = lan_discovery_init(ns); + broadcast = lan_discovery_init(mem, ns); log_write(LOG_LEVEL_INFO, "Initialized LAN discovery successfully.\n"); } diff --git a/other/docker/modules/check b/other/docker/modules/check index 0249efe486..51fee024d1 100755 --- a/other/docker/modules/check +++ b/other/docker/modules/check @@ -83,9 +83,9 @@ class Context: pass def bzl_exports_files( - self, - srcs: list[str], - visibility: Optional[list[str]] = None, + self, + srcs: list[str], + visibility: Optional[list[str]] = None, ) -> None: pass @@ -191,6 +191,7 @@ def main() -> None: for src in sorted( set(srcs) - set([ # TODO(iphydf): Figure out what's wrong here. + "toxcore/bin_pack_test.cc", "toxcore/crypto_core_test.cc", "toxcore/group_announce_test.cc", "toxcore/group_moderation_test.cc", diff --git a/other/event_tooling/generate_event_c.cpp b/other/event_tooling/generate_event_c.cpp index 9ac3d4856f..660b9f366d 100644 --- a/other/event_tooling/generate_event_c.cpp +++ b/other/event_tooling/generate_event_c.cpp @@ -843,4 +843,3 @@ int main(int argc, char** argv) { return 0; } - diff --git a/testing/BUILD.bazel b/testing/BUILD.bazel index 4427347f16..6eac427732 100644 --- a/testing/BUILD.bazel +++ b/testing/BUILD.bazel @@ -88,5 +88,8 @@ cc_binary( "//c-toxcore/toxcore:Messenger", "//c-toxcore/toxcore:ccompat", "//c-toxcore/toxcore:mono_time", + "//c-toxcore/toxcore:os_memory", + "//c-toxcore/toxcore:os_network", + "//c-toxcore/toxcore:os_random", ], ) diff --git a/testing/Messenger_test.c b/testing/Messenger_test.c index 65ea8a9d2e..2912d3f539 100644 --- a/testing/Messenger_test.c +++ b/testing/Messenger_test.c @@ -35,6 +35,9 @@ #include "../toxcore/Messenger.h" #include "../toxcore/ccompat.h" #include "../toxcore/mono_time.h" +#include "../toxcore/os_memory.h" +#include "../toxcore/os_network.h" +#include "../toxcore/os_random.h" #include "misc_tools.h" static void print_message(Messenger *m, uint32_t friendnumber, unsigned int type, const uint8_t *string, size_t length, @@ -93,7 +96,7 @@ int main(int argc, char *argv[]) } const Memory *mem = os_memory(); - Mono_Time *const mono_time = mono_time_new(mem, nullptr, nullptr); + Mono_Time *const mono_time = mono_time_new(mem, nullptr); if (mono_time == nullptr) { fputs("Failed to allocate monotonic timer datastructure\n", stderr); diff --git a/testing/fuzzing/BUILD.bazel b/testing/fuzzing/BUILD.bazel index ce23b792ad..3f11d7eaa4 100644 --- a/testing/fuzzing/BUILD.bazel +++ b/testing/fuzzing/BUILD.bazel @@ -12,7 +12,13 @@ cc_library( deps = [ "//c-toxcore/toxcore:crypto_core", "//c-toxcore/toxcore:network", + "//c-toxcore/toxcore:os_network", "//c-toxcore/toxcore:tox", + "//c-toxcore/toxcore:tox_memory", + "//c-toxcore/toxcore:tox_network", + "//c-toxcore/toxcore:tox_random", + "//c-toxcore/toxcore:tox_system", + "//c-toxcore/toxcore:tox_time", ], ) diff --git a/testing/fuzzing/bootstrap_fuzz_test.cc b/testing/fuzzing/bootstrap_fuzz_test.cc index 4a784f846a..f25e24319d 100644 --- a/testing/fuzzing/bootstrap_fuzz_test.cc +++ b/testing/fuzzing/bootstrap_fuzz_test.cc @@ -104,6 +104,7 @@ void TestBootstrap(Fuzz_Data &input) Ptr opts(tox_options_new(nullptr), tox_options_free); assert(opts != nullptr); + tox_options_set_operating_system(opts.get(), sys.sys.get()); tox_options_set_log_callback(opts.get(), [](Tox *tox, Tox_Log_Level level, const char *file, uint32_t line, const char *func, @@ -133,12 +134,8 @@ void TestBootstrap(Fuzz_Data &input) tox_options_set_tcp_port(opts.get(), 33445); } - Tox_Options_Testing tox_options_testing; - tox_options_testing.operating_system = sys.sys.get(); - Tox_Err_New error_new; - Tox_Err_New_Testing error_new_testing; - Tox *tox = tox_new_testing(opts.get(), &error_new, &tox_options_testing, &error_new_testing); + Tox *tox = tox_new(opts.get(), &error_new); if (tox == nullptr) { // It might fail, because some I/O happens in tox_new, and the fuzzer @@ -147,7 +144,6 @@ void TestBootstrap(Fuzz_Data &input) } assert(error_new == TOX_ERR_NEW_OK); - assert(error_new_testing == TOX_ERR_NEW_TESTING_OK); uint8_t pub_key[TOX_PUBLIC_KEY_SIZE] = {0}; diff --git a/testing/fuzzing/e2e_fuzz_test.cc b/testing/fuzzing/e2e_fuzz_test.cc index df4e03c698..e81139e1ba 100644 --- a/testing/fuzzing/e2e_fuzz_test.cc +++ b/testing/fuzzing/e2e_fuzz_test.cc @@ -138,6 +138,7 @@ void TestEndToEnd(Fuzz_Data &input) Ptr opts(tox_options_new(nullptr), tox_options_free); assert(opts != nullptr); + tox_options_set_operating_system(opts.get(), sys.sys.get()); tox_options_set_local_discovery_enabled(opts.get(), false); tox_options_set_log_callback(opts.get(), @@ -150,21 +151,11 @@ void TestEndToEnd(Fuzz_Data &input) } }); - Tox_Options_Testing tox_options_testing; - tox_options_testing.operating_system = sys.sys.get(); - Tox_Err_New error_new; - Tox_Err_New_Testing error_new_testing; - Tox *tox = tox_new_testing(opts.get(), &error_new, &tox_options_testing, &error_new_testing); - - if (tox == nullptr) { - // It might fail, because some I/O happens in tox_new, and the fuzzer - // might do things that make that I/O fail. - return; - } + Tox *tox = tox_new(opts.get(), &error_new); + // tox_new never fails, because we execute a recorded successful trace. assert(error_new == TOX_ERR_NEW_OK); - assert(error_new_testing == TOX_ERR_NEW_TESTING_OK); tox_events_init(tox); diff --git a/testing/fuzzing/fuzz_support.cc b/testing/fuzzing/fuzz_support.cc index 5cbdb7d515..92436c6e93 100644 --- a/testing/fuzzing/fuzz_support.cc +++ b/testing/fuzzing/fuzz_support.cc @@ -17,7 +17,12 @@ #include "../../toxcore/crypto_core.h" #include "../../toxcore/network.h" -#include "../../toxcore/tox_private.h" +#include "../../toxcore/os_network_impl.h" +#include "../../toxcore/tox_memory_impl.h" +#include "../../toxcore/tox_network_impl.h" +#include "../../toxcore/tox_random_impl.h" +#include "../../toxcore/tox_system_impl.h" +#include "../../toxcore/tox_time_impl.h" #include "func_conversion.hh" // TODO(iphydf): Put this somewhere shared. @@ -26,12 +31,14 @@ struct Network_Addr { size_t size; }; -System::System(std::unique_ptr in_sys, std::unique_ptr in_mem, - std::unique_ptr in_ns, std::unique_ptr in_rng) +System::System(std::unique_ptr in_sys, std::unique_ptr in_mem, + std::unique_ptr in_ns, std::unique_ptr in_rng, + std::unique_ptr in_tm) : sys(std::move(in_sys)) , mem(std::move(in_mem)) , ns(std::move(in_ns)) , rng(std::move(in_rng)) + , tm(std::move(in_tm)) { } System::System(System &&) = default; @@ -87,16 +94,11 @@ static void *alloc_common(const char *func, std::size_t size, Fuzz_Data &data, A return report_alloc("tox1", func, size, Func(args...)); } -static constexpr Memory_Funcs fuzz_memory_funcs = { +static constexpr Tox_Memory_Funcs fuzz_memory_funcs = { /* .malloc = */ ![](Fuzz_System *self, uint32_t size) { return alloc_common("malloc", size, self->data, size); }, - /* .calloc = */ - ![](Fuzz_System *self, uint32_t nmemb, uint32_t size) { - return alloc_common( - "calloc", nmemb * size, self->data, nmemb, size); - }, /* .realloc = */ ![](Fuzz_System *self, void *ptr, uint32_t size) { return alloc_common( @@ -106,7 +108,7 @@ static constexpr Memory_Funcs fuzz_memory_funcs = { ![](Fuzz_System *self, void *ptr) { std::free(ptr); }, }; -static constexpr Network_Funcs fuzz_network_funcs = { +static constexpr Tox_Network_Funcs fuzz_network_funcs = { /* .close = */ ![](Fuzz_System *self, Socket sock) { return 0; }, /* .accept = */ ![](Fuzz_System *self, Socket sock) { return Socket{1337}; }, /* .bind = */ ![](Fuzz_System *self, Socket sock, const Network_Addr *addr) { return 0; }, @@ -127,16 +129,14 @@ static constexpr Network_Funcs fuzz_network_funcs = { /* .recvfrom = */ ![](Fuzz_System *self, Socket sock, uint8_t *buf, size_t len, Network_Addr *addr) { assert(sock.value == 42 || sock.value == 1337); - - addr->addr = sockaddr_storage{}; - // Dummy Addr - addr->addr.ss_family = AF_INET; + assert(addr != nullptr); // We want an AF_INET address with dummy values - sockaddr_in *addr_in = reinterpret_cast(&addr->addr); - addr_in->sin_port = htons(33446); - addr_in->sin_addr.s_addr = htonl(0x7f000002); // 127.0.0.2 - addr->size = sizeof(struct sockaddr); + sockaddr_in addr_in{}; + addr_in.sin_port = htons(33446); + addr_in.sin_addr.s_addr = htonl(0x7f000002); // 127.0.0.2 + + net_addr_set(addr, &addr_in, sizeof(addr_in)); return recv_common(self->data, buf, len); }, @@ -165,7 +165,7 @@ static constexpr Network_Funcs fuzz_network_funcs = { }, }; -static constexpr Random_Funcs fuzz_random_funcs = { +static constexpr Tox_Random_Funcs fuzz_random_funcs = { /* .random_bytes = */ ![](Fuzz_System *self, uint8_t *bytes, size_t length) { // Amount of data is limited @@ -186,7 +186,7 @@ static constexpr Random_Funcs fuzz_random_funcs = { ![](Fuzz_System *self, uint32_t upper_bound) { uint32_t randnum = 0; if (upper_bound > 0) { - self->rng->funcs->random_bytes( + self->rng->funcs->bytes_callback( self, reinterpret_cast(&randnum), sizeof(randnum)); randnum %= upper_bound; } @@ -194,34 +194,37 @@ static constexpr Random_Funcs fuzz_random_funcs = { }, }; +static constexpr Tox_Time_Funcs fuzz_time_funcs = { + /* .monotonic = */ + ![](Fuzz_System *self) { return self->clock; }, +}; + Fuzz_System::Fuzz_System(Fuzz_Data &input) : System{ std::make_unique(), std::make_unique(Memory{&fuzz_memory_funcs, this}), std::make_unique(Network{&fuzz_network_funcs, this}), std::make_unique(Random{&fuzz_random_funcs, this}), + std::make_unique(Tox_Time{&fuzz_time_funcs, this}), } , data(input) { - sys->mono_time_callback = [](void *self) { return static_cast(self)->clock; }; - sys->mono_time_user_data = this; sys->mem = mem.get(); sys->ns = ns.get(); sys->rng = rng.get(); + sys->tm = tm.get(); } -static constexpr Memory_Funcs null_memory_funcs = { +static constexpr Tox_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 Tox_Network_Funcs null_network_funcs = { /* .close = */ ![](Null_System *self, Socket sock) { return 0; }, /* .accept = */ ![](Null_System *self, Socket sock) { return Socket{1337}; }, /* .bind = */ ![](Null_System *self, Socket sock, const Network_Addr *addr) { return 0; }, @@ -270,7 +273,7 @@ static uint64_t simple_rng(uint64_t &seed) return seed; } -static constexpr Random_Funcs null_random_funcs = { +static constexpr Tox_Random_Funcs null_random_funcs = { /* .random_bytes = */ ![](Null_System *self, uint8_t *bytes, size_t length) { for (size_t i = 0; i < length; ++i) { @@ -286,39 +289,24 @@ static constexpr Random_Funcs null_random_funcs = { Null_System::Null_System() : System{ std::make_unique(), - std::make_unique(Memory{&null_memory_funcs, this}), - std::make_unique(Network{&null_network_funcs, this}), - std::make_unique(Random{&null_random_funcs, this}), + std::make_unique(Tox_Memory{&null_memory_funcs, this}), + std::make_unique(Tox_Network{&null_network_funcs, this}), + std::make_unique(Tox_Random{&null_random_funcs, this}), + std::make_unique(Tox_Time{&fuzz_time_funcs, this}), } { - sys->mono_time_callback = [](void *self) { return static_cast(self)->clock; }; - sys->mono_time_user_data = this; sys->mem = mem.get(); sys->ns = ns.get(); sys->rng = rng.get(); + sys->tm = tm.get(); } -static uint16_t get_port(const Network_Addr *addr) -{ - if (addr->addr.ss_family == AF_INET6) { - return reinterpret_cast(&addr->addr)->sin6_port; - } else { - assert(addr->addr.ss_family == AF_INET); - return reinterpret_cast(&addr->addr)->sin_port; - } -} - -static constexpr Memory_Funcs record_memory_funcs = { +static constexpr Tox_Memory_Funcs record_memory_funcs = { /* .malloc = */ ![](Record_System *self, uint32_t size) { self->push(true); return report_alloc(self->name_, "malloc", size, std::malloc(size)); }, - /* .calloc = */ - ![](Record_System *self, uint32_t nmemb, uint32_t size) { - self->push(true); - return report_alloc(self->name_, "calloc", nmemb * size, std::calloc(nmemb, size)); - }, /* .realloc = */ ![](Record_System *self, void *ptr, uint32_t size) { self->push(true); @@ -328,12 +316,13 @@ static constexpr Memory_Funcs record_memory_funcs = { ![](Record_System *self, void *ptr) { std::free(ptr); }, }; -static constexpr Network_Funcs record_network_funcs = { +static constexpr Tox_Network_Funcs record_network_funcs = { /* .close = */ ![](Record_System *self, Socket sock) { return 0; }, /* .accept = */ ![](Record_System *self, Socket sock) { return Socket{2}; }, /* .bind = */ ![](Record_System *self, Socket sock, const Network_Addr *addr) { - const uint16_t port = get_port(addr); + assert(addr != nullptr); + const uint16_t port = net_addr_get_port(addr); if (self->global_.bound.find(port) != self->global_.bound.end()) { errno = EADDRINUSE; return -1; @@ -354,6 +343,7 @@ static constexpr Network_Funcs record_network_funcs = { /* .recvfrom = */ ![](Record_System *self, Socket sock, uint8_t *buf, size_t len, Network_Addr *addr) { assert(sock.value == 42); + assert(addr != nullptr); if (self->recvq.empty()) { self->push("\xff\xff"); errno = EWOULDBLOCK; @@ -367,15 +357,13 @@ static constexpr Network_Funcs record_network_funcs = { const size_t recvlen = std::min(len, packet.size()); std::copy(packet.begin(), packet.end(), buf); - addr->addr = sockaddr_storage{}; - // Dummy Addr - addr->addr.ss_family = AF_INET; - // We want an AF_INET address with dummy values - sockaddr_in *addr_in = reinterpret_cast(&addr->addr); - addr_in->sin_port = from; - addr_in->sin_addr.s_addr = htonl(0x7f000002); // 127.0.0.2 - addr->size = sizeof(struct sockaddr); + sockaddr_in addr_in{}; + addr_in.sin_family = AF_INET; + addr_in.sin_port = from; + addr_in.sin_addr.s_addr = htonl(0x7f000002); // 127.0.0.2 + + net_addr_set(addr, &addr_in, sizeof(addr_in)); assert(recvlen > 0 && recvlen <= INT_MAX); self->push(uint8_t(recvlen >> 8)); @@ -396,7 +384,8 @@ static constexpr Network_Funcs record_network_funcs = { ![](Record_System *self, Socket sock, const uint8_t *buf, size_t len, const Network_Addr *addr) { assert(sock.value == 42); - auto backend = self->global_.bound.find(get_port(addr)); + assert(addr != nullptr); + auto backend = self->global_.bound.find(net_addr_get_port(addr)); assert(backend != self->global_.bound.end()); backend->second->receive(self->port, buf, len); return static_cast(len); @@ -414,7 +403,7 @@ static constexpr Network_Funcs record_network_funcs = { size_t optlen) { return 0; }, }; -static constexpr Random_Funcs record_random_funcs = { +static constexpr Tox_Random_Funcs record_random_funcs = { /* .random_bytes = */ ![](Record_System *self, uint8_t *bytes, size_t length) { for (size_t i = 0; i < length; ++i) { @@ -427,7 +416,7 @@ static constexpr Random_Funcs record_random_funcs = { } }, /* .random_uniform = */ - fuzz_random_funcs.random_uniform, + fuzz_random_funcs.uniform_callback, }; Record_System::Record_System(Global &global, uint64_t seed, const char *name) @@ -436,16 +425,16 @@ Record_System::Record_System(Global &global, uint64_t seed, const char *name) std::make_unique(Memory{&record_memory_funcs, this}), std::make_unique(Network{&record_network_funcs, this}), std::make_unique(Random{&record_random_funcs, this}), + std::make_unique(Tox_Time{&fuzz_time_funcs, this}), } , global_(global) , seed_(seed) , name_(name) { - sys->mono_time_callback = [](void *self) { return static_cast(self)->clock; }; - sys->mono_time_user_data = this; sys->mem = mem.get(); sys->ns = ns.get(); sys->rng = rng.get(); + sys->tm = tm.get(); } void Record_System::receive(uint16_t send_port, const uint8_t *buf, size_t len) diff --git a/testing/fuzzing/fuzz_support.hh b/testing/fuzzing/fuzz_support.hh index 6a370f3dfd..f2505cb81d 100644 --- a/testing/fuzzing/fuzz_support.hh +++ b/testing/fuzzing/fuzz_support.hh @@ -16,7 +16,11 @@ #include #include "../../toxcore/tox.h" -#include "../../toxcore/tox_private.h" +#include "../../toxcore/tox_memory.h" +#include "../../toxcore/tox_network.h" +#include "../../toxcore/tox_random.h" +#include "../../toxcore/tox_system.h" +#include "../../toxcore/tox_time.h" struct Fuzz_Data { static constexpr bool DEBUG = false; @@ -187,9 +191,10 @@ void fuzz_select_target(const uint8_t *data, std::size_t size) return Fuzz_Target_Selector::select(selector, input); } -struct Memory; -struct Network; -struct Random; +struct Tox_Memory; +struct Tox_Network; +struct Tox_Random; +struct Tox_Time; struct System { /** @brief Deterministic system clock for this instance. @@ -205,12 +210,14 @@ struct System { uint64_t clock = 1000000000; std::unique_ptr sys; - std::unique_ptr mem; - std::unique_ptr ns; - std::unique_ptr rng; - - System(std::unique_ptr sys, std::unique_ptr mem, - std::unique_ptr ns, std::unique_ptr rng); + std::unique_ptr mem; + std::unique_ptr ns; + std::unique_ptr rng; + std::unique_ptr tm; + + System(std::unique_ptr sys, std::unique_ptr mem, + std::unique_ptr ns, std::unique_ptr rng, + std::unique_ptr tm); System(System &&); // Not inline because sizeof of the above 2 structs is not known everywhere. diff --git a/testing/fuzzing/protodump.cc b/testing/fuzzing/protodump.cc index 28df05a02a..b770d8cd9f 100644 --- a/testing/fuzzing/protodump.cc +++ b/testing/fuzzing/protodump.cc @@ -30,8 +30,8 @@ #include "../../toxcore/tox.h" #include "../../toxcore/tox_dispatch.h" #include "../../toxcore/tox_events.h" +#include "../../toxcore/tox_impl.h" #include "../../toxcore/tox_private.h" -#include "../../toxcore/tox_struct.h" #include "../../toxcore/util.h" #include "fuzz_support.hh" @@ -195,16 +195,13 @@ void RecordBootstrap(const char *init, const char *bootstrap) }); Tox_Err_New error_new; - Tox_Err_New_Testing error_new_testing; - Tox_Options_Testing tox_options_testing; Record_System sys1(global, 4, "tox1"); // fair dice roll tox_options_set_log_user_data(opts, &sys1); - tox_options_testing.operating_system = sys1.sys.get(); - Tox *tox1 = tox_new_testing(opts, &error_new, &tox_options_testing, &error_new_testing); + tox_options_set_operating_system(opts, sys1.sys.get()); + Tox *tox1 = tox_new(opts, &error_new); assert(tox1 != nullptr); assert(error_new == TOX_ERR_NEW_OK); - assert(error_new_testing == TOX_ERR_NEW_TESTING_OK); std::array address1; tox_self_get_address(tox1, address1.data()); std::array pk1; @@ -214,11 +211,10 @@ void RecordBootstrap(const char *init, const char *bootstrap) Record_System sys2(global, 5, "tox2"); // unfair dice roll tox_options_set_log_user_data(opts, &sys2); - tox_options_testing.operating_system = sys2.sys.get(); - Tox *tox2 = tox_new_testing(opts, &error_new, &tox_options_testing, &error_new_testing); + tox_options_set_operating_system(opts, sys2.sys.get()); + Tox *tox2 = tox_new(opts, &error_new); assert(tox2 != nullptr); assert(error_new == TOX_ERR_NEW_OK); - assert(error_new_testing == TOX_ERR_NEW_TESTING_OK); std::array address2; tox_self_get_address(tox2, address2.data()); std::array pk2; diff --git a/testing/fuzzing/protodump_reduce.cc b/testing/fuzzing/protodump_reduce.cc index 820a3fc7b8..ae9676ca31 100644 --- a/testing/fuzzing/protodump_reduce.cc +++ b/testing/fuzzing/protodump_reduce.cc @@ -142,11 +142,9 @@ void TestEndToEnd(Fuzz_Data &input) Ptr opts(tox_options_new(nullptr), tox_options_free); assert(opts != nullptr); + tox_options_set_operating_system(opts.get(), sys.sys.get()); tox_options_set_local_discovery_enabled(opts.get(), false); - Tox_Options_Testing tox_options_testing; - tox_options_testing.operating_system = sys.sys.get(); - tox_options_set_log_callback(opts.get(), [](Tox *tox, Tox_Log_Level level, const char *file, uint32_t line, const char *func, const char *message, void *user_data) { @@ -158,8 +156,7 @@ void TestEndToEnd(Fuzz_Data &input) }); Tox_Err_New error_new; - Tox_Err_New_Testing error_new_testing; - Tox *tox = tox_new_testing(opts.get(), &error_new, &tox_options_testing, &error_new_testing); + Tox *tox = tox_new(opts.get(), &error_new); if (tox == nullptr) { // It might fail, because some I/O happens in tox_new, and the fuzzer @@ -168,7 +165,6 @@ void TestEndToEnd(Fuzz_Data &input) } assert(error_new == TOX_ERR_NEW_OK); - assert(error_new_testing == TOX_ERR_NEW_TESTING_OK); tox_events_init(tox); diff --git a/testing/fuzzing/toxsave_fuzz_test.cc b/testing/fuzzing/toxsave_fuzz_test.cc index f48c2bf013..2cb134cbc1 100644 --- a/testing/fuzzing/toxsave_fuzz_test.cc +++ b/testing/fuzzing/toxsave_fuzz_test.cc @@ -20,15 +20,14 @@ void TestSaveDataLoading(Fuzz_Data &input) const size_t savedata_size = input.size(); CONSUME_OR_RETURN(const uint8_t *savedata, input, savedata_size); + Null_System sys; + tox_options_set_operating_system(tox_options, sys.sys.get()); + // pass test data to Tox tox_options_set_savedata_data(tox_options, savedata, savedata_size); tox_options_set_savedata_type(tox_options, TOX_SAVEDATA_TYPE_TOX_SAVE); - Tox_Options_Testing tox_options_testing; - Null_System sys; - tox_options_testing.operating_system = sys.sys.get(); - - Tox *tox = tox_new_testing(tox_options, nullptr, &tox_options_testing, nullptr); + Tox *tox = tox_new(tox_options, nullptr); tox_options_free(tox_options); if (tox == nullptr) { // Tox save was invalid, we're finished here diff --git a/tox.h b/tox.h new file mode 100644 index 0000000000..4209883cf6 --- /dev/null +++ b/tox.h @@ -0,0 +1,5 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2022-2023 The TokTok team. + */ + +#include "toxcore/tox.h" diff --git a/toxav.h b/toxav.h new file mode 100644 index 0000000000..83e5daa8e6 --- /dev/null +++ b/toxav.h @@ -0,0 +1,5 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2022-2023 The TokTok team. + */ + +#include "toxav/toxav.h" diff --git a/toxav/Makefile.inc b/toxav/Makefile.inc index 6d34135f3c..47dfba5d08 100644 --- a/toxav/Makefile.inc +++ b/toxav/Makefile.inc @@ -1,8 +1,9 @@ if BUILD_AV lib_LTLIBRARIES += libtoxav.la - libtoxav_la_include_HEADERS = ../toxav/toxav.h - libtoxav_la_includedir = $(includedir)/tox + +libtoxav_la_include_HEADERS = ../toxav/toxav.h +libtoxav_la_includedir = $(includedir)/tox/toxav libtoxav_la_SOURCES = ../toxav/rtp.h \ ../toxav/rtp.c \ diff --git a/toxav/audio.c b/toxav/audio.c index ab11cc0d6b..188782c183 100644 --- a/toxav/audio.c +++ b/toxav/audio.c @@ -195,7 +195,7 @@ void ac_iterate(ACSession *ac) free(temp_audio_buffer); } -int ac_queue_message(Mono_Time *mono_time, void *cs, struct RTPMessage *msg) +int ac_queue_message(const Mono_Time *mono_time, void *cs, struct RTPMessage *msg) { ACSession *ac = (ACSession *)cs; diff --git a/toxav/audio.h b/toxav/audio.h index 3ae4251137..83ef6d58f1 100644 --- a/toxav/audio.h +++ b/toxav/audio.h @@ -67,7 +67,7 @@ ACSession *ac_new(Mono_Time *mono_time, const Logger *log, ToxAV *av, uint32_t f toxav_audio_receive_frame_cb *cb, void *cb_data); void ac_kill(ACSession *ac); void ac_iterate(ACSession *ac); -int ac_queue_message(Mono_Time *mono_time, void *cs, struct RTPMessage *msg); +int ac_queue_message(const Mono_Time *mono_time, void *cs, struct RTPMessage *msg); int ac_reconfigure_encoder(ACSession *ac, uint32_t bit_rate, uint32_t sampling_rate, uint8_t channels); #endif /* C_TOXCORE_TOXAV_AUDIO_H */ diff --git a/toxav/groupav.c b/toxav/groupav.c index 14ca9bb293..16b4ef8203 100644 --- a/toxav/groupav.c +++ b/toxav/groupav.c @@ -10,7 +10,7 @@ #include "../toxcore/ccompat.h" #include "../toxcore/logger.h" #include "../toxcore/mono_time.h" -#include "../toxcore/tox_struct.h" +#include "../toxcore/tox_impl.h" #include "../toxcore/util.h" #define GROUP_JBUF_SIZE 6 diff --git a/toxav/rtp.h b/toxav/rtp.h index 1e2e2e8f0d..8ebd432422 100644 --- a/toxav/rtp.h +++ b/toxav/rtp.h @@ -147,7 +147,7 @@ struct RTPWorkBufferList { #define DISMISS_FIRST_LOST_VIDEO_PACKET_COUNT 10 -typedef int rtp_m_cb(Mono_Time *mono_time, void *cs, struct RTPMessage *msg); +typedef int rtp_m_cb(const Mono_Time *mono_time, void *cs, struct RTPMessage *msg); /** * RTP control session. diff --git a/toxav/rtp_test.cc b/toxav/rtp_test.cc index 674bc4b46c..24e5244804 100644 --- a/toxav/rtp_test.cc +++ b/toxav/rtp_test.cc @@ -3,6 +3,7 @@ #include #include "../toxcore/crypto_core.h" +#include "../toxcore/os_random.h" namespace { diff --git a/toxav/toxav.c b/toxav/toxav.c index dcb4597d66..f149a1d512 100644 --- a/toxav/toxav.c +++ b/toxav/toxav.c @@ -17,11 +17,12 @@ #include "../toxcore/ccompat.h" #include "../toxcore/logger.h" #include "../toxcore/mono_time.h" +#include "../toxcore/tox_impl.h" #include "../toxcore/net_crypto.h" #include "../toxcore/network.h" #include "../toxcore/tox.h" +#include "../toxcore/tox_impl.h" #include "../toxcore/tox_private.h" -#include "../toxcore/tox_struct.h" #include "../toxcore/util.h" // TODO(zoff99): don't hardcode this, let the application choose it @@ -227,7 +228,7 @@ ToxAV *toxav_new(Tox *tox, Toxav_Err_New *error) rtp_allow_receiving(av->tox); bwc_allow_receiving(av->tox); - av->toxav_mono_time = mono_time_new(tox->sys.mem, nullptr, nullptr); + av->toxav_mono_time = mono_time_new(tox->sys.mem, nullptr); if (av->msi == nullptr) { pthread_mutex_destroy(av->mutex); diff --git a/toxav/toxav.h b/toxav/toxav.h index a9e3485b67..9a686ce59f 100644 --- a/toxav/toxav.h +++ b/toxav/toxav.h @@ -59,22 +59,13 @@ #include #include +#include "../toxcore/tox.h" + #ifdef __cplusplus extern "C" { #endif -/** - * External Tox type. - */ -#ifndef APIGEN_IGNORE -#ifndef TOX_DEFINED -#define TOX_DEFINED -typedef struct Tox Tox; -#endif /* !TOX_DEFINED */ -#endif /* !APIGEN_IGNORE */ - #ifndef TOXAV_DEFINED -#define TOXAV_DEFINED /** * @brief The ToxAV instance type. * diff --git a/toxav/toxav_old.c b/toxav/toxav_old.c index 364cb3c176..9dba0e52b1 100644 --- a/toxav/toxav_old.c +++ b/toxav/toxav_old.c @@ -8,7 +8,7 @@ */ #include "toxav.h" -#include "../toxcore/tox_struct.h" +#include "../toxcore/tox_impl.h" #include "groupav.h" int toxav_add_av_groupchat(Tox *tox, audio_data_cb *audio_callback, void *userdata) diff --git a/toxav/video.c b/toxav/video.c index 4d1d5a9415..b3ad926959 100644 --- a/toxav/video.c +++ b/toxav/video.c @@ -143,7 +143,7 @@ static void vc_init_encoder_cfg(const Logger *log, vpx_codec_enc_cfg_t *cfg, int #endif /* 0 */ } -VCSession *vc_new(const Logger *log, Mono_Time *mono_time, ToxAV *av, uint32_t friend_number, +VCSession *vc_new(const Logger *log, const Mono_Time *mono_time, ToxAV *av, uint32_t friend_number, toxav_video_receive_frame_cb *cb, void *cb_data) { VCSession *vc = (VCSession *)calloc(1, sizeof(VCSession)); @@ -346,7 +346,7 @@ void vc_iterate(VCSession *vc) } } -int vc_queue_message(Mono_Time *mono_time, void *cs, struct RTPMessage *msg) +int vc_queue_message(const Mono_Time *mono_time, void *cs, struct RTPMessage *msg) { VCSession *vc = (VCSession *)cs; diff --git a/toxav/video.h b/toxav/video.h index 7bd54fa631..ea71af0a54 100644 --- a/toxav/video.h +++ b/toxav/video.h @@ -44,11 +44,11 @@ typedef struct VCSession { const Logger *log; } VCSession; -VCSession *vc_new(const Logger *log, Mono_Time *mono_time, ToxAV *av, uint32_t friend_number, +VCSession *vc_new(const Logger *log, const Mono_Time *mono_time, ToxAV *av, uint32_t friend_number, toxav_video_receive_frame_cb *cb, void *cb_data); void vc_kill(VCSession *vc); void vc_iterate(VCSession *vc); -int vc_queue_message(Mono_Time *mono_time, void *cs, struct RTPMessage *msg); +int vc_queue_message(const Mono_Time *mono_time, void *cs, struct RTPMessage *msg); int vc_reconfigure_encoder(VCSession *vc, uint32_t bit_rate, uint16_t width, uint16_t height, int16_t kf_max_dist); #endif /* C_TOXCORE_TOXAV_VIDEO_H */ diff --git a/toxcore/BUILD.bazel b/toxcore/BUILD.bazel index 1534d7a674..7c3461d828 100644 --- a/toxcore/BUILD.bazel +++ b/toxcore/BUILD.bazel @@ -1,10 +1,33 @@ load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test") load("@rules_fuzzing//fuzzing:cc_defs.bzl", "cc_fuzz_test") -exports_files( +sh_library( + name = "public", srcs = [ + "os_log.h", + "os_memory.h", + "os_network.h", + "os_random.h", + "os_system.h", + "os_time.h", "tox.h", - "tox_private.h", + "tox_attributes.h", + "tox_dispatch.h", + "tox_events.h", + "tox_log.h", + "tox_log_level.h", + "tox_log_impl.h", + "tox_memory.h", + "tox_memory_impl.h", + "tox_network.h", + "tox_network_impl.h", + "tox_options.h", + "tox_random.h", + "tox_random_impl.h", + "tox_system.h", + "tox_system_impl.h", + "tox_time.h", + "tox_time_impl.h", ], visibility = ["//c-toxcore:__subpackages__"], ) @@ -35,6 +58,12 @@ cc_library( visibility = ["//c-toxcore:__subpackages__"], ) +cc_library( + name = "tox_attributes", + hdrs = ["tox_attributes.h"], + visibility = ["//c-toxcore:__subpackages__"], +) + cc_library( name = "ccompat", srcs = ["ccompat.c"], @@ -43,6 +72,189 @@ cc_library( deps = [":attributes"], ) +cc_library( + name = "tox_memory", + srcs = ["tox_memory.c"], + hdrs = [ + "tox_memory.h", + "tox_memory_impl.h", + ], + visibility = ["//c-toxcore:__subpackages__"], + deps = [ + ":ccompat", + ":tox_attributes", + ], +) + +cc_library( + name = "tox_log_level", + srcs = ["tox_log_level.c"], + hdrs = ["tox_log_level.h"], + visibility = ["//c-toxcore:__subpackages__"], +) + +cc_library( + name = "tox_log", + srcs = ["tox_log.c"], + hdrs = [ + "tox_log.h", + "tox_log_impl.h", + ], + visibility = ["//c-toxcore:__subpackages__"], + deps = [ + ":ccompat", + ":tox_attributes", + ":tox_log_level", + ":tox_memory", + ], +) + +cc_library( + name = "tox_network", + srcs = ["tox_network.c"], + hdrs = [ + "tox_network.h", + "tox_network_impl.h", + ], + visibility = ["//c-toxcore:__subpackages__"], + deps = [ + ":ccompat", + ":tox_attributes", + ":tox_memory", + ], +) + +cc_library( + name = "tox_random", + srcs = ["tox_random.c"], + hdrs = [ + "tox_random.h", + "tox_random_impl.h", + ], + visibility = ["//c-toxcore:__subpackages__"], + deps = [ + ":ccompat", + ":tox_attributes", + ":tox_memory", + ], +) + +cc_library( + name = "tox_time", + srcs = ["tox_time.c"], + hdrs = [ + "tox_time.h", + "tox_time_impl.h", + ], + visibility = ["//c-toxcore:__subpackages__"], + deps = [ + ":ccompat", + ":tox_attributes", + ":tox_memory", + ], +) + +cc_library( + name = "tox_system", + srcs = ["tox_system.c"], + hdrs = [ + "tox_system.h", + "tox_system_impl.h", + ], + visibility = ["//c-toxcore:__subpackages__"], + deps = [ + ":ccompat", + ":tox_attributes", + ":tox_log", + ":tox_memory", + ":tox_network", + ":tox_random", + ":tox_time", + ], +) + +cc_library( + name = "os_log", + srcs = ["os_log.c"], + hdrs = ["os_log.h"], + visibility = ["//c-toxcore:__subpackages__"], + deps = [ + ":attributes", + ":ccompat", + ":tox_log", + ], +) + +cc_library( + name = "os_memory", + srcs = ["os_memory.c"], + hdrs = ["os_memory.h"], + visibility = ["//c-toxcore:__subpackages__"], + deps = [ + ":attributes", + ":ccompat", + ":tox_memory", + ], +) + +cc_library( + name = "os_network", + srcs = ["os_network.c"], + hdrs = [ + "os_network.h", + "os_network_impl.h", + ], + visibility = ["//c-toxcore:__subpackages__"], + deps = [ + ":attributes", + ":ccompat", + ":tox_memory", + ":tox_network", + "@psocket", + ], +) + +cc_library( + name = "os_random", + srcs = ["os_random.c"], + hdrs = ["os_random.h"], + visibility = ["//c-toxcore:__subpackages__"], + deps = [ + ":attributes", + ":ccompat", + ":tox_random", + "@libsodium", + ], +) + +cc_library( + name = "os_time", + srcs = ["os_time.c"], + hdrs = ["os_time.h"], + visibility = ["//c-toxcore:__subpackages__"], + deps = [ + ":attributes", + ":ccompat", + ":tox_time", + ], +) + +cc_library( + name = "os_system", + srcs = ["os_system.c"], + hdrs = ["os_system.h"], + visibility = ["//c-toxcore:__subpackages__"], + deps = [ + ":ccompat", + ":os_log", + ":os_memory", + ":os_network", + ":os_random", + ":os_time", + ":tox_system", + ], +) + cc_library( name = "mem", srcs = ["mem.c"], @@ -51,6 +263,7 @@ cc_library( deps = [ ":attributes", ":ccompat", + ":tox_memory", ], ) @@ -61,7 +274,9 @@ cc_library( hdrs = ["mem_test_util.hh"], deps = [ ":mem", + ":os_memory", ":test_util", + ":tox_memory", ], ) @@ -71,6 +286,7 @@ cc_test( srcs = ["mem_test.cc"], deps = [ ":mem", + ":os_memory", "@com_google_googletest//:gtest", "@com_google_googletest//:gtest_main", ], @@ -108,23 +324,6 @@ cc_test( ], ) -cc_library( - name = "logger", - srcs = ["logger.c"], - hdrs = ["logger.h"], - visibility = [ - "//c-toxcore/auto_tests:__pkg__", - "//c-toxcore/other:__pkg__", - "//c-toxcore/other/bootstrap_daemon:__pkg__", - "//c-toxcore/toxav:__pkg__", - ], - deps = [ - ":attributes", - ":ccompat", - ":mem", - ], -) - cc_library( name = "bin_pack", srcs = ["bin_pack.c"], @@ -134,6 +333,7 @@ cc_library( ":attributes", ":ccompat", ":logger", + ":mem", "//c-toxcore/third_party:cmp", ], ) @@ -146,6 +346,7 @@ cc_library( deps = [ ":attributes", ":ccompat", + ":mem", "//c-toxcore/third_party:cmp", ], ) @@ -158,6 +359,7 @@ cc_test( ":bin_pack", ":bin_unpack", ":logger", + ":mem_test_util", "@com_google_googletest//:gtest", "@com_google_googletest//:gtest_main", ], @@ -171,6 +373,8 @@ cc_library( deps = [ ":attributes", ":ccompat", + ":mem", + ":tox_random", ":util", "@libsodium", ], @@ -198,6 +402,7 @@ cc_library( deps = [ ":crypto_core", ":test_util", + ":tox_random", ], ) @@ -209,6 +414,9 @@ cc_test( deps = [ ":crypto_core", ":crypto_core_test_util", + ":mem", + ":os_memory", + ":os_random", ":util", "@com_google_googletest//:gtest", "@com_google_googletest//:gtest_main", @@ -222,6 +430,7 @@ cc_library( deps = [ ":attributes", ":ccompat", + ":mem", ], ) @@ -231,11 +440,30 @@ cc_test( srcs = ["list_test.cc"], deps = [ ":list", + ":mem", + ":os_memory", "@com_google_googletest//:gtest", "@com_google_googletest//:gtest_main", ], ) +cc_library( + name = "logger", + srcs = ["logger.c"], + hdrs = ["logger.h"], + visibility = [ + "//c-toxcore/auto_tests:__pkg__", + "//c-toxcore/other:__pkg__", + "//c-toxcore/other/bootstrap_daemon:__pkg__", + "//c-toxcore/toxav:__pkg__", + ], + deps = [ + ":attributes", + ":ccompat", + ":mem", + ], +) + cc_library( name = "state", srcs = ["state.c"], @@ -262,6 +490,8 @@ cc_library( ":attributes", ":ccompat", ":mem", + ":os_time", + ":tox_time", ":util", "@pthread", ], @@ -274,6 +504,8 @@ cc_test( deps = [ ":mem_test_util", ":mono_time", + ":os_memory", + ":tox_time", "@com_google_googletest//:gtest", "@com_google_googletest//:gtest_main", ], @@ -319,6 +551,8 @@ cc_library( ":logger", ":mem", ":mono_time", + ":os_network", + ":tox_network", ":util", "@libsodium", "@psocket", @@ -334,7 +568,9 @@ cc_library( deps = [ ":crypto_core", ":network", + ":os_network", ":test_util", + ":tox_network", ], ) @@ -384,6 +620,8 @@ cc_test( ":crypto_core_test_util", ":mem_test_util", ":mono_time", + ":os_memory", + ":os_random", ":ping_array", "@com_google_googletest//:gtest", "@com_google_googletest//:gtest_main", @@ -403,7 +641,9 @@ cc_library( ":attributes", ":ccompat", ":crypto_core", + ":mem", ":network", + ":tox_network", ":util", "@psocket", ], @@ -466,10 +706,13 @@ cc_test( ":crypto_core", ":crypto_core_test_util", ":logger", + ":mem", ":mem_test_util", ":mono_time", ":network", ":network_test_util", + ":os_memory", + ":os_network", ":test_util", "@com_google_googletest//:gtest", "@com_google_googletest//:gtest_main", @@ -483,6 +726,7 @@ cc_fuzz_test( corpus = ["//tools/toktok-fuzzer/corpus:DHT_fuzz_test"], deps = [ ":DHT", + ":os_memory", "//c-toxcore/testing/fuzzing:fuzz_support", ], ) @@ -517,6 +761,7 @@ cc_library( ":ccompat", ":crypto_core", ":logger", + ":mem", ":mono_time", ":network", ":timed_auth", @@ -530,6 +775,8 @@ cc_fuzz_test( corpus = ["//tools/toktok-fuzzer/corpus:forwarding_fuzz_test"], deps = [ ":forwarding", + ":os_memory", + ":os_network", "//c-toxcore/testing/fuzzing:fuzz_support", "//c-toxcore/testing/fuzzing:fuzz_tox", ], @@ -572,6 +819,7 @@ cc_library( ":logger", ":mem", ":network", + ":tox_network", ], ) @@ -600,6 +848,7 @@ cc_library( ":mono_time", ":network", ":onion", + ":tox_network", ":util", "@psocket", ], @@ -620,6 +869,7 @@ cc_library( ":mem", ":mono_time", ":network", + ":tox_network", ":util", ], ) @@ -726,6 +976,7 @@ cc_library( ":ccompat", ":crypto_core", ":logger", + ":mem", ":mono_time", ":network", ":util", @@ -741,9 +992,12 @@ cc_test( ":crypto_core", ":group_announce", ":logger", + ":mem", ":mem_test_util", ":mono_time", ":network", + ":os_memory", + ":tox_time", "@com_google_googletest//:gtest", "@com_google_googletest//:gtest_main", ], @@ -758,6 +1012,7 @@ cc_fuzz_test( deps = [ ":group_announce", ":mem_test_util", + ":tox_time", "//c-toxcore/testing/fuzzing:fuzz_support", ], ) @@ -778,6 +1033,7 @@ cc_library( ":crypto_core", ":group_announce", ":logger", + ":mem", ":mono_time", ":network", ":onion_announce", @@ -825,6 +1081,7 @@ cc_library( ":ccompat", ":crypto_core", ":logger", + ":mem", ":mono_time", ":net_crypto", ":network", @@ -849,6 +1106,7 @@ cc_library( ":ccompat", ":crypto_core", ":friend_connection", + ":mem", ":network", ":onion", ":onion_announce", @@ -886,6 +1144,7 @@ cc_test( ":group_moderation", ":logger", ":mem_test_util", + ":os_random", ":util", "@com_google_googletest//:gtest", "@com_google_googletest//:gtest_main", @@ -972,6 +1231,7 @@ cc_library( ":crypto_core", ":friend_connection", ":logger", + ":mem", ":mono_time", ":net_crypto", ":network", @@ -985,12 +1245,14 @@ cc_library( srcs = [ "tox.c", "tox_api.c", + "tox_options.c", "tox_private.c", ], hdrs = [ "tox.h", + "tox_impl.h", + "tox_options.h", "tox_private.h", - "tox_struct.h", ], visibility = ["//c-toxcore:__subpackages__"], deps = [ @@ -1009,7 +1271,12 @@ cc_library( ":net_crypto", ":network", ":onion_client", + ":os_system", ":state", + ":tox_attributes", + ":tox_log", + ":tox_log_level", + ":tox_system", ":util", "//c-toxcore/toxencryptsave:defines", "@pthread", @@ -1022,7 +1289,9 @@ cc_test( srcs = ["tox_test.cc"], deps = [ ":crypto_core", + ":os_random", ":tox", + ":tox_log", "@com_google_googletest//:gtest", "@com_google_googletest//:gtest_main", ], @@ -1076,7 +1345,9 @@ cc_library( ":logger", ":mem", ":tox", + ":tox_attributes", ":tox_pack", + ":tox_system", ":tox_unpack", "//c-toxcore/third_party:cmp", ], @@ -1088,8 +1359,10 @@ cc_test( srcs = ["tox_events_test.cc"], deps = [ ":crypto_core", + ":os_system", ":tox", ":tox_events", + ":tox_system", "@com_google_googletest//:gtest", "@com_google_googletest//:gtest_main", ], diff --git a/toxcore/DHT.c b/toxcore/DHT.c index 89c85c3463..dd529762da 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c @@ -281,7 +281,7 @@ const uint8_t *dht_get_shared_key_sent(DHT *dht, const uint8_t *public_key) int create_request(const Random *rng, const uint8_t *send_public_key, const uint8_t *send_secret_key, uint8_t *packet, const uint8_t *recv_public_key, - const uint8_t *data, uint32_t data_length, uint8_t request_id) + const uint8_t *data, uint32_t data_length, uint8_t request_id, const Memory *mem) { if (send_public_key == nullptr || packet == nullptr || recv_public_key == nullptr || data == nullptr) { return -1; @@ -297,7 +297,7 @@ int create_request(const Random *rng, const uint8_t *send_public_key, const uint temp[0] = request_id; memcpy(temp + 1, data, data_length); const int len = encrypt_data(recv_public_key, send_secret_key, nonce, temp, data_length + 1, - packet + CRYPTO_SIZE); + packet + CRYPTO_SIZE, mem); if (len == -1) { crypto_memzero(temp, MAX_CRYPTO_REQUEST_SIZE); @@ -313,7 +313,7 @@ int create_request(const Random *rng, const uint8_t *send_public_key, const uint } int handle_request(const uint8_t *self_public_key, const uint8_t *self_secret_key, uint8_t *public_key, uint8_t *data, - uint8_t *request_id, const uint8_t *packet, uint16_t packet_length) + uint8_t *request_id, const uint8_t *packet, uint16_t packet_length, const Memory *mem) { if (self_public_key == nullptr || public_key == nullptr || data == nullptr || request_id == nullptr || packet == nullptr) { @@ -332,7 +332,7 @@ int handle_request(const uint8_t *self_public_key, const uint8_t *self_secret_ke const uint8_t *const nonce = packet + 1 + CRYPTO_PUBLIC_KEY_SIZE * 2; uint8_t temp[MAX_CRYPTO_REQUEST_SIZE]; int32_t len1 = decrypt_data(public_key, self_secret_key, nonce, - packet + CRYPTO_SIZE, packet_length - CRYPTO_SIZE, temp); + packet + CRYPTO_SIZE, packet_length - CRYPTO_SIZE, temp, mem); if (len1 == -1 || len1 == 0) { crypto_memzero(temp, MAX_CRYPTO_REQUEST_SIZE); @@ -378,7 +378,7 @@ int dht_create_packet(const Memory *mem, const Random *rng, random_nonce(rng, nonce); - 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, mem); if (encrypted_length < 0) { mem_delete(mem, encrypted); @@ -874,7 +874,7 @@ static int handle_data_search_response(void *object, const IP_Port *source, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, plain_len + CRYPTO_MAC_SIZE, - plain) != plain_len) { + plain, dht->mem) != plain_len) { return 1; } @@ -1385,7 +1385,7 @@ static int handle_getnodes(void *object, const IP_Port *source, const uint8_t *p packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, CRYPTO_NODE_SIZE + CRYPTO_MAC_SIZE, - plain); + plain, dht->mem); if (len != CRYPTO_NODE_SIZE) { return 1; @@ -1446,7 +1446,7 @@ static bool handle_sendnodes_core(void *object, const IP_Port *source, const uin packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, 1 + data_size + sizeof(uint64_t) + CRYPTO_MAC_SIZE, - plain); + plain, dht->mem); if ((uint32_t)len != plain_size) { return false; @@ -2124,7 +2124,7 @@ static int send_nat_ping(const DHT *dht, const uint8_t *public_key, uint64_t pin /* 254 is NAT ping request packet id */ const int len = create_request( dht->rng, dht->self_public_key, dht->self_secret_key, packet_data, public_key, - data, sizeof(uint64_t) + 1, CRYPTO_PACKET_NAT_PING); + data, sizeof(uint64_t) + 1, CRYPTO_PACKET_NAT_PING, dht->mem); if (len == -1) { return -1; @@ -2459,7 +2459,7 @@ static int cryptopacket_handle(void *object, const IP_Port *source, const uint8_ uint8_t data[MAX_CRYPTO_REQUEST_SIZE]; uint8_t number; const int len = handle_request(dht->self_public_key, dht->self_secret_key, public_key, - data, &number, packet, length); + data, &number, packet, length, dht->mem); if (len == -1 || len == 0) { return 1; diff --git a/toxcore/DHT.h b/toxcore/DHT.h index 19a9e1d937..0140b9d89b 100644 --- a/toxcore/DHT.h +++ b/toxcore/DHT.h @@ -101,7 +101,7 @@ extern "C" { non_null() int create_request(const Random *rng, const uint8_t *send_public_key, const uint8_t *send_secret_key, uint8_t *packet, const uint8_t *recv_public_key, - const uint8_t *data, uint32_t data_length, uint8_t request_id); + const uint8_t *data, uint32_t data_length, uint8_t request_id, const Memory *mem); /** * @brief Decrypts and unpacks a DHT request packet. @@ -128,7 +128,7 @@ int create_request(const Random *rng, const uint8_t *send_public_key, const uint non_null() int handle_request( const uint8_t *self_public_key, const uint8_t *self_secret_key, uint8_t *public_key, uint8_t *data, - uint8_t *request_id, const uint8_t *packet, uint16_t packet_length); + uint8_t *request_id, const uint8_t *packet, uint16_t packet_length, const Memory *mem); typedef struct IPPTs { IP_Port ip_port; diff --git a/toxcore/DHT_fuzz_test.cc b/toxcore/DHT_fuzz_test.cc index 5b1b63503f..41446621ad 100644 --- a/toxcore/DHT_fuzz_test.cc +++ b/toxcore/DHT_fuzz_test.cc @@ -6,6 +6,7 @@ #include #include "../testing/fuzzing/fuzz_support.hh" +#include "os_memory.h" namespace { @@ -18,7 +19,7 @@ void TestHandleRequest(Fuzz_Data &input) uint8_t request[MAX_CRYPTO_REQUEST_SIZE]; uint8_t request_id; handle_request(self_public_key, self_secret_key, public_key, request, &request_id, input.data(), - input.size()); + input.size(), os_memory()); } void TestUnpackNodes(Fuzz_Data &input) diff --git a/toxcore/DHT_test.cc b/toxcore/DHT_test.cc index 45f886e3d8..e32ac74fb5 100644 --- a/toxcore/DHT_test.cc +++ b/toxcore/DHT_test.cc @@ -12,10 +12,13 @@ #include "crypto_core.h" #include "crypto_core_test_util.hh" #include "logger.h" +#include "mem.h" #include "mem_test_util.hh" #include "mono_time.h" #include "network.h" #include "network_test_util.hh" +#include "os_memory.h" +#include "os_network.h" #include "test_util.hh" namespace { @@ -275,6 +278,8 @@ TEST(AddToList, KeepsKeysInOrder) TEST(Request, CreateAndParse) { Test_Random rng; + const Memory *mem = os_memory(); + ASSERT_NE(mem, nullptr); // Peers. const KeyPair sender(rng); @@ -294,31 +299,31 @@ TEST(Request, CreateAndParse) random_bytes(rng, outgoing.data(), outgoing.size()); EXPECT_LT(create_request(rng, sender.pk.data(), sender.sk.data(), packet.data(), - receiver.pk.data(), outgoing.data(), outgoing.size(), sent_pkt_id), + receiver.pk.data(), outgoing.data(), outgoing.size(), sent_pkt_id, mem), 0); // Pop one element so the payload is 918 bytes. Packing should now succeed. outgoing.pop_back(); const int max_sent_length = create_request(rng, sender.pk.data(), sender.sk.data(), - packet.data(), receiver.pk.data(), outgoing.data(), outgoing.size(), sent_pkt_id); + packet.data(), receiver.pk.data(), outgoing.data(), outgoing.size(), sent_pkt_id, mem); ASSERT_GT(max_sent_length, 0); // success. // Check that handle_request rejects packets larger than the maximum created packet size. EXPECT_LT(handle_request(receiver.pk.data(), receiver.sk.data(), pk.data(), incoming.data(), - &recvd_pkt_id, packet.data(), max_sent_length + 1), + &recvd_pkt_id, packet.data(), max_sent_length + 1, mem), 0); // Now try all possible packet sizes from max (918) to 0. while (!outgoing.empty()) { // Pack: const int sent_length = create_request(rng, sender.pk.data(), sender.sk.data(), - packet.data(), receiver.pk.data(), outgoing.data(), outgoing.size(), sent_pkt_id); + packet.data(), receiver.pk.data(), outgoing.data(), outgoing.size(), sent_pkt_id, mem); ASSERT_GT(sent_length, 0); // Unpack: const int recvd_length = handle_request(receiver.pk.data(), receiver.sk.data(), pk.data(), - incoming.data(), &recvd_pkt_id, packet.data(), sent_length); + incoming.data(), &recvd_pkt_id, packet.data(), sent_length, mem); ASSERT_GE(recvd_length, 0); EXPECT_EQ( @@ -336,7 +341,7 @@ TEST(AnnounceNodes, SetAndTest) Logger *log = logger_new(mem); ASSERT_NE(log, nullptr); - Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); + Mono_Time *mono_time = mono_time_new(mem, nullptr); ASSERT_NE(mono_time, nullptr); Ptr net(new_networking_no_udp(log, mem, ns)); ASSERT_NE(net, nullptr); diff --git a/toxcore/LAN_discovery.c b/toxcore/LAN_discovery.c index aead975911..7971efccf0 100644 --- a/toxcore/LAN_discovery.c +++ b/toxcore/LAN_discovery.c @@ -8,8 +8,6 @@ */ #include "LAN_discovery.h" -#include - #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) // The mingw32/64 Windows library warns about including winsock2.h after // windows.h even though with the above it's a valid thing to do. So, to make @@ -41,11 +39,15 @@ #include "attributes.h" #include "ccompat.h" #include "crypto_core.h" +#include "mem.h" #include "network.h" +#include "tox_network.h" #define MAX_INTERFACES 16 struct Broadcast_Info { + const Memory *mem; + uint32_t count; IP ips[MAX_INTERFACES]; }; @@ -53,15 +55,17 @@ struct Broadcast_Info { #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) non_null() -static Broadcast_Info *fetch_broadcast_info(const Network *ns) +static Broadcast_Info *fetch_broadcast_info(const Memory *mem, const Network *ns) { - Broadcast_Info *broadcast = (Broadcast_Info *)calloc(1, sizeof(Broadcast_Info)); + Broadcast_Info *broadcast = (Broadcast_Info *)mem_alloc(mem, sizeof(Broadcast_Info)); if (broadcast == nullptr) { return nullptr; } - IP_ADAPTER_INFO *adapter_info = (IP_ADAPTER_INFO *)malloc(sizeof(IP_ADAPTER_INFO)); + broadcast->mem = mem; + + IP_ADAPTER_INFO *adapter_info = (IP_ADAPTER_INFO *)mem_balloc(mem, sizeof(IP_ADAPTER_INFO)); if (adapter_info == nullptr) { free(broadcast); @@ -71,11 +75,11 @@ static Broadcast_Info *fetch_broadcast_info(const Network *ns) unsigned long out_buf_len = sizeof(IP_ADAPTER_INFO); if (GetAdaptersInfo(adapter_info, &out_buf_len) == ERROR_BUFFER_OVERFLOW) { - free(adapter_info); + mem_delete(mem, adapter_info); IP_ADAPTER_INFO *new_adapter_info = (IP_ADAPTER_INFO *)malloc(out_buf_len); if (new_adapter_info == nullptr) { - free(broadcast); + mem_delete(mem, broadcast); return nullptr; } @@ -113,7 +117,7 @@ static Broadcast_Info *fetch_broadcast_info(const Network *ns) } if (adapter_info != nullptr) { - free(adapter_info); + mem_delete(mem, adapter_info); } return broadcast; @@ -122,14 +126,16 @@ static Broadcast_Info *fetch_broadcast_info(const Network *ns) #elif !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && (defined(__linux__) || defined(__FreeBSD__) || defined(__DragonFly__)) non_null() -static Broadcast_Info *fetch_broadcast_info(const Network *ns) +static Broadcast_Info *fetch_broadcast_info(const Memory *mem, const Network *ns) { - Broadcast_Info *broadcast = (Broadcast_Info *)calloc(1, sizeof(Broadcast_Info)); + Broadcast_Info *broadcast = (Broadcast_Info *)mem_alloc(mem, sizeof(Broadcast_Info)); if (broadcast == nullptr) { return nullptr; } + broadcast->mem = mem; + /* Not sure how many platforms this will run on, * so it's wrapped in `__linux__` for now. * Definitely won't work like this on Windows... @@ -137,7 +143,7 @@ static Broadcast_Info *fetch_broadcast_info(const Network *ns) const Socket sock = net_socket(ns, net_family_ipv4(), TOX_SOCK_STREAM, 0); if (!sock_valid(sock)) { - free(broadcast); + mem_delete(mem, broadcast); return nullptr; } @@ -150,7 +156,7 @@ static Broadcast_Info *fetch_broadcast_info(const Network *ns) if (ioctl(net_socket_to_native(sock), SIOCGIFCONF, &ifc) < 0) { kill_sock(ns, sock); - free(broadcast); + mem_delete(mem, broadcast); return nullptr; } @@ -197,9 +203,17 @@ static Broadcast_Info *fetch_broadcast_info(const Network *ns) #else // TODO(irungentoo): Other platforms? non_null() -static Broadcast_Info *fetch_broadcast_info(const Network *ns) +static Broadcast_Info *fetch_broadcast_info(const Memory *mem, const Network *ns) { - return (Broadcast_Info *)calloc(1, sizeof(Broadcast_Info)); + Broadcast_Info *broadcast = (Broadcast_Info *)mem_alloc(mem, sizeof(Broadcast_Info)); + + if (broadcast == nullptr) { + return nullptr; + } + + broadcast->mem = mem; + + return broadcast; } #endif /* platforms */ @@ -375,12 +389,16 @@ bool lan_discovery_send(const Networking_Core *net, const Broadcast_Info *broadc return res; } -Broadcast_Info *lan_discovery_init(const Network *ns) +Broadcast_Info *lan_discovery_init(const Memory *mem, const Network *ns) { - return fetch_broadcast_info(ns); + return fetch_broadcast_info(mem, ns); } void lan_discovery_kill(Broadcast_Info *broadcast) { - free(broadcast); + if (broadcast == nullptr) { + return; + } + + mem_delete(broadcast->mem, broadcast); } diff --git a/toxcore/LAN_discovery.h b/toxcore/LAN_discovery.h index 94e5d3581c..7c7de1f93f 100644 --- a/toxcore/LAN_discovery.h +++ b/toxcore/LAN_discovery.h @@ -10,6 +10,7 @@ #define C_TOXCORE_TOXCORE_LAN_DISCOVERY_H #include "attributes.h" +#include "mem.h" #include "network.h" /** @@ -32,7 +33,7 @@ bool lan_discovery_send(const Networking_Core *net, const Broadcast_Info *broadc * Discovers broadcast devices and IP addresses. */ non_null() -Broadcast_Info *lan_discovery_init(const Network *ns); +Broadcast_Info *lan_discovery_init(const Memory *mem, const Network *ns); /** * Free all resources associated with the broadcast info. diff --git a/toxcore/Makefile.inc b/toxcore/Makefile.inc index db3e193243..20de43258b 100644 --- a/toxcore/Makefile.inc +++ b/toxcore/Makefile.inc @@ -1,12 +1,24 @@ lib_LTLIBRARIES += libtoxcore.la libtoxcore_la_include_HEADERS = \ - ../toxcore/tox.h + ../toxcore/tox.h \ + ../toxcore/tox_attributes.h \ + ../toxcore/tox_dispatch.h \ + ../toxcore/tox_events.h \ + ../toxcore/tox_log.h \ + ../toxcore/tox_memory.h \ + ../toxcore/tox_network.h \ + ../toxcore/tox_options.h \ + ../toxcore/tox_system.h \ + ../toxcore/tox_system_impl.h \ + ../toxcore/tox_time.h -libtoxcore_la_includedir = $(includedir)/tox +libtoxcore_la_includedir = $(includedir)/tox/toxcore libtoxcore_la_SOURCES = ../third_party/cmp/cmp.c \ ../third_party/cmp/cmp.h \ + ../toxcore/announce.c \ + ../toxcore/announce.h \ ../toxcore/attributes.h \ ../toxcore/bin_pack.c \ ../toxcore/bin_pack.h \ @@ -14,6 +26,12 @@ libtoxcore_la_SOURCES = ../third_party/cmp/cmp.c \ ../toxcore/bin_unpack.h \ ../toxcore/ccompat.c \ ../toxcore/ccompat.h \ + ../toxcore/crypto_core.c \ + ../toxcore/crypto_core.h \ + ../toxcore/crypto_core_pack.c \ + ../toxcore/crypto_core_pack.h \ + ../toxcore/DHT.c \ + ../toxcore/DHT.h \ ../toxcore/events/conference_connected.c \ ../toxcore/events/conference_invite.c \ ../toxcore/events/conference_message.c \ @@ -37,7 +55,6 @@ libtoxcore_la_SOURCES = ../third_party/cmp/cmp.c \ ../toxcore/events/friend_status.c \ ../toxcore/events/friend_status_message.c \ ../toxcore/events/friend_typing.c \ - ../toxcore/events/self_connection_status.c \ ../toxcore/events/group_custom_packet.c \ ../toxcore/events/group_custom_private_packet.c \ ../toxcore/events/group_invite.c \ @@ -56,93 +73,120 @@ libtoxcore_la_SOURCES = ../third_party/cmp/cmp.c \ ../toxcore/events/group_topic.c \ ../toxcore/events/group_topic_lock.c \ ../toxcore/events/group_voice_state.c \ - ../toxcore/DHT.h \ - ../toxcore/DHT.c \ - ../toxcore/mem.h \ + ../toxcore/events/self_connection_status.c \ + ../toxcore/forwarding.c \ + ../toxcore/forwarding.h \ + ../toxcore/friend_connection.c \ + ../toxcore/friend_connection.h \ + ../toxcore/friend_requests.c \ + ../toxcore/friend_requests.h \ + ../toxcore/group_announce.c \ + ../toxcore/group_announce.h \ + ../toxcore/group.c \ + ../toxcore/group_chats.c \ + ../toxcore/group_chats.h \ + ../toxcore/group_common.h \ + ../toxcore/group_connection.c \ + ../toxcore/group_connection.h \ + ../toxcore/group.h \ + ../toxcore/group_moderation.c \ + ../toxcore/group_moderation.h \ + ../toxcore/group_onion_announce.c \ + ../toxcore/group_onion_announce.h \ + ../toxcore/group_pack.c \ + ../toxcore/group_pack.h \ + ../toxcore/LAN_discovery.c \ + ../toxcore/LAN_discovery.h \ + ../toxcore/list.c \ + ../toxcore/list.h \ + ../toxcore/logger.c \ + ../toxcore/logger.h \ ../toxcore/mem.c \ - ../toxcore/mono_time.h \ + ../toxcore/mem.h \ + ../toxcore/Messenger.c \ + ../toxcore/Messenger.h \ ../toxcore/mono_time.c \ - ../toxcore/network.h \ + ../toxcore/mono_time.h \ + ../toxcore/net_crypto.c \ + ../toxcore/net_crypto.h \ ../toxcore/network.c \ - ../toxcore/crypto_core.h \ - ../toxcore/crypto_core.c \ - ../toxcore/crypto_core_pack.h \ - ../toxcore/crypto_core_pack.c \ - ../toxcore/timed_auth.h \ - ../toxcore/timed_auth.c \ - ../toxcore/ping_array.h \ + ../toxcore/network.h \ + ../toxcore/onion_announce.c \ + ../toxcore/onion_announce.h \ + ../toxcore/onion.c \ + ../toxcore/onion_client.c \ + ../toxcore/onion_client.h \ + ../toxcore/onion.h \ + ../toxcore/os_log.c \ + ../toxcore/os_log.h \ + ../toxcore/os_memory.c \ + ../toxcore/os_memory.h \ + ../toxcore/os_network.c \ + ../toxcore/os_network.h \ + ../toxcore/os_network_impl.h \ + ../toxcore/os_random.c \ + ../toxcore/os_random.h \ + ../toxcore/os_system.c \ + ../toxcore/os_system.h \ + ../toxcore/os_time.c \ + ../toxcore/os_time.h \ ../toxcore/ping_array.c \ - ../toxcore/net_crypto.h \ - ../toxcore/net_crypto.c \ - ../toxcore/friend_requests.h \ - ../toxcore/friend_requests.c \ - ../toxcore/LAN_discovery.h \ - ../toxcore/LAN_discovery.c \ - ../toxcore/friend_connection.h \ - ../toxcore/friend_connection.c \ - ../toxcore/Messenger.h \ - ../toxcore/Messenger.c \ - ../toxcore/ping.h \ + ../toxcore/ping_array.h \ ../toxcore/ping.c \ - ../toxcore/shared_key_cache.h \ + ../toxcore/ping.h \ ../toxcore/shared_key_cache.c \ - ../toxcore/state.h \ + ../toxcore/shared_key_cache.h \ ../toxcore/state.c \ - ../toxcore/tox.h \ + ../toxcore/state.h \ + ../toxcore/TCP_client.c \ + ../toxcore/TCP_client.h \ + ../toxcore/TCP_common.c \ + ../toxcore/TCP_common.h \ + ../toxcore/TCP_connection.c \ + ../toxcore/TCP_connection.h \ + ../toxcore/TCP_server.c \ + ../toxcore/TCP_server.h \ + ../toxcore/timed_auth.c \ + ../toxcore/timed_auth.h \ + ../toxcore/tox_api.c \ + ../toxcore/tox_attributes.h \ ../toxcore/tox.c \ - ../toxcore/tox_dispatch.h \ ../toxcore/tox_dispatch.c \ - ../toxcore/tox_event.h \ + ../toxcore/tox_dispatch.h \ ../toxcore/tox_event.c \ - ../toxcore/tox_events.h \ + ../toxcore/tox_event.h \ ../toxcore/tox_events.c \ - ../toxcore/tox_pack.h \ + ../toxcore/tox_events.h \ + ../toxcore/tox.h \ + ../toxcore/tox_impl.h \ + ../toxcore/tox_log.c \ + ../toxcore/tox_log.h \ + ../toxcore/tox_log_impl.h \ + ../toxcore/tox_memory.c \ + ../toxcore/tox_memory.h \ + ../toxcore/tox_memory_impl.h \ + ../toxcore/tox_network.c \ + ../toxcore/tox_network.h \ + ../toxcore/tox_network_impl.h \ + ../toxcore/tox_options.c \ + ../toxcore/tox_options.h \ ../toxcore/tox_pack.c \ - ../toxcore/tox_unpack.h \ - ../toxcore/tox_unpack.c \ + ../toxcore/tox_pack.h \ ../toxcore/tox_private.c \ ../toxcore/tox_private.h \ - ../toxcore/tox_struct.h \ - ../toxcore/tox_api.c \ - ../toxcore/util.h \ + ../toxcore/tox_random.c \ + ../toxcore/tox_random.h \ + ../toxcore/tox_random_impl.h \ + ../toxcore/tox_system.c \ + ../toxcore/tox_system.h \ + ../toxcore/tox_system_impl.h \ + ../toxcore/tox_time.c \ + ../toxcore/tox_time.h \ + ../toxcore/tox_time_impl.h \ + ../toxcore/tox_unpack.c \ + ../toxcore/tox_unpack.h \ ../toxcore/util.c \ - ../toxcore/group.h \ - ../toxcore/group.c \ - ../toxcore/group_announce.h \ - ../toxcore/group_announce.c \ - ../toxcore/group_onion_announce.c \ - ../toxcore/group_onion_announce.h \ - ../toxcore/group_chats.h \ - ../toxcore/group_chats.c \ - ../toxcore/group_common.h \ - ../toxcore/group_connection.c \ - ../toxcore/group_connection.h \ - ../toxcore/group_pack.c \ - ../toxcore/group_pack.h \ - ../toxcore/group_moderation.c \ - ../toxcore/group_moderation.h \ - ../toxcore/onion.h \ - ../toxcore/onion.c \ - ../toxcore/logger.h \ - ../toxcore/logger.c \ - ../toxcore/onion_announce.h \ - ../toxcore/onion_announce.c \ - ../toxcore/onion_client.h \ - ../toxcore/onion_client.c \ - ../toxcore/announce.h \ - ../toxcore/announce.c \ - ../toxcore/forwarding.h \ - ../toxcore/forwarding.c \ - ../toxcore/TCP_client.h \ - ../toxcore/TCP_client.c \ - ../toxcore/TCP_common.h \ - ../toxcore/TCP_common.c \ - ../toxcore/TCP_server.h \ - ../toxcore/TCP_server.c \ - ../toxcore/TCP_connection.h \ - ../toxcore/TCP_connection.c \ - ../toxcore/list.c \ - ../toxcore/list.h + ../toxcore/util.h libtoxcore_la_CFLAGS = -I$(top_srcdir) \ -I$(top_srcdir)/toxcore \ diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index d2a84490b8..03b006e72c 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c @@ -3171,7 +3171,7 @@ static bool handle_groups_load(void *obj, Bin_Unpack *bu) non_null() static State_Load_Status groups_load(Messenger *m, const uint8_t *data, uint32_t length) { - if (!bin_unpack_obj(handle_groups_load, m, data, length)) { + if (!bin_unpack_obj(handle_groups_load, m, data, length, m->mem)) { LOGGER_ERROR(m->log, "msgpack failed to unpack groupchats array"); return STATE_LOAD_STATUS_ERROR; } @@ -3475,7 +3475,7 @@ Messenger *new_messenger(Mono_Time *mono_time, const Memory *mem, const Random * m->rng = rng; m->ns = ns; - m->fr = friendreq_new(); + m->fr = friendreq_new(mem); if (m->fr == nullptr) { mem_delete(mem, m); @@ -3544,7 +3544,7 @@ Messenger *new_messenger(Mono_Time *mono_time, const Memory *mem, const Random * return nullptr; } - m->group_announce = new_gca_list(); + m->group_announce = new_gca_list(m->mem); if (m->group_announce == nullptr) { LOGGER_WARNING(m->log, "DHT group chats initialisation failed"); @@ -3559,7 +3559,7 @@ Messenger *new_messenger(Mono_Time *mono_time, const Memory *mem, const Random * } 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->mem, m->rng, m->mono_time, m->dht); if (m->forwarding != nullptr) { m->announce = new_announcements(m->log, m->mem, m->rng, m->mono_time, m->forwarding); } else { @@ -3574,7 +3574,7 @@ Messenger *new_messenger(Mono_Time *mono_time, const Memory *mem, const Random * m->onion_a = new_onion_announce(m->log, m->mem, m->rng, m->mono_time, m->dht); m->onion_c = new_onion_client(m->log, m->mem, m->rng, m->mono_time, m->net_crypto); if (m->onion_c != nullptr) { - 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->mem, m->ns, m->onion_c, options->local_discovery_enabled); } if ((options->dht_announcements_enabled && (m->forwarding == nullptr || m->announce == nullptr)) || diff --git a/toxcore/TCP_client.c b/toxcore/TCP_client.c index 938c5cf83a..d58d14c876 100644 --- a/toxcore/TCP_client.c +++ b/toxcore/TCP_client.c @@ -21,6 +21,7 @@ #include "mem.h" #include "mono_time.h" #include "network.h" +#include "tox_network.h" #include "util.h" typedef struct TCP_Client_Conn { @@ -313,7 +314,7 @@ static int generate_handshake(TCP_Client_Connection *tcp_conn) memcpy(tcp_conn->con.last_packet, tcp_conn->self_public_key, CRYPTO_PUBLIC_KEY_SIZE); random_nonce(tcp_conn->con.rng, tcp_conn->con.last_packet + CRYPTO_PUBLIC_KEY_SIZE); const int len = encrypt_data_symmetric(tcp_conn->con.shared_key, tcp_conn->con.last_packet + CRYPTO_PUBLIC_KEY_SIZE, plain, - sizeof(plain), tcp_conn->con.last_packet + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE); + sizeof(plain), tcp_conn->con.last_packet + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, tcp_conn->con.mem); if (len != sizeof(plain) + CRYPTO_MAC_SIZE) { return -1; @@ -335,7 +336,7 @@ static int handle_handshake(TCP_Client_Connection *tcp_conn, const uint8_t *data { uint8_t plain[CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE]; const int len = decrypt_data_symmetric(tcp_conn->con.shared_key, data, data + CRYPTO_NONCE_SIZE, - TCP_SERVER_HANDSHAKE_SIZE - CRYPTO_NONCE_SIZE, plain); + TCP_SERVER_HANDSHAKE_SIZE - CRYPTO_NONCE_SIZE, plain, tcp_conn->con.mem); if (len != sizeof(plain)) { return -1; diff --git a/toxcore/TCP_client.h b/toxcore/TCP_client.h index ea2654b953..85e7f08b0f 100644 --- a/toxcore/TCP_client.h +++ b/toxcore/TCP_client.h @@ -9,13 +9,13 @@ #ifndef C_TOXCORE_TOXCORE_TCP_CLIENT_H #define C_TOXCORE_TOXCORE_TCP_CLIENT_H -#include "attributes.h" #include "crypto_core.h" #include "forwarding.h" #include "logger.h" #include "mem.h" #include "mono_time.h" #include "network.h" +#include "attributes.h" #define TCP_CONNECTION_TIMEOUT 10 diff --git a/toxcore/TCP_common.c b/toxcore/TCP_common.c index bd3b7ca4c7..74ec9f4fce 100644 --- a/toxcore/TCP_common.c +++ b/toxcore/TCP_common.c @@ -13,6 +13,7 @@ #include "logger.h" #include "mem.h" #include "network.h" +#include "tox_network.h" void wipe_priority_list(const Memory *mem, TCP_Priority_List *p) { @@ -157,7 +158,7 @@ int write_packet_tcp_secure_connection(const Logger *logger, TCP_Connection *con uint16_t c_length = net_htons(length + CRYPTO_MAC_SIZE); memcpy(packet, &c_length, sizeof(uint16_t)); - int len = encrypt_data_symmetric(con->shared_key, con->sent_nonce, data, length, packet + sizeof(uint16_t)); + int len = encrypt_data_symmetric(con->shared_key, con->sent_nonce, data, length, packet + sizeof(uint16_t), con->mem); if ((unsigned int)len != (packet_size - sizeof(uint16_t))) { return -1; @@ -305,7 +306,7 @@ int read_packet_tcp_secure_connection( *next_packet_length = 0; - const int len = decrypt_data_symmetric(shared_key, recv_nonce, data_encrypted, len_packet, data); + const int len = decrypt_data_symmetric(shared_key, recv_nonce, data_encrypted, len_packet, data, mem); if (len + CRYPTO_MAC_SIZE != len_packet) { LOGGER_ERROR(logger, "decrypted length %d does not match expected length %d", len + CRYPTO_MAC_SIZE, len_packet); diff --git a/toxcore/TCP_common.h b/toxcore/TCP_common.h index 9fa136609c..4c231222e6 100644 --- a/toxcore/TCP_common.h +++ b/toxcore/TCP_common.h @@ -11,6 +11,7 @@ #include "logger.h" #include "mem.h" #include "network.h" +#include "tox_network.h" typedef struct TCP_Priority_List TCP_Priority_List; struct TCP_Priority_List { diff --git a/toxcore/TCP_connection.h b/toxcore/TCP_connection.h index 2d35919f10..0c4c24d92a 100644 --- a/toxcore/TCP_connection.h +++ b/toxcore/TCP_connection.h @@ -15,13 +15,13 @@ #include "DHT.h" // for Node_format #include "TCP_client.h" #include "TCP_common.h" -#include "attributes.h" #include "crypto_core.h" #include "forwarding.h" #include "logger.h" #include "mem.h" #include "mono_time.h" #include "network.h" +#include "attributes.h" #define TCP_CONN_NONE 0 #define TCP_CONN_VALID 1 diff --git a/toxcore/TCP_server.c b/toxcore/TCP_server.c index 1363d90220..4ef39c948a 100644 --- a/toxcore/TCP_server.c +++ b/toxcore/TCP_server.c @@ -29,6 +29,7 @@ #include "mono_time.h" #include "network.h" #include "onion.h" +#include "tox_network.h" #ifdef TCP_SERVER_USE_EPOLL #define TCP_SOCKET_LISTENING 0 @@ -328,7 +329,8 @@ static int handle_tcp_handshake(const Logger *logger, TCP_Secure_Connection *con encrypt_precompute(data, self_secret_key, shared_key); uint8_t plain[TCP_HANDSHAKE_PLAIN_SIZE]; int len = decrypt_data_symmetric(shared_key, data + CRYPTO_PUBLIC_KEY_SIZE, - data + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, TCP_HANDSHAKE_PLAIN_SIZE + CRYPTO_MAC_SIZE, plain); + data + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, + TCP_HANDSHAKE_PLAIN_SIZE + CRYPTO_MAC_SIZE, plain, con->con.mem); if (len != TCP_HANDSHAKE_PLAIN_SIZE) { LOGGER_ERROR(logger, "invalid TCP handshake decrypted length: %d != %d", len, TCP_HANDSHAKE_PLAIN_SIZE); @@ -348,7 +350,7 @@ static int handle_tcp_handshake(const Logger *logger, TCP_Secure_Connection *con random_nonce(con->con.rng, response); len = encrypt_data_symmetric(shared_key, response, resp_plain, TCP_HANDSHAKE_PLAIN_SIZE, - response + CRYPTO_NONCE_SIZE); + response + CRYPTO_NONCE_SIZE, con->con.mem); if (len != TCP_HANDSHAKE_PLAIN_SIZE + CRYPTO_MAC_SIZE) { crypto_memzero(shared_key, sizeof(shared_key)); @@ -914,7 +916,7 @@ static int accept_connection(TCP_Server *tcp_server, Socket sock) } non_null() -static Socket new_listening_tcp_socket(const Logger *logger, const Network *ns, Family family, uint16_t port) +static Socket new_listening_tcp_socket(const Logger *logger, const Network *ns, const Memory *mem, Family family, uint16_t port) { const Socket sock = net_socket(ns, family, TOX_SOCK_STREAM, TOX_PROTO_TCP); @@ -933,7 +935,7 @@ static Socket new_listening_tcp_socket(const Logger *logger, const Network *ns, ok = set_socket_reuseaddr(ns, sock); } - ok = ok && bind_to_port(ns, sock, family, port) && (net_listen(ns, sock, TCP_MAX_BACKLOG) == 0); + ok = ok && bind_to_port(ns, mem, sock, family, port) && (net_listen(ns, sock, TCP_MAX_BACKLOG) == 0); if (!ok) { char *const error = net_new_strerror(net_error()); @@ -999,7 +1001,7 @@ TCP_Server *new_tcp_server(const Logger *logger, const Memory *mem, const Random const Family family = ipv6_enabled ? net_family_ipv6() : net_family_ipv4(); for (uint32_t i = 0; i < num_sockets; ++i) { - const Socket sock = new_listening_tcp_socket(logger, ns, family, ports[i]); + const Socket sock = new_listening_tcp_socket(logger, ns, mem, family, ports[i]); if (!sock_valid(sock)) { continue; @@ -1040,7 +1042,7 @@ TCP_Server *new_tcp_server(const Logger *logger, const Memory *mem, const Random memcpy(temp->secret_key, secret_key, CRYPTO_SECRET_KEY_SIZE); crypto_derive_public_key(temp->public_key, temp->secret_key); - bs_list_init(&temp->accepted_key_list, CRYPTO_PUBLIC_KEY_SIZE, 8, memcmp); + bs_list_init(&temp->accepted_key_list, CRYPTO_PUBLIC_KEY_SIZE, 8, memcmp, mem); return temp; } diff --git a/toxcore/announce.c b/toxcore/announce.c index 7bda993232..161074e9a9 100644 --- a/toxcore/announce.c +++ b/toxcore/announce.c @@ -9,7 +9,6 @@ #include "announce.h" #include -#include #include #include "DHT.h" @@ -239,9 +238,9 @@ bool announce_store_data(Announcements *announce, const uint8_t *data_public_key if (length > 0) { assert(data != nullptr); - free(entry->data); + mem_delete(announce->mem, entry->data); - uint8_t *entry_data = (uint8_t *)malloc(length); + uint8_t *entry_data = (uint8_t *)mem_balloc(announce->mem, length); if (entry_data == nullptr) { entry->data = nullptr; // TODO(iphydf): Is this necessary? @@ -455,7 +454,7 @@ static int create_reply_plain_store_announce_request(Announcements *announce, data + CRYPTO_PUBLIC_KEY_SIZE, data + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, plain_len + CRYPTO_MAC_SIZE, - plain) != plain_len) { + plain, announce->mem) != plain_len) { return -1; } @@ -553,11 +552,12 @@ static int create_reply_plain(Announcements *announce, } } -non_null(1, 2, 5, 7) nullable(3) +non_null(1, 2, 5, 7, 9) nullable(3) static int create_reply(Announcements *announce, const IP_Port *source, const uint8_t *sendback, uint16_t sendback_length, const uint8_t *data, uint16_t length, - uint8_t *reply, uint16_t reply_max_length) + uint8_t *reply, uint16_t reply_max_length, + const Memory *mem) { const int plain_len = (int)length - (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_MAC_SIZE); @@ -572,7 +572,7 @@ static int create_reply(Announcements *announce, const IP_Port *source, data + 1 + CRYPTO_PUBLIC_KEY_SIZE, data + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, plain_len + CRYPTO_MAC_SIZE, - plain) != plain_len) { + plain, mem) != plain_len) { return -1; } @@ -617,7 +617,8 @@ static void forwarded_request_callback(void *object, const IP_Port *forwarder, const int len = create_reply(announce, forwarder, sendback, sendback_length, - data, length, reply, sizeof(reply)); + data, length, reply, sizeof(reply), + announce->mem); if (len == -1) { return; @@ -634,8 +635,8 @@ static int handle_dht_announce_request( uint8_t reply[MAX_FORWARD_DATA_SIZE]; - const int len - = create_reply(announce, source, nullptr, 0, packet, length, reply, sizeof(reply)); + const int len = create_reply( + announce, source, nullptr, 0, packet, length, reply, sizeof(reply), announce->mem); if (len == -1) { return -1; @@ -651,7 +652,7 @@ Announcements *new_announcements(const Logger *log, const Memory *mem, const Ran return nullptr; } - Announcements *announce = (Announcements *)calloc(1, sizeof(Announcements)); + Announcements *announce = (Announcements *)mem_alloc(mem, sizeof(Announcements)); if (announce == nullptr) { return nullptr; @@ -669,7 +670,7 @@ Announcements *new_announcements(const Logger *log, const Memory *mem, const Ran new_hmac_key(announce->rng, announce->hmac_key); announce->shared_keys = shared_key_cache_new(log, mono_time, mem, announce->secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT); if (announce->shared_keys == nullptr) { - free(announce); + mem_delete(mem, announce); return nullptr; } @@ -700,8 +701,8 @@ void kill_announcements(Announcements *announce) shared_key_cache_free(announce->shared_keys); for (uint32_t i = 0; i < ANNOUNCE_BUCKETS * ANNOUNCE_BUCKET_SIZE; ++i) { - free(announce->entries[i].data); + mem_delete(announce->mem, announce->entries[i].data); } - free(announce); + mem_delete(announce->mem, announce); } diff --git a/toxcore/bin_pack.c b/toxcore/bin_pack.c index 56bdc9ec75..5b2fcc604b 100644 --- a/toxcore/bin_pack.c +++ b/toxcore/bin_pack.c @@ -11,8 +11,11 @@ #include "attributes.h" #include "ccompat.h" #include "logger.h" +#include "mem.h" struct Bin_Pack { + const Memory *mem; + uint8_t *bytes; uint32_t bytes_size; uint32_t bytes_pos; @@ -58,6 +61,7 @@ static size_t buf_writer(cmp_ctx_t *ctx, const void *data, size_t count) non_null(1) nullable(2) static void bin_pack_init(Bin_Pack *bp, uint8_t *buf, uint32_t buf_size) { + bp->mem = nullptr; bp->bytes = buf; bp->bytes_size = buf_size; bp->bytes_pos = 0; diff --git a/toxcore/bin_pack.h b/toxcore/bin_pack.h index ce6926a448..9286db02b6 100644 --- a/toxcore/bin_pack.h +++ b/toxcore/bin_pack.h @@ -9,6 +9,7 @@ #include "attributes.h" #include "logger.h" +#include "mem.h" #ifdef __cplusplus extern "C" { diff --git a/toxcore/bin_pack_test.cc b/toxcore/bin_pack_test.cc index 08e37ba549..42ee51c49b 100644 --- a/toxcore/bin_pack_test.cc +++ b/toxcore/bin_pack_test.cc @@ -8,6 +8,7 @@ #include "bin_unpack.h" #include "logger.h" +#include "mem_test_util.hh" namespace { @@ -24,6 +25,8 @@ TEST(BinPack, TooSmallBufferIsNotExceeded) TEST(BinPack, PackedUint64CanBeUnpacked) { + Test_Memory mem; + const uint64_t orig = 1234567812345678LL; std::array buf; EXPECT_TRUE(bin_pack_obj( @@ -37,12 +40,14 @@ TEST(BinPack, PackedUint64CanBeUnpacked) [](void *obj, Bin_Unpack *bu) { return bin_unpack_u64_b(bu, static_cast(obj)); }, - &unpacked, buf.data(), buf.size())); + &unpacked, buf.data(), buf.size(), mem)); EXPECT_EQ(unpacked, 1234567812345678LL); } TEST(BinPack, MsgPackedUint8CanBeUnpackedAsUint32) { + Test_Memory mem; + const uint8_t orig = 123; std::array buf; EXPECT_TRUE(bin_pack_obj( @@ -54,12 +59,14 @@ TEST(BinPack, MsgPackedUint8CanBeUnpackedAsUint32) uint32_t unpacked = 0; EXPECT_TRUE(bin_unpack_obj( [](void *obj, Bin_Unpack *bu) { return bin_unpack_u32(bu, static_cast(obj)); }, - &unpacked, buf.data(), buf.size())); + &unpacked, buf.data(), buf.size(), mem)); EXPECT_EQ(unpacked, 123); } TEST(BinPack, MsgPackedUint32CanBeUnpackedAsUint8IfSmallEnough) { + Test_Memory mem; + const uint32_t orig = 123; std::array buf; EXPECT_TRUE(bin_pack_obj( @@ -71,13 +78,15 @@ TEST(BinPack, MsgPackedUint32CanBeUnpackedAsUint8IfSmallEnough) uint8_t unpacked = 0; EXPECT_TRUE(bin_unpack_obj( [](void *obj, Bin_Unpack *bu) { return bin_unpack_u08(bu, static_cast(obj)); }, - &unpacked, buf.data(), buf.size())); + &unpacked, buf.data(), buf.size(), mem)); EXPECT_EQ(unpacked, 123); } TEST(BinPack, LargeMsgPackedUint32CannotBeUnpackedAsUint8) { + Test_Memory mem; + const uint32_t orig = 1234567; std::array buf; EXPECT_TRUE(bin_pack_obj( @@ -89,11 +98,13 @@ TEST(BinPack, LargeMsgPackedUint32CannotBeUnpackedAsUint8) uint8_t unpacked = 0; EXPECT_FALSE(bin_unpack_obj( [](void *obj, Bin_Unpack *bu) { return bin_unpack_u08(bu, static_cast(obj)); }, - &unpacked, buf.data(), buf.size())); + &unpacked, buf.data(), buf.size(), mem)); } TEST(BinPack, BinCanHoldPackedInts) { + Test_Memory mem; + struct Stuff { uint64_t u64; uint16_t u16; @@ -121,13 +132,15 @@ TEST(BinPack, BinCanHoldPackedInts) && bin_unpack_u64_b(bu, &stuff->u64) // && bin_unpack_u16_b(bu, &stuff->u16); }, - &unpacked, buf.data(), buf.size())); + &unpacked, buf.data(), buf.size(), mem)); EXPECT_EQ(unpacked.u64, 1234567812345678LL); EXPECT_EQ(unpacked.u16, 54321); } TEST(BinPack, BinCanHoldArbitraryData) { + Test_Memory mem; + std::array buf; EXPECT_TRUE(bin_pack_obj( [](const void *obj, const Logger *logger, Bin_Pack *bp) { @@ -142,12 +155,14 @@ TEST(BinPack, BinCanHoldArbitraryData) uint8_t *data = static_cast(obj); return bin_unpack_bin_fixed(bu, data, 5); }, - str.data(), buf.data(), buf.size())); + str.data(), buf.data(), buf.size(), mem)); EXPECT_EQ(str, (std::array{'h', 'e', 'l', 'l', 'o'})); } TEST(BinPack, OversizedArrayFailsUnpack) { + Test_Memory mem; + std::array buf = {0x91}; uint32_t size; @@ -156,7 +171,7 @@ TEST(BinPack, OversizedArrayFailsUnpack) uint32_t *size_ptr = static_cast(obj); return bin_unpack_array(bu, size_ptr); }, - &size, buf.data(), buf.size())); + &size, buf.data(), buf.size(), mem)); } } // namespace diff --git a/toxcore/bin_unpack.c b/toxcore/bin_unpack.c index d6b1c52ea5..22c2c13053 100644 --- a/toxcore/bin_unpack.c +++ b/toxcore/bin_unpack.c @@ -5,14 +5,16 @@ #include "bin_unpack.h" #include -#include #include #include "../third_party/cmp/cmp.h" #include "attributes.h" #include "ccompat.h" +#include "mem.h" struct Bin_Unpack { + const Memory *mem; + const uint8_t *bytes; uint32_t bytes_size; cmp_ctx_t ctx; @@ -54,17 +56,18 @@ static size_t null_writer(cmp_ctx_t *ctx, const void *data, size_t count) } non_null() -static void bin_unpack_init(Bin_Unpack *bu, const uint8_t *buf, uint32_t buf_size) +static void bin_unpack_init(Bin_Unpack *bu, const uint8_t *buf, uint32_t buf_size, const Memory *mem) { + bu->mem = mem; bu->bytes = buf; bu->bytes_size = buf_size; cmp_init(&bu->ctx, bu, buf_reader, buf_skipper, null_writer); } -bool bin_unpack_obj(bin_unpack_cb *callback, void *obj, const uint8_t *buf, uint32_t buf_size) +bool bin_unpack_obj(bin_unpack_cb *callback, void *obj, const uint8_t *buf, uint32_t buf_size, const Memory *mem) { Bin_Unpack bu; - bin_unpack_init(&bu, buf, buf_size); + bin_unpack_init(&bu, buf, buf_size, mem); return callback(obj, &bu); } @@ -120,10 +123,14 @@ bool bin_unpack_bin(Bin_Unpack *bu, uint8_t **data_ptr, uint32_t *data_length_pt // There aren't as many bytes as this bin claims to want to allocate. return false; } - uint8_t *const data = (uint8_t *)malloc(bin_size); + uint8_t *const data = (uint8_t *)mem_balloc(bu->mem, bin_size); + + if (data == nullptr) { + return false; + } if (!bin_unpack_bin_b(bu, data, bin_size)) { - free(data); + mem_delete(bu->mem, data); return false; } diff --git a/toxcore/bin_unpack.h b/toxcore/bin_unpack.h index 0554bd1a7a..a9aa4d7823 100644 --- a/toxcore/bin_unpack.h +++ b/toxcore/bin_unpack.h @@ -9,6 +9,7 @@ #include #include "attributes.h" +#include "mem.h" #ifdef __cplusplus extern "C" { @@ -46,7 +47,7 @@ typedef bool bin_unpack_cb(void *obj, Bin_Unpack *bu); * @retval false if an error occurred (e.g. buffer overrun). */ non_null() -bool bin_unpack_obj(bin_unpack_cb *callback, void *obj, const uint8_t *buf, uint32_t buf_size); +bool bin_unpack_obj(bin_unpack_cb *callback, void *obj, const uint8_t *buf, uint32_t buf_size, const Memory *mem); /** @brief Start unpacking a MessagePack array. * diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index 7bb5bb929f..482ef1b562 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -6,13 +6,14 @@ #include "crypto_core.h" #include -#include #include #include #include "attributes.h" #include "ccompat.h" +#include "mem.h" +#include "tox_random.h" #include "util.h" static_assert(CRYPTO_PUBLIC_KEY_SIZE == crypto_box_PUBLICKEYBYTES, @@ -88,9 +89,10 @@ const uint8_t *get_chat_id(const Extended_Public_Key *key) } #if !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) -static uint8_t *crypto_malloc(size_t bytes) +non_null() +static uint8_t *crypto_malloc(const Memory *mem, size_t bytes) { - uint8_t *ptr = (uint8_t *)malloc(bytes); + uint8_t *ptr = (uint8_t *)mem_balloc(mem, bytes); if (ptr != nullptr) { crypto_memlock(ptr, bytes); @@ -99,15 +101,15 @@ static uint8_t *crypto_malloc(size_t bytes) return ptr; } -nullable(1) -static void crypto_free(uint8_t *ptr, size_t bytes) +non_null(1) nullable(2) +static void crypto_free(const Memory *mem, uint8_t *ptr, size_t bytes) { if (ptr != nullptr) { crypto_memzero(ptr, bytes); crypto_memunlock(ptr, bytes); } - free(ptr); + mem_delete(mem, ptr); } #endif /* !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) */ @@ -205,7 +207,7 @@ uint64_t random_u64(const Random *rng) uint32_t random_range_u32(const Random *rng, uint32_t upper_bound) { - return rng->funcs->random_uniform(rng->obj, upper_bound); + return tox_random_uniform(rng, upper_bound); } bool crypto_signature_create(uint8_t signature[CRYPTO_SIGNATURE_SIZE], @@ -242,7 +244,8 @@ int32_t encrypt_precompute(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], int32_t encrypt_data_symmetric(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t nonce[CRYPTO_NONCE_SIZE], - const uint8_t *plain, size_t length, uint8_t *encrypted) + const uint8_t *plain, size_t length, uint8_t *encrypted, + const Memory *mem) { if (length == 0 || shared_key == nullptr || nonce == nullptr || plain == nullptr || encrypted == nullptr) { return -1; @@ -258,12 +261,12 @@ int32_t encrypt_data_symmetric(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const size_t size_temp_plain = length + crypto_box_ZEROBYTES; const size_t size_temp_encrypted = length + crypto_box_MACBYTES + crypto_box_BOXZEROBYTES; - uint8_t *temp_plain = crypto_malloc(size_temp_plain); - uint8_t *temp_encrypted = crypto_malloc(size_temp_encrypted); + uint8_t *temp_plain = crypto_malloc(mem, size_temp_plain); + uint8_t *temp_encrypted = crypto_malloc(mem, size_temp_encrypted); if (temp_plain == nullptr || temp_encrypted == nullptr) { - crypto_free(temp_plain, size_temp_plain); - crypto_free(temp_encrypted, size_temp_encrypted); + crypto_free(mem, temp_plain, size_temp_plain); + crypto_free(mem, temp_encrypted, size_temp_encrypted); return -1; } @@ -278,16 +281,16 @@ int32_t encrypt_data_symmetric(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], if (crypto_box_afternm(temp_encrypted, temp_plain, length + crypto_box_ZEROBYTES, nonce, shared_key) != 0) { - crypto_free(temp_plain, size_temp_plain); - crypto_free(temp_encrypted, size_temp_encrypted); + crypto_free(mem, temp_plain, size_temp_plain); + crypto_free(mem, temp_encrypted, size_temp_encrypted); return -1; } // Unpad the encrypted message. memcpy(encrypted, temp_encrypted + crypto_box_BOXZEROBYTES, length + crypto_box_MACBYTES); - crypto_free(temp_plain, size_temp_plain); - crypto_free(temp_encrypted, size_temp_encrypted); + crypto_free(mem, temp_plain, size_temp_plain); + crypto_free(mem, temp_encrypted, size_temp_encrypted); #endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ assert(length < INT32_MAX - crypto_box_MACBYTES); return (int32_t)(length + crypto_box_MACBYTES); @@ -295,7 +298,8 @@ int32_t encrypt_data_symmetric(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], int32_t decrypt_data_symmetric(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t nonce[CRYPTO_NONCE_SIZE], - const uint8_t *encrypted, size_t length, uint8_t *plain) + const uint8_t *encrypted, size_t length, uint8_t *plain, + const Memory *mem) { if (length <= crypto_box_BOXZEROBYTES || shared_key == nullptr || nonce == nullptr || encrypted == nullptr || plain == nullptr) { @@ -310,12 +314,12 @@ int32_t decrypt_data_symmetric(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const size_t size_temp_plain = length + crypto_box_ZEROBYTES; const size_t size_temp_encrypted = length + crypto_box_BOXZEROBYTES; - uint8_t *temp_plain = crypto_malloc(size_temp_plain); - uint8_t *temp_encrypted = crypto_malloc(size_temp_encrypted); + uint8_t *temp_plain = crypto_malloc(mem, size_temp_plain); + uint8_t *temp_encrypted = crypto_malloc(mem, size_temp_encrypted); if (temp_plain == nullptr || temp_encrypted == nullptr) { - crypto_free(temp_plain, size_temp_plain); - crypto_free(temp_encrypted, size_temp_encrypted); + crypto_free(mem, temp_plain, size_temp_plain); + crypto_free(mem, temp_encrypted, size_temp_encrypted); return -1; } @@ -330,15 +334,15 @@ int32_t decrypt_data_symmetric(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], if (crypto_box_open_afternm(temp_plain, temp_encrypted, length + crypto_box_BOXZEROBYTES, nonce, shared_key) != 0) { - crypto_free(temp_plain, size_temp_plain); - crypto_free(temp_encrypted, size_temp_encrypted); + crypto_free(mem, temp_plain, size_temp_plain); + crypto_free(mem, temp_encrypted, size_temp_encrypted); return -1; } memcpy(plain, temp_plain + crypto_box_ZEROBYTES, length - crypto_box_MACBYTES); - crypto_free(temp_plain, size_temp_plain); - crypto_free(temp_encrypted, size_temp_encrypted); + crypto_free(mem, temp_plain, size_temp_plain); + crypto_free(mem, temp_encrypted, size_temp_encrypted); #endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ assert(length > crypto_box_MACBYTES); assert(length < INT32_MAX); @@ -348,7 +352,8 @@ int32_t decrypt_data_symmetric(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], int32_t encrypt_data(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], const uint8_t secret_key[CRYPTO_SECRET_KEY_SIZE], const uint8_t nonce[CRYPTO_NONCE_SIZE], - const uint8_t *plain, size_t length, uint8_t *encrypted) + const uint8_t *plain, size_t length, uint8_t *encrypted, + const Memory *mem) { if (public_key == nullptr || secret_key == nullptr) { return -1; @@ -356,7 +361,7 @@ int32_t encrypt_data(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], uint8_t k[crypto_box_BEFORENMBYTES]; encrypt_precompute(public_key, secret_key, k); - const int ret = encrypt_data_symmetric(k, nonce, plain, length, encrypted); + const int ret = encrypt_data_symmetric(k, nonce, plain, length, encrypted, mem); crypto_memzero(k, sizeof(k)); return ret; } @@ -364,7 +369,8 @@ int32_t encrypt_data(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], int32_t decrypt_data(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], const uint8_t secret_key[CRYPTO_SECRET_KEY_SIZE], const uint8_t nonce[CRYPTO_NONCE_SIZE], - const uint8_t *encrypted, size_t length, uint8_t *plain) + const uint8_t *encrypted, size_t length, uint8_t *plain, + const Memory *mem) { if (public_key == nullptr || secret_key == nullptr) { return -1; @@ -372,7 +378,7 @@ int32_t decrypt_data(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], uint8_t k[crypto_box_BEFORENMBYTES]; encrypt_precompute(public_key, secret_key, k); - const int ret = decrypt_data_symmetric(k, nonce, encrypted, length, plain); + const int ret = decrypt_data_symmetric(k, nonce, encrypted, length, plain, mem); crypto_memzero(k, sizeof(k)); return ret; } @@ -490,41 +496,7 @@ void crypto_sha512(uint8_t hash[CRYPTO_SHA512_SIZE], const uint8_t *data, size_t #endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ } -non_null() -static void sys_random_bytes(void *obj, uint8_t *bytes, size_t length) -{ - randombytes(bytes, length); -} - -non_null() -static uint32_t sys_random_uniform(void *obj, uint32_t upper_bound) -{ - return randombytes_uniform(upper_bound); -} - -static const Random_Funcs os_random_funcs = { - sys_random_bytes, - sys_random_uniform, -}; - -static const Random os_random_obj = {&os_random_funcs}; - -const Random *os_random(void) -{ -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - if ((true)) { - return nullptr; - } -#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ - // It is safe to call this function more than once and from different - // threads -- subsequent calls won't have any effects. - if (sodium_init() == -1) { - return nullptr; - } - return &os_random_obj; -} - void random_bytes(const Random *rng, uint8_t *bytes, size_t length) { - rng->funcs->random_bytes(rng->obj, bytes, length); + tox_random_bytes(rng, bytes, length); } diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h index 979791bd97..88a89a975b 100644 --- a/toxcore/crypto_core.h +++ b/toxcore/crypto_core.h @@ -16,6 +16,8 @@ #include #include "attributes.h" +#include "mem.h" +#include "tox_random.h" #ifdef __cplusplus extern "C" { @@ -77,44 +79,6 @@ extern "C" { */ #define CRYPTO_SHA512_SIZE 64 -/** @brief Fill a byte array with random bytes. - * - * This is the key generator callback and as such must be a cryptographically - * secure pseudo-random number generator (CSPRNG). The security of Tox heavily - * depends on the security of this RNG. - */ -typedef void crypto_random_bytes_cb(void *obj, uint8_t *bytes, size_t length); - -/** @brief Generate a random integer between 0 and @p upper_bound. - * - * Should produce a uniform random distribution, but Tox security does not - * depend on this being correct. In principle, it could even be a non-CSPRNG. - */ -typedef uint32_t crypto_random_uniform_cb(void *obj, uint32_t upper_bound); - -/** @brief Virtual function table for Random. */ -typedef struct Random_Funcs { - crypto_random_bytes_cb *random_bytes; - crypto_random_uniform_cb *random_uniform; -} Random_Funcs; - -/** @brief Random number generator object. - * - * Can be used by test code and fuzzers to make toxcore behave in specific - * well-defined (non-random) ways. Production code ought to use libsodium's - * CSPRNG and use `os_random` below. - */ -typedef struct Random { - const Random_Funcs *funcs; - void *obj; -} Random; - -/** @brief System random number generator. - * - * Uses libsodium's CSPRNG (on Linux, `/dev/urandom`). - */ -const Random *os_random(void); - /** * @brief The number of bytes in an encryption public key used by DHT group chats. */ @@ -237,6 +201,11 @@ bool crypto_sha512_eq(const uint8_t cksum1[CRYPTO_SHA512_SIZE], const uint8_t ck non_null() bool crypto_sha256_eq(const uint8_t cksum1[CRYPTO_SHA256_SIZE], const uint8_t cksum2[CRYPTO_SHA256_SIZE]); +/** + * @brief Shorter internal name for the RNG type. + */ +typedef Tox_Random Random; + /** * @brief Return a random 8 bit integer. */ @@ -389,7 +358,8 @@ non_null() int32_t encrypt_data(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], const uint8_t secret_key[CRYPTO_SECRET_KEY_SIZE], const uint8_t nonce[CRYPTO_NONCE_SIZE], - const uint8_t *plain, size_t length, uint8_t *encrypted); + const uint8_t *plain, size_t length, uint8_t *encrypted, + const Memory *mem); /** * @brief Decrypt message from public key to secret key. @@ -406,7 +376,8 @@ non_null() int32_t decrypt_data(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], const uint8_t secret_key[CRYPTO_SECRET_KEY_SIZE], const uint8_t nonce[CRYPTO_NONCE_SIZE], - const uint8_t *encrypted, size_t length, uint8_t *plain); + const uint8_t *encrypted, size_t length, uint8_t *plain, + const Memory *mem); /** * @brief Fast encrypt/decrypt operations. @@ -433,7 +404,8 @@ int32_t encrypt_precompute(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], non_null() int32_t encrypt_data_symmetric(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t nonce[CRYPTO_NONCE_SIZE], - const uint8_t *plain, size_t length, uint8_t *encrypted); + const uint8_t *plain, size_t length, uint8_t *encrypted, + const Memory *mem); /** * @brief Decrypt message with precomputed shared key. @@ -448,7 +420,8 @@ int32_t encrypt_data_symmetric(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], non_null() int32_t decrypt_data_symmetric(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE], const uint8_t nonce[CRYPTO_NONCE_SIZE], - const uint8_t *encrypted, size_t length, uint8_t *plain); + const uint8_t *encrypted, size_t length, uint8_t *plain, + const Memory *mem); /** * @brief Increment the given nonce by 1 in big endian (rightmost byte incremented first). diff --git a/toxcore/crypto_core_test.cc b/toxcore/crypto_core_test.cc index d18ae2daab..0092f29a11 100644 --- a/toxcore/crypto_core_test.cc +++ b/toxcore/crypto_core_test.cc @@ -7,6 +7,8 @@ #include #include "crypto_core_test_util.hh" +#include "mem.h" +#include "os_memory.h" #include "util.h" namespace { @@ -20,6 +22,8 @@ using Nonce = std::array; TEST(CryptoCore, EncryptLargeData) { Test_Random rng; + const Memory *mem = os_memory(); + ASSERT_NE(mem, nullptr); Nonce nonce{}; PublicKey pk; @@ -30,7 +34,8 @@ TEST(CryptoCore, EncryptLargeData) std::vector plain(100 * 1024 * 1024); std::vector encrypted(plain.size() + CRYPTO_MAC_SIZE); - encrypt_data(pk.data(), sk.data(), nonce.data(), plain.data(), plain.size(), encrypted.data()); + encrypt_data( + pk.data(), sk.data(), nonce.data(), plain.data(), plain.size(), encrypted.data(), mem); } TEST(CryptoCore, IncrementNonce) diff --git a/toxcore/crypto_core_test_util.cc b/toxcore/crypto_core_test_util.cc index b48871a538..19d8ff9492 100644 --- a/toxcore/crypto_core_test_util.cc +++ b/toxcore/crypto_core_test_util.cc @@ -5,15 +5,16 @@ #include "crypto_core.h" #include "test_util.hh" +#include "tox_random_impl.h" -Random_Funcs const Random_Class::vtable = { - Method::invoke<&Random_Class::random_bytes>, - Method::invoke<&Random_Class::random_uniform>, +Tox_Random_Funcs const Random_Class::vtable = { + Method::invoke<&Random_Class::random_bytes>, + Method::invoke<&Random_Class::random_uniform>, }; Random_Class::~Random_Class() = default; -void Test_Random::random_bytes(void *obj, uint8_t *bytes, size_t length) +void Test_Random::random_bytes(void *obj, uint8_t *bytes, uint32_t length) { std::generate(bytes, &bytes[length], std::ref(lcg)); } diff --git a/toxcore/crypto_core_test_util.hh b/toxcore/crypto_core_test_util.hh index 91a9d68ee2..53b9b07d1b 100644 --- a/toxcore/crypto_core_test_util.hh +++ b/toxcore/crypto_core_test_util.hh @@ -8,12 +8,13 @@ #include "crypto_core.h" #include "test_util.hh" +#include "tox_random_impl.h" struct Random_Class { - static Random_Funcs const vtable; - Random const self; + static Tox_Random_Funcs const vtable; + Tox_Random const self; - operator Random const *() const { return &self; } + operator Tox_Random const *() const { return &self; } Random_Class(Random_Class const &) = default; Random_Class() @@ -22,8 +23,8 @@ struct Random_Class { } virtual ~Random_Class(); - virtual crypto_random_bytes_cb random_bytes = 0; - virtual crypto_random_uniform_cb random_uniform = 0; + virtual tox_random_bytes_cb random_bytes = 0; + virtual tox_random_uniform_cb random_uniform = 0; }; /** @@ -35,7 +36,7 @@ struct Random_Class { class Test_Random : public Random_Class { std::minstd_rand lcg; - void random_bytes(void *obj, uint8_t *bytes, size_t length) override; + void random_bytes(void *obj, uint8_t *bytes, uint32_t length) override; uint32_t random_uniform(void *obj, uint32_t upper_bound) override; }; @@ -83,6 +84,6 @@ inline bool operator==(PublicKey::Base const &pk1, PublicKey const &pk2) std::ostream &operator<<(std::ostream &out, PublicKey const &pk); -PublicKey random_pk(const Random *rng); +PublicKey random_pk(const Tox_Random *rng); #endif // C_TOXCORE_TOXCORE_CRYPTO_CORE_TEST_UTIL_H diff --git a/toxcore/events/dht_get_nodes_response.c b/toxcore/events/dht_get_nodes_response.c index f637b9c93a..079c441757 100644 --- a/toxcore/events/dht_get_nodes_response.c +++ b/toxcore/events/dht_get_nodes_response.c @@ -15,6 +15,7 @@ #include "../tox.h" #include "../tox_events.h" #include "../tox_private.h" +#include "../tox_system_impl.h" /***************************************************** * diff --git a/toxcore/events/friend_request.c b/toxcore/events/friend_request.c index 6cd8ac66c7..0916c14a23 100644 --- a/toxcore/events/friend_request.c +++ b/toxcore/events/friend_request.c @@ -15,6 +15,7 @@ #include "../tox.h" #include "../tox_events.h" #include "../tox_private.h" +#include "../tox_system_impl.h" /***************************************************** * diff --git a/toxcore/forwarding.c b/toxcore/forwarding.c index 18ff3203fc..270a012da0 100644 --- a/toxcore/forwarding.c +++ b/toxcore/forwarding.c @@ -5,7 +5,6 @@ #include "forwarding.h" #include -#include #include #include "DHT.h" @@ -13,12 +12,14 @@ #include "ccompat.h" #include "crypto_core.h" #include "logger.h" +#include "mem.h" #include "mono_time.h" #include "network.h" #include "timed_auth.h" struct Forwarding { const Logger *log; + const Memory *mem; const Random *rng; DHT *dht; const Mono_Time *mono_time; @@ -357,19 +358,20 @@ void set_callback_forward_reply(Forwarding *forwarding, forward_reply_cb *functi forwarding->forward_reply_callback_object = object; } -Forwarding *new_forwarding(const Logger *log, const Random *rng, const Mono_Time *mono_time, DHT *dht) +Forwarding *new_forwarding(const Logger *log, const Memory *mem, const Random *rng, const Mono_Time *mono_time, DHT *dht) { if (log == nullptr || mono_time == nullptr || dht == nullptr) { return nullptr; } - Forwarding *forwarding = (Forwarding *)calloc(1, sizeof(Forwarding)); + Forwarding *forwarding = (Forwarding *)mem_alloc(mem, sizeof(Forwarding)); if (forwarding == nullptr) { return nullptr; } forwarding->log = log; + forwarding->mem = mem; forwarding->rng = rng; forwarding->mono_time = mono_time; forwarding->dht = dht; @@ -396,5 +398,5 @@ void kill_forwarding(Forwarding *forwarding) crypto_memzero(forwarding->hmac_key, CRYPTO_HMAC_KEY_SIZE); - free(forwarding); + mem_delete(forwarding->mem, forwarding); } diff --git a/toxcore/forwarding.h b/toxcore/forwarding.h index bd0ef09e1c..6c3986cf4c 100644 --- a/toxcore/forwarding.h +++ b/toxcore/forwarding.h @@ -9,6 +9,7 @@ #include "attributes.h" #include "crypto_core.h" #include "logger.h" +#include "mem.h" #include "mono_time.h" #include "network.h" @@ -116,7 +117,7 @@ non_null(1) nullable(2, 3) void set_callback_forward_reply(Forwarding *forwarding, forward_reply_cb *function, void *object); non_null() -Forwarding *new_forwarding(const Logger *log, const Random *rng, const Mono_Time *mono_time, DHT *dht); +Forwarding *new_forwarding(const Logger *log, const Memory *mem, const Random *rng, const Mono_Time *mono_time, DHT *dht); nullable(1) void kill_forwarding(Forwarding *forwarding); diff --git a/toxcore/forwarding_fuzz_test.cc b/toxcore/forwarding_fuzz_test.cc index 4b8521ab07..77bbea853f 100644 --- a/toxcore/forwarding_fuzz_test.cc +++ b/toxcore/forwarding_fuzz_test.cc @@ -7,6 +7,8 @@ #include "../testing/fuzzing/fuzz_support.hh" #include "../testing/fuzzing/fuzz_tox.hh" +#include "os_memory.h" +#include "os_network.h" namespace { diff --git a/toxcore/friend_connection.c b/toxcore/friend_connection.c index f017b08888..32d32449a6 100644 --- a/toxcore/friend_connection.c +++ b/toxcore/friend_connection.c @@ -18,6 +18,7 @@ #include "ccompat.h" #include "crypto_core.h" #include "logger.h" +#include "mem.h" #include "mono_time.h" #include "net_crypto.h" #include "network.h" @@ -70,6 +71,7 @@ static const Friend_Conn empty_friend_conn = {0}; struct Friend_Connections { const Mono_Time *mono_time; const Logger *logger; + const Memory *mem; Net_Crypto *net_crypto; DHT *dht; Broadcast_Info *broadcast; @@ -119,19 +121,19 @@ static bool friendconn_id_valid(const Friend_Connections *fr_c, int friendcon_id /** @brief Set the size of the friend connections list to num. * - * @retval false if realloc fails. + * @retval false if mem_vrealloc fails. * @retval true if it succeeds. */ non_null() static bool realloc_friendconns(Friend_Connections *fr_c, uint32_t num) { if (num == 0) { - free(fr_c->conns); + mem_delete(fr_c->mem, fr_c->conns); fr_c->conns = nullptr; return true; } - Friend_Conn *newgroup_cons = (Friend_Conn *)realloc(fr_c->conns, num * sizeof(Friend_Conn)); + Friend_Conn *newgroup_cons = (Friend_Conn *)mem_vrealloc(fr_c->mem, fr_c->conns, num, sizeof(Friend_Conn)); if (newgroup_cons == nullptr) { return false; @@ -908,14 +910,14 @@ int send_friend_request_packet(Friend_Connections *fr_c, int friendcon_id, uint3 /** Create new friend_connections instance. */ Friend_Connections *new_friend_connections( - const Logger *logger, const Mono_Time *mono_time, const Network *ns, + const Logger *logger, const Mono_Time *mono_time, const Memory *mem, const Network *ns, Onion_Client *onion_c, bool local_discovery_enabled) { if (onion_c == nullptr) { return nullptr; } - Friend_Connections *const temp = (Friend_Connections *)calloc(1, sizeof(Friend_Connections)); + Friend_Connections *const temp = (Friend_Connections *)mem_alloc(mem, sizeof(Friend_Connections)); if (temp == nullptr) { return nullptr; @@ -924,7 +926,7 @@ Friend_Connections *new_friend_connections( temp->local_discovery_enabled = local_discovery_enabled; if (temp->local_discovery_enabled) { - temp->broadcast = lan_discovery_init(ns); + temp->broadcast = lan_discovery_init(mem, ns); if (temp->broadcast == nullptr) { LOGGER_ERROR(logger, "could not initialise LAN discovery"); @@ -934,6 +936,7 @@ Friend_Connections *new_friend_connections( temp->mono_time = mono_time; temp->logger = logger; + temp->mem = mem; temp->dht = onion_get_dht(onion_c); temp->net_crypto = onion_get_net_crypto(onion_c); temp->onion_c = onion_c; @@ -1038,5 +1041,5 @@ void kill_friend_connections(Friend_Connections *fr_c) } lan_discovery_kill(fr_c->broadcast); - free(fr_c); + mem_delete(fr_c->mem, fr_c); } diff --git a/toxcore/friend_connection.h b/toxcore/friend_connection.h index bbd4454729..e14c6404f6 100644 --- a/toxcore/friend_connection.h +++ b/toxcore/friend_connection.h @@ -15,6 +15,7 @@ #include "LAN_discovery.h" #include "attributes.h" #include "logger.h" +#include "mem.h" #include "mono_time.h" #include "net_crypto.h" #include "network.h" @@ -161,7 +162,7 @@ void set_friend_request_callback(Friend_Connections *fr_c, fr_request_cb *fr_req /** Create new friend_connections instance. */ non_null() Friend_Connections *new_friend_connections( - const Logger *logger, const Mono_Time *mono_time, const Network *ns, + const Logger *logger, const Mono_Time *mono_time, const Memory *mem, const Network *ns, Onion_Client *onion_c, bool local_discovery_enabled); /** main friend_connections loop. */ diff --git a/toxcore/friend_requests.c b/toxcore/friend_requests.c index 8b915449cd..c0911af0a8 100644 --- a/toxcore/friend_requests.c +++ b/toxcore/friend_requests.c @@ -8,13 +8,13 @@ */ #include "friend_requests.h" -#include #include #include "attributes.h" #include "ccompat.h" #include "crypto_core.h" #include "friend_connection.h" +#include "mem.h" #include "network.h" #include "onion.h" #include "onion_announce.h" @@ -32,6 +32,8 @@ struct Received_Requests { }; struct Friend_Requests { + const Memory *mem; + uint32_t nospam; fr_friend_request_cb *handle_friendrequest; uint8_t handle_friendrequest_isset; @@ -164,12 +166,20 @@ void friendreq_init(Friend_Requests *fr, Friend_Connections *fr_c) set_friend_request_callback(fr_c, &friendreq_handlepacket, fr); } -Friend_Requests *friendreq_new(void) +Friend_Requests *friendreq_new(const Memory *mem) { - return (Friend_Requests *)calloc(1, sizeof(Friend_Requests)); + Friend_Requests *fr = (Friend_Requests *)mem_alloc(mem, sizeof(Friend_Requests)); + + if (fr == nullptr) { + return nullptr; + } + + fr->mem = mem; + + return fr; } void friendreq_kill(Friend_Requests *fr) { - free(fr); + mem_delete(fr->mem, fr); } diff --git a/toxcore/friend_requests.h b/toxcore/friend_requests.h index a78a570dfa..0258665197 100644 --- a/toxcore/friend_requests.h +++ b/toxcore/friend_requests.h @@ -13,6 +13,7 @@ #include "attributes.h" #include "friend_connection.h" +#include "mem.h" #define MAX_FRIEND_REQUEST_DATA_SIZE (ONION_CLIENT_MAX_DATA_SIZE - (1 + sizeof(uint32_t))) @@ -49,7 +50,8 @@ void set_filter_function(Friend_Requests *fr, filter_function_cb *function, void non_null() void friendreq_init(Friend_Requests *fr, Friend_Connections *fr_c); -Friend_Requests *friendreq_new(void); +non_null() +Friend_Requests *friendreq_new(const Memory *mem); nullable(1) void friendreq_kill(Friend_Requests *fr); diff --git a/toxcore/group.c b/toxcore/group.c index 3d96b962de..d03ccc6318 100644 --- a/toxcore/group.c +++ b/toxcore/group.c @@ -20,6 +20,7 @@ #include "friend_connection.h" #include "group_common.h" #include "logger.h" +#include "mem.h" #include "mono_time.h" #include "net_crypto.h" #include "network.h" @@ -147,6 +148,7 @@ typedef struct Group_c { } Group_c; struct Group_Chats { + const Memory *mem; const Mono_Time *mono_time; Messenger *m; @@ -246,19 +248,19 @@ static bool is_groupnumber_valid(const Group_Chats *g_c, uint32_t groupnumber) /** @brief Set the size of the groupchat list to num. * - * @retval false if realloc fails. + * @retval false if mem_vrealloc fails. * @retval true if it succeeds. */ non_null() static bool realloc_conferences(Group_Chats *g_c, uint16_t num) { if (num == 0) { - free(g_c->chats); + mem_delete(g_c->mem, g_c->chats); g_c->chats = nullptr; return true; } - Group_c *newgroup_chats = (Group_c *)realloc(g_c->chats, num * sizeof(Group_c)); + Group_c *newgroup_chats = (Group_c *)mem_vrealloc(g_c->mem, g_c->chats, num, sizeof(Group_c)); if (newgroup_chats == nullptr) { return false; @@ -300,10 +302,10 @@ static int32_t create_group_chat(Group_Chats *g_c) } non_null() -static void wipe_group_c(Group_c *g) +static void wipe_group_c(Group_c *g, const Memory *mem) { - free(g->frozen); - free(g->group); + mem_delete(mem, g->frozen); + mem_delete(mem, g->group); crypto_memzero(g, sizeof(Group_c)); } @@ -318,7 +320,7 @@ static bool wipe_group_chat(Group_Chats *g_c, uint32_t groupnumber) return false; } - wipe_group_c(&g_c->chats[groupnumber]); + wipe_group_c(&g_c->chats[groupnumber], g_c->mem); uint16_t i; @@ -667,7 +669,7 @@ static int get_frozen_index(const Group_c *g, uint16_t peer_number) } non_null() -static bool delete_frozen(Group_c *g, uint32_t frozen_index) +static bool delete_frozen(Group_c *g, uint32_t frozen_index, const Memory *mem) { if (frozen_index >= g->numfrozen) { return false; @@ -676,14 +678,14 @@ static bool delete_frozen(Group_c *g, uint32_t frozen_index) --g->numfrozen; if (g->numfrozen == 0) { - free(g->frozen); + mem_delete(mem, g->frozen); g->frozen = nullptr; } else { if (g->numfrozen != frozen_index) { g->frozen[frozen_index] = g->frozen[g->numfrozen]; } - Group_Peer *const frozen_temp = (Group_Peer *)realloc(g->frozen, g->numfrozen * sizeof(Group_Peer)); + Group_Peer *const frozen_temp = (Group_Peer *)mem_vrealloc(mem, g->frozen, g->numfrozen, sizeof(Group_Peer)); if (frozen_temp == nullptr) { return false; @@ -700,8 +702,8 @@ static bool delete_frozen(Group_c *g, uint32_t frozen_index) * @return peer index if peer is in the conference. * @retval -1 otherwise, and on error. */ -non_null(1) nullable(4) -static int note_peer_active(Group_Chats *g_c, uint32_t groupnumber, uint16_t peer_number, void *userdata) +non_null(1, 5) nullable(4) +static int note_peer_active(Group_Chats *g_c, uint32_t groupnumber, uint16_t peer_number, void *userdata, const Memory *mem) { Group_c *g = get_group_c(g_c, groupnumber); @@ -724,7 +726,7 @@ static int note_peer_active(Group_Chats *g_c, uint32_t groupnumber, uint16_t pee /* Now thaw the peer */ - Group_Peer *temp = (Group_Peer *)realloc(g->group, (g->numpeers + 1) * sizeof(Group_Peer)); + Group_Peer *temp = (Group_Peer *)mem_vrealloc(mem, g->group, g->numpeers + 1, sizeof(Group_Peer)); if (temp == nullptr) { return -1; @@ -741,7 +743,7 @@ static int note_peer_active(Group_Chats *g_c, uint32_t groupnumber, uint16_t pee ++g->numpeers; - delete_frozen(g, frozen_index); + delete_frozen(g, frozen_index, g_c->mem); if (g_c->peer_list_changed_callback != nullptr) { g_c->peer_list_changed_callback(g_c->m, groupnumber, userdata); @@ -777,7 +779,7 @@ static void delete_any_peer_with_pk(Group_Chats *g_c, uint32_t groupnumber, cons const int frozen_index = frozen_in_group(g, real_pk); if (frozen_index >= 0) { - delete_frozen(g, frozen_index); + delete_frozen(g, frozen_index, g_c->mem); } } @@ -804,7 +806,7 @@ static int addpeer(Group_Chats *g_c, uint32_t groupnumber, const uint8_t *real_p } const int peer_index = fresh ? - note_peer_active(g_c, groupnumber, peer_number, userdata) : + note_peer_active(g_c, groupnumber, peer_number, userdata, g_c->mem) : get_peer_index(g, peer_number); if (peer_index != -1) { @@ -837,7 +839,7 @@ static int addpeer(Group_Chats *g_c, uint32_t groupnumber, const uint8_t *real_p delete_any_peer_with_pk(g_c, groupnumber, real_pk, userdata); - Group_Peer *temp = (Group_Peer *)realloc(g->group, (g->numpeers + 1) * sizeof(Group_Peer)); + Group_Peer *temp = (Group_Peer *)mem_vrealloc(g_c->mem, g->group, g->numpeers + 1, sizeof(Group_Peer)); if (temp == nullptr) { return -1; @@ -928,14 +930,14 @@ static bool delpeer(Group_Chats *g_c, uint32_t groupnumber, int peer_index, void void *peer_object = g->group[peer_index].object; if (g->numpeers == 0) { - free(g->group); + mem_delete(g_c->mem, g->group); g->group = nullptr; } else { if (g->numpeers != (uint32_t)peer_index) { g->group[peer_index] = g->group[g->numpeers]; } - Group_Peer *temp = (Group_Peer *)realloc(g->group, g->numpeers * sizeof(Group_Peer)); + Group_Peer *temp = (Group_Peer *)mem_vrealloc(g_c->mem, g->group, g->numpeers, sizeof(Group_Peer)); if (temp == nullptr) { return false; @@ -974,14 +976,14 @@ static int cmp_frozen(const void *a, const void *b) * @retval true if any frozen peers are removed. */ non_null() -static bool delete_old_frozen(Group_c *g) +static bool delete_old_frozen(Group_c *g, const Memory *mem) { if (g->numfrozen <= g->maxfrozen) { return false; } if (g->maxfrozen == 0) { - free(g->frozen); + mem_delete(mem, g->frozen); g->frozen = nullptr; g->numfrozen = 0; return true; @@ -989,7 +991,7 @@ static bool delete_old_frozen(Group_c *g) qsort(g->frozen, g->numfrozen, sizeof(Group_Peer), cmp_frozen); - Group_Peer *temp = (Group_Peer *)realloc(g->frozen, g->maxfrozen * sizeof(Group_Peer)); + Group_Peer *temp = (Group_Peer *)mem_vrealloc(mem, g->frozen, g->maxfrozen, sizeof(Group_Peer)); if (temp == nullptr) { return false; @@ -1014,7 +1016,7 @@ static bool freeze_peer(Group_Chats *g_c, uint32_t groupnumber, int peer_index, return false; } - Group_Peer *temp = (Group_Peer *)realloc(g->frozen, (g->numfrozen + 1) * sizeof(Group_Peer)); + Group_Peer *temp = (Group_Peer *)mem_vrealloc(g_c->mem, g->frozen, g->numfrozen + 1, sizeof(Group_Peer)); if (temp == nullptr) { return false; @@ -1032,7 +1034,7 @@ static bool freeze_peer(Group_Chats *g_c, uint32_t groupnumber, int peer_index, ++g->numfrozen; - delete_old_frozen(g); + delete_old_frozen(g, g_c->mem); return true; } @@ -1519,7 +1521,7 @@ int group_set_max_frozen(const Group_Chats *g_c, uint32_t groupnumber, uint32_t } g->maxfrozen = maxfrozen; - delete_old_frozen(g); + delete_old_frozen(g, g_c->mem); return 0; } @@ -2859,7 +2861,7 @@ static void handle_message_packet_group(Group_Chats *g_c, uint32_t groupnumber, const bool ignore_frozen = message_id == GROUP_MESSAGE_FREEZE_PEER_ID; const int index = ignore_frozen ? get_peer_index(g, peer_number) - : note_peer_active(g_c, groupnumber, peer_number, userdata); + : note_peer_active(g_c, groupnumber, peer_number, userdata, g_c->mem); if (index == -1) { if (ignore_frozen) { @@ -3612,7 +3614,7 @@ static uint32_t load_group(Group_c *g, const Group_Chats *g_c, const uint8_t *da } // This is inefficient, but allows us to check data consistency before allocating memory - Group_Peer *tmp_frozen = (Group_Peer *)realloc(g->frozen, (j + 1) * sizeof(Group_Peer)); + Group_Peer *tmp_frozen = (Group_Peer *)mem_vrealloc(g_c->mem, g->frozen, j + 1, sizeof(Group_Peer)); if (tmp_frozen == nullptr) { // Memory allocation failure @@ -3752,18 +3754,19 @@ bool conferences_load_state_section(Group_Chats *g_c, const uint8_t *data, uint3 } /** Create new groupchat instance. */ -Group_Chats *new_groupchats(const Mono_Time *mono_time, Messenger *m) +Group_Chats *new_groupchats(const Mono_Time *mono_time, const Memory *mem, Messenger *m) { if (m == nullptr) { return nullptr; } - Group_Chats *temp = (Group_Chats *)calloc(1, sizeof(Group_Chats)); + Group_Chats *temp = (Group_Chats *)mem_alloc(mem, sizeof(Group_Chats)); if (temp == nullptr) { return nullptr; } + temp->mem = mem; temp->mono_time = mono_time; temp->m = m; temp->fr_c = m->fr_c; @@ -3814,7 +3817,7 @@ void kill_groupchats(Group_Chats *g_c) m_callback_conference_invite(g_c->m, nullptr); set_global_status_callback(g_c->m->fr_c, nullptr, nullptr); g_c->m->conferences_object = nullptr; - free(g_c); + mem_delete(g_c->mem, g_c); } /** diff --git a/toxcore/group.h b/toxcore/group.h index 5ce03275ec..5482943d25 100644 --- a/toxcore/group.h +++ b/toxcore/group.h @@ -13,10 +13,11 @@ #include #include "Messenger.h" -#include "attributes.h" #include "crypto_core.h" +#include "mem.h" #include "mono_time.h" #include "state.h" +#include "attributes.h" typedef enum Groupchat_Type { GROUPCHAT_TYPE_TEXT, @@ -390,7 +391,7 @@ bool conferences_load_state_section( /** Create new groupchat instance. */ non_null() -Group_Chats *new_groupchats(const Mono_Time *mono_time, Messenger *m); +Group_Chats *new_groupchats(const Mono_Time *mono_time, const Memory *mem, Messenger *m); /** main groupchats loop. */ non_null(1) nullable(2) diff --git a/toxcore/group_announce.c b/toxcore/group_announce.c index ee083198c1..24acd2d1cb 100644 --- a/toxcore/group_announce.c +++ b/toxcore/group_announce.c @@ -5,7 +5,6 @@ #include "group_announce.h" -#include #include #include "DHT.h" @@ -13,14 +12,15 @@ #include "ccompat.h" #include "crypto_core.h" #include "logger.h" +#include "mem.h" #include "mono_time.h" #include "network.h" /** * Removes `announces` from `gc_announces_list`. */ -non_null() -static void remove_announces(GC_Announces_List *gc_announces_list, GC_Announces *announces) +non_null() static void remove_announces( + GC_Announces_List *gc_announces_list, GC_Announces *announces) { if (announces == nullptr || gc_announces_list == nullptr) { return; @@ -36,15 +36,15 @@ static void remove_announces(GC_Announces_List *gc_announces_list, GC_Announces announces->next_announce->prev_announce = announces->prev_announce; } - free(announces); + mem_delete(gc_announces_list->mem, announces); } /** * Returns the announce designated by `chat_id`. * Returns null if no announce is found. */ -non_null() -static GC_Announces *get_announces_by_chat_id(const GC_Announces_List *gc_announces_list, const uint8_t *chat_id) +non_null() static GC_Announces *get_announces_by_chat_id( + const GC_Announces_List *gc_announces_list, const uint8_t *chat_id) { GC_Announces *announces = gc_announces_list->root_announces; @@ -59,11 +59,11 @@ static GC_Announces *get_announces_by_chat_id(const GC_Announces_List *gc_announ return nullptr; } -int gca_get_announces(const GC_Announces_List *gc_announces_list, GC_Announce *gc_announces, uint8_t max_nodes, - const uint8_t *chat_id, const uint8_t *except_public_key) +int gca_get_announces(const GC_Announces_List *gc_announces_list, GC_Announce *gc_announces, + uint8_t max_nodes, const uint8_t *chat_id, const uint8_t *except_public_key) { - if (gc_announces == nullptr || gc_announces_list == nullptr || chat_id == nullptr || max_nodes == 0 - || except_public_key == nullptr) { + if (gc_announces == nullptr || gc_announces_list == nullptr || chat_id == nullptr + || max_nodes == 0 || except_public_key == nullptr) { return -1; } @@ -75,7 +75,9 @@ int gca_get_announces(const GC_Announces_List *gc_announces_list, GC_Announce *g uint16_t added_count = 0; - for (size_t i = 0; i < announces->index && i < GCA_MAX_SAVED_ANNOUNCES_PER_GC && added_count < max_nodes; ++i) { + for (size_t i = 0; + i < announces->index && i < GCA_MAX_SAVED_ANNOUNCES_PER_GC && added_count < max_nodes; + ++i) { const size_t index = i % GCA_MAX_SAVED_ANNOUNCES_PER_GC; if (memcmp(except_public_key, announces->peer_announces[index].base_announce.peer_public_key, @@ -107,7 +109,8 @@ uint16_t gca_pack_announces_list_size(uint16_t count) return count * GCA_ANNOUNCE_MAX_SIZE; } -int gca_pack_announce(const Logger *log, uint8_t *data, uint16_t length, const GC_Announce *announce) +int gca_pack_announce( + const Logger *log, uint8_t *data, uint16_t length, const GC_Announce *announce) { if (length < GCA_ANNOUNCE_MAX_SIZE) { LOGGER_ERROR(log, "Invalid announce length: %u", length); @@ -140,7 +143,8 @@ int gca_pack_announce(const Logger *log, uint8_t *data, uint16_t length, const G } if (announce->ip_port_is_set) { - const int ip_port_length = pack_ip_port(log, data + offset, length - offset, &announce->ip_port); + const int ip_port_length + = pack_ip_port(log, data + offset, length - offset, &announce->ip_port); if (ip_port_length == -1) { LOGGER_ERROR(log, "Failed to pack ip_port"); @@ -150,8 +154,8 @@ int gca_pack_announce(const Logger *log, uint8_t *data, uint16_t length, const G offset += ip_port_length; } - const int nodes_length = pack_nodes(log, data + offset, length - offset, announce->tcp_relays, - announce->tcp_relays_count); + const int nodes_length = pack_nodes( + log, data + offset, length - offset, announce->tcp_relays, announce->tcp_relays_count); if (nodes_length == -1) { LOGGER_ERROR(log, "Failed to pack TCP nodes"); @@ -167,8 +171,8 @@ int gca_pack_announce(const Logger *log, uint8_t *data, uint16_t length, const G * Returns the size of the unpacked data on success. * Returns -1 on failure. */ -non_null() -static int gca_unpack_announce(const Logger *log, const uint8_t *data, uint16_t length, GC_Announce *announce) +non_null() static int gca_unpack_announce( + const Logger *log, const uint8_t *data, uint16_t length, GC_Announce *announce) { if (length < ENC_PUBLIC_KEY_SIZE + 2) { LOGGER_ERROR(log, "Invalid announce length: %u", length); @@ -204,7 +208,8 @@ static int gca_unpack_announce(const Logger *log, const uint8_t *data, uint16_t return -1; } - const int ip_port_length = unpack_ip_port(&announce->ip_port, data + offset, length - offset, false); + const int ip_port_length + = unpack_ip_port(&announce->ip_port, data + offset, length - offset, false); if (ip_port_length == -1) { LOGGER_ERROR(log, "Failed to unpack ip_port"); @@ -215,8 +220,8 @@ static int gca_unpack_announce(const Logger *log, const uint8_t *data, uint16_t } uint16_t nodes_length; - const int nodes_count = unpack_nodes(announce->tcp_relays, announce->tcp_relays_count, &nodes_length, - data + offset, length - offset, true); + const int nodes_count = unpack_nodes(announce->tcp_relays, announce->tcp_relays_count, + &nodes_length, data + offset, length - offset, true); if (nodes_count != announce->tcp_relays_count) { LOGGER_ERROR(log, "Failed to unpack TCP nodes"); @@ -226,8 +231,8 @@ static int gca_unpack_announce(const Logger *log, const uint8_t *data, uint16_t return offset + nodes_length; } -int gca_pack_public_announce(const Logger *log, uint8_t *data, uint16_t length, - const GC_Public_Announce *public_announce) +int gca_pack_public_announce( + const Logger *log, uint8_t *data, uint16_t length, const GC_Public_Announce *public_announce) { if (public_announce == nullptr || data == nullptr || length < CHAT_ID_SIZE) { return -1; @@ -235,8 +240,8 @@ int gca_pack_public_announce(const Logger *log, uint8_t *data, uint16_t length, memcpy(data, public_announce->chat_public_key, CHAT_ID_SIZE); - const int packed_size = gca_pack_announce(log, data + CHAT_ID_SIZE, length - CHAT_ID_SIZE, - &public_announce->base_announce); + const int packed_size = gca_pack_announce( + log, data + CHAT_ID_SIZE, length - CHAT_ID_SIZE, &public_announce->base_announce); if (packed_size < 0) { LOGGER_ERROR(log, "Failed to pack public group announce"); @@ -246,8 +251,8 @@ int gca_pack_public_announce(const Logger *log, uint8_t *data, uint16_t length, return packed_size + CHAT_ID_SIZE; } -int gca_unpack_public_announce(const Logger *log, const uint8_t *data, uint16_t length, - GC_Public_Announce *public_announce) +int gca_unpack_public_announce( + const Logger *log, const uint8_t *data, uint16_t length, GC_Public_Announce *public_announce) { if (length < CHAT_ID_SIZE) { LOGGER_ERROR(log, "invalid public announce length: %u", length); @@ -266,8 +271,8 @@ int gca_unpack_public_announce(const Logger *log, const uint8_t *data, uint16_t memcpy(public_announce->chat_public_key, data, CHAT_ID_SIZE); - const int base_announce_size = gca_unpack_announce(log, data + ENC_PUBLIC_KEY_SIZE, length - ENC_PUBLIC_KEY_SIZE, - &public_announce->base_announce); + const int base_announce_size = gca_unpack_announce(log, data + ENC_PUBLIC_KEY_SIZE, + length - ENC_PUBLIC_KEY_SIZE, &public_announce->base_announce); if (base_announce_size == -1) { LOGGER_ERROR(log, "Failed to unpack group announce"); @@ -277,8 +282,8 @@ int gca_unpack_public_announce(const Logger *log, const uint8_t *data, uint16_t return base_announce_size + CHAT_ID_SIZE; } -int gca_pack_announces_list(const Logger *log, uint8_t *data, uint16_t length, const GC_Announce *announces, - uint8_t announces_count, size_t *processed) +int gca_pack_announces_list(const Logger *log, uint8_t *data, uint16_t length, + const GC_Announce *announces, uint8_t announces_count, size_t *processed) { if (data == nullptr) { LOGGER_ERROR(log, "data is null"); @@ -293,7 +298,8 @@ int gca_pack_announces_list(const Logger *log, uint8_t *data, uint16_t length, c uint16_t offset = 0; for (size_t i = 0; i < announces_count; ++i) { - const int packed_length = gca_pack_announce(log, data + offset, length - offset, &announces[i]); + const int packed_length + = gca_pack_announce(log, data + offset, length - offset, &announces[i]); if (packed_length < 0) { LOGGER_ERROR(log, "Failed to pack group announce"); @@ -310,8 +316,8 @@ int gca_pack_announces_list(const Logger *log, uint8_t *data, uint16_t length, c return announces_count; } -int gca_unpack_announces_list(const Logger *log, const uint8_t *data, uint16_t length, GC_Announce *announces, - uint8_t max_count) +int gca_unpack_announces_list(const Logger *log, const uint8_t *data, uint16_t length, + GC_Announce *announces, uint8_t max_count) { if (data == nullptr) { LOGGER_ERROR(log, "data is null"); @@ -327,7 +333,8 @@ int gca_unpack_announces_list(const Logger *log, const uint8_t *data, uint16_t l int announces_count = 0; for (size_t i = 0; i < max_count && length > offset; ++i) { - const int unpacked_length = gca_unpack_announce(log, data + offset, length - offset, &announces[i]); + const int unpacked_length + = gca_unpack_announce(log, data + offset, length - offset, &announces[i]); if (unpacked_length == -1) { LOGGER_WARNING(log, "Failed to unpack group announce: %d %d", length, offset); @@ -346,7 +353,7 @@ static GC_Announces *gca_new_announces( GC_Announces_List *gc_announces_list, const GC_Public_Announce *public_announce) { - GC_Announces *announces = (GC_Announces *)calloc(1, sizeof(GC_Announces)); + GC_Announces *announces = (GC_Announces *)mem_alloc(gc_announces_list->mem, sizeof(GC_Announces)); if (announces == nullptr) { return nullptr; @@ -373,7 +380,8 @@ GC_Peer_Announce *gca_add_announce(const Mono_Time *mono_time, GC_Announces_List return nullptr; } - GC_Announces *announces = get_announces_by_chat_id(gc_announces_list, public_announce->chat_public_key); + GC_Announces *announces + = get_announces_by_chat_id(gc_announces_list, public_announce->chat_public_key); // No entry for this chat_id exists so we create one if (announces == nullptr) { @@ -410,9 +418,18 @@ bool gca_is_valid_announce(const GC_Announce *announce) return announce->tcp_relays_count > 0 || announce->ip_port_is_set; } -GC_Announces_List *new_gca_list(void) +GC_Announces_List *new_gca_list(const Memory *mem) { - return (GC_Announces_List *)calloc(1, sizeof(GC_Announces_List)); + GC_Announces_List *announces_list + = (GC_Announces_List *)mem_alloc(mem, sizeof(GC_Announces_List)); + + if (announces_list == nullptr) { + return nullptr; + } + + announces_list->mem = mem; + + return announces_list; } void kill_gca(GC_Announces_List *announces_list) @@ -425,11 +442,11 @@ void kill_gca(GC_Announces_List *announces_list) while (root != nullptr) { GC_Announces *next = root->next_announce; - free(root); + mem_delete(announces_list->mem, root); root = next; } - free(announces_list); + mem_delete(announces_list->mem, announces_list); } /* How long we save a peer's announce before we consider it stale and remove it. */ @@ -444,7 +461,8 @@ void do_gca(const Mono_Time *mono_time, GC_Announces_List *gc_announces_list) return; } - if (!mono_time_is_timeout(mono_time, gc_announces_list->last_timeout_check, GCA_DO_GCA_TIMEOUT)) { + if (!mono_time_is_timeout( + mono_time, gc_announces_list->last_timeout_check, GCA_DO_GCA_TIMEOUT)) { return; } @@ -453,7 +471,8 @@ void do_gca(const Mono_Time *mono_time, GC_Announces_List *gc_announces_list) GC_Announces *announces = gc_announces_list->root_announces; while (announces != nullptr) { - if (mono_time_is_timeout(mono_time, announces->last_announce_received_timestamp, GCA_ANNOUNCE_SAVE_TIMEOUT)) { + if (mono_time_is_timeout(mono_time, announces->last_announce_received_timestamp, + GCA_ANNOUNCE_SAVE_TIMEOUT)) { GC_Announces *to_delete = announces; announces = announces->next_announce; remove_announces(gc_announces_list, to_delete); diff --git a/toxcore/group_announce.h b/toxcore/group_announce.h index 72f2cfc1b8..c2d92e3542 100644 --- a/toxcore/group_announce.h +++ b/toxcore/group_announce.h @@ -16,6 +16,7 @@ #include "attributes.h" #include "crypto_core.h" #include "logger.h" +#include "mem.h" #include "mono_time.h" #include "network.h" @@ -79,6 +80,8 @@ struct GC_Announces { /* A list of all announces. */ struct GC_Announces_List { + const Memory *mem; + GC_Announces *root_announces; uint64_t last_timeout_check; }; @@ -87,7 +90,8 @@ struct GC_Announces_List { * * The caller is responsible for freeing the memory with `kill_gca`. */ -GC_Announces_List *new_gca_list(void); +non_null() +GC_Announces_List *new_gca_list(const Memory *mem); /** @brief Frees all dynamically allocated memory associated with `announces_list`. */ nullable(1) diff --git a/toxcore/group_announce_fuzz_test.cc b/toxcore/group_announce_fuzz_test.cc index 9f5655ac15..38d3847ba3 100644 --- a/toxcore/group_announce_fuzz_test.cc +++ b/toxcore/group_announce_fuzz_test.cc @@ -7,6 +7,7 @@ #include "../testing/fuzzing/fuzz_support.hh" #include "mem_test_util.hh" +#include "tox_time_impl.h" namespace { @@ -53,14 +54,18 @@ void TestDoGca(Fuzz_Data &input) { Test_Memory mem; std::unique_ptr logger(logger_new(mem), logger_kill); + constexpr Tox_Time_Funcs mock_time_funcs = { + [](void *user_data) { return *static_cast(user_data); }, + }; uint64_t clock = 1; + std::unique_ptr tm( + tox_time_new(&mock_time_funcs, &clock, mem), tox_time_free); std::unique_ptr> mono_time( - mono_time_new( - mem, [](void *user_data) { return *static_cast(user_data); }, &clock), - [mem](Mono_Time *ptr) { mono_time_free(mem, ptr); }); + mono_time_new(mem, tm.get()), [mem](Mono_Time *ptr) { mono_time_free(mem, ptr); }); assert(mono_time != nullptr); - std::unique_ptr gca(new_gca_list(), kill_gca); + std::unique_ptr gca( + new_gca_list(mem), kill_gca); assert(gca != nullptr); while (!input.empty()) { diff --git a/toxcore/group_announce_test.cc b/toxcore/group_announce_test.cc index f1027f3437..39dbc7915c 100644 --- a/toxcore/group_announce_test.cc +++ b/toxcore/group_announce_test.cc @@ -5,15 +5,22 @@ #include "DHT.h" #include "crypto_core.h" #include "logger.h" +#include "mem.h" #include "mem_test_util.hh" #include "mono_time.h" #include "network.h" +#include "os_memory.h" +#include "tox_time_impl.h" namespace { struct Announces : ::testing::Test { protected: Test_Memory mem_; + static constexpr Tox_Time_Funcs mock_time_funcs = { + [](void *user_data) { return *static_cast(user_data); }, + }; + Tox_Time *tm_; uint64_t clock_ = 1000; Mono_Time *mono_time_ = nullptr; GC_Announces_List *gca_ = nullptr; @@ -22,12 +29,12 @@ struct Announces : ::testing::Test { void SetUp() override { - mono_time_ = mono_time_new(mem_, nullptr, nullptr); + ASSERT_NE(mem_, nullptr); + tm_ = tox_time_new(&mock_time_funcs, &this->clock_, mem_); + ASSERT_NE(tm_, nullptr); + mono_time_ = mono_time_new(mem_, tm_); ASSERT_NE(mono_time_, nullptr); - mono_time_set_current_time_callback( - mono_time_, [](void *user_data) { return *static_cast(user_data); }, - &clock_); - gca_ = new_gca_list(); + gca_ = new_gca_list(mem_); ASSERT_NE(gca_, nullptr); } @@ -35,6 +42,7 @@ struct Announces : ::testing::Test { { kill_gca(gca_); mono_time_free(mem_, mono_time_); + tox_time_free(tm_); } void advance_clock(uint64_t increment) diff --git a/toxcore/group_chats.c b/toxcore/group_chats.c index 2d64ae60ec..69b31148ac 100644 --- a/toxcore/group_chats.c +++ b/toxcore/group_chats.c @@ -12,7 +12,6 @@ #include #include -#include #include #include "DHT.h" @@ -30,6 +29,7 @@ #include "group_moderation.h" #include "group_pack.h" #include "logger.h" +#include "mem.h" #include "mono_time.h" #include "net_crypto.h" #include "network.h" @@ -1473,8 +1473,9 @@ static bool sign_gc_shared_state(GC_Chat *chat) * Return -2 on decryption failure. * Return -3 if plaintext payload length is invalid. */ -non_null(1, 2, 3, 5, 6) nullable(4) -static int group_packet_unwrap(const Logger *log, const GC_Connection *gconn, uint8_t *data, uint64_t *message_id, +non_null(1, 2, 3, 4, 6, 7) nullable(5) +static int group_packet_unwrap(const Logger *log, const Memory *mem, const GC_Connection *gconn, + uint8_t *data, uint64_t *message_id, uint8_t *packet_type, const uint8_t *packet, uint16_t length) { assert(data != nullptr); @@ -1485,7 +1486,7 @@ static int group_packet_unwrap(const Logger *log, const GC_Connection *gconn, ui return -1; } - uint8_t *plain = (uint8_t *)malloc(length); + uint8_t *plain = (uint8_t *)mem_balloc(mem, length); if (plain == nullptr) { LOGGER_ERROR(log, "Failed to allocate memory for plain data buffer"); @@ -1493,10 +1494,10 @@ static int group_packet_unwrap(const Logger *log, const GC_Connection *gconn, ui } int plain_len = decrypt_data_symmetric(gconn->session_shared_key, packet, packet + CRYPTO_NONCE_SIZE, - length - CRYPTO_NONCE_SIZE, plain); + length - CRYPTO_NONCE_SIZE, plain, mem); if (plain_len <= 0) { - free(plain); + mem_delete(mem, plain); return plain_len == 0 ? -3 : -2; } @@ -1510,7 +1511,7 @@ static int group_packet_unwrap(const Logger *log, const GC_Connection *gconn, ui --plain_len; if (plain_len < min_plain_len) { - free(plain); + mem_delete(mem, plain); return -3; } } @@ -1527,13 +1528,14 @@ static int group_packet_unwrap(const Logger *log, const GC_Connection *gconn, ui memcpy(data, real_plain + header_len, plain_len); - free(plain); + mem_delete(mem, plain); return plain_len; } int group_packet_wrap( - const Logger *log, const Random *rng, const uint8_t *self_pk, const uint8_t *shared_key, uint8_t *packet, + const Logger *log, const Memory *mem, const Random *rng, + const uint8_t *self_pk, const uint8_t *shared_key, uint8_t *packet, uint16_t packet_size, const uint8_t *data, uint16_t length, uint64_t message_id, uint8_t gp_packet_type, Net_Packet_Type net_packet_type) { @@ -1553,7 +1555,7 @@ int group_packet_wrap( return -1; } - uint8_t *plain = (uint8_t *)malloc(packet_size); + uint8_t *plain = (uint8_t *)mem_balloc(mem, packet_size); if (plain == nullptr) { return -1; @@ -1581,20 +1583,20 @@ int group_packet_wrap( const uint16_t plain_len = padding_len + enc_header_len + length; const uint16_t encrypt_buf_size = plain_len + CRYPTO_MAC_SIZE; - uint8_t *encrypt = (uint8_t *)malloc(encrypt_buf_size); + uint8_t *encrypt = (uint8_t *)mem_balloc(mem, encrypt_buf_size); if (encrypt == nullptr) { - free(plain); + mem_delete(mem, plain); return -2; } - const int enc_len = encrypt_data_symmetric(shared_key, nonce, plain, plain_len, encrypt); + const int enc_len = encrypt_data_symmetric(shared_key, nonce, plain, plain_len, encrypt, mem); - free(plain); + mem_delete(mem, plain); if (enc_len != encrypt_buf_size) { LOGGER_ERROR(log, "encryption failed. packet type: 0x%02x, enc_len: %d", gp_packet_type, enc_len); - free(encrypt); + mem_delete(mem, encrypt); return -3; } @@ -1603,7 +1605,7 @@ int group_packet_wrap( memcpy(packet + 1 + ENC_PUBLIC_KEY_SIZE, nonce, CRYPTO_NONCE_SIZE); memcpy(packet + 1 + ENC_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, encrypt, enc_len); - free(encrypt); + mem_delete(mem, encrypt); return 1 + ENC_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + enc_len; } @@ -1627,25 +1629,25 @@ static bool send_lossy_group_packet(const GC_Chat *chat, const GC_Connection *gc } const uint16_t packet_size = gc_get_wrapped_packet_size(length, NET_PACKET_GC_LOSSY); - uint8_t *packet = (uint8_t *)malloc(packet_size); + uint8_t *packet = (uint8_t *)mem_balloc(chat->mem, packet_size); if (packet == nullptr) { return false; } const int len = group_packet_wrap( - chat->log, chat->rng, chat->self_public_key.enc, gconn->session_shared_key, packet, + chat->log, chat->mem, chat->rng, chat->self_public_key.enc, gconn->session_shared_key, packet, packet_size, data, length, 0, packet_type, NET_PACKET_GC_LOSSY); if (len < 0) { LOGGER_ERROR(chat->log, "Failed to encrypt packet (type: 0x%02x, error: %d)", packet_type, len); - free(packet); + mem_delete(chat->mem, packet); return false; } const bool ret = gcc_send_packet(chat, gconn, packet, (uint16_t)len); - free(packet); + mem_delete(chat->mem, packet); return ret; } @@ -1883,7 +1885,7 @@ static bool sync_response_send_peers(GC_Chat *chat, GC_Connection *gconn, uint32 return true; } - uint8_t *response = (uint8_t *)malloc(MAX_GC_PACKET_CHUNK_SIZE); + uint8_t *response = (uint8_t *)mem_balloc(chat->mem, MAX_GC_PACKET_CHUNK_SIZE); if (response == nullptr) { return false; @@ -1923,7 +1925,7 @@ static bool sync_response_send_peers(GC_Chat *chat, GC_Connection *gconn, uint32 ++num_announces; } - free(response); + mem_delete(chat->mem, response); if (num_announces == 0) { // we send an empty sync response even if we didn't send any peers as an acknowledgement @@ -2387,7 +2389,7 @@ static bool send_gc_broadcast_message(const GC_Chat *chat, const uint8_t *data, return false; } - uint8_t *packet = (uint8_t *)malloc(length + GC_BROADCAST_ENC_HEADER_SIZE); + uint8_t *packet = (uint8_t *)mem_balloc(chat->mem, length + GC_BROADCAST_ENC_HEADER_SIZE); if (packet == nullptr) { return false; @@ -2397,7 +2399,7 @@ static bool send_gc_broadcast_message(const GC_Chat *chat, const uint8_t *data, const bool ret = send_gc_lossless_packet_all_peers(chat, packet, packet_len, GP_BROADCAST); - free(packet); + mem_delete(chat->mem, packet); return ret; } @@ -2631,7 +2633,7 @@ void gc_get_chat_id(const GC_Chat *chat, uint8_t *dest) non_null() static bool send_self_to_peer(const GC_Chat *chat, GC_Connection *gconn) { - GC_Peer *self = (GC_Peer *)calloc(1, sizeof(GC_Peer)); + GC_Peer *self = (GC_Peer *)mem_alloc(chat->mem, sizeof(GC_Peer)); if (self == nullptr) { return false; @@ -2640,10 +2642,10 @@ static bool send_self_to_peer(const GC_Chat *chat, GC_Connection *gconn) copy_self(chat, self); const uint16_t data_size = PACKED_GC_PEER_SIZE + sizeof(uint16_t) + MAX_GC_PASSWORD_SIZE; - uint8_t *data = (uint8_t *)malloc(data_size); + uint8_t *data = (uint8_t *)mem_balloc(chat->mem, data_size); if (data == nullptr) { - free(self); + mem_delete(chat->mem, self); return false; } @@ -2660,17 +2662,17 @@ static bool send_self_to_peer(const GC_Chat *chat, GC_Connection *gconn) const int packed_len = pack_gc_peer(data + length, data_size - length, self); length += packed_len; - free(self); + mem_delete(chat->mem, self); if (packed_len <= 0) { LOGGER_DEBUG(chat->log, "pack_gc_peer failed in handle_gc_peer_info_request_request %d", packed_len); - free(data); + mem_delete(chat->mem, data); return false; } const bool ret = send_lossless_group_packet(chat, gconn, data, length, GP_PEER_INFO_RESPONSE); - free(data); + mem_delete(chat->mem, data); return ret; } @@ -2736,7 +2738,7 @@ static bool send_gc_peer_exchange(const GC_Chat *chat, GC_Connection *gconn) * Return -5 if supplied group password is invalid. * Return -6 if we fail to add the peer to the peer list. * Return -7 if peer's role cannot be validated. - * Return -8 if malloc fails. + * Return -8 if memory allocation fails. */ non_null(1, 2, 4) nullable(6) static int handle_gc_peer_info_response(const GC_Session *c, GC_Chat *chat, uint32_t peer_number, @@ -2781,7 +2783,7 @@ static int handle_gc_peer_info_response(const GC_Session *c, GC_Chat *chat, uint return -1; } - GC_Peer *peer_info = (GC_Peer *)calloc(1, sizeof(GC_Peer)); + GC_Peer *peer_info = (GC_Peer *)mem_alloc(chat->mem, sizeof(GC_Peer)); if (peer_info == nullptr) { return -8; @@ -2789,17 +2791,17 @@ static int handle_gc_peer_info_response(const GC_Session *c, GC_Chat *chat, uint if (unpack_gc_peer(peer_info, data + unpacked_len, length - unpacked_len) == -1) { LOGGER_ERROR(chat->log, "unpack_gc_peer() failed"); - free(peer_info); + mem_delete(chat->mem, peer_info); return -6; } if (peer_update(chat, peer_info, peer_number) == -1) { LOGGER_WARNING(chat->log, "peer_update() failed"); - free(peer_info); + mem_delete(chat->mem, peer_info); return -6; } - free(peer_info); + mem_delete(chat->mem, peer_info); const bool was_confirmed = gconn->confirmed; gconn->confirmed = true; @@ -3181,7 +3183,7 @@ static int handle_gc_sanctions_list(const GC_Session *c, GC_Chat *chat, const ui Mod_Sanction_Creds creds; - Mod_Sanction *sanctions = (Mod_Sanction *)calloc(num_sanctions, sizeof(Mod_Sanction)); + Mod_Sanction *sanctions = (Mod_Sanction *)mem_valloc(chat->mem, num_sanctions, sizeof(Mod_Sanction)); if (sanctions == nullptr) { return -1; @@ -3192,25 +3194,25 @@ static int handle_gc_sanctions_list(const GC_Session *c, GC_Chat *chat, const ui if (unpacked_num != num_sanctions) { LOGGER_WARNING(chat->log, "Failed to unpack sanctions list: %d", unpacked_num); - free(sanctions); + mem_delete(chat->mem, sanctions); return handle_gc_sanctions_list_error(chat); } if (!sanctions_list_check_integrity(&chat->moderation, &creds, sanctions, num_sanctions)) { LOGGER_WARNING(chat->log, "Sanctions list failed integrity check"); - free(sanctions); + mem_delete(chat->mem, sanctions); return handle_gc_sanctions_list_error(chat); } if (creds.version < chat->moderation.sanctions_creds.version) { - free(sanctions); + mem_delete(chat->mem, sanctions); return 0; } // this may occur if two mods change the sanctions list at the exact same time if (creds.version == chat->moderation.sanctions_creds.version && creds.checksum <= chat->moderation.sanctions_creds.checksum) { - free(sanctions); + mem_delete(chat->mem, sanctions); return 0; } @@ -3247,7 +3249,7 @@ static int make_gc_mod_list_packet(const GC_Chat *chat, uint8_t *data, uint32_t const uint16_t length = sizeof(uint16_t) + mod_list_size; if (mod_list_size > 0) { - uint8_t *packed_mod_list = (uint8_t *)malloc(mod_list_size); + uint8_t *packed_mod_list = (uint8_t *)mem_balloc(chat->mem, mod_list_size); if (packed_mod_list == nullptr) { return -1; @@ -3256,7 +3258,7 @@ static int make_gc_mod_list_packet(const GC_Chat *chat, uint8_t *data, uint32_t mod_list_pack(&chat->moderation, packed_mod_list); memcpy(data + sizeof(uint16_t), packed_mod_list, mod_list_size); - free(packed_mod_list); + mem_delete(chat->mem, packed_mod_list); } return length; @@ -3271,7 +3273,7 @@ static bool send_peer_mod_list(const GC_Chat *chat, GC_Connection *gconn) { const uint16_t mod_list_size = chat->moderation.num_mods * MOD_LIST_ENTRY_SIZE; const uint16_t length = sizeof(uint16_t) + mod_list_size; - uint8_t *packet = (uint8_t *)malloc(length); + uint8_t *packet = (uint8_t *)mem_balloc(chat->mem, length); if (packet == nullptr) { return false; @@ -3280,13 +3282,13 @@ static bool send_peer_mod_list(const GC_Chat *chat, GC_Connection *gconn) const int packet_len = make_gc_mod_list_packet(chat, packet, length, mod_list_size); if (packet_len != length) { - free(packet); + mem_delete(chat->mem, packet); return false; } const bool ret = send_lossless_group_packet(chat, gconn, packet, length, GP_MOD_LIST); - free(packet); + mem_delete(chat->mem, packet); return ret; } @@ -3330,7 +3332,7 @@ static bool send_peer_sanctions_list(const GC_Chat *chat, GC_Connection *gconn) const uint16_t packet_size = MOD_SANCTION_PACKED_SIZE * chat->moderation.num_sanctions + sizeof(uint16_t) + MOD_SANCTIONS_CREDS_SIZE; - uint8_t *packet = (uint8_t *)malloc(packet_size); + uint8_t *packet = (uint8_t *)mem_balloc(chat->mem, packet_size); if (packet == nullptr) { return false; @@ -3339,13 +3341,13 @@ static bool send_peer_sanctions_list(const GC_Chat *chat, GC_Connection *gconn) const int packet_len = make_gc_sanctions_list_packet(chat, packet, packet_size); if (packet_len == -1) { - free(packet); + mem_delete(chat->mem, packet); return false; } const bool ret = send_lossless_group_packet(chat, gconn, packet, (uint16_t)packet_len, GP_SANCTIONS_LIST); - free(packet); + mem_delete(chat->mem, packet); return ret; } @@ -3360,7 +3362,7 @@ static bool broadcast_gc_sanctions_list(const GC_Chat *chat) const uint16_t packet_size = MOD_SANCTION_PACKED_SIZE * chat->moderation.num_sanctions + sizeof(uint16_t) + MOD_SANCTIONS_CREDS_SIZE; - uint8_t *packet = (uint8_t *)malloc(packet_size); + uint8_t *packet = (uint8_t *)mem_balloc(chat->mem, packet_size); if (packet == nullptr) { return false; @@ -3369,13 +3371,13 @@ static bool broadcast_gc_sanctions_list(const GC_Chat *chat) const int packet_len = make_gc_sanctions_list_packet(chat, packet, packet_size); if (packet_len == -1) { - free(packet); + mem_delete(chat->mem, packet); return false; } const bool ret = send_gc_lossless_packet_all_peers(chat, packet, (uint16_t)packet_len, GP_SANCTIONS_LIST); - free(packet); + mem_delete(chat->mem, packet); return ret; } @@ -3406,7 +3408,7 @@ static bool broadcast_gc_mod_list(const GC_Chat *chat) { const uint16_t mod_list_size = chat->moderation.num_mods * MOD_LIST_ENTRY_SIZE; const uint16_t length = sizeof(uint16_t) + mod_list_size; - uint8_t *packet = (uint8_t *)malloc(length); + uint8_t *packet = (uint8_t *)mem_balloc(chat->mem, length); if (packet == nullptr) { return false; @@ -3415,13 +3417,13 @@ static bool broadcast_gc_mod_list(const GC_Chat *chat) const int packet_len = make_gc_mod_list_packet(chat, packet, length, mod_list_size); if (packet_len != length) { - free(packet); + mem_delete(chat->mem, packet); return false; } const bool ret = send_gc_lossless_packet_all_peers(chat, packet, length, GP_MOD_LIST); - free(packet); + mem_delete(chat->mem, packet); return ret; } @@ -3699,7 +3701,7 @@ non_null() static bool send_peer_topic(const GC_Chat *chat, GC_Connection *gconn) { const uint16_t packet_buf_size = SIGNATURE_SIZE + chat->topic_info.length + GC_MIN_PACKED_TOPIC_INFO_SIZE; - uint8_t *packet = (uint8_t *)malloc(packet_buf_size); + uint8_t *packet = (uint8_t *)mem_balloc(chat->mem, packet_buf_size); if (packet == nullptr) { return false; @@ -3708,16 +3710,16 @@ static bool send_peer_topic(const GC_Chat *chat, GC_Connection *gconn) const int packet_len = make_gc_topic_packet(chat, packet, packet_buf_size); if (packet_len != packet_buf_size) { - free(packet); + mem_delete(chat->mem, packet); return false; } if (!send_lossless_group_packet(chat, gconn, packet, packet_buf_size, GP_TOPIC)) { - free(packet); + mem_delete(chat->mem, packet); return false; } - free(packet); + mem_delete(chat->mem, packet); return true; } @@ -3767,7 +3769,7 @@ non_null() static bool broadcast_gc_topic(const GC_Chat *chat) { const uint16_t packet_buf_size = SIGNATURE_SIZE + chat->topic_info.length + GC_MIN_PACKED_TOPIC_INFO_SIZE; - uint8_t *packet = (uint8_t *)malloc(packet_buf_size); + uint8_t *packet = (uint8_t *)mem_balloc(chat->mem, packet_buf_size); if (packet == nullptr) { return false; @@ -3776,13 +3778,13 @@ static bool broadcast_gc_topic(const GC_Chat *chat) const int packet_len = make_gc_topic_packet(chat, packet, packet_buf_size); if (packet_len != packet_buf_size) { - free(packet); + mem_delete(chat->mem, packet); return false; } const bool ret = send_gc_lossless_packet_all_peers(chat, packet, packet_buf_size, GP_TOPIC); - free(packet); + mem_delete(chat->mem, packet); return ret; } @@ -3832,7 +3834,7 @@ int gc_set_topic(GC_Chat *chat, const uint8_t *topic, uint16_t length) chat->topic_info.checksum = get_gc_topic_checksum(&chat->topic_info); const uint16_t packet_buf_size = length + GC_MIN_PACKED_TOPIC_INFO_SIZE; - uint8_t *packed_topic = (uint8_t *)malloc(packet_buf_size); + uint8_t *packed_topic = (uint8_t *)mem_balloc(chat->mem, packet_buf_size); if (packed_topic == nullptr) { return -3; @@ -3859,13 +3861,13 @@ int gc_set_topic(GC_Chat *chat, const uint8_t *topic, uint16_t length) chat->topic_prev_checksum = old_topic_info.checksum; chat->topic_time_set = mono_time_get(chat->mono_time); - free(packed_topic); + mem_delete(chat->mem, packed_topic); return 0; ON_ERROR: chat->topic_info = old_topic_info; memcpy(chat->topic_sig, old_topic_sig, SIGNATURE_SIZE); - free(packed_topic); + mem_delete(chat->mem, packed_topic); return err; } @@ -4123,17 +4125,17 @@ int gc_founder_set_password(GC_Chat *chat, const uint8_t *password, uint16_t pas } if (!set_gc_password_local(chat, password, password_length)) { - free(oldpasswd); + mem_delete(chat->mem, oldpasswd); return -2; } if (!sign_gc_shared_state(chat)) { set_gc_password_local(chat, oldpasswd, oldlen); - free(oldpasswd); + mem_delete(chat->mem, oldpasswd); return -2; } - free(oldpasswd); + mem_delete(chat->mem, oldpasswd); if (!broadcast_gc_shared_state(chat)) { return -3; @@ -4258,7 +4260,7 @@ non_null() static bool send_gc_set_mod(const GC_Chat *chat, const GC_Connection *gconn, bool add_mod) { const uint16_t length = 1 + SIG_PUBLIC_KEY_SIZE; - uint8_t *data = (uint8_t *)malloc(length); + uint8_t *data = (uint8_t *)mem_balloc(chat->mem, length); if (data == nullptr) { return false; @@ -4269,11 +4271,11 @@ static bool send_gc_set_mod(const GC_Chat *chat, const GC_Connection *gconn, boo memcpy(data + 1, get_sig_pk(&gconn->addr.public_key), SIG_PUBLIC_KEY_SIZE); if (!send_gc_broadcast_message(chat, data, length, GM_SET_MOD)) { - free(data); + mem_delete(chat->mem, data); return false; } - free(data); + mem_delete(chat->mem, data); return true; } @@ -4461,7 +4463,7 @@ static bool send_gc_set_observer(const GC_Chat *chat, const Extended_Public_Key const uint8_t *sanction_data, uint16_t length, bool add_obs) { const uint16_t packet_len = 1 + ENC_PUBLIC_KEY_SIZE + SIG_PUBLIC_KEY_SIZE + length; - uint8_t *packet = (uint8_t *)malloc(packet_len); + uint8_t *packet = (uint8_t *)mem_balloc(chat->mem, packet_len); if (packet == nullptr) { return false; @@ -4474,11 +4476,11 @@ static bool send_gc_set_observer(const GC_Chat *chat, const Extended_Public_Key memcpy(packet + 1 + ENC_PUBLIC_KEY_SIZE + SIG_PUBLIC_KEY_SIZE, sanction_data, length); if (!send_gc_broadcast_message(chat, packet, packet_len, GM_SET_OBSERVER)) { - free(packet); + mem_delete(chat->mem, packet); return false; } - free(packet); + mem_delete(chat->mem, packet); return true; } @@ -4895,7 +4897,7 @@ int gc_send_message(const GC_Chat *chat, const uint8_t *message, uint16_t length const uint8_t packet_type = type == GC_MESSAGE_TYPE_NORMAL ? GM_PLAIN_MESSAGE : GM_ACTION_MESSAGE; const uint16_t length_raw = length + GC_MESSAGE_PSEUDO_ID_SIZE; - uint8_t *message_raw = (uint8_t *)malloc(length_raw); + uint8_t *message_raw = (uint8_t *)mem_balloc(chat->mem, length_raw); if (message_raw == nullptr) { return -5; @@ -4907,11 +4909,11 @@ int gc_send_message(const GC_Chat *chat, const uint8_t *message, uint16_t length memcpy(message_raw + GC_MESSAGE_PSEUDO_ID_SIZE, message, length); if (!send_gc_broadcast_message(chat, message_raw, length_raw, packet_type)) { - free(message_raw); + mem_delete(chat->mem, message_raw); return -5; } - free(message_raw); + mem_delete(chat->mem, message_raw); if (message_id != nullptr) { *message_id = pseudo_msg_id; @@ -4983,7 +4985,7 @@ int gc_send_private_message(const GC_Chat *chat, GC_Peer_Id peer_id, uint8_t typ } const uint16_t raw_length = 1 + length + GC_MESSAGE_PSEUDO_ID_SIZE; - uint8_t *message_with_type = (uint8_t *)malloc(raw_length); + uint8_t *message_with_type = (uint8_t *)mem_balloc(chat->mem, raw_length); if (message_with_type == nullptr) { return -6; @@ -4996,23 +4998,23 @@ int gc_send_private_message(const GC_Chat *chat, GC_Peer_Id peer_id, uint8_t typ memcpy(message_with_type + 1 + GC_MESSAGE_PSEUDO_ID_SIZE, message, length); - uint8_t *packet = (uint8_t *)malloc(raw_length + GC_BROADCAST_ENC_HEADER_SIZE); + uint8_t *packet = (uint8_t *)mem_balloc(chat->mem, raw_length + GC_BROADCAST_ENC_HEADER_SIZE); if (packet == nullptr) { - free(message_with_type); + mem_delete(chat->mem, message_with_type); return -6; } const uint16_t packet_len = make_gc_broadcast_header(message_with_type, raw_length, packet, GM_PRIVATE_MESSAGE); - free(message_with_type); + mem_delete(chat->mem, message_with_type); if (!send_lossless_group_packet(chat, gconn, packet, packet_len, GP_BROADCAST)) { - free(packet); + mem_delete(chat->mem, packet); return -6; } - free(packet); + mem_delete(chat->mem, packet); if (message_id != nullptr) { *message_id = pseudo_msg_id; @@ -5330,7 +5332,7 @@ static int handle_gc_message_ack(const GC_Chat *chat, GC_Connection *gconn, cons const Group_Message_Ack_Type type = (Group_Message_Ack_Type) data[0]; if (type == GR_ACK_RECV) { - if (!gcc_handle_ack(chat->log, gconn, message_id)) { + if (!gcc_handle_ack(chat->log, gconn, message_id, chat->mem)) { return -2; } @@ -5509,7 +5511,7 @@ static int handle_gc_broadcast(const GC_Session *c, GC_Chat *chat, uint32_t peer */ non_null() static int unwrap_group_handshake_packet(const Logger *log, const uint8_t *self_sk, const uint8_t *sender_pk, - uint8_t *plain, size_t plain_size, const uint8_t *packet, uint16_t length) + uint8_t *plain, size_t plain_size, const uint8_t *packet, uint16_t length, const Memory *mem) { if (length <= CRYPTO_NONCE_SIZE) { LOGGER_FATAL(log, "Invalid handshake packet length %u", length); @@ -5517,7 +5519,7 @@ static int unwrap_group_handshake_packet(const Logger *log, const uint8_t *self_ } const int plain_len = decrypt_data(sender_pk, self_sk, packet, packet + CRYPTO_NONCE_SIZE, - length - CRYPTO_NONCE_SIZE, plain); + length - CRYPTO_NONCE_SIZE, plain, mem); if (plain_len < 0 || (uint32_t)plain_len != plain_size) { LOGGER_DEBUG(log, "decrypt handshake request failed: len: %d, size: %zu", plain_len, plain_size); @@ -5534,12 +5536,13 @@ static int unwrap_group_handshake_packet(const Logger *log, const uint8_t *self_ * * Return length of encrypted packet on success. * Return -1 if packet size is invalid. - * Return -2 on malloc failure. + * Return -2 on memory allocation failure. * Return -3 if encryption fails. */ non_null() static int wrap_group_handshake_packet( - const Logger *log, const Random *rng, const uint8_t *self_pk, const uint8_t *self_sk, + const Logger *log, const Memory *mem, const Random *rng, + const uint8_t *self_pk, const uint8_t *self_sk, const uint8_t *target_pk, uint8_t *packet, uint32_t packet_size, const uint8_t *data, uint16_t length) { @@ -5552,17 +5555,17 @@ static int wrap_group_handshake_packet( random_nonce(rng, nonce); const size_t encrypt_buf_size = length + CRYPTO_MAC_SIZE; - uint8_t *encrypt = (uint8_t *)malloc(encrypt_buf_size); + uint8_t *encrypt = (uint8_t *)mem_balloc(mem, encrypt_buf_size); if (encrypt == nullptr) { return -2; } - const int enc_len = encrypt_data(target_pk, self_sk, nonce, data, length, encrypt); + const int enc_len = encrypt_data(target_pk, self_sk, nonce, data, length, encrypt, mem); if (enc_len < 0 || (size_t)enc_len != encrypt_buf_size) { LOGGER_ERROR(log, "Failed to encrypt group handshake packet (len: %d)", enc_len); - free(encrypt); + mem_delete(mem, encrypt); return -3; } @@ -5572,7 +5575,7 @@ static int wrap_group_handshake_packet( memcpy(packet + 1 + ENC_PUBLIC_KEY_SIZE + ENC_PUBLIC_KEY_SIZE, nonce, CRYPTO_NONCE_SIZE); memcpy(packet + 1 + ENC_PUBLIC_KEY_SIZE + ENC_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, encrypt, enc_len); - free(encrypt); + mem_delete(mem, encrypt); return 1 + ENC_PUBLIC_KEY_SIZE + ENC_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + enc_len; } @@ -5622,7 +5625,7 @@ static int make_gc_handshake_packet(const GC_Chat *chat, const GC_Connection *gc } const int enc_len = wrap_group_handshake_packet( - chat->log, chat->rng, chat->self_public_key.enc, chat->self_secret_key.enc, + chat->log, chat->mem, chat->rng, chat->self_public_key.enc, chat->self_secret_key.enc, gconn->addr.public_key.enc, packet, (uint16_t)packet_size, data, length); if (enc_len != GC_MIN_ENCRYPTED_HS_PAYLOAD_SIZE + nodes_size) { @@ -5945,18 +5948,18 @@ static int handle_gc_handshake_packet(GC_Chat *chat, const uint8_t *sender_pk, c } const size_t data_buf_size = length - CRYPTO_NONCE_SIZE - CRYPTO_MAC_SIZE; - uint8_t *data = (uint8_t *)malloc(data_buf_size); + uint8_t *data = (uint8_t *)mem_balloc(chat->mem, data_buf_size); if (data == nullptr) { return -1; } const int plain_len = unwrap_group_handshake_packet(chat->log, chat->self_secret_key.enc, sender_pk, data, - data_buf_size, packet, length); + data_buf_size, packet, length, chat->mem); if (plain_len < GC_MIN_HS_PACKET_PAYLOAD_SIZE) { LOGGER_DEBUG(chat->log, "Failed to unwrap handshake packet (probably a stale request using an old key)"); - free(data); + mem_delete(chat->mem, data); return -1; } @@ -5972,11 +5975,11 @@ static int handle_gc_handshake_packet(GC_Chat *chat, const uint8_t *sender_pk, c } else if (handshake_type == GH_RESPONSE) { peer_number = handle_gc_handshake_response(chat, sender_pk, real_data, real_len); } else { - free(data); + mem_delete(chat->mem, data); return -1; } - free(data); + mem_delete(chat->mem, data); GC_Connection *gconn = get_gc_connection(chat, peer_number); @@ -6171,7 +6174,7 @@ static bool handle_gc_lossless_packet(const GC_Session *c, GC_Chat *chat, const return true; } - uint8_t *data = (uint8_t *)malloc(length); + uint8_t *data = (uint8_t *)mem_balloc(chat->mem, length); if (data == nullptr) { LOGGER_DEBUG(chat->log, "Failed to allocate memory for packet data buffer"); @@ -6181,19 +6184,19 @@ static bool handle_gc_lossless_packet(const GC_Session *c, GC_Chat *chat, const uint8_t packet_type; uint64_t message_id; - const int len = group_packet_unwrap(chat->log, gconn, data, &message_id, &packet_type, packet, length); + const int len = group_packet_unwrap(chat->log, chat->mem, gconn, data, &message_id, &packet_type, packet, length); if (len < 0) { Ip_Ntoa ip_str; LOGGER_DEBUG(chat->log, "Failed to unwrap lossless packet from %s:%d: %d", net_ip_ntoa(&gconn->addr.ip_port.ip, &ip_str), net_ntohs(gconn->addr.ip_port.port), len); - free(data); + mem_delete(chat->mem, data); return false; } if (!gconn->handshaked && (packet_type != GP_HS_RESPONSE_ACK && packet_type != GP_INVITE_REQUEST)) { LOGGER_DEBUG(chat->log, "Got lossless packet type 0x%02x from unconfirmed peer", packet_type); - free(data); + mem_delete(chat->mem, data); return false; } @@ -6203,28 +6206,28 @@ static bool handle_gc_lossless_packet(const GC_Session *c, GC_Chat *chat, const if (message_id == 3 && is_invite_packet && gconn->received_message_id <= 1) { // we missed initial handshake request. Drop this packet and wait for another handshake request. LOGGER_DEBUG(chat->log, "Missed handshake packet, type: 0x%02x", packet_type); - free(data); + mem_delete(chat->mem, data); return false; } const int lossless_ret = gcc_handle_received_message(chat->log, chat->mono_time, gconn, data, (uint16_t) len, - packet_type, message_id, direct_conn); + packet_type, message_id, direct_conn, chat->mem); if (packet_type == GP_INVITE_REQUEST && !gconn->handshaked) { // Both peers sent request at same time - free(data); + mem_delete(chat->mem, data); return true; } if (lossless_ret < 0) { LOGGER_DEBUG(chat->log, "failed to handle packet %llu (type: 0x%02x, id: %llu)", (unsigned long long)message_id, packet_type, (unsigned long long)message_id); - free(data); + mem_delete(chat->mem, data); return false; } /* Duplicate packet */ if (lossless_ret == 0) { - free(data); + mem_delete(chat->mem, data); return gc_send_message_ack(chat, gconn, message_id, GR_ACK_RECV); } @@ -6232,7 +6235,7 @@ static bool handle_gc_lossless_packet(const GC_Session *c, GC_Chat *chat, const if (lossless_ret == 1) { LOGGER_TRACE(chat->log, "received out of order packet from peer %u. expected %llu, got %llu", peer_number, (unsigned long long)gconn->received_message_id + 1, (unsigned long long)message_id); - free(data); + mem_delete(chat->mem, data); return gc_send_message_ack(chat, gconn, gconn->received_message_id + 1, GR_ACK_REQ); } @@ -6240,13 +6243,13 @@ static bool handle_gc_lossless_packet(const GC_Session *c, GC_Chat *chat, const if (lossless_ret == 3) { const bool frag_ret = handle_gc_packet_fragment(c, chat, peer_number, gconn, data, (uint16_t)len, packet_type, message_id, userdata); - free(data); + mem_delete(chat->mem, data); return frag_ret; } const bool ret = handle_gc_lossless_helper(c, chat, peer_number, data, (uint16_t)len, packet_type, userdata); - free(data); + mem_delete(chat->mem, data); if (!ret) { return false; @@ -6325,7 +6328,7 @@ static bool handle_gc_lossy_packet(const GC_Session *c, GC_Chat *chat, const uin return false; } - uint8_t *data = (uint8_t *)malloc(length); + uint8_t *data = (uint8_t *)mem_balloc(chat->mem, length); if (data == nullptr) { LOGGER_ERROR(chat->log, "Failed to allocate memory for packet buffer"); @@ -6334,19 +6337,19 @@ static bool handle_gc_lossy_packet(const GC_Session *c, GC_Chat *chat, const uin uint8_t packet_type; - const int len = group_packet_unwrap(chat->log, gconn, data, nullptr, &packet_type, packet, length); + const int len = group_packet_unwrap(chat->log, chat->mem, gconn, data, nullptr, &packet_type, packet, length); if (len <= 0) { Ip_Ntoa ip_str; LOGGER_DEBUG(chat->log, "Failed to unwrap lossy packet from %s:%d: %d", net_ip_ntoa(&gconn->addr.ip_port.ip, &ip_str), net_ntohs(gconn->addr.ip_port.port), len); - free(data); + mem_delete(chat->mem, data); return false; } const int ret = handle_gc_lossy_packet_decoded(c, chat, gconn, peer, packet_type, data, (uint16_t)len, userdata); - free(data); + mem_delete(chat->mem, data); if (ret < 0) { LOGGER_DEBUG(chat->log, "Lossy packet handle error %d: type: 0x%02x, peernumber %d", ret, packet_type, @@ -6720,7 +6723,7 @@ static bool peer_delete(const GC_Session *c, GC_Chat *chat, uint32_t peer_number assert(nick_length <= MAX_GC_NICK_SIZE); memcpy(nick, peer->nick, nick_length); - gcc_peer_cleanup(&peer->gconn); + gcc_peer_cleanup(&peer->gconn, chat->mem); --chat->numpeers; @@ -6732,7 +6735,7 @@ static bool peer_delete(const GC_Session *c, GC_Chat *chat, uint32_t peer_number 0 }; - GC_Peer *tmp_group = (GC_Peer *)realloc(chat->group, chat->numpeers * sizeof(GC_Peer)); + GC_Peer *tmp_group = (GC_Peer *)mem_vrealloc(chat->mem, chat->group, chat->numpeers, sizeof(GC_Peer)); if (tmp_group == nullptr) { return false; @@ -6808,8 +6811,8 @@ int peer_add(GC_Chat *chat, const IP_Port *ipp, const uint8_t *public_key) } } - GC_Message_Array_Entry *send = (GC_Message_Array_Entry *)calloc(GCC_BUFFER_SIZE, sizeof(GC_Message_Array_Entry)); - GC_Message_Array_Entry *recv = (GC_Message_Array_Entry *)calloc(GCC_BUFFER_SIZE, sizeof(GC_Message_Array_Entry)); + GC_Message_Array_Entry *send = (GC_Message_Array_Entry *)mem_valloc(chat->mem, GCC_BUFFER_SIZE, sizeof(GC_Message_Array_Entry)); + GC_Message_Array_Entry *recv = (GC_Message_Array_Entry *)mem_valloc(chat->mem, GCC_BUFFER_SIZE, sizeof(GC_Message_Array_Entry)); if (send == nullptr || recv == nullptr) { LOGGER_ERROR(chat->log, "Failed to allocate memory for gconn buffers"); @@ -6818,22 +6821,22 @@ int peer_add(GC_Chat *chat, const IP_Port *ipp, const uint8_t *public_key) kill_tcp_connection_to(chat->tcp_conn, tcp_connection_num); } - free(send); - free(recv); + mem_delete(chat->mem, send); + mem_delete(chat->mem, recv); return -1; } - GC_Peer *tmp_group = (GC_Peer *)realloc(chat->group, (chat->numpeers + 1) * sizeof(GC_Peer)); + GC_Peer *tmp_group = (GC_Peer *)mem_vrealloc(chat->mem, chat->group, chat->numpeers + 1, sizeof(GC_Peer)); if (tmp_group == nullptr) { - LOGGER_ERROR(chat->log, "Failed to allocate memory for group realloc"); + LOGGER_ERROR(chat->log, "Failed to allocate memory for group mem_vrealloc"); if (tcp_connection_num != -1) { kill_tcp_connection_to(chat->tcp_conn, tcp_connection_num); } - free(send); - free(recv); + mem_delete(chat->mem, send); + mem_delete(chat->mem, recv); return -1; } @@ -7056,7 +7059,7 @@ non_null() static bool ping_peer(const GC_Chat *chat, const GC_Connection *gconn) { const uint16_t buf_size = GC_PING_PACKET_MIN_DATA_SIZE + sizeof(IP_Port); - uint8_t *data = (uint8_t *)malloc(buf_size); + uint8_t *data = (uint8_t *)mem_balloc(chat->mem, buf_size); if (data == nullptr) { return false; @@ -7102,11 +7105,11 @@ static bool ping_peer(const GC_Chat *chat, const GC_Connection *gconn) } if (!send_lossy_group_packet(chat, gconn, data, packed_len, GP_PING)) { - free(data); + mem_delete(chat->mem, data); return false; } - free(data); + mem_delete(chat->mem, data); return true; } @@ -7322,12 +7325,12 @@ non_null() static bool realloc_groupchats(GC_Session *c, uint32_t n) { if (n == 0) { - free(c->chats); + mem_delete(c->messenger->mem, c->chats); c->chats = nullptr; return true; } - GC_Chat *temp = (GC_Chat *)realloc(c->chats, n * sizeof(GC_Chat)); + GC_Chat *temp = (GC_Chat *)mem_vrealloc(c->messenger->mem, c->chats, n, sizeof(GC_Chat)); if (temp == nullptr) { return false; @@ -7378,7 +7381,7 @@ static void add_tcp_relays_to_chat(const GC_Session *c, GC_Chat *chat) return; } - Node_format *tcp_relays = (Node_format *)calloc(num_relays, sizeof(Node_format)); + Node_format *tcp_relays = (Node_format *)mem_valloc(m->mem, num_relays, sizeof(Node_format)); if (tcp_relays == nullptr) { return; @@ -7390,7 +7393,7 @@ static void add_tcp_relays_to_chat(const GC_Session *c, GC_Chat *chat) add_tcp_relay_global(chat->tcp_conn, &tcp_relays[i].ip_port, tcp_relays[i].public_key); } - free(tcp_relays); + mem_delete(m->mem, tcp_relays); } non_null() @@ -7860,7 +7863,7 @@ int gc_invite_friend(const GC_Session *c, GC_Chat *chat, int32_t friend_number, assert(group_name_length <= MAX_GC_GROUP_NAME_SIZE); - uint8_t *packet = (uint8_t *)malloc(2 + CHAT_ID_SIZE + ENC_PUBLIC_KEY_SIZE + group_name_length); + uint8_t *packet = (uint8_t *)mem_balloc(c->messenger->mem, 2 + CHAT_ID_SIZE + ENC_PUBLIC_KEY_SIZE + group_name_length); if (packet == nullptr) { return -1; @@ -7881,11 +7884,11 @@ int gc_invite_friend(const GC_Session *c, GC_Chat *chat, int32_t friend_number, assert(length <= MAX_GC_PACKET_SIZE); if (!callback(c->messenger, friend_number, packet, length)) { - free(packet); + mem_delete(c->messenger->mem, packet); return -2; } - free(packet); + mem_delete(c->messenger->mem, packet); chat->saved_invites[chat->saved_invites_index] = friend_number; chat->saved_invites_index = (chat->saved_invites_index + 1) % MAX_GC_SAVED_INVITES; @@ -7954,7 +7957,7 @@ static bool send_gc_invite_confirmed_packet(const Messenger *m, const GC_Chat *c } const uint16_t packet_length = 2 + length; - uint8_t *packet = (uint8_t *)malloc(packet_length); + uint8_t *packet = (uint8_t *)mem_balloc(m->mem, packet_length); if (packet == nullptr) { return false; @@ -7966,11 +7969,11 @@ static bool send_gc_invite_confirmed_packet(const Messenger *m, const GC_Chat *c memcpy(packet + 2, data, length); if (!send_group_invite_packet(m, friend_number, packet, packet_length)) { - free(packet); + mem_delete(m->mem, packet); return false; } - free(packet); + mem_delete(m->mem, packet); return true; } @@ -8232,7 +8235,7 @@ GC_Session *new_dht_groupchats(Messenger *m) return nullptr; } - GC_Session *c = (GC_Session *)calloc(1, sizeof(GC_Session)); + GC_Session *c = (GC_Session *)mem_alloc(m->mem, sizeof(GC_Session)); if (c == nullptr) { return nullptr; @@ -8263,7 +8266,7 @@ static void group_cleanup(const GC_Session *c, GC_Chat *chat) gcc_cleanup(chat); if (chat->group != nullptr) { - free(chat->group); + mem_delete(chat->mem, chat->group); chat->group = nullptr; } @@ -8341,8 +8344,8 @@ void kill_dht_groupchats(GC_Session *c) networking_registerhandler(c->messenger->net, NET_PACKET_GC_HANDSHAKE, nullptr, nullptr); onion_group_announce_register(c->messenger->onion_c, nullptr, nullptr); - free(c->chats); - free(c); + mem_delete(c->messenger->mem, c->chats); + mem_delete(c->messenger->mem, c); } bool gc_group_is_valid(const GC_Chat *chat) diff --git a/toxcore/group_chats.h b/toxcore/group_chats.h index d22ce400e6..9da648fae0 100644 --- a/toxcore/group_chats.h +++ b/toxcore/group_chats.h @@ -22,6 +22,7 @@ #include "group_common.h" #include "group_connection.h" #include "logger.h" +#include "mem.h" #include "network.h" #define GC_PING_TIMEOUT 12 @@ -141,9 +142,10 @@ int get_peer_number_of_enc_pk(const GC_Chat *chat, const uint8_t *public_enc_key * Return -2 if malloc fails. * Return -3 if encryption fails. */ -non_null(1, 2, 3, 4, 5) nullable(7) +non_null(1, 2, 3, 4, 5, 6) nullable(8) int group_packet_wrap( - const Logger *log, const Random *rng, const uint8_t *self_pk, const uint8_t *shared_key, uint8_t *packet, + const Logger *log, const Memory *mem, const Random *rng, + const uint8_t *self_pk, const uint8_t *shared_key, uint8_t *packet, uint16_t packet_size, const uint8_t *data, uint16_t length, uint64_t message_id, uint8_t gp_packet_type, Net_Packet_Type net_packet_type); diff --git a/toxcore/group_connection.c b/toxcore/group_connection.c index 1c2d1ec3da..977ae3f297 100644 --- a/toxcore/group_connection.c +++ b/toxcore/group_connection.c @@ -22,6 +22,7 @@ #include "group_chats.h" #include "group_common.h" #include "logger.h" +#include "mem.h" #include "mono_time.h" #include "network.h" #include "util.h" @@ -30,18 +31,17 @@ #define GCC_UDP_DIRECT_TIMEOUT (GC_PING_TIMEOUT + 4) /** Returns true if array entry does not contain an active packet. */ -non_null() -static bool array_entry_is_empty(const GC_Message_Array_Entry *array_entry) +non_null() static bool array_entry_is_empty(const GC_Message_Array_Entry *array_entry) { assert(array_entry != nullptr); return array_entry->time_added == 0; } /** @brief Clears an array entry. */ -non_null() -static void clear_array_entry(GC_Message_Array_Entry *const array_entry) +non_null() static void clear_array_entry( + GC_Message_Array_Entry *const array_entry, const Memory *mem) { - free(array_entry->data); + mem_delete(mem, array_entry->data); *array_entry = (GC_Message_Array_Entry) { nullptr @@ -53,15 +53,15 @@ static void clear_array_entry(GC_Message_Array_Entry *const array_entry) * `start_id` and ending at `end_id`, and sets the send_message_id for `gconn` * to `start_id`. */ -non_null() -static void clear_send_queue_id_range(GC_Connection *gconn, uint64_t start_id, uint64_t end_id) +non_null() static void clear_send_queue_id_range( + GC_Connection *gconn, uint64_t start_id, uint64_t end_id, const Memory *mem) { const uint16_t start_idx = gcc_get_array_index(start_id); const uint16_t end_idx = gcc_get_array_index(end_id); for (uint16_t i = start_idx; i != end_idx; i = (i + 1) % GCC_BUFFER_SIZE) { GC_Message_Array_Entry *entry = &gconn->send_array[i]; - clear_array_entry(entry); + clear_array_entry(entry, mem); } gconn->send_message_id = start_id; @@ -90,9 +90,9 @@ void gcc_set_recv_message_id(GC_Connection *gconn, uint64_t id) * * Return true on success. */ -non_null(1, 2, 3) nullable(4) +non_null(1, 2, 3, 8) nullable(4) static bool create_array_entry(const Logger *log, const Mono_Time *mono_time, GC_Message_Array_Entry *array_entry, - const uint8_t *data, uint16_t length, uint8_t packet_type, uint64_t message_id) + const uint8_t *data, uint16_t length, uint8_t packet_type, uint64_t message_id, const Memory *mem) { if (!array_entry_is_empty(array_entry)) { LOGGER_WARNING(log, "Failed to create array entry; entry is not empty."); @@ -109,7 +109,7 @@ static bool create_array_entry(const Logger *log, const Mono_Time *mono_time, GC return false; } - uint8_t *entry_data = (uint8_t *)malloc(length); + uint8_t *entry_data = (uint8_t *)mem_balloc(mem, length); if (entry_data == nullptr) { return false; @@ -134,9 +134,9 @@ static bool create_array_entry(const Logger *log, const Mono_Time *mono_time, GC * * Returns true and increments gconn's send_message_id on success. */ -non_null(1, 2, 3) nullable(4) -static bool add_to_send_array(const Logger *log, const Mono_Time *mono_time, GC_Connection *gconn, const uint8_t *data, - uint16_t length, uint8_t packet_type) +non_null(1, 2, 3, 7) nullable(4) static bool add_to_send_array(const Logger *log, + const Mono_Time *mono_time, GC_Connection *gconn, const uint8_t *data, uint16_t length, + uint8_t packet_type, const Memory *mem) { /* check if send_array is full */ if ((gconn->send_message_id % GCC_BUFFER_SIZE) == (uint16_t)(gconn->send_array_start - 1)) { @@ -147,7 +147,7 @@ static bool add_to_send_array(const Logger *log, const Mono_Time *mono_time, GC_ const uint16_t idx = gcc_get_array_index(gconn->send_message_id); GC_Message_Array_Entry *array_entry = &gconn->send_array[idx]; - if (!create_array_entry(log, mono_time, array_entry, data, length, packet_type, gconn->send_message_id)) { + if (!create_array_entry(log, mono_time, array_entry, data, length, packet_type, gconn->send_message_id, mem)) { return false; } @@ -156,13 +156,15 @@ static bool add_to_send_array(const Logger *log, const Mono_Time *mono_time, GC_ return true; } -int gcc_send_lossless_packet(const GC_Chat *chat, GC_Connection *gconn, const uint8_t *data, uint16_t length, - uint8_t packet_type) +int gcc_send_lossless_packet(const GC_Chat *chat, GC_Connection *gconn, const uint8_t *data, + uint16_t length, uint8_t packet_type) { const uint64_t message_id = gconn->send_message_id; - if (!add_to_send_array(chat->log, chat->mono_time, gconn, data, length, packet_type)) { - LOGGER_WARNING(chat->log, "Failed to add payload to send array: (type: 0x%02x, length: %d)", packet_type, length); + if (!add_to_send_array( + chat->log, chat->mono_time, gconn, data, length, packet_type, chat->mem)) { + LOGGER_WARNING(chat->log, "Failed to add payload to send array: (type: 0x%02x, length: %d)", + packet_type, length); return -1; } @@ -172,7 +174,7 @@ int gcc_send_lossless_packet(const GC_Chat *chat, GC_Connection *gconn, const ui if (gcc_encrypt_and_send_lossless_packet(chat, gconn, data, length, message_id, packet_type) == -1) { const uint16_t idx = gcc_get_array_index(message_id); GC_Message_Array_Entry *array_entry = &gconn->send_array[idx]; - clear_array_entry(array_entry); + clear_array_entry(array_entry, chat->mem); gconn->send_message_id = message_id; LOGGER_ERROR(chat->log, "Failed to encrypt payload: (type: 0x%02x, length: %d)", packet_type, length); return -2; @@ -181,8 +183,8 @@ int gcc_send_lossless_packet(const GC_Chat *chat, GC_Connection *gconn, const ui return 0; } -bool gcc_send_lossless_packet_fragments(const GC_Chat *chat, GC_Connection *gconn, const uint8_t *data, - uint16_t length, uint8_t packet_type) +bool gcc_send_lossless_packet_fragments(const GC_Chat *chat, GC_Connection *gconn, + const uint8_t *data, uint16_t length, uint8_t packet_type) { if (length <= MAX_GC_PACKET_CHUNK_SIZE || data == nullptr) { LOGGER_FATAL(chat->log, "invalid length or null data pointer"); @@ -196,7 +198,8 @@ bool gcc_send_lossless_packet_fragments(const GC_Chat *chat, GC_Connection *gcon chunk[0] = packet_type; memcpy(chunk + 1, data, MAX_GC_PACKET_CHUNK_SIZE - 1); - if (!add_to_send_array(chat->log, chat->mono_time, gconn, chunk, MAX_GC_PACKET_CHUNK_SIZE, GP_FRAGMENT)) { + if (!add_to_send_array(chat->log, chat->mono_time, gconn, chunk, MAX_GC_PACKET_CHUNK_SIZE, + GP_FRAGMENT, chat->mem)) { return false; } @@ -209,15 +212,16 @@ bool gcc_send_lossless_packet_fragments(const GC_Chat *chat, GC_Connection *gcon memcpy(chunk, data + processed, chunk_len); processed += chunk_len; - if (!add_to_send_array(chat->log, chat->mono_time, gconn, chunk, chunk_len, GP_FRAGMENT)) { - clear_send_queue_id_range(gconn, start_id, gconn->send_message_id); + if (!add_to_send_array( + chat->log, chat->mono_time, gconn, chunk, chunk_len, GP_FRAGMENT, chat->mem)) { + clear_send_queue_id_range(gconn, start_id, gconn->send_message_id, chat->mem); return false; } } // empty packet signals the end of the sequence - if (!add_to_send_array(chat->log, chat->mono_time, gconn, nullptr, 0, GP_FRAGMENT)) { - clear_send_queue_id_range(gconn, start_id, gconn->send_message_id); + if (!add_to_send_array(chat->log, chat->mono_time, gconn, nullptr, 0, GP_FRAGMENT, chat->mem)) { + clear_send_queue_id_range(gconn, start_id, gconn->send_message_id, chat->mem); return false; } @@ -234,14 +238,14 @@ bool gcc_send_lossless_packet_fragments(const GC_Chat *chat, GC_Connection *gcon assert(entry->packet_type == GP_FRAGMENT); - gcc_encrypt_and_send_lossless_packet(chat, gconn, entry->data, entry->data_length, - entry->message_id, entry->packet_type); + gcc_encrypt_and_send_lossless_packet( + chat, gconn, entry->data, entry->data_length, entry->message_id, entry->packet_type); } return true; } -bool gcc_handle_ack(const Logger *log, GC_Connection *gconn, uint64_t message_id) +bool gcc_handle_ack(const Logger *log, GC_Connection *gconn, uint64_t message_id, const Memory *mem) { uint16_t idx = gcc_get_array_index(message_id); GC_Message_Array_Entry *array_entry = &gconn->send_array[idx]; @@ -255,7 +259,7 @@ bool gcc_handle_ack(const Logger *log, GC_Connection *gconn, uint64_t message_id return false; } - clear_array_entry(array_entry); + clear_array_entry(array_entry, mem); /* Put send_array_start in proper position */ if (idx == gconn->send_array_start) { @@ -336,15 +340,15 @@ int gcc_save_tcp_relay(const Random *rng, GC_Connection *gconn, const Node_forma * * Return true on success. */ -non_null(1, 2, 3) nullable(4) -static bool store_in_recv_array(const Logger *log, const Mono_Time *mono_time, GC_Connection *gconn, - const uint8_t *data, - uint16_t length, uint8_t packet_type, uint64_t message_id) +non_null(1, 2, 3, 8) nullable(4) +static bool store_in_recv_array(const Logger *log, + const Mono_Time *mono_time, GC_Connection *gconn, const uint8_t *data, uint16_t length, + uint8_t packet_type, uint64_t message_id, const Memory *mem) { const uint16_t idx = gcc_get_array_index(message_id); GC_Message_Array_Entry *ary_entry = &gconn->recv_array[idx]; - return create_array_entry(log, mono_time, ary_entry, data, length, packet_type, message_id); + return create_array_entry(log, mono_time, ary_entry, data, length, packet_type, message_id, mem); } /** @@ -358,8 +362,8 @@ static bool store_in_recv_array(const Logger *log, const Mono_Time *mono_time, G * Return the length of the fully reassembled packet on success. * Return 0 on failure. */ -non_null(1, 3) nullable(2) -static uint16_t reassemble_packet(const Logger *log, GC_Connection *gconn, uint8_t **payload, uint64_t message_id) +non_null(1, 3, 5) nullable(2) static uint16_t reassemble_packet(const Logger *log, + GC_Connection *gconn, uint8_t **payload, uint64_t message_id, const Memory *mem) { uint16_t end_idx = gcc_get_array_index(message_id - 1); uint16_t start_idx = end_idx; @@ -378,7 +382,8 @@ static uint16_t reassemble_packet(const Logger *log, GC_Connection *gconn, uint8 packet_length = diff; if (packet_length > MAX_GC_PACKET_SIZE) { - LOGGER_ERROR(log, "Payload of size %u exceeded max packet size", packet_length); // should never happen + LOGGER_ERROR(log, "Payload of size %u exceeded max packet size", + packet_length); // should never happen return 0; } @@ -395,7 +400,7 @@ static uint16_t reassemble_packet(const Logger *log, GC_Connection *gconn, uint8 return 0; } - uint8_t *tmp_payload = (uint8_t *)malloc(packet_length); + uint8_t *tmp_payload = (uint8_t *)mem_balloc(mem, packet_length); if (tmp_payload == nullptr) { LOGGER_ERROR(log, "Failed to allocate %u bytes for payload buffer", packet_length); @@ -414,7 +419,7 @@ static uint16_t reassemble_packet(const Logger *log, GC_Connection *gconn, uint8 memcpy(tmp_payload + processed, entry->data, entry->data_length); processed += entry->data_length; - clear_array_entry(entry); + clear_array_entry(entry, mem); } assert(*payload == nullptr); @@ -428,7 +433,8 @@ int gcc_handle_packet_fragment(const GC_Session *c, GC_Chat *chat, uint32_t peer uint64_t message_id, void *userdata) { if (length > 0) { - if (!store_in_recv_array(chat->log, chat->mono_time, gconn, chunk, length, packet_type, message_id)) { + if (!store_in_recv_array(chat->log, chat->mono_time, gconn, chunk, length, packet_type, + message_id, chat->mem)) { return -1; } @@ -442,15 +448,17 @@ int gcc_handle_packet_fragment(const GC_Session *c, GC_Chat *chat, uint32_t peer memcpy(sender_pk, get_enc_key(&gconn->addr.public_key), ENC_PUBLIC_KEY_SIZE); uint8_t *payload = nullptr; - const uint16_t processed_len = reassemble_packet(chat->log, gconn, &payload, message_id); + const uint16_t processed_len + = reassemble_packet(chat->log, gconn, &payload, message_id, chat->mem); if (processed_len == 0) { - free(payload); + mem_delete(chat->mem, payload); return -1; } - if (!handle_gc_lossless_helper(c, chat, peer_number, payload + 1, processed_len - 1, payload[0], userdata)) { - free(payload); + if (!handle_gc_lossless_helper( + c, chat, peer_number, payload + 1, processed_len - 1, payload[0], userdata)) { + mem_delete(chat->mem, payload); return -1; } @@ -466,14 +474,14 @@ int gcc_handle_packet_fragment(const GC_Session *c, GC_Chat *chat, uint32_t peer gcc_set_recv_message_id(gconn, gconn->received_message_id + 1); gconn->last_chunk_id = 0; - free(payload); + mem_delete(chat->mem, payload); return 0; } int gcc_handle_received_message(const Logger *log, const Mono_Time *mono_time, GC_Connection *gconn, const uint8_t *data, uint16_t length, uint8_t packet_type, uint64_t message_id, - bool direct_conn) + bool direct_conn, const Memory *mem) { if (direct_conn) { gconn->last_received_direct_time = mono_time_get(mono_time); @@ -484,13 +492,14 @@ int gcc_handle_received_message(const Logger *log, const Mono_Time *mono_time, G return 0; } - if (packet_type == GP_FRAGMENT) { // we handle packet fragments as a special case + if (packet_type == GP_FRAGMENT) { // we handle packet fragments as a special case return 3; } /* we're missing an older message from this peer so we store it in recv_array */ if (message_id > gconn->received_message_id + 1) { - if (!store_in_recv_array(log, mono_time, gconn, data, length, packet_type, message_id)) { + if (!store_in_recv_array( + log, mono_time, gconn, data, length, packet_type, message_id, mem)) { return -1; } @@ -508,21 +517,21 @@ int gcc_handle_received_message(const Logger *log, const Mono_Time *mono_time, G * * Return true on success. */ -non_null(1, 2, 3, 5) nullable(6) -static bool process_recv_array_entry(const GC_Session *c, GC_Chat *chat, GC_Connection *gconn, uint32_t peer_number, - GC_Message_Array_Entry *const array_entry, void *userdata) +non_null(1, 2, 3, 5) nullable(6) static bool process_recv_array_entry(const GC_Session *c, + GC_Chat *chat, GC_Connection *gconn, uint32_t peer_number, + GC_Message_Array_Entry *const array_entry, void *userdata) { uint8_t sender_pk[ENC_PUBLIC_KEY_SIZE]; memcpy(sender_pk, get_enc_key(&gconn->addr.public_key), ENC_PUBLIC_KEY_SIZE); - const bool ret = handle_gc_lossless_helper(c, chat, peer_number, array_entry->data, array_entry->data_length, - array_entry->packet_type, userdata); + const bool ret = handle_gc_lossless_helper(c, chat, peer_number, array_entry->data, + array_entry->data_length, array_entry->packet_type, userdata); /* peer number can change from peer add operations in packet handlers */ peer_number = get_peer_number_of_enc_pk(chat, sender_pk, false); gconn = get_gc_connection(chat, peer_number); - clear_array_entry(array_entry); + clear_array_entry(array_entry, chat->mem); if (gconn == nullptr) { return true; @@ -540,8 +549,8 @@ static bool process_recv_array_entry(const GC_Session *c, GC_Chat *chat, GC_Conn return true; } -void gcc_check_recv_array(const GC_Session *c, GC_Chat *chat, GC_Connection *gconn, uint32_t peer_number, - void *userdata) +void gcc_check_recv_array( + const GC_Session *c, GC_Chat *chat, GC_Connection *gconn, uint32_t peer_number, void *userdata) { if (gconn->last_chunk_id != 0) { // dont check array if we have an unfinished fragment sequence return; @@ -589,13 +598,14 @@ void gcc_resend_packets(const GC_Chat *chat, GC_Connection *gconn) /* if this occurrs less than once per second this won't be reliable */ if (delta > 1 && is_power_of_2(delta)) { - gcc_encrypt_and_send_lossless_packet(chat, gconn, array_entry->data, array_entry->data_length, - array_entry->message_id, array_entry->packet_type); + gcc_encrypt_and_send_lossless_packet(chat, gconn, array_entry->data, + array_entry->data_length, array_entry->message_id, array_entry->packet_type); } } } -bool gcc_send_packet(const GC_Chat *chat, const GC_Connection *gconn, const uint8_t *packet, uint16_t length) +bool gcc_send_packet( + const GC_Chat *chat, const GC_Connection *gconn, const uint8_t *packet, uint16_t length) { if (packet == nullptr || length == 0) { return false; @@ -605,46 +615,47 @@ bool gcc_send_packet(const GC_Chat *chat, const GC_Connection *gconn, const uint if (gcc_direct_conn_is_possible(chat, gconn)) { if (gcc_conn_is_direct(chat->mono_time, gconn)) { - return (uint16_t) sendpacket(chat->net, &gconn->addr.ip_port, packet, length) == length; + return (uint16_t)sendpacket(chat->net, &gconn->addr.ip_port, packet, length) == length; } - if ((uint16_t) sendpacket(chat->net, &gconn->addr.ip_port, packet, length) == length) { + if ((uint16_t)sendpacket(chat->net, &gconn->addr.ip_port, packet, length) == length) { direct_send_attempt = true; } } - const int ret = send_packet_tcp_connection(chat->tcp_conn, gconn->tcp_connection_num, packet, length); + const int ret + = send_packet_tcp_connection(chat->tcp_conn, gconn->tcp_connection_num, packet, length); return ret == 0 || direct_send_attempt; } -int gcc_encrypt_and_send_lossless_packet(const GC_Chat *chat, const GC_Connection *gconn, const uint8_t *data, - uint16_t length, uint64_t message_id, uint8_t packet_type) +int gcc_encrypt_and_send_lossless_packet(const GC_Chat *chat, const GC_Connection *gconn, + const uint8_t *data, uint16_t length, uint64_t message_id, uint8_t packet_type) { const uint16_t packet_size = gc_get_wrapped_packet_size(length, NET_PACKET_GC_LOSSLESS); - uint8_t *packet = (uint8_t *)malloc(packet_size); + uint8_t *packet = (uint8_t *)mem_balloc(chat->mem, packet_size); if (packet == nullptr) { LOGGER_ERROR(chat->log, "Failed to allocate memory for packet buffer"); return -1; } - const int enc_len = group_packet_wrap( - chat->log, chat->rng, chat->self_public_key.enc, gconn->session_shared_key, packet, - packet_size, data, length, message_id, packet_type, NET_PACKET_GC_LOSSLESS); + const int enc_len = group_packet_wrap(chat->log, chat->mem, chat->rng, chat->self_public_key.enc, + gconn->session_shared_key, packet, packet_size, data, length, message_id, packet_type, + NET_PACKET_GC_LOSSLESS); if (enc_len < 0) { LOGGER_ERROR(chat->log, "Failed to wrap packet (type: 0x%02x, error: %d)", packet_type, enc_len); - free(packet); + mem_delete(chat->mem, packet); return -1; } if (!gcc_send_packet(chat, gconn, packet, (uint16_t)enc_len)) { LOGGER_DEBUG(chat->log, "Failed to send packet (type: 0x%02x, enc_len: %d)", packet_type, enc_len); - free(packet); + mem_delete(chat->mem, packet); return -2; } - free(packet); + mem_delete(chat->mem, packet); return 0; } @@ -661,7 +672,8 @@ bool gcc_conn_is_direct(const Mono_Time *mono_time, const GC_Connection *gconn) bool gcc_direct_conn_is_possible(const GC_Chat *chat, const GC_Connection *gconn) { - return !net_family_is_unspec(gconn->addr.ip_port.ip.family) && !net_family_is_unspec(net_family(chat->net)); + return !net_family_is_unspec(gconn->addr.ip_port.ip.family) + && !net_family_is_unspec(net_family(chat->net)); } void gcc_mark_for_deletion(GC_Connection *gconn, TCP_Connections *tcp_conn, Group_Exit_Type type, @@ -680,21 +692,21 @@ void gcc_mark_for_deletion(GC_Connection *gconn, TCP_Connections *tcp_conn, Grou kill_tcp_connection_to(tcp_conn, gconn->tcp_connection_num); - if (length > 0 && length <= MAX_GC_PART_MESSAGE_SIZE && part_message != nullptr) { + if (length > 0 && length <= MAX_GC_PART_MESSAGE_SIZE && part_message != nullptr) { memcpy(gconn->exit_info.part_message, part_message, length); gconn->exit_info.length = length; } } -void gcc_peer_cleanup(GC_Connection *gconn) +void gcc_peer_cleanup(GC_Connection *gconn, const Memory *mem) { for (size_t i = 0; i < GCC_BUFFER_SIZE; ++i) { - free(gconn->send_array[i].data); - free(gconn->recv_array[i].data); + mem_delete(mem, gconn->send_array[i].data); + mem_delete(mem, gconn->recv_array[i].data); } - free(gconn->recv_array); - free(gconn->send_array); + mem_delete(mem, gconn->recv_array); + mem_delete(mem, gconn->send_array); crypto_memunlock(gconn->session_secret_key, sizeof(gconn->session_secret_key)); crypto_memunlock(gconn->session_shared_key, sizeof(gconn->session_shared_key)); @@ -707,6 +719,6 @@ void gcc_cleanup(const GC_Chat *chat) GC_Connection *gconn = get_gc_connection(chat, i); assert(gconn != nullptr); - gcc_peer_cleanup(gconn); + gcc_peer_cleanup(gconn, chat->mem); } } diff --git a/toxcore/group_connection.h b/toxcore/group_connection.h index 4a9ccad0b3..7648f4507b 100644 --- a/toxcore/group_connection.h +++ b/toxcore/group_connection.h @@ -16,6 +16,7 @@ #include "crypto_core.h" #include "group_common.h" #include "logger.h" +#include "mem.h" #include "mono_time.h" #include "network.h" @@ -35,10 +36,10 @@ void gcc_mark_for_deletion(GC_Connection *gconn, TCP_Connections *tcp_conn, Grou * Return 0 if message is a duplicate. * Return -1 on failure */ -non_null(1, 2, 3) nullable(4) +non_null(1, 2, 3, 9) nullable(4) int gcc_handle_received_message(const Logger *log, const Mono_Time *mono_time, GC_Connection *gconn, const uint8_t *data, uint16_t length, uint8_t packet_type, uint64_t message_id, - bool direct_conn); + bool direct_conn, const Memory *mem); /** @brief Handles a packet fragment. * @@ -63,7 +64,7 @@ uint16_t gcc_get_array_index(uint64_t message_id); * Return true on success. */ non_null() -bool gcc_handle_ack(const Logger *log, GC_Connection *gconn, uint64_t message_id); +bool gcc_handle_ack(const Logger *log, GC_Connection *gconn, uint64_t message_id, const Memory *mem); /** @brief Sets the send_message_id and send_array_start for `gconn` to `id`. * @@ -188,7 +189,7 @@ int gcc_encrypt_and_send_lossless_packet(const GC_Chat *chat, const GC_Connectio /** @brief Called when a peer leaves the group. */ non_null() -void gcc_peer_cleanup(GC_Connection *gconn); +void gcc_peer_cleanup(GC_Connection *gconn, const Memory *mem); /** @brief Called on group exit. */ non_null() diff --git a/toxcore/group_moderation.c b/toxcore/group_moderation.c index 3cb69e9403..bbc4ad9cfb 100644 --- a/toxcore/group_moderation.c +++ b/toxcore/group_moderation.c @@ -11,7 +11,6 @@ #include -#include #include #include @@ -20,6 +19,7 @@ #include "ccompat.h" #include "crypto_core.h" #include "logger.h" +#include "mem.h" #include "network.h" #include "util.h" @@ -51,7 +51,7 @@ int mod_list_unpack(Moderation *moderation, const uint8_t *data, uint16_t length return 0; } - uint8_t **tmp_list = (uint8_t **)calloc(num_mods, sizeof(uint8_t *)); + uint8_t **tmp_list = (uint8_t **)mem_valloc(moderation->mem, num_mods, sizeof(uint8_t *)); if (tmp_list == nullptr) { return -1; @@ -60,7 +60,7 @@ int mod_list_unpack(Moderation *moderation, const uint8_t *data, uint16_t length uint16_t unpacked_len = 0; for (uint16_t i = 0; i < num_mods; ++i) { - uint8_t *entry = (uint8_t *)malloc(MOD_LIST_ENTRY_SIZE); + uint8_t *entry = (uint8_t *)mem_balloc(moderation->mem, MOD_LIST_ENTRY_SIZE); if (entry == nullptr) { free_uint8_t_pointer_array(moderation->mem, tmp_list, i); @@ -102,7 +102,7 @@ bool mod_list_make_hash(const Moderation *moderation, uint8_t *hash) assert(data_buf_size > 0); - uint8_t *data = (uint8_t *)malloc(data_buf_size); + uint8_t *data = (uint8_t *)mem_balloc(moderation->mem, data_buf_size); if (data == nullptr) { return false; @@ -112,7 +112,7 @@ bool mod_list_make_hash(const Moderation *moderation, uint8_t *hash) mod_list_get_data_hash(hash, data, data_buf_size); - free(data); + mem_delete(moderation->mem, data); return true; } @@ -166,10 +166,10 @@ bool mod_list_remove_index(Moderation *moderation, uint16_t index) MOD_LIST_ENTRY_SIZE); } - free(moderation->mod_list[moderation->num_mods]); + mem_delete(moderation->mem, moderation->mod_list[moderation->num_mods]); moderation->mod_list[moderation->num_mods] = nullptr; - uint8_t **tmp_list = (uint8_t **)realloc(moderation->mod_list, moderation->num_mods * sizeof(uint8_t *)); + uint8_t **tmp_list = (uint8_t **)mem_vrealloc(moderation->mem, moderation->mod_list, moderation->num_mods, sizeof(uint8_t *)); if (tmp_list == nullptr) { return false; @@ -203,7 +203,7 @@ bool mod_list_add_entry(Moderation *moderation, const uint8_t *mod_data) return false; } - uint8_t **tmp_list = (uint8_t **)realloc(moderation->mod_list, (moderation->num_mods + 1) * sizeof(uint8_t *)); + uint8_t **tmp_list = (uint8_t **)mem_vrealloc(moderation->mem, moderation->mod_list, moderation->num_mods + 1, sizeof(uint8_t *)); if (tmp_list == nullptr) { return false; @@ -211,7 +211,7 @@ bool mod_list_add_entry(Moderation *moderation, const uint8_t *mod_data) moderation->mod_list = tmp_list; - uint8_t *entry = (uint8_t *)malloc(MOD_LIST_ENTRY_SIZE); + uint8_t *entry = (uint8_t *)mem_balloc(moderation->mem, MOD_LIST_ENTRY_SIZE); if (entry == nullptr) { return false; @@ -405,9 +405,9 @@ int sanctions_list_unpack(Mod_Sanction *sanctions, Mod_Sanction_Creds *creds, ui * * Return true on success. */ -non_null(4) nullable(1) +non_null(4, 5) nullable(1) static bool sanctions_list_make_hash(const Mod_Sanction *sanctions, uint32_t new_version, uint16_t num_sanctions, - uint8_t *hash) + uint8_t *hash, const Memory *mem) { if (num_sanctions == 0 || sanctions == nullptr) { memzero(hash, MOD_SANCTION_HASH_SIZE); @@ -422,7 +422,7 @@ static bool sanctions_list_make_hash(const Mod_Sanction *sanctions, uint32_t new return false; } - uint8_t *data = (uint8_t *)malloc(data_buf_size); + uint8_t *data = (uint8_t *)mem_balloc(mem, data_buf_size); if (data == nullptr) { return false; @@ -435,7 +435,7 @@ static bool sanctions_list_make_hash(const Mod_Sanction *sanctions, uint32_t new memcpy(&data[sig_data_size], &new_version, sizeof(uint32_t)); crypto_sha256(hash, data, data_buf_size); - free(data); + mem_delete(mem, data); return true; } @@ -493,7 +493,7 @@ bool sanctions_list_make_creds(Moderation *moderation) uint8_t hash[MOD_SANCTION_HASH_SIZE]; if (!sanctions_list_make_hash(moderation->sanctions, moderation->sanctions_creds.version, - moderation->num_sanctions, hash)) { + moderation->num_sanctions, hash, moderation->mem)) { moderation->sanctions_creds = old_creds; return false; } @@ -533,7 +533,7 @@ static bool sanctions_creds_validate(const Moderation *moderation, const Mod_San uint8_t hash[MOD_SANCTION_HASH_SIZE]; - if (!sanctions_list_make_hash(sanctions, creds->version, num_sanctions, hash)) { + if (!sanctions_list_make_hash(sanctions, creds->version, num_sanctions, hash, moderation->mem)) { return false; } @@ -612,9 +612,9 @@ static bool sanctions_apply_new(Moderation *moderation, Mod_Sanction *new_sancti * memory returned by this function. */ non_null() -static Mod_Sanction *sanctions_list_copy(const Mod_Sanction *sanctions, uint16_t num_sanctions) +static Mod_Sanction *sanctions_list_copy(const Mod_Sanction *sanctions, uint16_t num_sanctions, const Memory *mem) { - Mod_Sanction *copy = (Mod_Sanction *)calloc(num_sanctions, sizeof(Mod_Sanction)); + Mod_Sanction *copy = (Mod_Sanction *)mem_valloc(mem, num_sanctions, sizeof(Mod_Sanction)); if (copy == nullptr) { return nullptr; @@ -655,7 +655,7 @@ static bool sanctions_list_remove_index(Moderation *moderation, uint16_t index, } /* Operate on a copy of the list in case something goes wrong. */ - Mod_Sanction *sanctions_copy = sanctions_list_copy(moderation->sanctions, moderation->num_sanctions); + Mod_Sanction *sanctions_copy = sanctions_list_copy(moderation->sanctions, moderation->num_sanctions, moderation->mem); if (sanctions_copy == nullptr) { return false; @@ -665,15 +665,15 @@ static bool sanctions_list_remove_index(Moderation *moderation, uint16_t index, sanctions_copy[index] = sanctions_copy[new_num]; } - Mod_Sanction *new_list = (Mod_Sanction *)realloc(sanctions_copy, new_num * sizeof(Mod_Sanction)); + Mod_Sanction *new_list = (Mod_Sanction *)mem_vrealloc(moderation->mem, sanctions_copy, new_num, sizeof(Mod_Sanction)); if (new_list == nullptr) { - free(sanctions_copy); + mem_delete(moderation->mem, sanctions_copy); return false; } if (!sanctions_apply_new(moderation, new_list, creds, new_num)) { - free(new_list); + mem_delete(moderation->mem, new_list); return false; } @@ -753,7 +753,7 @@ bool sanctions_list_add_entry(Moderation *moderation, const Mod_Sanction *sancti Mod_Sanction *sanctions_copy = nullptr; if (moderation->num_sanctions > 0) { - sanctions_copy = sanctions_list_copy(moderation->sanctions, moderation->num_sanctions); + sanctions_copy = sanctions_list_copy(moderation->sanctions, moderation->num_sanctions, moderation->mem); if (sanctions_copy == nullptr) { return false; @@ -761,17 +761,17 @@ bool sanctions_list_add_entry(Moderation *moderation, const Mod_Sanction *sancti } const uint16_t index = moderation->num_sanctions; - Mod_Sanction *new_list = (Mod_Sanction *)realloc(sanctions_copy, (index + 1) * sizeof(Mod_Sanction)); + Mod_Sanction *new_list = (Mod_Sanction *)mem_vrealloc(moderation->mem, sanctions_copy, index + 1, sizeof(Mod_Sanction)); if (new_list == nullptr) { - free(sanctions_copy); + mem_delete(moderation->mem, sanctions_copy); return false; } new_list[index] = *sanction; if (!sanctions_apply_new(moderation, new_list, creds, index + 1)) { - free(new_list); + mem_delete(moderation->mem, new_list); return false; } @@ -864,7 +864,7 @@ uint16_t sanctions_list_replace_sig(Moderation *moderation, const uint8_t *publi void sanctions_list_cleanup(Moderation *moderation) { - free(moderation->sanctions); + mem_delete(moderation->mem, moderation->sanctions); moderation->sanctions = nullptr; moderation->num_sanctions = 0; diff --git a/toxcore/group_onion_announce.c b/toxcore/group_onion_announce.c index d05db09a07..4a270a0160 100644 --- a/toxcore/group_onion_announce.c +++ b/toxcore/group_onion_announce.c @@ -14,6 +14,7 @@ #include "crypto_core.h" #include "group_announce.h" #include "logger.h" +#include "mem.h" #include "mono_time.h" #include "network.h" #include "onion_announce.h" @@ -76,10 +77,10 @@ void gca_onion_init(GC_Announces_List *group_announce, Onion_Announce *onion_a) } int create_gca_announce_request( - const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *dest_client_id, - const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *ping_id, - const uint8_t *client_id, const uint8_t *data_public_key, uint64_t sendback_data, - const uint8_t *gc_data, uint16_t gc_data_length) + const Random *rng, const Memory *mem, uint8_t *packet, uint16_t max_packet_length, + const uint8_t *dest_client_id, const uint8_t *public_key, const uint8_t *secret_key, + const uint8_t *ping_id, const uint8_t *client_id, const uint8_t *data_public_key, + uint64_t sendback_data, const uint8_t *gc_data, uint16_t gc_data_length) { if (max_packet_length < ONION_ANNOUNCE_REQUEST_MAX_SIZE || gc_data_length == 0) { return -1; @@ -109,7 +110,8 @@ int create_gca_announce_request( memcpy(packet + 1 + CRYPTO_NONCE_SIZE, public_key, CRYPTO_PUBLIC_KEY_SIZE); const int len = encrypt_data(dest_client_id, secret_key, packet + 1, plain, - encrypted_size, packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE); + encrypted_size, packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE, + mem); const uint32_t full_length = (uint32_t)len + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE; diff --git a/toxcore/group_onion_announce.h b/toxcore/group_onion_announce.h index 5fbac02e0a..37488407cf 100644 --- a/toxcore/group_onion_announce.h +++ b/toxcore/group_onion_announce.h @@ -9,6 +9,7 @@ #include "attributes.h" #include "crypto_core.h" #include "group_announce.h" +#include "mem.h" #include "onion_announce.h" non_null() @@ -16,9 +17,9 @@ void gca_onion_init(GC_Announces_List *group_announce, Onion_Announce *onion_a); non_null() int create_gca_announce_request( - const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *dest_client_id, - const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *ping_id, - const uint8_t *client_id, const uint8_t *data_public_key, uint64_t sendback_data, - const uint8_t *gc_data, uint16_t gc_data_length); + const Random *rng, const Memory *mem, uint8_t *packet, uint16_t max_packet_length, + const uint8_t *dest_client_id, const uint8_t *public_key, const uint8_t *secret_key, + const uint8_t *ping_id, const uint8_t *client_id, const uint8_t *data_public_key, + uint64_t sendback_data, const uint8_t *gc_data, uint16_t gc_data_length); #endif /* C_TOXCORE_TOXCORE_GROUP_ONION_ANNOUNCE_H */ diff --git a/toxcore/group_pack.c b/toxcore/group_pack.c index c20d6a1213..6047550c6d 100644 --- a/toxcore/group_pack.c +++ b/toxcore/group_pack.c @@ -10,7 +10,6 @@ #include "group_pack.h" #include -#include #include #include "DHT.h" @@ -23,6 +22,7 @@ #include "group_common.h" #include "group_moderation.h" #include "logger.h" +#include "mem.h" #include "network.h" #include "util.h" @@ -180,7 +180,7 @@ static bool load_unpack_mod_list(GC_Chat *chat, Bin_Unpack *bu) chat->moderation.num_mods = MOD_MAX_NUM_MODERATORS; } - uint8_t *packed_mod_list = (uint8_t *)malloc(chat->moderation.num_mods * MOD_LIST_ENTRY_SIZE); + uint8_t *packed_mod_list = (uint8_t *)mem_balloc(chat->mem, chat->moderation.num_mods * MOD_LIST_ENTRY_SIZE); if (packed_mod_list == nullptr) { LOGGER_ERROR(chat->log, "Failed to allocate memory for packed mod list"); @@ -191,17 +191,17 @@ static bool load_unpack_mod_list(GC_Chat *chat, Bin_Unpack *bu) if (!bin_unpack_bin_fixed(bu, packed_mod_list, packed_size)) { LOGGER_ERROR(chat->log, "Failed to unpack mod list binary data"); - free(packed_mod_list); + mem_delete(chat->mem, packed_mod_list); return false; } if (mod_list_unpack(&chat->moderation, packed_mod_list, packed_size, chat->moderation.num_mods) == -1) { LOGGER_ERROR(chat->log, "Failed to unpack mod list info"); - free(packed_mod_list); + mem_delete(chat->mem, packed_mod_list); return false; } - free(packed_mod_list); + mem_delete(chat->mem, packed_mod_list); return true; } @@ -299,7 +299,7 @@ static bool load_unpack_saved_peers(GC_Chat *chat, Bin_Unpack *bu) return true; } - uint8_t *saved_peers = (uint8_t *)malloc(saved_peers_size * GC_SAVED_PEER_SIZE); + uint8_t *saved_peers = (uint8_t *)mem_balloc(chat->mem, saved_peers_size * GC_SAVED_PEER_SIZE); if (saved_peers == nullptr) { LOGGER_ERROR(chat->log, "Failed to allocate memory for saved peer list"); @@ -308,7 +308,7 @@ static bool load_unpack_saved_peers(GC_Chat *chat, Bin_Unpack *bu) if (!bin_unpack_bin_fixed(bu, saved_peers, saved_peers_size)) { LOGGER_ERROR(chat->log, "Failed to unpack saved peers binary data"); - free(saved_peers); + mem_delete(chat->mem, saved_peers); return false; } @@ -316,7 +316,7 @@ static bool load_unpack_saved_peers(GC_Chat *chat, Bin_Unpack *bu) LOGGER_ERROR(chat->log, "Failed to unpack saved peers"); // recoverable error } - free(saved_peers); + mem_delete(chat->mem, saved_peers); return true; } @@ -390,7 +390,7 @@ static void save_pack_mod_list(const GC_Chat *chat, Bin_Pack *bp) return; } - uint8_t *packed_mod_list = (uint8_t *)malloc(num_mods * MOD_LIST_ENTRY_SIZE); + uint8_t *packed_mod_list = (uint8_t *)mem_balloc(chat->mem, num_mods * MOD_LIST_ENTRY_SIZE); // we can still recover without the mod list if (packed_mod_list == nullptr) { @@ -408,7 +408,7 @@ static void save_pack_mod_list(const GC_Chat *chat, Bin_Pack *bp) bin_pack_bin(bp, packed_mod_list, packed_size); // 2 - free(packed_mod_list); + mem_delete(chat->mem, packed_mod_list); } non_null() @@ -445,7 +445,7 @@ static void save_pack_saved_peers(const GC_Chat *chat, Bin_Pack *bp) { bin_pack_array(bp, 2); - uint8_t *saved_peers = (uint8_t *)malloc(GC_MAX_SAVED_PEERS * GC_SAVED_PEER_SIZE); + uint8_t *saved_peers = (uint8_t *)mem_balloc(chat->mem, GC_MAX_SAVED_PEERS * GC_SAVED_PEER_SIZE); // we can still recover without the saved peers list if (saved_peers == nullptr) { @@ -466,13 +466,13 @@ static void save_pack_saved_peers(const GC_Chat *chat, Bin_Pack *bp) if (packed_size == 0) { bin_pack_nil(bp); // 2 - free(saved_peers); + mem_delete(chat->mem, saved_peers); return; } bin_pack_bin(bp, saved_peers, packed_size); // 2 - free(saved_peers); + mem_delete(chat->mem, saved_peers); } void gc_save_pack_group(const GC_Chat *chat, Bin_Pack *bp) diff --git a/toxcore/list.c b/toxcore/list.c index bf3db247f1..9d44beadba 100644 --- a/toxcore/list.c +++ b/toxcore/list.c @@ -12,11 +12,11 @@ #include #include -#include #include #include "attributes.h" #include "ccompat.h" +#include "mem.h" /** * Basically, the elements in the list are placed in order so that they can be searched for easily @@ -115,7 +115,7 @@ static bool resize(BS_List *list, uint32_t new_size) return true; } - uint8_t *data = (uint8_t *)realloc(list->data, list->element_size * new_size); + uint8_t *data = (uint8_t *)mem_brealloc(list->mem, list->data, new_size * list->element_size); if (data == nullptr) { return false; @@ -123,7 +123,7 @@ static bool resize(BS_List *list, uint32_t new_size) list->data = data; - int *ids = (int *)realloc(list->ids, new_size * sizeof(int)); + int *ids = (int *)mem_brealloc(list->mem, list->ids, new_size * sizeof(int)); if (ids == nullptr) { return false; @@ -134,8 +134,10 @@ static bool resize(BS_List *list, uint32_t new_size) return true; } -int bs_list_init(BS_List *list, uint32_t element_size, uint32_t initial_capacity, bs_list_cmp_cb *cmp_callback) +int bs_list_init(BS_List *list, uint32_t element_size, uint32_t initial_capacity, bs_list_cmp_cb *cmp_callback, const Memory *mem) { + list->mem = mem; + // set initial values list->n = 0; list->element_size = element_size; @@ -162,10 +164,10 @@ void bs_list_free(BS_List *list) } // free both arrays - free(list->data); + mem_delete(list->mem, list->data); list->data = nullptr; - free(list->ids); + mem_delete(list->mem, list->ids); list->ids = nullptr; } diff --git a/toxcore/list.h b/toxcore/list.h index 1dc66d01a4..20afaded61 100644 --- a/toxcore/list.h +++ b/toxcore/list.h @@ -16,6 +16,7 @@ #include #include "attributes.h" +#include "mem.h" #ifdef __cplusplus extern "C" { @@ -24,6 +25,8 @@ extern "C" { typedef int bs_list_cmp_cb(const void *a, const void *b, size_t size); typedef struct BS_List { + const Memory *mem; + uint32_t n; // number of elements uint32_t capacity; // number of elements memory is allocated for uint32_t element_size; // size of the elements @@ -41,7 +44,7 @@ typedef struct BS_List { * @retval 0 failure */ non_null() -int bs_list_init(BS_List *list, uint32_t element_size, uint32_t initial_capacity, bs_list_cmp_cb *cmp_callback); +int bs_list_init(BS_List *list, uint32_t element_size, uint32_t initial_capacity, bs_list_cmp_cb *cmp_callback, const Memory *mem); /** Free a list initiated with list_init */ nullable(1) diff --git a/toxcore/list_test.cc b/toxcore/list_test.cc index 0d8f646c10..35a7ff7641 100644 --- a/toxcore/list_test.cc +++ b/toxcore/list_test.cc @@ -2,26 +2,34 @@ #include +#include "mem.h" +#include "os_memory.h" + namespace { -TEST(List, CreateAndDestroyWithNonZeroSize) +struct List : ::testing::Test { +protected: + const Memory *mem_ = os_memory(); +}; + +TEST_F(List, CreateAndDestroyWithNonZeroSize) { BS_List list; - bs_list_init(&list, sizeof(int), 10, memcmp); + bs_list_init(&list, sizeof(int), 10, memcmp, mem_); bs_list_free(&list); } -TEST(List, CreateAndDestroyWithZeroSize) +TEST_F(List, CreateAndDestroyWithZeroSize) { BS_List list; - bs_list_init(&list, sizeof(int), 0, memcmp); + bs_list_init(&list, sizeof(int), 0, memcmp, mem_); bs_list_free(&list); } -TEST(List, DeleteFromEmptyList) +TEST_F(List, DeleteFromEmptyList) { BS_List list; - bs_list_init(&list, sizeof(int), 0, memcmp); + bs_list_init(&list, sizeof(int), 0, memcmp, mem_); const uint8_t data[sizeof(int)] = {0}; bs_list_remove(&list, data, 0); bs_list_free(&list); diff --git a/toxcore/logger.c b/toxcore/logger.c index 69d7f50fc3..e15ebb8833 100644 --- a/toxcore/logger.c +++ b/toxcore/logger.c @@ -8,13 +8,15 @@ */ #include "logger.h" +#include #include #include -#include +#include // IWYU pragma: keep #include #include "ccompat.h" #include "mem.h" +#include "mem.h" struct Logger { const Memory *mem; @@ -52,6 +54,7 @@ void logger_kill(Logger *log) void logger_callback_log(Logger *log, logger_cb *function, void *context, void *userdata) { + assert(log != nullptr); log->callback = function; log->context = context; log->userdata = userdata; diff --git a/toxcore/mem.c b/toxcore/mem.c index bddc335b82..d0b58ff2c1 100644 --- a/toxcore/mem.c +++ b/toxcore/mem.c @@ -1,61 +1,34 @@ /* SPDX-License-Identifier: GPL-3.0-or-later - * Copyright © 2016-2018 The TokTok team. + * Copyright © 2016-2023 The TokTok team. * Copyright © 2013 Tox project. */ #include "mem.h" -#include +#include #include "attributes.h" #include "ccompat.h" +#include "tox_memory.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 os_memory_funcs = { - sys_malloc, - sys_calloc, - sys_realloc, - sys_free, -}; -static const Memory os_memory_obj = {&os_memory_funcs}; - -const Memory *os_memory(void) +void *mem_balloc(const Memory *mem, uint32_t size) { - return &os_memory_obj; + void *const ptr = tox_memory_malloc(mem, size); + return ptr; } -void *mem_balloc(const Memory *mem, uint32_t size) +void *mem_brealloc(const Memory *mem, void *ptr, uint32_t size) { - void *const ptr = mem->funcs->malloc(mem->obj, size); - return ptr; + void *const new_ptr = tox_memory_realloc(mem, ptr, size); + return new_ptr; } void *mem_alloc(const Memory *mem, uint32_t size) { - void *const ptr = mem->funcs->calloc(mem->obj, 1, size); + void *const ptr = tox_memory_malloc(mem, size); + if (ptr != nullptr) { + memset(ptr, 0, size); + } return ptr; } @@ -67,7 +40,10 @@ void *mem_valloc(const Memory *mem, uint32_t nmemb, uint32_t size) return nullptr; } - void *const ptr = mem->funcs->calloc(mem->obj, nmemb, size); + void *const ptr = tox_memory_malloc(mem, bytes); + if (ptr != nullptr) { + memset(ptr, 0, bytes); + } return ptr; } @@ -79,11 +55,11 @@ void *mem_vrealloc(const Memory *mem, void *ptr, uint32_t nmemb, uint32_t size) return nullptr; } - void *const new_ptr = mem->funcs->realloc(mem->obj, ptr, bytes); + void *const new_ptr = tox_memory_realloc(mem, ptr, bytes); return new_ptr; } void mem_delete(const Memory *mem, void *ptr) { - mem->funcs->free(mem->obj, ptr); + tox_memory_dealloc(mem, ptr); } diff --git a/toxcore/mem.h b/toxcore/mem.h index 7a96b6d358..1db89a3c6c 100644 --- a/toxcore/mem.h +++ b/toxcore/mem.h @@ -12,30 +12,13 @@ #include // uint*_t #include "attributes.h" +#include "tox_memory.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 *os_memory(void); +typedef Tox_Memory Memory; /** * @brief Allocate an array of a given size for built-in types. @@ -45,6 +28,14 @@ const Memory *os_memory(void); */ non_null() void *mem_balloc(const Memory *mem, uint32_t size); +/** + * @brief Resize an array of a given size for built-in types. + * + * If used for a type other than byte-sized types, `size` needs to be manually + * multiplied by the element size. + */ +non_null(1) nullable(2) void *mem_brealloc(const Memory *mem, void *ptr, uint32_t size); + /** * @brief Allocate a single object. * diff --git a/toxcore/mem_test.cc b/toxcore/mem_test.cc index 5b649e2113..bdd567cf07 100644 --- a/toxcore/mem_test.cc +++ b/toxcore/mem_test.cc @@ -2,6 +2,8 @@ #include +#include "os_memory.h" + namespace { TEST(Mem, AllocLarge) @@ -25,15 +27,15 @@ TEST(Mem, AllocOverflow) const Memory *mem = os_memory(); // 1 gibi-elements of 100 bytes each. - void *ptr = mem_valloc(mem, GI, 100); + void *ptr = mem_vrealloc(mem, nullptr, GI, 100); EXPECT_EQ(ptr, nullptr); // 100 elements of 1 gibibyte each. - ptr = mem_valloc(mem, 100, GI); + ptr = mem_vrealloc(mem, nullptr, 100, GI); EXPECT_EQ(ptr, nullptr); // 128 (a multiple of 2) elements of 1 gibibyte each. - ptr = mem_valloc(mem, 128, GI); + ptr = mem_vrealloc(mem, nullptr, 128, GI); EXPECT_EQ(ptr, nullptr); } diff --git a/toxcore/mem_test_util.cc b/toxcore/mem_test_util.cc index 02ade8fc68..e628871030 100644 --- a/toxcore/mem_test_util.cc +++ b/toxcore/mem_test_util.cc @@ -2,28 +2,28 @@ #include -#include "mem.h" #include "test_util.hh" +#include "tox_memory_impl.h" -Memory_Funcs const Memory_Class::vtable = { - Method::invoke<&Memory_Class::malloc>, - Method::invoke<&Memory_Class::calloc>, - Method::invoke<&Memory_Class::realloc>, - Method::invoke<&Memory_Class::free>, +Tox_Memory_Funcs const Memory_Class::vtable = { + Method::invoke<&Memory_Class::malloc>, + Method::invoke<&Memory_Class::realloc>, + Method::invoke<&Memory_Class::dealloc>, }; Memory_Class::~Memory_Class() = default; -void *Test_Memory::malloc(void *obj, uint32_t size) { return mem->funcs->malloc(mem->obj, size); } - -void *Test_Memory::calloc(void *obj, uint32_t nmemb, uint32_t size) +void *Test_Memory::malloc(void *obj, uint32_t size) { - return mem->funcs->calloc(mem->obj, nmemb, size); + return mem->funcs->malloc_callback(mem->user_data, size); } void *Test_Memory::realloc(void *obj, void *ptr, uint32_t size) { - return mem->funcs->realloc(mem->obj, ptr, size); + return mem->funcs->realloc_callback(mem->user_data, ptr, size); } -void Test_Memory::free(void *obj, void *ptr) { return mem->funcs->free(mem->obj, ptr); } +void Test_Memory::dealloc(void *obj, void *ptr) +{ + return mem->funcs->dealloc_callback(mem->user_data, ptr); +} diff --git a/toxcore/mem_test_util.hh b/toxcore/mem_test_util.hh index 03094eb578..7a02a22e30 100644 --- a/toxcore/mem_test_util.hh +++ b/toxcore/mem_test_util.hh @@ -2,13 +2,15 @@ #define C_TOXCORE_TOXCORE_MEM_TEST_UTIL_H #include "mem.h" +#include "os_memory.h" #include "test_util.hh" +#include "tox_memory_impl.h" struct Memory_Class { - static Memory_Funcs const vtable; - Memory const self; + static Tox_Memory_Funcs const vtable; + Tox_Memory const self; - operator Memory const *() const { return &self; } + operator Tox_Memory const *() const { return &self; } Memory_Class(Memory_Class const &) = default; Memory_Class() @@ -17,10 +19,9 @@ struct Memory_Class { } virtual ~Memory_Class(); - virtual mem_malloc_cb malloc = 0; - virtual mem_calloc_cb calloc = 0; - virtual mem_realloc_cb realloc = 0; - virtual mem_free_cb free = 0; + virtual tox_memory_malloc_cb malloc = 0; + virtual tox_memory_realloc_cb realloc = 0; + virtual tox_memory_dealloc_cb dealloc = 0; }; /** @@ -28,12 +29,11 @@ struct Memory_Class { * subclassed to override individual (or all) functions. */ class Test_Memory : public Memory_Class { - const Memory *mem = REQUIRE_NOT_NULL(os_memory()); + const Tox_Memory *mem = REQUIRE_NOT_NULL(os_memory()); void *malloc(void *obj, uint32_t size) override; - void *calloc(void *obj, uint32_t nmemb, uint32_t size) override; void *realloc(void *obj, void *ptr, uint32_t size) override; - void free(void *obj, void *ptr) override; + void dealloc(void *obj, void *ptr) override; }; #endif // C_TOXCORE_TOXCORE_MEM_TEST_UTIL_H diff --git a/toxcore/mono_time.c b/toxcore/mono_time.c index 124f94fc23..bccfe7b29c 100644 --- a/toxcore/mono_time.c +++ b/toxcore/mono_time.c @@ -6,35 +6,16 @@ #define _XOPEN_SOURCE 600 #endif /* _XOPEN_SOURCE */ -#if !defined(OS_WIN32) && (defined(_WIN32) || defined(__WIN32__) || defined(WIN32)) -#define OS_WIN32 -#endif /* WIN32 */ - #include "mono_time.h" -#ifdef OS_WIN32 -#define WIN32_LEAN_AND_MEAN -#include -#endif /* OS_WIN32 */ - -#ifdef __APPLE__ -#include -#include -#endif /* __APPLE__ */ - -#ifndef OS_WIN32 -#include -#endif /* OS_WIN32 */ - -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -#include -#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ #include #include #include "attributes.h" #include "ccompat.h" #include "mem.h" +#include "os_time.h" +#include "tox_time.h" #include "util.h" /** don't call into system billions of times for no reason */ @@ -47,70 +28,10 @@ struct Mono_Time { pthread_rwlock_t *time_update_lock; #endif /* ESP_PLATFORM */ - mono_time_current_time_cb *current_time_callback; - void *user_data; + const Tox_Time *tm; }; -static uint64_t timespec_to_u64(struct timespec clock_mono) -{ - return UINT64_C(1000) * clock_mono.tv_sec + (clock_mono.tv_nsec / UINT64_C(1000000)); -} - -#ifdef OS_WIN32 -non_null() -static uint64_t current_time_monotonic_default(void *user_data) -{ - LARGE_INTEGER freq; - LARGE_INTEGER count; - if (!QueryPerformanceFrequency(&freq)) { - return 0; - } - if (!QueryPerformanceCounter(&count)) { - return 0; - } - struct timespec sp = {0}; - sp.tv_sec = count.QuadPart / freq.QuadPart; - if (freq.QuadPart < 1000000000) { - sp.tv_nsec = (count.QuadPart % freq.QuadPart) * 1000000000 / freq.QuadPart; - } else { - sp.tv_nsec = (long)((count.QuadPart % freq.QuadPart) * (1000000000.0 / freq.QuadPart)); - } - return timespec_to_u64(sp); -} -#else -#ifdef __APPLE__ -non_null() -static uint64_t current_time_monotonic_default(void *user_data) -{ - struct timespec clock_mono; - clock_serv_t muhclock; - mach_timespec_t machtime; - - host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &muhclock); - clock_get_time(muhclock, &machtime); - mach_port_deallocate(mach_task_self(), muhclock); - - clock_mono.tv_sec = machtime.tv_sec; - clock_mono.tv_nsec = machtime.tv_nsec; - return timespec_to_u64(clock_mono); -} -#else // !__APPLE__ -non_null() -static uint64_t current_time_monotonic_default(void *user_data) -{ -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - // This assert should always fail. If it does, the fuzzing harness didn't - // override the mono time callback. - assert(user_data == nullptr); -#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ - struct timespec clock_mono; - clock_gettime(CLOCK_MONOTONIC, &clock_mono); - return timespec_to_u64(clock_mono); -} -#endif /* !__APPLE__ */ -#endif /* !OS_WIN32 */ - -Mono_Time *mono_time_new(const Memory *mem, mono_time_current_time_cb *current_time_callback, void *user_data) +Mono_Time *mono_time_new(const Memory *mem, const Tox_Time *tm) { Mono_Time *mono_time = (Mono_Time *)mem_alloc(mem, sizeof(Mono_Time)); @@ -135,7 +56,7 @@ Mono_Time *mono_time_new(const Memory *mem, mono_time_current_time_cb *current_t mono_time->time_update_lock = rwlock; #endif /* ESP_PLATFORM */ - mono_time_set_current_time_callback(mono_time, current_time_callback, user_data); + mono_time_set_current_time_callback(mono_time, tm); mono_time->cur_time = 0; #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION @@ -166,8 +87,7 @@ void mono_time_free(const Memory *mem, Mono_Time *mono_time) void mono_time_update(Mono_Time *mono_time) { - const uint64_t cur_time = - mono_time->base_time + mono_time->current_time_callback(mono_time->user_data); + const uint64_t cur_time = tox_time_monotonic(mono_time->tm) + mono_time->base_time; #ifndef ESP_PLATFORM pthread_rwlock_wrlock(mono_time->time_update_lock); @@ -201,16 +121,9 @@ bool mono_time_is_timeout(const Mono_Time *mono_time, uint64_t timestamp, uint64 return timestamp + timeout <= mono_time_get(mono_time); } -void mono_time_set_current_time_callback(Mono_Time *mono_time, - mono_time_current_time_cb *current_time_callback, void *user_data) +void mono_time_set_current_time_callback(Mono_Time *mono_time, const Tox_Time *tm) { - if (current_time_callback == nullptr) { - mono_time->current_time_callback = current_time_monotonic_default; - mono_time->user_data = mono_time; - } else { - mono_time->current_time_callback = current_time_callback; - mono_time->user_data = user_data; - } + mono_time->tm = tm != nullptr ? tm : os_time(); } /** @brief Return current monotonic time in milliseconds (ms). @@ -218,7 +131,7 @@ void mono_time_set_current_time_callback(Mono_Time *mono_time, * The starting point is unspecified and in particular is likely not comparable * to the return value of `mono_time_get_ms()`. */ -uint64_t current_time_monotonic(Mono_Time *mono_time) +uint64_t current_time_monotonic(const Mono_Time *mono_time) { - return mono_time->current_time_callback(mono_time->user_data); + return tox_time_monotonic(mono_time->tm); } diff --git a/toxcore/mono_time.h b/toxcore/mono_time.h index d0f2b7a6d3..68a1e3fbdb 100644 --- a/toxcore/mono_time.h +++ b/toxcore/mono_time.h @@ -10,6 +10,7 @@ #include "attributes.h" #include "mem.h" +#include "tox_time.h" #ifdef __cplusplus extern "C" { @@ -46,10 +47,8 @@ extern "C" { */ typedef struct Mono_Time Mono_Time; -typedef uint64_t mono_time_current_time_cb(void *user_data); - -non_null(1) nullable(2, 3) -Mono_Time *mono_time_new(const Memory *mem, mono_time_current_time_cb *current_time_callback, void *user_data); +non_null(1) nullable(2) +Mono_Time *mono_time_new(const Memory *mem, const Tox_Time *tm); non_null(1) nullable(2) void mono_time_free(const Memory *mem, Mono_Time *mono_time); @@ -87,7 +86,7 @@ bool mono_time_is_timeout(const Mono_Time *mono_time, uint64_t timestamp, uint64 * to the return value of `mono_time_get_ms()`. */ non_null() -uint64_t current_time_monotonic(Mono_Time *mono_time); +uint64_t current_time_monotonic(const Mono_Time *mono_time); /** * Override implementation of `current_time_monotonic()` (for tests). @@ -95,9 +94,8 @@ uint64_t current_time_monotonic(Mono_Time *mono_time); * The caller is obligated to ensure that `current_time_monotonic()` continues * to increase monotonically. */ -non_null(1) nullable(2, 3) -void mono_time_set_current_time_callback(Mono_Time *mono_time, - mono_time_current_time_cb *current_time_callback, void *user_data); +non_null(1) nullable(2) +void mono_time_set_current_time_callback(Mono_Time *mono_time, const Tox_Time *tm); #ifdef __cplusplus } /* extern "C" */ diff --git a/toxcore/mono_time_test.cc b/toxcore/mono_time_test.cc index 0334f32322..80e883b2b8 100644 --- a/toxcore/mono_time_test.cc +++ b/toxcore/mono_time_test.cc @@ -6,13 +6,14 @@ #include #include "mem_test_util.hh" +#include "tox_time_impl.h" namespace { TEST(MonoTime, UnixTimeIncreasesOverTime) { Test_Memory mem; - Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); + Mono_Time *mono_time = mono_time_new(mem, nullptr); ASSERT_NE(mono_time, nullptr); mono_time_update(mono_time); @@ -31,7 +32,7 @@ TEST(MonoTime, UnixTimeIncreasesOverTime) TEST(MonoTime, IsTimeout) { Test_Memory mem; - Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); + Mono_Time *mono_time = mono_time_new(mem, nullptr); ASSERT_NE(mono_time, nullptr); uint64_t const start = mono_time_get(mono_time); @@ -49,7 +50,7 @@ TEST(MonoTime, IsTimeout) TEST(MonoTime, IsTimeoutReal) { Test_Memory mem; - Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); + Mono_Time *mono_time = mono_time_new(mem, nullptr); ASSERT_NE(mono_time, nullptr); uint64_t const start = mono_time_get(mono_time); @@ -70,13 +71,17 @@ TEST(MonoTime, IsTimeoutReal) TEST(MonoTime, CustomTime) { Test_Memory mem; - Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); + Mono_Time *mono_time = mono_time_new(mem, nullptr); ASSERT_NE(mono_time, nullptr); uint64_t test_time = current_time_monotonic(mono_time) + 42137; - mono_time_set_current_time_callback( - mono_time, [](void *user_data) { return *static_cast(user_data); }, &test_time); + constexpr Tox_Time_Funcs mock_time_funcs = { + [](void *user_data) { return *static_cast(user_data); }, + }; + Tox_Time *tm = tox_time_new(&mock_time_funcs, &test_time, mem); + ASSERT_NE(tm, nullptr); + mono_time_set_current_time_callback(mono_time, tm); mono_time_update(mono_time); EXPECT_EQ(current_time_monotonic(mono_time), test_time); @@ -91,6 +96,7 @@ TEST(MonoTime, CustomTime) EXPECT_EQ(current_time_monotonic(mono_time), test_time); mono_time_free(mem, mono_time); + tox_time_free(tm); } } // namespace diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 5aafe8a8a9..0c187b31c3 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -10,6 +10,7 @@ */ #include "net_crypto.h" +#include #include #include "DHT.h" @@ -231,7 +232,7 @@ static int create_cookie_request(const Net_Crypto *c, uint8_t *packet, const uin memcpy(packet + 1, dht_get_self_public_key(c->dht), CRYPTO_PUBLIC_KEY_SIZE); memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, nonce, CRYPTO_NONCE_SIZE); const int len = encrypt_data_symmetric(shared_key, nonce, plain, sizeof(plain), - packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE); + packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, c->mem); if (len != COOKIE_REQUEST_PLAIN_LENGTH + CRYPTO_MAC_SIZE) { return -1; @@ -246,7 +247,7 @@ static int create_cookie_request(const Net_Crypto *c, uint8_t *packet, const uin * @retval 0 on success. */ non_null() -static int create_cookie(const Random *rng, const Mono_Time *mono_time, uint8_t *cookie, const uint8_t *bytes, +static int create_cookie(const Random *rng, const Memory *mem, const Mono_Time *mono_time, uint8_t *cookie, const uint8_t *bytes, const uint8_t *encryption_key) { uint8_t contents[COOKIE_CONTENTS_LENGTH]; @@ -254,7 +255,7 @@ static int create_cookie(const Random *rng, const Mono_Time *mono_time, uint8_t memcpy(contents, &temp_time, sizeof(temp_time)); memcpy(contents + sizeof(temp_time), bytes, COOKIE_DATA_LENGTH); random_nonce(rng, cookie); - const int len = encrypt_data_symmetric(encryption_key, cookie, contents, sizeof(contents), cookie + CRYPTO_NONCE_SIZE); + const int len = encrypt_data_symmetric(encryption_key, cookie, contents, sizeof(contents), cookie + CRYPTO_NONCE_SIZE, mem); if (len != COOKIE_LENGTH - CRYPTO_NONCE_SIZE) { return -1; @@ -269,12 +270,12 @@ static int create_cookie(const Random *rng, const Mono_Time *mono_time, uint8_t * @retval 0 on success. */ non_null() -static int open_cookie(const Mono_Time *mono_time, uint8_t *bytes, const uint8_t *cookie, +static int open_cookie(const Memory *mem, const Mono_Time *mono_time, uint8_t *bytes, const uint8_t *cookie, const uint8_t *encryption_key) { uint8_t contents[COOKIE_CONTENTS_LENGTH]; const int len = decrypt_data_symmetric(encryption_key, cookie, cookie + CRYPTO_NONCE_SIZE, - COOKIE_LENGTH - CRYPTO_NONCE_SIZE, contents); + COOKIE_LENGTH - CRYPTO_NONCE_SIZE, contents, mem); if (len != sizeof(contents)) { return -1; @@ -308,14 +309,14 @@ static int create_cookie_response(const Net_Crypto *c, uint8_t *packet, const ui memcpy(cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, dht_public_key, CRYPTO_PUBLIC_KEY_SIZE); uint8_t plain[COOKIE_LENGTH + sizeof(uint64_t)]; - if (create_cookie(c->rng, c->mono_time, plain, cookie_plain, c->secret_symmetric_key) != 0) { + if (create_cookie(c->rng, c->mem, c->mono_time, plain, cookie_plain, c->secret_symmetric_key) != 0) { return -1; } memcpy(plain + COOKIE_LENGTH, request_plain + COOKIE_DATA_LENGTH, sizeof(uint64_t)); packet[0] = NET_PACKET_COOKIE_RESPONSE; random_nonce(c->rng, packet + 1); - const int len = encrypt_data_symmetric(shared_key, packet + 1, plain, sizeof(plain), packet + 1 + CRYPTO_NONCE_SIZE); + const int len = encrypt_data_symmetric(shared_key, packet + 1, plain, sizeof(plain), packet + 1 + CRYPTO_NONCE_SIZE, c->mem); if (len != COOKIE_RESPONSE_LENGTH - (1 + CRYPTO_NONCE_SIZE)) { return -1; @@ -344,7 +345,7 @@ static int handle_cookie_request(const Net_Crypto *c, uint8_t *request_plain, ui memcpy(shared_key, tmp_shared_key, CRYPTO_SHARED_KEY_SIZE); const int len = decrypt_data_symmetric(shared_key, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, COOKIE_REQUEST_PLAIN_LENGTH + CRYPTO_MAC_SIZE, - request_plain); + request_plain, c->mem); if (len != COOKIE_REQUEST_PLAIN_LENGTH) { return -1; @@ -441,7 +442,7 @@ static int tcp_oob_handle_cookie_request(const Net_Crypto *c, unsigned int tcp_c non_null() static int handle_cookie_response(uint8_t *cookie, uint64_t *number, const uint8_t *packet, uint16_t length, - const uint8_t *shared_key) + const uint8_t *shared_key, const Memory *mem) { if (length != COOKIE_RESPONSE_LENGTH) { return -1; @@ -449,7 +450,7 @@ static int handle_cookie_response(uint8_t *cookie, uint64_t *number, uint8_t plain[COOKIE_LENGTH + sizeof(uint64_t)]; const int len = decrypt_data_symmetric(shared_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE, - length - (1 + CRYPTO_NONCE_SIZE), plain); + length - (1 + CRYPTO_NONCE_SIZE), plain, mem); if (len != sizeof(plain)) { return -1; @@ -481,14 +482,14 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u memcpy(cookie_plain, peer_real_pk, CRYPTO_PUBLIC_KEY_SIZE); memcpy(cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, peer_dht_pubkey, CRYPTO_PUBLIC_KEY_SIZE); - if (create_cookie(c->rng, c->mono_time, plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE, + if (create_cookie(c->rng, c->mem, c->mono_time, plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE, cookie_plain, c->secret_symmetric_key) != 0) { return -1; } random_nonce(c->rng, packet + 1 + COOKIE_LENGTH); const int len = encrypt_data(peer_real_pk, c->self_secret_key, packet + 1 + COOKIE_LENGTH, plain, sizeof(plain), - packet + 1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE); + packet + 1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE, c->mem); if (len != HANDSHAKE_PACKET_LENGTH - (1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE)) { return -1; @@ -528,7 +529,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t uint8_t cookie_plain[COOKIE_DATA_LENGTH]; - if (open_cookie(c->mono_time, cookie_plain, packet + 1, c->secret_symmetric_key) != 0) { + if (open_cookie(c->mem, c->mono_time, cookie_plain, packet + 1, c->secret_symmetric_key) != 0) { return false; } @@ -542,7 +543,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t uint8_t plain[CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH]; const int len = decrypt_data(cookie_plain, c->self_secret_key, packet + 1 + COOKIE_LENGTH, packet + 1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE, - HANDSHAKE_PACKET_LENGTH - (1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE), plain); + HANDSHAKE_PACKET_LENGTH - (1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE), plain, c->mem); if (len != sizeof(plain)) { return false; @@ -673,7 +674,7 @@ static IP_Port return_ip_port_connection(const Net_Crypto *c, int crypt_connecti * @retval 0 on success. */ non_null() -static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t *data, uint16_t length) +static int send_packet_to(const Net_Crypto *c, int crypt_connection_id, const uint8_t *data, uint16_t length) { // TODO(irungentoo): TCP, etc... Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); @@ -981,7 +982,7 @@ static int generate_request_packet(uint8_t *data, uint16_t length, const Packets * @return number of requested packets on success. */ non_null() -static int handle_request_packet(const Memory *mem, Mono_Time *mono_time, Packets_Array *send_array, +static int handle_request_packet(const Memory *mem, const Mono_Time *mono_time, Packets_Array *send_array, const uint8_t *data, uint16_t length, uint64_t *latest_send_time, uint64_t rtt_time) { @@ -1064,7 +1065,7 @@ static int handle_request_packet(const Memory *mem, Mono_Time *mono_time, Packet * @retval 0 on success. */ non_null() -static int send_data_packet(Net_Crypto *c, int crypt_connection_id, const uint8_t *data, uint16_t length) +static int send_data_packet(const Net_Crypto *c, int crypt_connection_id, const uint8_t *data, uint16_t length) { const uint16_t max_length = MAX_CRYPTO_PACKET_SIZE - (1 + sizeof(uint16_t) + CRYPTO_MAC_SIZE); @@ -1084,7 +1085,7 @@ static int send_data_packet(Net_Crypto *c, int crypt_connection_id, const uint8_ VLA(uint8_t, packet, packet_size); packet[0] = NET_PACKET_CRYPTO_DATA; memcpy(packet + 1, conn->sent_nonce + (CRYPTO_NONCE_SIZE - sizeof(uint16_t)), sizeof(uint16_t)); - const int len = encrypt_data_symmetric(conn->shared_key, conn->sent_nonce, data, length, packet + 1 + sizeof(uint16_t)); + const int len = encrypt_data_symmetric(conn->shared_key, conn->sent_nonce, data, length, packet + 1 + sizeof(uint16_t), c->mem); if (len + 1 + sizeof(uint16_t) != packet_size) { LOGGER_ERROR(c->log, "encryption failed: %d", len); @@ -1102,7 +1103,7 @@ static int send_data_packet(Net_Crypto *c, int crypt_connection_id, const uint8_ * @retval 0 on success. */ non_null() -static int send_data_packet_helper(Net_Crypto *c, int crypt_connection_id, uint32_t buffer_start, uint32_t num, +static int send_data_packet_helper(const Net_Crypto *c, int crypt_connection_id, uint32_t buffer_start, uint32_t num, const uint8_t *data, uint16_t length) { if (length == 0 || length > MAX_CRYPTO_DATA_SIZE) { @@ -1256,7 +1257,7 @@ static int handle_data_packet(const Net_Crypto *c, int crypt_connection_id, uint const uint16_t diff = num - num_cur_nonce; increment_nonce_number(nonce, diff); const int len = decrypt_data_symmetric(conn->shared_key, nonce, packet + 1 + sizeof(uint16_t), - length - (1 + sizeof(uint16_t)), data); + length - (1 + sizeof(uint16_t)), data, c->mem); if ((unsigned int)len != length - crypto_packet_overhead) { return -1; @@ -1414,7 +1415,7 @@ static int clear_temp_packet(const Net_Crypto *c, int crypt_connection_id) * @retval 0 on success. */ non_null() -static int send_temp_packet(Net_Crypto *c, int crypt_connection_id) +static int send_temp_packet(const Net_Crypto *c, int crypt_connection_id) { Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); @@ -1442,7 +1443,7 @@ static int send_temp_packet(Net_Crypto *c, int crypt_connection_id) * @retval 0 on success. */ non_null() -static int create_send_handshake(Net_Crypto *c, int crypt_connection_id, const uint8_t *cookie, +static int create_send_handshake(const Net_Crypto *c, int crypt_connection_id, const uint8_t *cookie, const uint8_t *dht_public_key) { const Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); @@ -1662,7 +1663,7 @@ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id, uint8_t cookie[COOKIE_LENGTH]; uint64_t number; - if (handle_cookie_response(cookie, &number, packet, length, conn->shared_key) != sizeof(cookie)) { + if (handle_cookie_response(cookie, &number, packet, length, conn->shared_key, c->mem) != sizeof(cookie)) { return -1; } @@ -3026,7 +3027,7 @@ Net_Crypto *new_net_crypto(const Logger *log, const Memory *mem, const Random *r networking_registerhandler(dht_get_net(dht), NET_PACKET_CRYPTO_HS, &udp_handle_packet, temp); networking_registerhandler(dht_get_net(dht), NET_PACKET_CRYPTO_DATA, &udp_handle_packet, temp); - bs_list_init(&temp->ip_port_list, sizeof(IP_Port), 8, ipport_cmp_handler); + bs_list_init(&temp->ip_port_list, sizeof(IP_Port), 8, ipport_cmp_handler, mem); return temp; } diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h index 8368d46e39..d221daa861 100644 --- a/toxcore/net_crypto.h +++ b/toxcore/net_crypto.h @@ -9,8 +9,6 @@ #ifndef C_TOXCORE_TOXCORE_NET_CRYPTO_H #define C_TOXCORE_TOXCORE_NET_CRYPTO_H -#include - #include "DHT.h" #include "LAN_discovery.h" #include "TCP_client.h" diff --git a/toxcore/network.c b/toxcore/network.c index 8800bf7e40..62099304ff 100644 --- a/toxcore/network.c +++ b/toxcore/network.c @@ -47,15 +47,9 @@ #include #endif /* OS_WIN32 */ -#ifdef __APPLE__ -#include -#include -#endif /* __APPLE__ */ - #if !defined(OS_WIN32) #include #include -#include #include #include #include @@ -86,13 +80,10 @@ #include "ccompat.h" #include "logger.h" #include "mem.h" +#include "os_network_impl.h" +#include "tox_network.h" #include "util.h" -// Disable MSG_NOSIGNAL on systems not supporting it, e.g. Windows, FreeBSD -#if !defined(MSG_NOSIGNAL) -#define MSG_NOSIGNAL 0 -#endif /* !defined(MSG_NOSIGNAL) */ - #ifndef IPV6_ADD_MEMBERSHIP #ifdef IPV6_JOIN_GROUP #define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP @@ -480,173 +471,16 @@ bool sock_valid(Socket sock) return sock.value != invalid_socket.value; } -struct Network_Addr { - struct sockaddr_storage addr; - size_t size; -}; - -non_null() -static int sys_close(void *obj, Socket sock) -{ -#if defined(OS_WIN32) - return closesocket(net_socket_to_native(sock)); -#else // !OS_WIN32 - return close(net_socket_to_native(sock)); -#endif /* OS_WIN32 */ -} - -non_null() -static Socket sys_accept(void *obj, Socket sock) -{ - return net_socket_from_native(accept(net_socket_to_native(sock), nullptr, nullptr)); -} - -non_null() -static int sys_bind(void *obj, Socket sock, const Network_Addr *addr) -{ - return bind(net_socket_to_native(sock), (const struct sockaddr *)&addr->addr, addr->size); -} - -non_null() -static int sys_listen(void *obj, Socket sock, int backlog) -{ - return listen(net_socket_to_native(sock), backlog); -} - -non_null() -static int sys_connect(void *obj, Socket sock, const Network_Addr *addr) -{ - return connect(net_socket_to_native(sock), (const struct sockaddr *)&addr->addr, addr->size); -} - -non_null() -static int sys_recvbuf(void *obj, Socket sock) -{ -#ifdef OS_WIN32 - u_long count = 0; - ioctlsocket(net_socket_to_native(sock), FIONREAD, &count); -#else - int count = 0; - ioctl(net_socket_to_native(sock), FIONREAD, &count); -#endif /* OS_WIN32 */ - - return count; -} - -non_null() -static int sys_recv(void *obj, Socket sock, uint8_t *buf, size_t len) -{ - return recv(net_socket_to_native(sock), (char *)buf, len, MSG_NOSIGNAL); -} - -non_null() -static int sys_send(void *obj, Socket sock, const uint8_t *buf, size_t len) -{ - return send(net_socket_to_native(sock), (const char *)buf, len, MSG_NOSIGNAL); -} - -non_null() -static int sys_sendto(void *obj, Socket sock, const uint8_t *buf, size_t len, const Network_Addr *addr) -{ - return sendto(net_socket_to_native(sock), (const char *)buf, len, 0, (const struct sockaddr *)&addr->addr, addr->size); -} - -non_null() -static int sys_recvfrom(void *obj, Socket sock, uint8_t *buf, size_t len, Network_Addr *addr) -{ - socklen_t size = addr->size; - const int ret = recvfrom(net_socket_to_native(sock), (char *)buf, len, 0, (struct sockaddr *)&addr->addr, &size); - addr->size = size; - return ret; -} - -non_null() -static Socket sys_socket(void *obj, int domain, int type, int proto) -{ - return net_socket_from_native(socket(domain, type, proto)); -} - -non_null() -static int sys_socket_nonblock(void *obj, Socket sock, bool nonblock) -{ -#ifdef OS_WIN32 - u_long mode = nonblock ? 1 : 0; - return ioctlsocket(net_socket_to_native(sock), FIONBIO, &mode); -#else - return fcntl(net_socket_to_native(sock), F_SETFL, O_NONBLOCK, nonblock ? 1 : 0); -#endif /* OS_WIN32 */ -} - -non_null() -static int sys_getsockopt(void *obj, Socket sock, int level, int optname, void *optval, size_t *optlen) -{ - socklen_t len = *optlen; - const int ret = getsockopt(net_socket_to_native(sock), level, optname, (char *)optval, &len); - *optlen = len; - return ret; -} - -non_null() -static int sys_setsockopt(void *obj, Socket sock, int level, int optname, const void *optval, size_t optlen) -{ - return setsockopt(net_socket_to_native(sock), level, optname, (const char *)optval, optlen); -} - -static const Network_Funcs os_network_funcs = { - sys_close, - sys_accept, - sys_bind, - sys_listen, - sys_connect, - sys_recvbuf, - sys_recv, - sys_recvfrom, - sys_send, - sys_sendto, - sys_socket, - sys_socket_nonblock, - sys_getsockopt, - sys_setsockopt, -}; -static const Network os_network_obj = {&os_network_funcs}; - -const Network *os_network(void) -{ -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - if ((true)) { - return nullptr; - } -#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ -#ifdef OS_WIN32 - WSADATA wsaData; - - if (WSAStartup(MAKEWORD(2, 2), &wsaData) != NO_ERROR) { - return nullptr; - } -#endif /* OS_WIN32 */ - return &os_network_obj; -} - -#if 0 -/* TODO(iphydf): Call this from functions that use `os_network()`. */ -void os_network_deinit(const Network *ns) -{ -#ifdef OS_WIN32 - WSACleanup(); -#endif /* OS_WIN32 */ -} -#endif /* 0 */ - non_null() static int net_setsockopt(const Network *ns, Socket sock, int level, int optname, const void *optval, size_t optlen) { - return ns->funcs->setsockopt(ns->obj, sock, level, optname, optval, optlen); + return tox_network_setsockopt(ns, sock, level, optname, optval, optlen); } non_null() static int net_getsockopt(const Network *ns, Socket sock, int level, int optname, void *optval, size_t *optlen) { - return ns->funcs->getsockopt(ns->obj, sock, level, optname, optval, optlen); + return tox_network_getsockopt(ns, sock, level, optname, optval, optlen); } non_null() @@ -821,7 +655,7 @@ static void loglogdata(const Logger *log, const char *message, const uint8_t *bu int net_send(const Network *ns, const Logger *log, Socket sock, const uint8_t *buf, size_t len, const IP_Port *ip_port) { - const int res = ns->funcs->send(ns->obj, sock, buf, len); + const int res = tox_network_send(ns, sock, buf, len); loglogdata(log, "T=>", buf, len, ip_port, res); return res; } @@ -831,13 +665,13 @@ static int net_sendto( const Network *ns, Socket sock, const uint8_t *buf, size_t len, const Network_Addr *addr, const IP_Port *ip_port) { - return ns->funcs->sendto(ns->obj, sock, buf, len, addr); + return tox_network_sendto(ns, sock, buf, len, addr); } int net_recv(const Network *ns, const Logger *log, Socket sock, uint8_t *buf, size_t len, const IP_Port *ip_port) { - const int res = ns->funcs->recv(ns->obj, sock, buf, len); + const int res = tox_network_recv(ns, sock, buf, len); loglogdata(log, "=>T", buf, len, ip_port, res); return res; } @@ -846,34 +680,34 @@ non_null() static int net_recvfrom(const Network *ns, Socket sock, uint8_t *buf, size_t len, Network_Addr *addr) { - return ns->funcs->recvfrom(ns->obj, sock, buf, len, addr); + return tox_network_recvfrom(ns, sock, buf, len, addr); } int net_listen(const Network *ns, Socket sock, int backlog) { - return ns->funcs->listen(ns->obj, sock, backlog); + return tox_network_listen(ns, sock, backlog); } non_null() static int net_bind(const Network *ns, Socket sock, const Network_Addr *addr) { - return ns->funcs->bind(ns->obj, sock, addr); + return tox_network_bind(ns, sock, addr); } Socket net_accept(const Network *ns, Socket sock) { - return ns->funcs->accept(ns->obj, sock); + return tox_network_accept(ns, sock); } /** Close the socket. */ void kill_sock(const Network *ns, Socket sock) { - ns->funcs->close(ns->obj, sock); + tox_network_close(ns, sock); } bool set_socket_nonblock(const Network *ns, Socket sock) { - return ns->funcs->socket_nonblock(ns->obj, sock, true) == 0; + return tox_network_socket_nonblock(ns, sock, true) == 0; } bool set_socket_nosigpipe(const Network *ns, Socket sock) @@ -978,34 +812,41 @@ int send_packet(const Networking_Core *net, const IP_Port *ip_port, Packet packe ipp_copy.ip.ip.v6 = ip6; } - Network_Addr addr; + Network_Addr *addr; if (net_family_is_ipv4(ipp_copy.ip.family)) { - struct sockaddr_in *const addr4 = (struct sockaddr_in *)&addr.addr; + struct sockaddr_in addr4 = {0}; - addr.size = sizeof(struct sockaddr_in); - addr4->sin_family = AF_INET; - addr4->sin_port = ipp_copy.port; - fill_addr4(&ipp_copy.ip.ip.v4, &addr4->sin_addr); + addr4.sin_family = AF_INET; + addr4.sin_port = ipp_copy.port; + fill_addr4(&ipp_copy.ip.ip.v4, &addr4.sin_addr); + + addr = net_addr_new(&addr4, sizeof(addr4), net->mem); } else if (net_family_is_ipv6(ipp_copy.ip.family)) { - struct sockaddr_in6 *const addr6 = (struct sockaddr_in6 *)&addr.addr; + struct sockaddr_in6 addr6 = {0}; - addr.size = sizeof(struct sockaddr_in6); - addr6->sin6_family = AF_INET6; - addr6->sin6_port = ipp_copy.port; - fill_addr6(&ipp_copy.ip.ip.v6, &addr6->sin6_addr); + addr6.sin6_family = AF_INET6; + addr6.sin6_port = ipp_copy.port; + fill_addr6(&ipp_copy.ip.ip.v6, &addr6.sin6_addr); - addr6->sin6_flowinfo = 0; - addr6->sin6_scope_id = 0; + addr6.sin6_flowinfo = 0; + addr6.sin6_scope_id = 0; + + addr = net_addr_new(&addr6, sizeof(addr6), net->mem); } else { LOGGER_ERROR(net->log, "unknown address type: %d", ipp_copy.ip.family.value); return -1; } - const long res = net_sendto(net->ns, net->sock, packet.data, packet.length, &addr, &ipp_copy); + if (addr == nullptr) { + return -1; + } + + const long res = net_sendto(net->ns, net->sock, packet.data, packet.length, addr, &ipp_copy); loglogdata(net->log, "O=>", packet.data, packet.length, ip_port, res); assert(res <= INT_MAX); + net_addr_free(addr, net->mem); return (int)res; } @@ -1029,11 +870,14 @@ non_null() static int receivepacket(const Network *ns, const Memory *mem, const Logger *log, Socket sock, IP_Port *ip_port, uint8_t *data, uint32_t *length) { memset(ip_port, 0, sizeof(IP_Port)); - Network_Addr addr = {{0}}; - addr.size = sizeof(addr.addr); + Network_Addr *addr = net_addr_new(nullptr, 0, mem); *length = 0; - const int fail_or_len = net_recvfrom(ns, sock, data, MAX_UDP_PACKET_SIZE, &addr); + if (addr == nullptr) { + return -1; + } + + const int fail_or_len = net_recvfrom(ns, sock, data, MAX_UDP_PACKET_SIZE, addr); if (fail_or_len < 0) { const int error = net_error(); @@ -1044,30 +888,33 @@ static int receivepacket(const Network *ns, const Memory *mem, const Logger *log net_kill_strerror(strerror); } + net_addr_free(addr, mem); return -1; /* Nothing received. */ } *length = (uint32_t)fail_or_len; - if (addr.addr.ss_family == AF_INET) { - const struct sockaddr_in *addr_in = (const struct sockaddr_in *)&addr.addr; + if (net_addr_is_ipv4(addr)) { + const struct sockaddr_in *addr_in = (const struct sockaddr_in *)net_addr_get_addr(addr); const Family *const family = make_tox_family(addr_in->sin_family); assert(family != nullptr); if (family == nullptr) { + net_addr_free(addr, mem); return -1; } ip_port->ip.family = *family; get_ip4(&ip_port->ip.ip.v4, &addr_in->sin_addr); ip_port->port = addr_in->sin_port; - } else if (addr.addr.ss_family == AF_INET6) { - const struct sockaddr_in6 *addr_in6 = (const struct sockaddr_in6 *)&addr.addr; + } else if (net_addr_is_ipv6(addr)) { + const struct sockaddr_in6 *addr_in6 = (const struct sockaddr_in6 *)net_addr_get_addr(addr); const Family *const family = make_tox_family(addr_in6->sin6_family); assert(family != nullptr); if (family == nullptr) { + net_addr_free(addr, mem); return -1; } @@ -1080,11 +927,13 @@ static int receivepacket(const Network *ns, const Memory *mem, const Logger *log ip_port->ip.ip.v4.uint32 = ip_port->ip.ip.v6.uint32[3]; } } else { + net_addr_free(addr, mem); return -1; } loglogdata(log, "=>O", data, MAX_UDP_PACKET_SIZE, ip_port, *length); + net_addr_free(addr, mem); return 0; } @@ -1238,21 +1087,31 @@ Networking_Core *new_networking_ex( /* Bind our socket to port PORT and the given IP address (usually 0.0.0.0 or ::) */ uint16_t *portptr = nullptr; - Network_Addr addr = {{0}}; + Network_Addr *addr = net_addr_new(nullptr, 0, mem); + + if (addr == nullptr) { + kill_networking(temp); + + if (error != nullptr) { + *error = 2; + } + + return nullptr; + } if (net_family_is_ipv4(temp->family)) { - struct sockaddr_in *addr4 = (struct sockaddr_in *)&addr.addr; + struct sockaddr_in *addr4 = (struct sockaddr_in *)net_addr_mut_addr(addr); - addr.size = sizeof(struct sockaddr_in); + net_addr_set_size(addr, sizeof(struct sockaddr_in)); addr4->sin_family = AF_INET; addr4->sin_port = 0; fill_addr4(&ip->ip.v4, &addr4->sin_addr); portptr = &addr4->sin_port; } else if (net_family_is_ipv6(temp->family)) { - struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr.addr; + struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)net_addr_mut_addr(addr); - addr.size = sizeof(struct sockaddr_in6); + net_addr_set_size(addr, sizeof(struct sockaddr_in6)); addr6->sin6_family = AF_INET6; addr6->sin6_port = 0; fill_addr6(&ip->ip.v6, &addr6->sin6_addr); @@ -1263,6 +1122,7 @@ Networking_Core *new_networking_ex( portptr = &addr6->sin6_port; } else { mem_delete(mem, temp); + net_addr_free(addr, mem); return nullptr; } @@ -1318,7 +1178,7 @@ Networking_Core *new_networking_ex( *portptr = net_htons(port_to_try); for (uint16_t tries = port_from; tries <= port_to; ++tries) { - const int res = net_bind(ns, temp->sock, &addr); + const int res = net_bind(ns, temp->sock, addr); if (res == 0) { temp->port = *portptr; @@ -1338,6 +1198,7 @@ Networking_Core *new_networking_ex( *error = 0; } + net_addr_free(addr, mem); return temp; } @@ -1362,6 +1223,7 @@ Networking_Core *new_networking_ex( *error = 1; } + net_addr_free(addr, mem); return nullptr; } @@ -1930,19 +1792,23 @@ bool addr_resolve_or_parse_ip(const Network *ns, const char *address, IP *to, IP bool net_connect(const Network *ns, const Memory *mem, const Logger *log, Socket sock, const IP_Port *ip_port) { - Network_Addr addr = {{0}}; + Network_Addr *addr = net_addr_new(ns, 0, mem); + + if (addr == nullptr) { + return false; + } if (net_family_is_ipv4(ip_port->ip.family)) { - struct sockaddr_in *addr4 = (struct sockaddr_in *)&addr.addr; + struct sockaddr_in *addr4 = (struct sockaddr_in *)net_addr_mut_addr(addr); - addr.size = sizeof(struct sockaddr_in); + net_addr_set_size(addr, sizeof(struct sockaddr_in)); addr4->sin_family = AF_INET; fill_addr4(&ip_port->ip.ip.v4, &addr4->sin_addr); addr4->sin_port = ip_port->port; } else if (net_family_is_ipv6(ip_port->ip.family)) { - struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr.addr; + struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)net_addr_mut_addr(addr); - addr.size = sizeof(struct sockaddr_in6); + net_addr_set_size(addr, sizeof(struct sockaddr_in6)); addr6->sin6_family = AF_INET6; fill_addr6(&ip_port->ip.ip.v6, &addr6->sin6_addr); addr6->sin6_port = ip_port->port; @@ -1950,11 +1816,13 @@ bool net_connect(const Network *ns, const Memory *mem, const Logger *log, Socket Ip_Ntoa ip_str; LOGGER_ERROR(log, "cannot connect to %s:%d which is neither IPv4 nor IPv6", net_ip_ntoa(&ip_port->ip, &ip_str), net_ntohs(ip_port->port)); + net_addr_free(addr, mem); return false; } #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION if ((true)) { + net_addr_free(addr, mem); return true; } #endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ @@ -1964,7 +1832,7 @@ bool net_connect(const Network *ns, const Memory *mem, const Logger *log, Socket net_socket_to_native(sock), net_ip_ntoa(&ip_port->ip, &ip_str), net_ntohs(ip_port->port)); errno = 0; - if (ns->funcs->connect(ns->obj, sock, &addr) == -1) { + if (tox_network_connect(ns, sock, addr) == -1) { const int error = net_error(); // Non-blocking socket: "Operation in progress" means it's connecting. @@ -1973,10 +1841,12 @@ bool net_connect(const Network *ns, const Memory *mem, const Logger *log, Socket LOGGER_WARNING(log, "failed to connect to %s:%d: %d (%s)", net_ip_ntoa(&ip_port->ip, &ip_str), net_ntohs(ip_port->port), error, net_strerror); net_kill_strerror(net_strerror); + net_addr_free(addr, mem); return false; } } + net_addr_free(addr, mem); return true; } @@ -1994,6 +1864,7 @@ int32_t net_getipport(const Memory *mem, const char *node, IP_Port **res, int to IP_Port *tmp = (IP_Port *)mem_alloc(mem, sizeof(IP_Port)); if (tmp == nullptr) { + *res = nullptr; return -1; } @@ -2005,9 +1876,11 @@ int32_t net_getipport(const Memory *mem, const char *node, IP_Port **res, int to #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION if ((true)) { IP_Port *ip_port = (IP_Port *)mem_alloc(mem, sizeof(IP_Port)); + if (ip_port == nullptr) { - abort(); + return -1; } + ip_port->ip.ip.v4.uint32 = net_htonl(0x7F000003); // 127.0.0.3 ip_port->ip.family = *make_tox_family(AF_INET); @@ -2096,27 +1969,31 @@ void net_freeipport(const Memory *mem, IP_Port *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, const Memory *mem, Socket sock, Family family, uint16_t port) { - Network_Addr addr = {{0}}; + Network_Addr *addr; if (net_family_is_ipv4(family)) { - struct sockaddr_in *addr4 = (struct sockaddr_in *)&addr.addr; + struct sockaddr_in addr4 = {0}; - addr.size = sizeof(struct sockaddr_in); - addr4->sin_family = AF_INET; - addr4->sin_port = net_htons(port); + addr4.sin_family = AF_INET; + addr4.sin_port = net_htons(port); + + addr = net_addr_new(&addr4, sizeof(addr4), mem); } else if (net_family_is_ipv6(family)) { - struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr.addr; + struct sockaddr_in6 addr6 = {0}; - addr.size = sizeof(struct sockaddr_in6); - addr6->sin6_family = AF_INET6; - addr6->sin6_port = net_htons(port); + addr6.sin6_family = AF_INET6; + addr6.sin6_port = net_htons(port); + + addr = net_addr_new(&addr6, sizeof(addr6), mem); } else { return false; } - return net_bind(ns, sock, &addr) == 0; + const bool ok = net_bind(ns, sock, addr) == 0; + net_addr_free(addr, mem); + return ok; } Socket net_socket(const Network *ns, Family domain, int type, int protocol) @@ -2124,12 +2001,12 @@ Socket net_socket(const Network *ns, Family domain, int type, int protocol) const int platform_domain = make_family(domain); const int platform_type = make_socktype(type); const int platform_prot = make_proto(protocol); - return ns->funcs->socket(ns->obj, platform_domain, platform_type, platform_prot); + return tox_network_socket(ns, platform_domain, platform_type, platform_prot); } uint16_t net_socket_data_recv_buffer(const Network *ns, Socket sock) { - const int count = ns->funcs->recvbuf(ns->obj, sock); + const int count = tox_network_recvbuf(ns, sock); return (uint16_t)max_s32(0, min_s32(count, UINT16_MAX)); } diff --git a/toxcore/network.h b/toxcore/network.h index 8c6cc5de2e..13dc6bee7d 100644 --- a/toxcore/network.h +++ b/toxcore/network.h @@ -17,72 +17,12 @@ #include "bin_pack.h" #include "logger.h" #include "mem.h" +#include "tox_network.h" #ifdef __cplusplus extern "C" { #endif -/** - * @brief Wrapper for sockaddr_storage and size. - */ -typedef struct Network_Addr Network_Addr; - -typedef bitwise int Socket_Value; -typedef struct Socket { - Socket_Value value; -} Socket; - -int net_socket_to_native(Socket sock); -Socket net_socket_from_native(int sock); - -typedef int net_close_cb(void *obj, Socket sock); -typedef Socket net_accept_cb(void *obj, Socket sock); -typedef int net_bind_cb(void *obj, Socket sock, const Network_Addr *addr); -typedef int net_listen_cb(void *obj, Socket sock, int backlog); -typedef int net_connect_cb(void *obj, Socket sock, const Network_Addr *addr); -typedef int net_recvbuf_cb(void *obj, Socket sock); -typedef int net_recv_cb(void *obj, Socket sock, uint8_t *buf, size_t len); -typedef int net_recvfrom_cb(void *obj, Socket sock, uint8_t *buf, size_t len, Network_Addr *addr); -typedef int net_send_cb(void *obj, Socket sock, const uint8_t *buf, size_t len); -typedef int net_sendto_cb(void *obj, Socket sock, const uint8_t *buf, size_t len, const Network_Addr *addr); -typedef Socket net_socket_cb(void *obj, int domain, int type, int proto); -typedef int net_socket_nonblock_cb(void *obj, Socket sock, bool nonblock); -typedef int net_getsockopt_cb(void *obj, Socket sock, int level, int optname, void *optval, size_t *optlen); -typedef int net_setsockopt_cb(void *obj, Socket sock, int level, int optname, const void *optval, size_t optlen); -typedef int net_getaddrinfo_cb(void *obj, int family, Network_Addr **addrs); -typedef int net_freeaddrinfo_cb(void *obj, Network_Addr *addrs); - -/** @brief Functions wrapping POSIX network functions. - * - * Refer to POSIX man pages for documentation of what these functions are - * expected to do when providing alternative Network implementations. - */ -typedef struct Network_Funcs { - net_close_cb *close; - net_accept_cb *accept; - net_bind_cb *bind; - net_listen_cb *listen; - net_connect_cb *connect; - net_recvbuf_cb *recvbuf; - net_recv_cb *recv; - net_recvfrom_cb *recvfrom; - net_send_cb *send; - net_sendto_cb *sendto; - net_socket_cb *socket; - net_socket_nonblock_cb *socket_nonblock; - net_getsockopt_cb *getsockopt; - net_setsockopt_cb *setsockopt; - net_getaddrinfo_cb *getaddrinfo; - net_freeaddrinfo_cb *freeaddrinfo; -} Network_Funcs; - -typedef struct Network { - const Network_Funcs *funcs; - void *obj; -} Network; - -const Network *os_network(void); - typedef struct Family { uint8_t value; } Family; @@ -221,6 +161,8 @@ typedef struct IP_Port { uint16_t port; } IP_Port; +typedef Tox_Network Network; + non_null() Socket net_socket(const Network *ns, Family domain, int type, int protocol); @@ -552,7 +494,7 @@ int unpack_ip_port(IP_Port *ip_port, const uint8_t *data, uint16_t length, bool * @return true on success, false on failure. */ non_null() -bool bind_to_port(const Network *ns, Socket sock, Family family, uint16_t port); +bool bind_to_port(const Network *ns, const Memory *mem, Socket sock, Family family, uint16_t port); /** @brief Get the last networking error code. * diff --git a/toxcore/network_test_util.cc b/toxcore/network_test_util.cc index bdb42ae1d9..8e10dad419 100644 --- a/toxcore/network_test_util.cc +++ b/toxcore/network_test_util.cc @@ -5,83 +5,93 @@ #include "crypto_core.h" #include "network.h" #include "test_util.hh" +#include "tox_network_impl.h" -Network_Funcs const Network_Class::vtable = { - Method::invoke<&Network_Class::close>, - Method::invoke<&Network_Class::accept>, - Method::invoke<&Network_Class::bind>, - Method::invoke<&Network_Class::listen>, - Method::invoke<&Network_Class::connect>, - Method::invoke<&Network_Class::recvbuf>, - Method::invoke<&Network_Class::recv>, - Method::invoke<&Network_Class::recvfrom>, - Method::invoke<&Network_Class::send>, - Method::invoke<&Network_Class::sendto>, - Method::invoke<&Network_Class::socket>, - Method::invoke<&Network_Class::socket_nonblock>, - Method::invoke<&Network_Class::getsockopt>, - Method::invoke<&Network_Class::setsockopt>, - Method::invoke<&Network_Class::getaddrinfo>, - Method::invoke<&Network_Class::freeaddrinfo>, +Tox_Network_Funcs const Network_Class::vtable = { + Method::invoke<&Network_Class::close>, + Method::invoke<&Network_Class::accept>, + Method::invoke<&Network_Class::bind>, + Method::invoke<&Network_Class::listen>, + Method::invoke<&Network_Class::connect>, + Method::invoke<&Network_Class::recvbuf>, + Method::invoke<&Network_Class::recv>, + Method::invoke<&Network_Class::recvfrom>, + Method::invoke<&Network_Class::send>, + Method::invoke<&Network_Class::sendto>, + Method::invoke<&Network_Class::socket>, + Method::invoke<&Network_Class::socket_nonblock>, + Method::invoke<&Network_Class::getsockopt>, + Method::invoke<&Network_Class::setsockopt>, + Method::invoke<&Network_Class::getaddrinfo>, + Method::invoke<&Network_Class::freeaddrinfo>, }; -int Test_Network::close(void *obj, Socket sock) { return net->funcs->close(net->obj, sock); } -Socket Test_Network::accept(void *obj, Socket sock) { return net->funcs->accept(net->obj, sock); } +int Test_Network::close(void *obj, Socket sock) +{ + return net->funcs->close_callback(net->user_data, sock); +} +Socket Test_Network::accept(void *obj, Socket sock) +{ + return net->funcs->accept_callback(net->user_data, sock); +} int Test_Network::bind(void *obj, Socket sock, const Network_Addr *addr) { - return net->funcs->bind(net->obj, sock, addr); + return net->funcs->bind_callback(net->user_data, sock, addr); } int Test_Network::listen(void *obj, Socket sock, int backlog) { - return net->funcs->listen(net->obj, sock, backlog); + return net->funcs->listen_callback(net->user_data, sock, backlog); } int Test_Network::connect(void *obj, Socket sock, const Network_Addr *addr) { - return net->funcs->connect(net->obj, sock, addr); + return net->funcs->connect_callback(net->user_data, sock, addr); +} +int Test_Network::recvbuf(void *obj, Socket sock) +{ + return net->funcs->recvbuf_callback(net->user_data, sock); } -int Test_Network::recvbuf(void *obj, Socket sock) { return net->funcs->recvbuf(net->obj, sock); } int Test_Network::recv(void *obj, Socket sock, uint8_t *buf, size_t len) { - return net->funcs->recv(net->obj, sock, buf, len); + return net->funcs->recv_callback(net->user_data, sock, buf, len); } int Test_Network::recvfrom(void *obj, Socket sock, uint8_t *buf, size_t len, Network_Addr *addr) { - return net->funcs->recvfrom(net->obj, sock, buf, len, addr); + return net->funcs->recvfrom_callback(net->user_data, sock, buf, len, addr); } int Test_Network::send(void *obj, Socket sock, const uint8_t *buf, size_t len) { - return net->funcs->send(net->obj, sock, buf, len); + return net->funcs->send_callback(net->user_data, sock, buf, len); } int Test_Network::sendto( void *obj, Socket sock, const uint8_t *buf, size_t len, const Network_Addr *addr) { - return net->funcs->sendto(net->obj, sock, buf, len, addr); + return net->funcs->sendto_callback(net->user_data, sock, buf, len, addr); } Socket Test_Network::socket(void *obj, int domain, int type, int proto) { - return net->funcs->socket(net->obj, domain, type, proto); + return net->funcs->socket_callback(net->user_data, domain, type, proto); } int Test_Network::socket_nonblock(void *obj, Socket sock, bool nonblock) { - return net->funcs->socket_nonblock(net->obj, sock, nonblock); + return net->funcs->socket_nonblock_callback(net->user_data, sock, nonblock); } int Test_Network::getsockopt( void *obj, Socket sock, int level, int optname, void *optval, size_t *optlen) { - return net->funcs->getsockopt(net->obj, sock, level, optname, optval, optlen); + return net->funcs->getsockopt_callback(net->user_data, sock, level, optname, optval, optlen); } int Test_Network::setsockopt( void *obj, Socket sock, int level, int optname, const void *optval, size_t optlen) { - return net->funcs->setsockopt(net->obj, sock, level, optname, optval, optlen); + return net->funcs->setsockopt_callback(net->user_data, sock, level, optname, optval, optlen); } int Test_Network::getaddrinfo(void *obj, int family, Network_Addr **addrs) { - return net->funcs->getaddrinfo(net->obj, family, addrs); + return net->funcs->getaddrinfo_callback(net->user_data, family, addrs); } int Test_Network::freeaddrinfo(void *obj, Network_Addr *addrs) { - return net->funcs->freeaddrinfo(net->obj, addrs); + return net->funcs->freeaddrinfo_callback(net->user_data, addrs); } Network_Class::~Network_Class() = default; diff --git a/toxcore/network_test_util.hh b/toxcore/network_test_util.hh index 88084b1fb9..317f154a12 100644 --- a/toxcore/network_test_util.hh +++ b/toxcore/network_test_util.hh @@ -5,13 +5,15 @@ #include "crypto_core.h" #include "network.h" +#include "os_network.h" #include "test_util.hh" +#include "tox_network_impl.h" struct Network_Class { - static Network_Funcs const vtable; - Network const self; + static Tox_Network_Funcs const vtable; + Tox_Network const self; - operator Network const *() const { return &self; } + operator Tox_Network const *() const { return &self; } Network_Class(Network_Class const &) = default; Network_Class() @@ -20,22 +22,22 @@ struct Network_Class { } virtual ~Network_Class(); - virtual net_close_cb close = 0; - virtual net_accept_cb accept = 0; - virtual net_bind_cb bind = 0; - virtual net_listen_cb listen = 0; - virtual net_connect_cb connect = 0; - virtual net_recvbuf_cb recvbuf = 0; - virtual net_recv_cb recv = 0; - virtual net_recvfrom_cb recvfrom = 0; - virtual net_send_cb send = 0; - virtual net_sendto_cb sendto = 0; - virtual net_socket_cb socket = 0; - virtual net_socket_nonblock_cb socket_nonblock = 0; - virtual net_getsockopt_cb getsockopt = 0; - virtual net_setsockopt_cb setsockopt = 0; - virtual net_getaddrinfo_cb getaddrinfo = 0; - virtual net_freeaddrinfo_cb freeaddrinfo = 0; + virtual tox_network_close_cb close = 0; + virtual tox_network_accept_cb accept = 0; + virtual tox_network_bind_cb bind = 0; + virtual tox_network_listen_cb listen = 0; + virtual tox_network_connect_cb connect = 0; + virtual tox_network_recvbuf_cb recvbuf = 0; + virtual tox_network_recv_cb recv = 0; + virtual tox_network_recvfrom_cb recvfrom = 0; + virtual tox_network_send_cb send = 0; + virtual tox_network_sendto_cb sendto = 0; + virtual tox_network_socket_cb socket = 0; + virtual tox_network_socket_nonblock_cb socket_nonblock = 0; + virtual tox_network_getsockopt_cb getsockopt = 0; + virtual tox_network_setsockopt_cb setsockopt = 0; + virtual tox_network_getaddrinfo_cb getaddrinfo = 0; + virtual tox_network_freeaddrinfo_cb freeaddrinfo = 0; }; /** @@ -43,7 +45,7 @@ struct Network_Class { * subclassed to override individual (or all) functions. */ class Test_Network : public Network_Class { - const Network *net = REQUIRE_NOT_NULL(os_network()); + const Tox_Network *net = REQUIRE_NOT_NULL(os_network()); int close(void *obj, Socket sock) override; Socket accept(void *obj, Socket sock) override; diff --git a/toxcore/onion.c b/toxcore/onion.c index 9fab57af90..90909498f6 100644 --- a/toxcore/onion.c +++ b/toxcore/onion.c @@ -182,7 +182,7 @@ int onion_path_to_nodes(Node_format *nodes, unsigned int num_nodes, const Onion_ */ int create_onion_packet(const Random *rng, uint8_t *packet, uint16_t max_packet_length, const Onion_Path *path, const IP_Port *dest, - const uint8_t *data, uint16_t length) + const uint8_t *data, uint16_t length, const Memory *mem) { if (1 + length + SEND_1 > max_packet_length || length == 0) { return -1; @@ -203,7 +203,7 @@ int create_onion_packet(const Random *rng, uint8_t *packet, uint16_t max_packet_ memcpy(step2 + SIZE_IPPORT, path->public_key3, CRYPTO_PUBLIC_KEY_SIZE); int len = encrypt_data_symmetric(path->shared_key3, nonce, step1, step1_size, - step2 + SIZE_IPPORT + CRYPTO_PUBLIC_KEY_SIZE); + step2 + SIZE_IPPORT + CRYPTO_PUBLIC_KEY_SIZE, mem); if (len != SIZE_IPPORT + length + CRYPTO_MAC_SIZE) { return -1; @@ -214,7 +214,7 @@ int create_onion_packet(const Random *rng, uint8_t *packet, uint16_t max_packet_ ipport_pack(step3, &path->ip_port2); memcpy(step3 + SIZE_IPPORT, path->public_key2, CRYPTO_PUBLIC_KEY_SIZE); len = encrypt_data_symmetric(path->shared_key2, nonce, step2, step2_size, - step3 + SIZE_IPPORT + CRYPTO_PUBLIC_KEY_SIZE); + step3 + SIZE_IPPORT + CRYPTO_PUBLIC_KEY_SIZE, mem); if (len != SIZE_IPPORT + SEND_BASE + length + CRYPTO_MAC_SIZE) { return -1; @@ -225,7 +225,7 @@ int create_onion_packet(const Random *rng, uint8_t *packet, uint16_t max_packet_ memcpy(packet + 1 + CRYPTO_NONCE_SIZE, path->public_key1, CRYPTO_PUBLIC_KEY_SIZE); len = encrypt_data_symmetric(path->shared_key1, nonce, step3, step3_size, - packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE); + packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE, mem); if (len != SIZE_IPPORT + SEND_BASE * 2 + length + CRYPTO_MAC_SIZE) { return -1; @@ -245,7 +245,7 @@ int create_onion_packet(const Random *rng, uint8_t *packet, uint16_t max_packet_ */ int create_onion_packet_tcp(const Random *rng, uint8_t *packet, uint16_t max_packet_length, const Onion_Path *path, const IP_Port *dest, - const uint8_t *data, uint16_t length) + const uint8_t *data, uint16_t length, const Memory *mem) { if (CRYPTO_NONCE_SIZE + SIZE_IPPORT + SEND_BASE * 2 + length > max_packet_length || length == 0) { return -1; @@ -266,7 +266,7 @@ int create_onion_packet_tcp(const Random *rng, uint8_t *packet, uint16_t max_pac memcpy(step2 + SIZE_IPPORT, path->public_key3, CRYPTO_PUBLIC_KEY_SIZE); int len = encrypt_data_symmetric(path->shared_key3, nonce, step1, step1_size, - step2 + SIZE_IPPORT + CRYPTO_PUBLIC_KEY_SIZE); + step2 + SIZE_IPPORT + CRYPTO_PUBLIC_KEY_SIZE, mem); if (len != SIZE_IPPORT + length + CRYPTO_MAC_SIZE) { return -1; @@ -275,7 +275,7 @@ int create_onion_packet_tcp(const Random *rng, uint8_t *packet, uint16_t max_pac ipport_pack(packet + CRYPTO_NONCE_SIZE, &path->ip_port2); memcpy(packet + CRYPTO_NONCE_SIZE + SIZE_IPPORT, path->public_key2, CRYPTO_PUBLIC_KEY_SIZE); len = encrypt_data_symmetric(path->shared_key2, nonce, step2, step2_size, - packet + CRYPTO_NONCE_SIZE + SIZE_IPPORT + CRYPTO_PUBLIC_KEY_SIZE); + packet + CRYPTO_NONCE_SIZE + SIZE_IPPORT + CRYPTO_PUBLIC_KEY_SIZE, mem); if (len != SIZE_IPPORT + SEND_BASE + length + CRYPTO_MAC_SIZE) { return -1; @@ -355,7 +355,7 @@ static int handle_send_initial(void *object, const IP_Port *source, const uint8_ } const int len = decrypt_data_symmetric( - shared_key, &packet[nonce_start], &packet[ciphertext_start], ciphertext_length, plain); + shared_key, &packet[nonce_start], &packet[ciphertext_start], ciphertext_length, plain, onion->mem); if (len != plaintext_length) { LOGGER_TRACE(onion->log, "decrypt failed: %d != %d", len, plaintext_length); @@ -394,7 +394,7 @@ int onion_send_1(const Onion *onion, const uint8_t *plain, uint16_t len, const I uint8_t *ret_part = data + data_len; random_nonce(onion->rng, ret_part); len = encrypt_data_symmetric(onion->secret_symmetric_key, ret_part, ip_port, SIZE_IPPORT, - ret_part + CRYPTO_NONCE_SIZE); + ret_part + CRYPTO_NONCE_SIZE, onion->mem); if (len != SIZE_IPPORT + CRYPTO_MAC_SIZE) { return 1; @@ -437,7 +437,7 @@ static int handle_send_1(void *object, const IP_Port *source, const uint8_t *pac } int len = decrypt_data_symmetric(shared_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE, - length - (1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + RETURN_1), plain); + length - (1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + RETURN_1), plain, onion->mem); if (len != length - (1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + RETURN_1 + CRYPTO_MAC_SIZE)) { return 1; @@ -460,7 +460,7 @@ static int handle_send_1(void *object, const IP_Port *source, const uint8_t *pac ipport_pack(ret_data, source); memcpy(ret_data + SIZE_IPPORT, packet + (length - RETURN_1), RETURN_1); len = encrypt_data_symmetric(onion->secret_symmetric_key, ret_part, ret_data, sizeof(ret_data), - ret_part + CRYPTO_NONCE_SIZE); + ret_part + CRYPTO_NONCE_SIZE, onion->mem); if (len != RETURN_2 - CRYPTO_NONCE_SIZE) { return 1; @@ -503,7 +503,7 @@ static int handle_send_2(void *object, const IP_Port *source, const uint8_t *pac } int len = decrypt_data_symmetric(shared_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE, - length - (1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + RETURN_2), plain); + length - (1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + RETURN_2), plain, onion->mem); if (len != length - (1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + RETURN_2 + CRYPTO_MAC_SIZE)) { return 1; @@ -533,7 +533,7 @@ static int handle_send_2(void *object, const IP_Port *source, const uint8_t *pac ipport_pack(ret_data, source); memcpy(ret_data + SIZE_IPPORT, packet + (length - RETURN_2), RETURN_2); len = encrypt_data_symmetric(onion->secret_symmetric_key, ret_part, ret_data, sizeof(ret_data), - ret_part + CRYPTO_NONCE_SIZE); + ret_part + CRYPTO_NONCE_SIZE, onion->mem); if (len != RETURN_3 - CRYPTO_NONCE_SIZE) { return 1; @@ -575,7 +575,7 @@ static int handle_recv_3(void *object, const IP_Port *source, const uint8_t *pac uint8_t plain[SIZE_IPPORT + RETURN_2]; const int len = decrypt_data_symmetric(onion->secret_symmetric_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE, - SIZE_IPPORT + RETURN_2 + CRYPTO_MAC_SIZE, plain); + SIZE_IPPORT + RETURN_2 + CRYPTO_MAC_SIZE, plain, onion->mem); if ((uint32_t)len != sizeof(plain)) { return 1; @@ -628,7 +628,7 @@ static int handle_recv_2(void *object, const IP_Port *source, const uint8_t *pac uint8_t plain[SIZE_IPPORT + RETURN_1]; const int len = decrypt_data_symmetric(onion->secret_symmetric_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE, - SIZE_IPPORT + RETURN_1 + CRYPTO_MAC_SIZE, plain); + SIZE_IPPORT + RETURN_1 + CRYPTO_MAC_SIZE, plain, onion->mem); if ((uint32_t)len != sizeof(plain)) { return 1; @@ -680,7 +680,7 @@ static int handle_recv_1(void *object, const IP_Port *source, const uint8_t *pac uint8_t plain[SIZE_IPPORT]; const int len = decrypt_data_symmetric(onion->secret_symmetric_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE, - SIZE_IPPORT + CRYPTO_MAC_SIZE, plain); + SIZE_IPPORT + CRYPTO_MAC_SIZE, plain, onion->mem); if ((uint32_t)len != SIZE_IPPORT) { return 1; diff --git a/toxcore/onion.h b/toxcore/onion.h index a5d3554e7b..e41baaec5b 100644 --- a/toxcore/onion.h +++ b/toxcore/onion.h @@ -107,7 +107,7 @@ int onion_path_to_nodes(Node_format *nodes, unsigned int num_nodes, const Onion_ non_null() int create_onion_packet(const Random *rng, uint8_t *packet, uint16_t max_packet_length, const Onion_Path *path, const IP_Port *dest, - const uint8_t *data, uint16_t length); + const uint8_t *data, uint16_t length, const Memory *mem); /** @brief Create a onion packet to be sent over tcp. * @@ -121,7 +121,7 @@ int create_onion_packet(const Random *rng, uint8_t *packet, uint16_t max_packet_ non_null() int create_onion_packet_tcp(const Random *rng, uint8_t *packet, uint16_t max_packet_length, const Onion_Path *path, const IP_Port *dest, - const uint8_t *data, uint16_t length); + const uint8_t *data, uint16_t length, const Memory *mem); /** @brief Create and send a onion response sent initially to dest with. * Maximum length of data is ONION_RESPONSE_MAX_DATA_SIZE. diff --git a/toxcore/onion_announce.c b/toxcore/onion_announce.c index 593d81aa2c..cc12f79c9c 100644 --- a/toxcore/onion_announce.c +++ b/toxcore/onion_announce.c @@ -103,7 +103,7 @@ void onion_announce_entry_set_time(Onion_Announce *onion_a, uint32_t entry, uint * return -1 on failure. * return packet length on success. */ -int create_announce_request(const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *dest_client_id, +int create_announce_request(const Random *rng, const Memory *mem, uint8_t *packet, uint16_t max_packet_length, const uint8_t *dest_client_id, const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *ping_id, const uint8_t *client_id, const uint8_t *data_public_key, uint64_t sendback_data) { @@ -123,7 +123,7 @@ int create_announce_request(const Random *rng, uint8_t *packet, uint16_t max_pac random_nonce(rng, packet + 1); const int len = encrypt_data(dest_client_id, secret_key, packet + 1, plain, sizeof(plain), - packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE); + packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE, mem); if ((uint32_t)len + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE != ONION_ANNOUNCE_REQUEST_MIN_SIZE) { return -1; @@ -146,8 +146,9 @@ int create_announce_request(const Random *rng, uint8_t *packet, uint16_t max_pac * return -1 on failure. * return 0 on success. */ -int create_data_request(const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *public_key, - const uint8_t *encrypt_public_key, const uint8_t *nonce, const uint8_t *data, uint16_t length) +int create_data_request(const Random *rng, const Memory *mem, uint8_t *packet, uint16_t max_packet_length, + const uint8_t *public_key, const uint8_t *encrypt_public_key, const uint8_t *nonce, + const uint8_t *data, uint16_t length) { if (DATA_REQUEST_MIN_SIZE + length > max_packet_length) { return -1; @@ -168,7 +169,7 @@ int create_data_request(const Random *rng, uint8_t *packet, uint16_t max_packet_ memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, random_public_key, CRYPTO_PUBLIC_KEY_SIZE); const int len = encrypt_data(encrypt_public_key, random_secret_key, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, data, length, - packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE); + packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE, mem); if (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + len != DATA_REQUEST_MIN_SIZE + length) { @@ -193,14 +194,14 @@ int create_data_request(const Random *rng, uint8_t *packet, uint16_t max_packet_ * return 0 on success. */ int send_announce_request( - const Logger *log, const Networking_Core *net, const Random *rng, + const Logger *log, const Networking_Core *net, const Random *rng, const Memory *mem, const Onion_Path *path, const Node_format *dest, const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *ping_id, const uint8_t *client_id, const uint8_t *data_public_key, uint64_t sendback_data) { uint8_t request[ONION_ANNOUNCE_REQUEST_MIN_SIZE]; - int len = create_announce_request(rng, request, sizeof(request), dest->public_key, public_key, secret_key, ping_id, + int len = create_announce_request(rng, mem, request, sizeof(request), dest->public_key, public_key, secret_key, ping_id, client_id, data_public_key, sendback_data); if (len != sizeof(request)) { @@ -208,7 +209,7 @@ int send_announce_request( } uint8_t packet[ONION_MAX_PACKET_SIZE]; - len = create_onion_packet(rng, packet, sizeof(packet), path, &dest->ip_port, request, sizeof(request)); + len = create_onion_packet(rng, packet, sizeof(packet), path, &dest->ip_port, request, sizeof(request), mem); if (len == -1) { return -1; @@ -238,19 +239,20 @@ int send_announce_request( * return 0 on success. */ int send_data_request( - const Logger *log, const Networking_Core *net, const Random *rng, const Onion_Path *path, const IP_Port *dest, + const Logger *log, const Networking_Core *net, const Random *rng, const Memory *mem, + const Onion_Path *path, const IP_Port *dest, const uint8_t *public_key, const uint8_t *encrypt_public_key, const uint8_t *nonce, const uint8_t *data, uint16_t length) { uint8_t request[ONION_MAX_DATA_SIZE]; - int len = create_data_request(rng, request, sizeof(request), public_key, encrypt_public_key, nonce, data, length); + int len = create_data_request(rng, mem, request, sizeof(request), public_key, encrypt_public_key, nonce, data, length); if (len == -1) { return -1; } uint8_t packet[ONION_MAX_PACKET_SIZE]; - len = create_onion_packet(rng, packet, sizeof(packet), path, dest, request, len); + len = create_onion_packet(rng, packet, sizeof(packet), path, dest, request, len, mem); if (len == -1) { return -1; @@ -456,7 +458,7 @@ static int handle_announce_request_common( } const int decrypted_len = decrypt_data_symmetric(shared_key, packet + 1, - 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, onion_a->mem); if ((uint32_t)decrypted_len != plain_size) { mem_delete(onion_a->mem, plain); @@ -543,7 +545,7 @@ static int handle_announce_request_common( uint8_t data[ONION_ANNOUNCE_RESPONSE_MAX_SIZE]; const int len = encrypt_data_symmetric(shared_key, nonce, response, offset, - data + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE); + data + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE, onion_a->mem); if (len != offset + CRYPTO_MAC_SIZE) { LOGGER_ERROR(onion_a->log, "Failed to encrypt announce response"); diff --git a/toxcore/onion_announce.h b/toxcore/onion_announce.h index 1158093170..a35a31753d 100644 --- a/toxcore/onion_announce.h +++ b/toxcore/onion_announce.h @@ -65,9 +65,10 @@ void onion_announce_entry_set_time(Onion_Announce *onion_a, uint32_t entry, uint * return packet length on success. */ non_null() -int create_announce_request(const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *dest_client_id, - const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *ping_id, const uint8_t *client_id, - const uint8_t *data_public_key, uint64_t sendback_data); +int create_announce_request( + const Random *rng, const Memory *mem, uint8_t *packet, uint16_t max_packet_length, const uint8_t *dest_client_id, + const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *ping_id, const uint8_t *client_id, + const uint8_t *data_public_key, uint64_t sendback_data); /** @brief Create an onion data request packet in packet of max_packet_length. * @@ -82,8 +83,9 @@ int create_announce_request(const Random *rng, uint8_t *packet, uint16_t max_pac * return 0 on success. */ non_null() -int create_data_request(const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *public_key, - const uint8_t *encrypt_public_key, const uint8_t *nonce, const uint8_t *data, uint16_t length); +int create_data_request(const Random *rng, const Memory *mem, uint8_t *packet, uint16_t max_packet_length, + const uint8_t *public_key, const uint8_t *encrypt_public_key, const uint8_t *nonce, + const uint8_t *data, uint16_t length); /** @brief Create and send an onion announce request packet. * @@ -101,7 +103,7 @@ int create_data_request(const Random *rng, uint8_t *packet, uint16_t max_packet_ */ non_null() int send_announce_request( - const Logger *log, const Networking_Core *net, const Random *rng, + const Logger *log, const Networking_Core *net, const Random *rng, const Memory *mem, const Onion_Path *path, const Node_format *dest, const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *ping_id, const uint8_t *client_id, @@ -125,7 +127,8 @@ int send_announce_request( */ non_null() int send_data_request( - const Logger *log, const Networking_Core *net, const Random *rng, const Onion_Path *path, const IP_Port *dest, + const Logger *log, const Networking_Core *net, const Random *rng, const Memory *mem, + const Onion_Path *path, const IP_Port *dest, const uint8_t *public_key, const uint8_t *encrypt_public_key, const uint8_t *nonce, const uint8_t *data, uint16_t length); diff --git a/toxcore/onion_client.c b/toxcore/onion_client.c index 326575963b..a132b0868b 100644 --- a/toxcore/onion_client.c +++ b/toxcore/onion_client.c @@ -528,7 +528,7 @@ static int send_onion_packet_tcp_udp(const Onion_Client *onion_c, const Onion_Pa { if (net_family_is_ipv4(path->ip_port1.ip.family) || net_family_is_ipv6(path->ip_port1.ip.family)) { uint8_t packet[ONION_MAX_PACKET_SIZE]; - const int len = create_onion_packet(onion_c->rng, packet, sizeof(packet), path, dest, data, length); + const int len = create_onion_packet(onion_c->rng, packet, sizeof(packet), path, dest, data, length, onion_c->mem); if (len == -1) { return -1; @@ -545,7 +545,7 @@ static int send_onion_packet_tcp_udp(const Onion_Client *onion_c, const Onion_Pa if (ip_port_to_tcp_connections_number(&path->ip_port1, &tcp_connections_number)) { uint8_t packet[ONION_MAX_PACKET_SIZE]; - const int len = create_onion_packet_tcp(onion_c->rng, packet, sizeof(packet), path, dest, data, length); + const int len = create_onion_packet_tcp(onion_c->rng, packet, sizeof(packet), path, dest, data, length, onion_c->mem); if (len == -1) { return -1; @@ -661,7 +661,7 @@ static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, con if (num == 0) { len = create_announce_request( - onion_c->rng, request, sizeof(request), dest_pubkey, nc_get_self_public_key(onion_c->c), + onion_c->rng, onion_c->mem, request, sizeof(request), dest_pubkey, nc_get_self_public_key(onion_c->c), nc_get_self_secret_key(onion_c->c), ping_id, nc_get_self_public_key(onion_c->c), onion_c->temp_public_key, sendback); } else { @@ -669,14 +669,14 @@ static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, con if (onion_friend->gc_data_length == 0) { // contact is a friend len = create_announce_request( - onion_c->rng, request, sizeof(request), dest_pubkey, onion_friend->temp_public_key, + onion_c->rng, onion_c->mem, request, sizeof(request), dest_pubkey, onion_friend->temp_public_key, onion_friend->temp_secret_key, ping_id, onion_friend->real_public_key, zero_ping_id, sendback); } else { // contact is a gc onion_friend->is_groupchat = true; len = create_gca_announce_request( - onion_c->rng, request, sizeof(request), dest_pubkey, onion_friend->temp_public_key, + onion_c->rng, onion_c->mem, request, sizeof(request), dest_pubkey, onion_friend->temp_public_key, onion_friend->temp_secret_key, ping_id, onion_friend->real_public_key, zero_ping_id, sendback, onion_friend->gc_data, onion_friend->gc_data_length); @@ -963,7 +963,7 @@ static int handle_announce_response(void *object, const IP_Port *source, const u if (num == 0) { len = decrypt_data(public_key, nc_get_self_secret_key(onion_c->c), - &packet[nonce_start], &packet[ciphertext_start], ciphertext_size, plain); + &packet[nonce_start], &packet[ciphertext_start], ciphertext_size, plain, onion_c->mem); } else { if (!onion_c->friends_list[num - 1].is_valid) { LOGGER_TRACE(onion_c->logger, "friend number %lu is invalid", (unsigned long)(num - 1)); @@ -971,7 +971,8 @@ static int handle_announce_response(void *object, const IP_Port *source, const u } len = decrypt_data(public_key, onion_c->friends_list[num - 1].temp_secret_key, - &packet[nonce_start], &packet[ciphertext_start], ciphertext_size, plain); + &packet[nonce_start], &packet[ciphertext_start], ciphertext_size, plain, + onion_c->mem); } if (len < 0) { @@ -1067,7 +1068,8 @@ static int handle_announce_response_old(void *object, const IP_Port *source, con if (num == 0) { len = decrypt_data(public_key, nc_get_self_secret_key(onion_c->c), - &packet[nonce_start], &packet[ciphertext_start], ciphertext_size, plain); + &packet[nonce_start], &packet[ciphertext_start], ciphertext_size, plain, + onion_c->mem); } else { if (!onion_c->friends_list[num - 1].is_valid) { LOGGER_TRACE(onion_c->logger, "friend number %lu is invalid", (unsigned long)(num - 1)); @@ -1075,7 +1077,8 @@ static int handle_announce_response_old(void *object, const IP_Port *source, con } len = decrypt_data(public_key, onion_c->friends_list[num - 1].temp_secret_key, - &packet[nonce_start], &packet[ciphertext_start], ciphertext_size, plain); + &packet[nonce_start], &packet[ciphertext_start], ciphertext_size, plain, + onion_c->mem); } if (len < 0) { @@ -1138,7 +1141,8 @@ static int handle_data_response(void *object, const IP_Port *source, const uint8 VLA(uint8_t, temp_plain, temp_plain_size); int len = decrypt_data(packet + 1 + CRYPTO_NONCE_SIZE, onion_c->temp_secret_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE, - length - (1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE), temp_plain); + length - (1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE), temp_plain, + onion_c->mem); if ((uint32_t)len != temp_plain_size) { return 1; @@ -1148,7 +1152,8 @@ static int handle_data_response(void *object, const IP_Port *source, const uint8 VLA(uint8_t, plain, plain_size); len = decrypt_data(temp_plain, nc_get_self_secret_key(onion_c->c), packet + 1, temp_plain + CRYPTO_PUBLIC_KEY_SIZE, - temp_plain_size - CRYPTO_PUBLIC_KEY_SIZE, plain); + temp_plain_size - CRYPTO_PUBLIC_KEY_SIZE, plain, + onion_c->mem); if ((uint32_t)len != plain_size) { return 1; @@ -1307,7 +1312,8 @@ int send_onion_data(Onion_Client *onion_c, int friend_num, const uint8_t *data, memcpy(packet, nc_get_self_public_key(onion_c->c), CRYPTO_PUBLIC_KEY_SIZE); int len = encrypt_data(onion_c->friends_list[friend_num].real_public_key, nc_get_self_secret_key(onion_c->c), nonce, data, - length, packet + CRYPTO_PUBLIC_KEY_SIZE); + length, packet + CRYPTO_PUBLIC_KEY_SIZE, + onion_c->mem); if ((uint32_t)len + CRYPTO_PUBLIC_KEY_SIZE != packet_size) { return -1; @@ -1324,7 +1330,7 @@ int send_onion_data(Onion_Client *onion_c, int friend_num, const uint8_t *data, uint8_t o_packet[ONION_MAX_PACKET_SIZE]; len = create_data_request( - onion_c->rng, o_packet, sizeof(o_packet), onion_c->friends_list[friend_num].real_public_key, + onion_c->rng, onion_c->mem, o_packet, sizeof(o_packet), onion_c->friends_list[friend_num].real_public_key, node_list[good_nodes[i]].data_public_key, nonce, packet, packet_size); if (len == -1) { @@ -1366,7 +1372,8 @@ static int send_dht_dhtpk(const Onion_Client *onion_c, int friend_num, const uin memcpy(temp + CRYPTO_PUBLIC_KEY_SIZE, nonce, CRYPTO_NONCE_SIZE); int len = encrypt_data(onion_c->friends_list[friend_num].real_public_key, nc_get_self_secret_key(onion_c->c), nonce, data, - length, temp + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE); + length, temp + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, + onion_c->mem); if ((uint32_t)len + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE != temp_size) { return -1; @@ -1375,7 +1382,7 @@ static int send_dht_dhtpk(const Onion_Client *onion_c, int friend_num, const uin uint8_t packet_data[MAX_CRYPTO_REQUEST_SIZE]; len = create_request( onion_c->rng, dht_get_self_public_key(onion_c->dht), dht_get_self_secret_key(onion_c->dht), packet_data, - onion_c->friends_list[friend_num].dht_public_key, temp, temp_size, CRYPTO_PACKET_DHTPK); + onion_c->friends_list[friend_num].dht_public_key, temp, temp_size, CRYPTO_PACKET_DHTPK, onion_c->mem); assert(len <= UINT16_MAX); const Packet packet = {packet_data, (uint16_t)len}; @@ -1404,7 +1411,8 @@ static int handle_dht_dhtpk(void *object, const IP_Port *source, const uint8_t * const int len = decrypt_data(packet, nc_get_self_secret_key(onion_c->c), packet + CRYPTO_PUBLIC_KEY_SIZE, packet + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, - length - (CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE), plain); + length - (CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE), plain, + onion_c->mem); if (len != length - (DATA_IN_RESPONSE_MIN_SIZE + CRYPTO_NONCE_SIZE)) { return 1; diff --git a/toxcore/os_log.c b/toxcore/os_log.c new file mode 100644 index 0000000000..c218b1b19b --- /dev/null +++ b/toxcore/os_log.c @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2022-2023 The TokTok team. + */ +#include "os_log.h" + +#include + +#include "attributes.h" +#include "tox_log.h" +#include "tox_log_impl.h" + +non_null() +static void os_log_log( + void *self, Tox_Log_Level level, + const char *file, uint32_t line, const char *func, + const char *message) +{ + // Do nothing with the log message by default. + return; +} + +static const Tox_Log_Funcs os_log_funcs = { + os_log_log, +}; + +const Tox_Log os_log_obj = {&os_log_funcs}; + +const Tox_Log *os_log(void) +{ + return &os_log_obj; +} diff --git a/toxcore/os_log.h b/toxcore/os_log.h new file mode 100644 index 0000000000..cc0e7f7ab0 --- /dev/null +++ b/toxcore/os_log.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2022-2023 The TokTok team. + */ + +#ifndef C_TOXCORE_TOXCORE_OS_LOG_H +#define C_TOXCORE_TOXCORE_OS_LOG_H + +#include "tox_log.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern const Tox_Log os_log_obj; + +const Tox_Log *os_log(void); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* C_TOXCORE_TOXCORE_OS_LOG_H */ diff --git a/toxcore/os_memory.c b/toxcore/os_memory.c new file mode 100644 index 0000000000..0018c26d60 --- /dev/null +++ b/toxcore/os_memory.c @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2022-2023 The TokTok team. + */ +#include "os_memory.h" + +#include + +#include "attributes.h" +#include "tox_memory.h" +#include "tox_memory_impl.h" + +non_null() +static void *os_malloc(void *self, uint32_t size) +{ + // cppcheck-suppress misra-c2012-21.3 + return malloc(size); +} + +non_null(1) nullable(2) +static void *os_realloc(void *self, void *ptr, uint32_t size) +{ + // cppcheck-suppress misra-c2012-21.3 + return realloc(ptr, size); +} + +non_null(1) nullable(2) +static void os_free(void *self, void *ptr) +{ + // cppcheck-suppress misra-c2012-21.3 + free(ptr); +} + +static const Tox_Memory_Funcs os_memory_funcs = { + os_malloc, + os_realloc, + os_free, +}; +const Tox_Memory os_memory_obj = {&os_memory_funcs}; + +const Tox_Memory *os_memory(void) +{ + return &os_memory_obj; +} diff --git a/toxcore/os_memory.h b/toxcore/os_memory.h new file mode 100644 index 0000000000..41b7116053 --- /dev/null +++ b/toxcore/os_memory.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2022-2023 The TokTok team. + */ + +#ifndef C_TOXCORE_TOXCORE_OS_MEMORY_H +#define C_TOXCORE_TOXCORE_OS_MEMORY_H + +#include "tox_memory.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern const Tox_Memory os_memory_obj; + +const Tox_Memory *os_memory(void); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* C_TOXCORE_TOXCORE_OS_MEMORY_H */ diff --git a/toxcore/os_network.c b/toxcore/os_network.c new file mode 100644 index 0000000000..c90cce12d5 --- /dev/null +++ b/toxcore/os_network.c @@ -0,0 +1,309 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2022-2023 The TokTok team. + */ +#ifdef __APPLE__ +#define _DARWIN_C_SOURCE +#endif /* __APPLE__ */ + +// For Solaris. +#ifdef __sun +#define __EXTENSIONS__ 1 +#endif /* __sun */ + +// For Linux (and some BSDs). +#ifndef _XOPEN_SOURCE +#define _XOPEN_SOURCE 700 +#endif /* _XOPEN_SOURCE */ + +#if defined(_WIN32) && _WIN32_WINNT >= _WIN32_WINNT_WINXP +#undef _WIN32_WINNT +#define _WIN32_WINNT 0x501 +#endif /* _WIN32 */ + +#if !defined(OS_WIN32) && (defined(_WIN32) || defined(__WIN32__) || defined(WIN32)) +#define OS_WIN32 +#endif /* OS_WIN32 */ + +#if defined(OS_WIN32) && !defined(WINVER) +// Windows XP +#define WINVER 0x0501 +#endif /* OS_WIN32 */ + +#include "os_network.h" + +#ifdef OS_WIN32 // Put win32 includes here +// The mingw32/64 Windows library warns about including winsock2.h after +// windows.h even though with the above it's a valid thing to do. So, to make +// mingw32 headers happy, we include winsock2.h first. +#include +// Comment line here to avoid reordering by source code formatters. +#include +#include +#endif /* OS_WIN32 */ + +#if !defined(OS_WIN32) +#include +#include +#include +#include +#include +#include +#include + +#ifdef __sun +#include +#include +#endif /* __sun */ + +#else +#ifndef IPV6_V6ONLY +#define IPV6_V6ONLY 27 +#endif /* IPV6_V6ONLY */ +#endif /* OS_WIN32 */ + +#include +#include // memcpy + +#include "ccompat.h" +#include "os_network_impl.h" +#include "attributes.h" +#include "tox_memory.h" +#include "tox_network.h" +#include "tox_network_impl.h" + +// Disable MSG_NOSIGNAL on systems not supporting it, e.g. Windows, FreeBSD +#if !defined(MSG_NOSIGNAL) +#define MSG_NOSIGNAL 0 +#endif /* MSG_NOSIGNAL */ + +non_null() +static int os_close(void *self, Socket sock) +{ +#if defined(OS_WIN32) + return closesocket(net_socket_to_native(sock)); +#else // !OS_WIN32 + return close(net_socket_to_native(sock)); +#endif /* OS_WIN32 */ +} + +struct Network_Addr { + struct sockaddr_storage addr; + size_t size; +}; + +Network_Addr *net_addr_new(const void *data, size_t size, const Tox_Memory *mem) +{ + Network_Addr *addr = (Network_Addr *)tox_memory_malloc(mem, sizeof(Network_Addr)); + + if (addr == nullptr) { + return nullptr; + } + + if (data != nullptr) { + net_addr_set(addr, data, size); + } else { + addr->size = sizeof(struct sockaddr_storage); + } + + return addr; +} + +void net_addr_free(Network_Addr *addr, const Tox_Memory *mem) +{ + tox_memory_dealloc(mem, addr); +} + +void net_addr_set(Network_Addr *addr, const void *data, size_t size) +{ + assert(size <= sizeof(struct sockaddr_storage)); + memcpy(&addr->addr, data, size); + addr->size = size; +} + +void *net_addr_mut_addr(Network_Addr *addr) +{ + return &addr->addr; +} + +const void *net_addr_get_addr(const Network_Addr *addr) +{ + return &addr->addr; +} + +void net_addr_set_size(Network_Addr *addr, size_t size) +{ + addr->size = size; +} + +size_t net_addr_get_size(const Network_Addr *addr) +{ + return addr->size; +} + +bool net_addr_is_ipv4(const Network_Addr *addr) +{ + return addr->addr.ss_family == AF_INET; +} + +bool net_addr_is_ipv6(const Network_Addr *addr) +{ + return addr->addr.ss_family == AF_INET6; +} + +uint16_t net_addr_get_port(const Network_Addr *addr) +{ + const int family = addr->addr.ss_family; + if (family == AF_INET6) { + const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *)&addr->addr; + return addr6->sin6_port; + } else { + assert(family == AF_INET); + const struct sockaddr_in *addr4 = (const struct sockaddr_in *)&addr->addr; + return addr4->sin_port; + } +} + + +non_null() +static Socket os_accept(void *self, Socket sock) +{ + return net_socket_from_native(accept(net_socket_to_native(sock), nullptr, nullptr)); +} + +non_null() +static int os_bind(void *self, Socket sock, const Network_Addr *addr) +{ + return bind(net_socket_to_native(sock), (const struct sockaddr *)net_addr_get_addr(addr), net_addr_get_size(addr)); +} + +non_null() +static int os_listen(void *self, Socket sock, int backlog) +{ + return listen(net_socket_to_native(sock), backlog); +} + +non_null() +static int os_connect(void *self, Socket sock, const Network_Addr *addr) +{ + return connect(net_socket_to_native(sock), (const struct sockaddr *)net_addr_get_addr(addr), net_addr_get_size(addr)); +} + +non_null() +static int os_recvbuf(void *self, Socket sock) +{ +#ifdef OS_WIN32 + u_long count = 0; + ioctlsocket(net_socket_to_native(sock), FIONREAD, &count); +#else + int count = 0; + ioctl(net_socket_to_native(sock), FIONREAD, &count); +#endif /* OS_WIN32 */ + + return count; +} + +non_null() +static int os_recv(void *self, Socket sock, uint8_t *buf, size_t len) +{ + return recv(net_socket_to_native(sock), (char *)buf, len, MSG_NOSIGNAL); +} + +non_null() +static int os_send(void *self, Socket sock, const uint8_t *buf, size_t len) +{ + return send(net_socket_to_native(sock), (const char *)buf, len, MSG_NOSIGNAL); +} + +non_null() +static int os_sendto(void *self, Socket sock, const uint8_t *buf, size_t len, const Network_Addr *addr) +{ + return sendto(net_socket_to_native(sock), (const char *)buf, len, 0, (const struct sockaddr *)&addr->addr, addr->size); +} + +non_null() +static int os_recvfrom(void *self, Socket sock, uint8_t *buf, size_t len, Network_Addr *addr) +{ + socklen_t size = addr->size; + const int ret = recvfrom(net_socket_to_native(sock), (char *)buf, len, 0, (struct sockaddr *)&addr->addr, &size); + addr->size = size; + return ret; +} + +non_null() +static Socket os_socket(void *self, int domain, int type, int proto) +{ + return net_socket_from_native(socket(domain, type, proto)); +} + +non_null() +static int os_socket_nonblock(void *self, Socket sock, bool nonblock) +{ +#ifdef OS_WIN32 + u_long mode = nonblock ? 1 : 0; + return ioctlsocket(net_socket_to_native(sock), FIONBIO, &mode); +#else + return fcntl(net_socket_to_native(sock), F_SETFL, O_NONBLOCK, nonblock ? 1 : 0); +#endif /* OS_WIN32 */ +} + +non_null() +static int os_getsockopt(void *self, Socket sock, int level, int optname, void *optval, size_t *optlen) +{ + char *optval_bytes = (char *)optval; + socklen_t len = *optlen; + const int ret = getsockopt(net_socket_to_native(sock), level, optname, optval_bytes, &len); + *optlen = len; + return ret; +} + +non_null() +static int os_setsockopt(void *self, Socket sock, int level, int optname, const void *optval, size_t optlen) +{ + const char *optval_bytes = (const char *)optval; + return setsockopt(net_socket_to_native(sock), level, optname, optval_bytes, optlen); +} + +static const Tox_Network_Funcs os_network_funcs = { + os_close, + os_accept, + os_bind, + os_listen, + os_connect, + os_recvbuf, + os_recv, + os_recvfrom, + os_send, + os_sendto, + os_socket, + os_socket_nonblock, + os_getsockopt, + os_setsockopt, +}; +const Tox_Network os_network_obj = {&os_network_funcs}; + +#if 0 +/* TODO(iphydf): Call this from functions that use `os_network()`. */ +void os_network_deinit(const Network *ns) +{ +#ifdef OS_WIN32 + WSACleanup(); +#endif /* OS_WIN32 */ +} +#endif /* 0 */ + +const Tox_Network *os_network(void) +{ +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + if ((true)) { + return nullptr; + } +#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ +#ifdef OS_WIN32 + WSADATA wsaData; + + if (WSAStartup(MAKEWORD(2, 2), &wsaData) != NO_ERROR) { + return nullptr; + } +#endif /* OS_WIN32 */ + return &os_network_obj; +} diff --git a/toxcore/os_network.h b/toxcore/os_network.h new file mode 100644 index 0000000000..3bf383e2e4 --- /dev/null +++ b/toxcore/os_network.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2022-2023 The TokTok team. + */ + +#ifndef C_TOXCORE_TOXCORE_OS_NETWORK_H +#define C_TOXCORE_TOXCORE_OS_NETWORK_H + +#include "tox_network.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern const Tox_Network os_network_obj; + +const Tox_Network *os_network(void); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* C_TOXCORE_TOXCORE_OS_NETWORK_H */ diff --git a/toxcore/os_network_impl.h b/toxcore/os_network_impl.h new file mode 100644 index 0000000000..aac633bf1e --- /dev/null +++ b/toxcore/os_network_impl.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2022-2023 The TokTok team. + */ + +#ifndef C_TOXCORE_TOXCORE_OS_NETWORK_IMPL_H +#define C_TOXCORE_TOXCORE_OS_NETWORK_IMPL_H + +#include "attributes.h" +#include "tox_memory.h" +#include "tox_network.h" + +#ifdef __cplusplus +extern "C" { +#endif + +non_null(3) nullable(1) Network_Addr *net_addr_new(const void *data, size_t size, const Tox_Memory *mem); +non_null(2) nullable(1) void net_addr_free(Network_Addr *addr, const Tox_Memory *mem); + +non_null() void net_addr_set(Network_Addr *addr, const void *data, size_t size); + +non_null() void *net_addr_mut_addr(Network_Addr *addr); +non_null() const void *net_addr_get_addr(const Network_Addr *addr); + +non_null() void net_addr_set_size(Network_Addr *addr, size_t size); +non_null() size_t net_addr_get_size(const Network_Addr *addr); + +non_null() bool net_addr_is_ipv4(const Network_Addr *addr); +non_null() bool net_addr_is_ipv6(const Network_Addr *addr); + +non_null() uint16_t net_addr_get_port(const Network_Addr *addr); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* C_TOXCORE_TOXCORE_OS_NETWORK_IMPL_H */ diff --git a/toxcore/os_random.c b/toxcore/os_random.c new file mode 100644 index 0000000000..65027c06fa --- /dev/null +++ b/toxcore/os_random.c @@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2022-2023 The TokTok team. + */ +#include "os_random.h" + +#include + +#include "attributes.h" +#include "ccompat.h" +#include "tox_random.h" +#include "tox_random_impl.h" + +non_null() +static void os_random_bytes(void *self, uint8_t *bytes, uint32_t length) +{ + randombytes(bytes, length); +} + +non_null() +static uint32_t os_random_uniform(void *self, uint32_t upper_bound) +{ + return randombytes_uniform(upper_bound); +} + +static const Tox_Random_Funcs os_random_funcs = { + os_random_bytes, + os_random_uniform, +}; + +const Tox_Random os_random_obj = {&os_random_funcs}; + +const Tox_Random *os_random(void) +{ +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + if ((true)) { + return nullptr; + } +#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ + // It is safe to call this function more than once and from different + // threads -- subsequent calls won't have any effects. + if (sodium_init() == -1) { + return nullptr; + } + return &os_random_obj; +} diff --git a/toxcore/os_random.h b/toxcore/os_random.h new file mode 100644 index 0000000000..3004780837 --- /dev/null +++ b/toxcore/os_random.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2022-2023 The TokTok team. + */ + +#ifndef C_TOXCORE_TOXCORE_OS_RANDOM_H +#define C_TOXCORE_TOXCORE_OS_RANDOM_H + +#include "tox_random.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern const Tox_Random os_random_obj; + +/** @brief System random number generator. + * + * Uses libsodium's CSPRNG (on Linux, `/dev/urandom`). + */ +const Tox_Random *os_random(void); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* C_TOXCORE_TOXCORE_OS_RANDOM_H */ diff --git a/toxcore/os_system.c b/toxcore/os_system.c new file mode 100644 index 0000000000..9b1de31273 --- /dev/null +++ b/toxcore/os_system.c @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2022-2023 The TokTok team. + */ +#include "os_system.h" + +#include "ccompat.h" +#include "os_log.h" +#include "os_memory.h" +#include "os_network.h" +#include "os_random.h" +#include "tox_system.h" +#include "tox_system_impl.h" + +static const Tox_System os_system_obj = { + &os_log_obj, + &os_memory_obj, + &os_network_obj, + &os_random_obj, + nullptr, +}; + +const Tox_System *os_system(void) +{ + const Tox_System *sys = &os_system_obj; + + if (sys->log != os_log() + || sys->mem != os_memory() + || sys->ns != os_network() + || sys->rng != os_random()) { + return nullptr; + } + + return sys; +} diff --git a/toxcore/os_system.h b/toxcore/os_system.h new file mode 100644 index 0000000000..e3a68020e3 --- /dev/null +++ b/toxcore/os_system.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2022-2023 The TokTok team. + */ + +#ifndef C_TOXCORE_TOXCORE_OS_SYSTEM_H +#define C_TOXCORE_TOXCORE_OS_SYSTEM_H + +#include "tox_system.h" +#include "tox_system_impl.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief Default operating-system-backed `Tox_System`. + * + * Only `Tox_Time` does not have a subsystem here, and instead is created in + * `mono_time`. + * + * This function, and by extension all the subsystem functions, does not + * allocate any dynamic memory. + */ +const Tox_System *os_system(void); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* C_TOXCORE_TOXCORE_OS_SYSTEM_H */ diff --git a/toxcore/os_time.c b/toxcore/os_time.c new file mode 100644 index 0000000000..ac0a121da3 --- /dev/null +++ b/toxcore/os_time.c @@ -0,0 +1,113 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2022-2023 The TokTok team. + */ +#ifndef _XOPEN_SOURCE +#define _XOPEN_SOURCE 600 +#endif /* _XOPEN_SOURCE */ + +#if !defined(OS_WIN32) && (defined(_WIN32) || defined(__WIN32__) || defined(WIN32)) +#define OS_WIN32 +#endif /* WIN32 */ + +#include "os_time.h" + +#ifdef OS_WIN32 +#define WIN32_LEAN_AND_MEAN +#include +#endif /* OS_WIN32 */ + +#ifdef __APPLE__ +#include +#include +#endif /* __APPLE__ */ + +#ifndef OS_WIN32 +#include +#endif /* OS_WIN32 */ + +#include +#include + +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION +#include +#include "ccompat.h" +#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ + +#include "attributes.h" +#include "tox_time.h" +#include "tox_time_impl.h" + +static uint64_t timespec_to_u64(struct timespec clock_mono) +{ + return UINT64_C(1000) * clock_mono.tv_sec + (clock_mono.tv_nsec / UINT64_C(1000000)); +} + +#ifdef OS_WIN32 +non_null() +static uint64_t current_time_monotonic_default(void *user_data) +{ + LARGE_INTEGER freq; + LARGE_INTEGER count; + if (!QueryPerformanceFrequency(&freq)) { + return 0; + } + if (!QueryPerformanceCounter(&count)) { + return 0; + } + struct timespec sp = {0}; + sp.tv_sec = count.QuadPart / freq.QuadPart; + if (freq.QuadPart < 1000000000) { + sp.tv_nsec = (count.QuadPart % freq.QuadPart) * 1000000000 / freq.QuadPart; + } else { + sp.tv_nsec = (long)((count.QuadPart % freq.QuadPart) * (1000000000.0 / freq.QuadPart)); + } + return timespec_to_u64(sp); +} +#else +#ifdef __APPLE__ +non_null() +static uint64_t current_time_monotonic_default(void *user_data) +{ + struct timespec clock_mono; + clock_serv_t muhclock; + mach_timespec_t machtime; + + host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &muhclock); + clock_get_time(muhclock, &machtime); + mach_port_deallocate(mach_task_self(), muhclock); + + clock_mono.tv_sec = machtime.tv_sec; + clock_mono.tv_nsec = machtime.tv_nsec; + return timespec_to_u64(clock_mono); +} +#else // !__APPLE__ +non_null() +static uint64_t current_time_monotonic_default(void *user_data) +{ +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + // This assert should always fail. If it does, the fuzzing harness didn't + // override the mono time callback. + assert(user_data == nullptr); +#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ + struct timespec clock_mono; + clock_gettime(CLOCK_MONOTONIC, &clock_mono); + return timespec_to_u64(clock_mono); +} +#endif /* !__APPLE__ */ +#endif /* !OS_WIN32 */ + +static const Tox_Time_Funcs os_time_funcs = { + current_time_monotonic_default, +}; + +const Tox_Time os_time_obj = {&os_time_funcs}; + +const Tox_Time *os_time(void) +{ +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + if ((true)) { + return nullptr; + } +#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ + return &os_time_obj; +} diff --git a/toxcore/os_time.h b/toxcore/os_time.h new file mode 100644 index 0000000000..80a1c50caa --- /dev/null +++ b/toxcore/os_time.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2022-2023 The TokTok team. + */ + +#ifndef C_TOXCORE_TOXCORE_OS_TIME_H +#define C_TOXCORE_TOXCORE_OS_TIME_H + +#include "tox_time.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern const Tox_Time os_time_obj; + +const Tox_Time *os_time(void); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* C_TOXCORE_TOXCORE_OS_TIME_H */ diff --git a/toxcore/ping.c b/toxcore/ping.c index 303c418cea..635ff00d14 100644 --- a/toxcore/ping.c +++ b/toxcore/ping.c @@ -31,6 +31,7 @@ struct Ping { const Mono_Time *mono_time; const Random *rng; + const Memory *mem; DHT *dht; Ping_Array *ping_array; @@ -75,7 +76,8 @@ void ping_send_request(Ping *ping, const IP_Port *ipp, const uint8_t *public_key rc = encrypt_data_symmetric(shared_key, pk + 1 + CRYPTO_PUBLIC_KEY_SIZE, ping_plain, sizeof(ping_plain), - pk + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE); + pk + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, + ping->mem); if (rc != PING_PLAIN_SIZE + CRYPTO_MAC_SIZE) { return; @@ -107,7 +109,8 @@ static int ping_send_response(const Ping *ping, const IP_Port *ipp, const uint8_ const int rc = encrypt_data_symmetric(shared_encryption_key, pk + 1 + CRYPTO_PUBLIC_KEY_SIZE, ping_plain, sizeof(ping_plain), - pk + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE); + pk + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, + ping->mem); if (rc != PING_PLAIN_SIZE + CRYPTO_MAC_SIZE) { return 1; @@ -141,7 +144,8 @@ static int handle_ping_request(void *object, const IP_Port *source, const uint8_ packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, PING_PLAIN_SIZE + CRYPTO_MAC_SIZE, - ping_plain); + ping_plain, + ping->mem); if (rc != sizeof(ping_plain)) { return 1; @@ -186,7 +190,7 @@ static int handle_ping_response(void *object, const IP_Port *source, const uint8 packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, PING_PLAIN_SIZE + CRYPTO_MAC_SIZE, - ping_plain); + ping_plain, ping->mem); if (rc != sizeof(ping_plain)) { return 1; @@ -348,6 +352,7 @@ Ping *ping_new(const Memory *mem, const Mono_Time *mono_time, const Random *rng, ping->mono_time = mono_time; ping->rng = rng; + ping->mem = mem; ping->dht = dht; networking_registerhandler(dht_get_net(ping->dht), NET_PACKET_PING_REQUEST, &handle_ping_request, dht); networking_registerhandler(dht_get_net(ping->dht), NET_PACKET_PING_RESPONSE, &handle_ping_response, dht); diff --git a/toxcore/ping_array_test.cc b/toxcore/ping_array_test.cc index cc9d0bfc8b..d3342ac5f2 100644 --- a/toxcore/ping_array_test.cc +++ b/toxcore/ping_array_test.cc @@ -7,6 +7,7 @@ #include "crypto_core_test_util.hh" #include "mem_test_util.hh" #include "mono_time.h" +#include "os_random.h" namespace { @@ -65,7 +66,7 @@ TEST(PingArray, StoredDataCanBeRetrieved) Test_Random rng; Ping_Array_Ptr const arr(ping_array_new(mem, 2, 1)); - Mono_Time_Ptr const mono_time(mono_time_new(mem, nullptr, nullptr), mem); + Mono_Time_Ptr const mono_time(mono_time_new(mem, nullptr), mem); ASSERT_NE(mono_time, nullptr); uint64_t const ping_id = ping_array_add( @@ -83,7 +84,7 @@ TEST(PingArray, RetrievingDataWithTooSmallOutputBufferHasNoEffect) Test_Random rng; Ping_Array_Ptr const arr(ping_array_new(mem, 2, 1)); - Mono_Time_Ptr const mono_time(mono_time_new(mem, nullptr, nullptr), mem); + Mono_Time_Ptr const mono_time(mono_time_new(mem, nullptr), mem); ASSERT_NE(mono_time, nullptr); uint64_t const ping_id = ping_array_add( @@ -105,7 +106,7 @@ TEST(PingArray, ZeroLengthDataCanBeAdded) Test_Random rng; Ping_Array_Ptr const arr(ping_array_new(mem, 2, 1)); - Mono_Time_Ptr const mono_time(mono_time_new(mem, nullptr, nullptr), mem); + Mono_Time_Ptr const mono_time(mono_time_new(mem, nullptr), mem); ASSERT_NE(mono_time, nullptr); uint8_t c = 0; @@ -120,7 +121,7 @@ TEST(PingArray, PingId0IsInvalid) Test_Memory mem; Ping_Array_Ptr const arr(ping_array_new(mem, 2, 1)); - Mono_Time_Ptr const mono_time(mono_time_new(mem, nullptr, nullptr), mem); + Mono_Time_Ptr const mono_time(mono_time_new(mem, nullptr), mem); ASSERT_NE(mono_time, nullptr); uint8_t c = 0; @@ -134,7 +135,7 @@ TEST(PingArray, DataCanOnlyBeRetrievedOnce) Test_Random rng; Ping_Array_Ptr const arr(ping_array_new(mem, 2, 1)); - Mono_Time_Ptr const mono_time(mono_time_new(mem, nullptr, nullptr), mem); + Mono_Time_Ptr const mono_time(mono_time_new(mem, nullptr), mem); ASSERT_NE(mono_time, nullptr); uint8_t c = 0; @@ -151,7 +152,7 @@ TEST(PingArray, PingIdMustMatchOnCheck) Test_Random rng; Ping_Array_Ptr const arr(ping_array_new(mem, 1, 1)); - Mono_Time_Ptr const mono_time(mono_time_new(mem, nullptr, nullptr), mem); + Mono_Time_Ptr const mono_time(mono_time_new(mem, nullptr), mem); ASSERT_NE(mono_time, nullptr); uint8_t c = 0; diff --git a/toxcore/tox.c b/toxcore/tox.c index b02eb4e98b..3b6f68051c 100644 --- a/toxcore/tox.c +++ b/toxcore/tox.c @@ -13,8 +13,10 @@ #include "tox.h" #include +#include #include +#include "../toxencryptsave/defines.h" #include "DHT.h" #include "Messenger.h" #include "TCP_client.h" @@ -31,13 +33,14 @@ #include "net_crypto.h" #include "network.h" #include "onion_client.h" +#include "os_system.h" #include "state.h" +#include "tox_impl.h" +#include "tox_log.h" #include "tox_private.h" -#include "tox_struct.h" +#include "tox_system.h" #include "util.h" -#include "../toxencryptsave/defines.h" - #define SET_ERROR_PARAMETER(param, x) \ do { \ if (param != nullptr) { \ @@ -72,6 +75,36 @@ static_assert(TOX_GROUP_MAX_MESSAGE_LENGTH == GROUP_MAX_MESSAGE_LENGTH, static_assert(TOX_MAX_CUSTOM_PACKET_SIZE == MAX_GC_CUSTOM_LOSSLESS_PACKET_SIZE, "TOX_MAX_CUSTOM_PACKET_SIZE is assumed to be equal to MAX_GC_CUSTOM_LOSSLESS_PACKET_SIZE"); +struct Tox_Mutex { + pthread_mutex_t underlying; +}; + +void tox_lock(const Tox *tox) +{ + if (tox->mutex != nullptr) { + pthread_mutex_lock(&tox->mutex->underlying); + } +} + +void tox_unlock(const Tox *tox) +{ + if (tox->mutex != nullptr) { + pthread_mutex_unlock(&tox->mutex->underlying); + } +} + +non_null() +static void tox_mutex_init(Tox_Mutex *mutex) +{ + pthread_mutex_init(&mutex->underlying, nullptr); +} + +non_null() +static void tox_mutex_destroy(Tox_Mutex *mutex) +{ + pthread_mutex_destroy(&mutex->underlying); +} + struct Tox_Userdata { Tox *tox; void *user_data; @@ -712,10 +745,9 @@ static int tox_load(Tox *tox, const uint8_t *data, uint32_t length) length - cookie_len, STATE_COOKIE_TYPE); } -nullable(1, 2, 3) -static Tox *tox_new_system(const struct Tox_Options *options, Tox_Err_New *error, const Tox_System *sys) +Tox *tox_new(const Tox_Options *options, Tox_Err_New *error) { - struct Tox_Options *default_options = nullptr; + Tox_Options *default_options = nullptr; if (options == nullptr) { Tox_Err_Options_New err; @@ -734,16 +766,16 @@ static Tox *tox_new_system(const struct Tox_Options *options, Tox_Err_New *error } } - const struct Tox_Options *const opts = options != nullptr ? options : default_options; + const Tox_Options *const opts = options != nullptr ? options : default_options; assert(opts != nullptr); - const Tox_System default_system = tox_default_system(); + const Tox_System *sys = tox_options_get_operating_system(opts); if (sys == nullptr) { - sys = &default_system; + sys = os_system(); } - if (sys->rng == nullptr || sys->ns == nullptr || sys->mem == nullptr) { + if (sys == nullptr || sys->rng == nullptr || sys->ns == nullptr || sys->mem == nullptr) { // TODO(iphydf): Not quite right, but similar. SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC); tox_options_free(default_options); @@ -868,7 +900,7 @@ static Tox *tox_new_system(const struct Tox_Options *options, Tox_Err_New *error m_options.proxy_info.ip_port.port = net_htons(tox_options_get_proxy_port(opts)); } - tox->mono_time = mono_time_new(tox->sys.mem, sys->mono_time_callback, sys->mono_time_user_data); + tox->mono_time = mono_time_new(tox->sys.mem, sys->tm); if (tox->mono_time == nullptr) { SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC); @@ -878,7 +910,7 @@ static Tox *tox_new_system(const struct Tox_Options *options, Tox_Err_New *error } if (tox_options_get_experimental_thread_safety(opts)) { - pthread_mutex_t *mutex = (pthread_mutex_t *)mem_alloc(sys->mem, sizeof(pthread_mutex_t)); + Tox_Mutex *mutex = (Tox_Mutex *)mem_alloc(sys->mem, sizeof(Tox_Mutex)); if (mutex == nullptr) { SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC); @@ -887,8 +919,7 @@ static Tox *tox_new_system(const struct Tox_Options *options, Tox_Err_New *error return nullptr; } - pthread_mutex_init(mutex, nullptr); - + tox_mutex_init(mutex); tox->mutex = mutex; } else { tox->mutex = nullptr; @@ -917,7 +948,7 @@ static Tox *tox_new_system(const struct Tox_Options *options, Tox_Err_New *error tox_unlock(tox); if (tox->mutex != nullptr) { - pthread_mutex_destroy(tox->mutex); + tox_mutex_destroy(tox->mutex); } mem_delete(sys->mem, tox->mutex); @@ -926,7 +957,7 @@ static Tox *tox_new_system(const struct Tox_Options *options, Tox_Err_New *error return nullptr; } - tox->m->conferences_object = new_groupchats(tox->mono_time, tox->m); + tox->m->conferences_object = new_groupchats(tox->mono_time, sys->mem, tox->m); if (tox->m->conferences_object == nullptr) { kill_messenger(tox->m); @@ -935,7 +966,7 @@ static Tox *tox_new_system(const struct Tox_Options *options, Tox_Err_New *error tox_unlock(tox); if (tox->mutex != nullptr) { - pthread_mutex_destroy(tox->mutex); + tox_mutex_destroy(tox->mutex); } mem_delete(sys->mem, tox->mutex); @@ -955,7 +986,7 @@ static Tox *tox_new_system(const struct Tox_Options *options, Tox_Err_New *error tox_unlock(tox); if (tox->mutex != nullptr) { - pthread_mutex_destroy(tox->mutex); + tox_mutex_destroy(tox->mutex); } mem_delete(sys->mem, tox->mutex); @@ -1020,37 +1051,6 @@ static Tox *tox_new_system(const struct Tox_Options *options, Tox_Err_New *error return tox; } -Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error) -{ - return tox_new_system(options, error, nullptr); -} - -Tox *tox_new_testing(const Tox_Options *options, Tox_Err_New *error, const Tox_Options_Testing *testing, Tox_Err_New_Testing *testing_error) -{ - if (testing == nullptr) { - SET_ERROR_PARAMETER(error, TOX_ERR_NEW_NULL); - SET_ERROR_PARAMETER(testing_error, TOX_ERR_NEW_TESTING_NULL); - return nullptr; - } - - if (testing->operating_system == nullptr) { - SET_ERROR_PARAMETER(error, TOX_ERR_NEW_NULL); - SET_ERROR_PARAMETER(testing_error, TOX_ERR_NEW_TESTING_NULL); - return nullptr; - } - - const Tox_System *sys = testing->operating_system; - - if (sys->rng == nullptr || sys->ns == nullptr || sys->mem == nullptr) { - SET_ERROR_PARAMETER(error, TOX_ERR_NEW_NULL); - SET_ERROR_PARAMETER(testing_error, TOX_ERR_NEW_TESTING_NULL); - return nullptr; - } - - SET_ERROR_PARAMETER(testing_error, TOX_ERR_NEW_TESTING_OK); - return tox_new_system(options, error, sys); -} - void tox_kill(Tox *tox) { if (tox == nullptr) { @@ -1065,7 +1065,7 @@ void tox_kill(Tox *tox) tox_unlock(tox); if (tox->mutex != nullptr) { - pthread_mutex_destroy(tox->mutex); + tox_mutex_destroy(tox->mutex); mem_delete(tox->sys.mem, tox->mutex); } diff --git a/toxcore/tox.h b/toxcore/tox.h index ebeed3b1f5..4e65c91cfa 100644 --- a/toxcore/tox.h +++ b/toxcore/tox.h @@ -95,10 +95,24 @@ #include #include +#include "tox_attributes.h" +#include "tox_log_level.h" + +//!TOKSTYLE- +#ifndef DOXYGEN_IGNORE +#include "tox_options.h" +#endif +//!TOKSTYLE+ + #ifdef __cplusplus extern "C" { #endif +#ifndef TOX_SYSTEM_DEFINED +#define TOX_SYSTEM_DEFINED +typedef struct Tox_System Tox_System; +#endif + /** @{ @namespace tox */ #ifndef TOX_DEFINED @@ -113,7 +127,7 @@ extern "C" { * limiting factor is the number of usable ports on a device. */ typedef struct Tox Tox; -#endif /* TOX_DEFINED */ +#endif /** @{ * @name API version @@ -394,7 +408,6 @@ const char *tox_message_type_to_string(Tox_Message_Type value); * @brief Type of proxy used to connect to TCP relays. */ typedef enum Tox_Proxy_Type { - /** * Don't use a proxy. */ @@ -409,7 +422,6 @@ typedef enum Tox_Proxy_Type { * SOCKS proxy for simple socket pipes. */ TOX_PROXY_TYPE_SOCKS5, - } Tox_Proxy_Type; const char *tox_proxy_type_to_string(Tox_Proxy_Type value); @@ -418,7 +430,6 @@ const char *tox_proxy_type_to_string(Tox_Proxy_Type value); * @brief Type of savedata to create the Tox instance from. */ typedef enum Tox_Savedata_Type { - /** * No savedata. */ @@ -433,47 +444,12 @@ typedef enum Tox_Savedata_Type { * Savedata is a secret key of length TOX_SECRET_KEY_SIZE. */ TOX_SAVEDATA_TYPE_SECRET_KEY, - } Tox_Savedata_Type; const char *tox_savedata_type_to_string(Tox_Savedata_Type value); /** - * @brief Severity level of log messages. - */ -typedef enum Tox_Log_Level { - - /** - * Very detailed traces including all network activity. - */ - TOX_LOG_LEVEL_TRACE, - - /** - * Debug messages such as which port we bind to. - */ - TOX_LOG_LEVEL_DEBUG, - - /** - * Informational log messages such as video call status changes. - */ - TOX_LOG_LEVEL_INFO, - - /** - * Warnings about internal inconsistency or logic errors. - */ - TOX_LOG_LEVEL_WARNING, - - /** - * Severe unexpected errors caused by external or internal inconsistency. - */ - TOX_LOG_LEVEL_ERROR, - -} Tox_Log_Level; - -const char *tox_log_level_to_string(Tox_Log_Level value); - -/** - * @brief This event is triggered when Tox logs an internal message. + * @brief This event is triggered when the toxcore library logs a message. * * This is mostly useful for debugging. This callback can be called from any * function, not just tox_iterate. This means the user data lifetime must at @@ -511,9 +487,7 @@ typedef void tox_log_cb(Tox *tox, Tox_Log_Level level, const char *file, uint32_ * members. The struct will become opaque (i.e. the definition will become * private) in v0.3.0. */ -typedef struct Tox_Options Tox_Options; struct Tox_Options { - /** * The type of socket to create. * @@ -656,6 +630,12 @@ struct Tox_Options { */ bool experimental_thread_safety; + /** + * Low level operating system functionality such as send/recv, random + * number generation, and memory allocation. + */ + const Tox_System *operating_system; + /** * Enable saving DHT-based group chats to Tox save data (via * `tox_get_savedata`). This format will change in the future, so don't rely @@ -670,128 +650,117 @@ struct Tox_Options { bool experimental_groups_persistence; }; -bool tox_options_get_ipv6_enabled(const Tox_Options *options); - -void tox_options_set_ipv6_enabled(Tox_Options *options, bool ipv6_enabled); - -bool tox_options_get_udp_enabled(const Tox_Options *options); +tox_non_null() +bool tox_options_get_ipv6_enabled(const struct Tox_Options *options); -void tox_options_set_udp_enabled(Tox_Options *options, bool udp_enabled); +tox_non_null() +void tox_options_set_ipv6_enabled(struct Tox_Options *options, bool ipv6_enabled); -bool tox_options_get_local_discovery_enabled(const Tox_Options *options); +tox_non_null() +bool tox_options_get_udp_enabled(const struct Tox_Options *options); -void tox_options_set_local_discovery_enabled(Tox_Options *options, bool local_discovery_enabled); +tox_non_null() +void tox_options_set_udp_enabled(struct Tox_Options *options, bool udp_enabled); -bool tox_options_get_dht_announcements_enabled(const Tox_Options *options); +tox_non_null() +bool tox_options_get_local_discovery_enabled(const struct Tox_Options *options); -void tox_options_set_dht_announcements_enabled(Tox_Options *options, bool dht_announcements_enabled); +tox_non_null() +void tox_options_set_local_discovery_enabled(struct Tox_Options *options, bool local_discovery_enabled); -Tox_Proxy_Type tox_options_get_proxy_type(const Tox_Options *options); +tox_non_null() +bool tox_options_get_dht_announcements_enabled(const struct Tox_Options *options); -void tox_options_set_proxy_type(Tox_Options *options, Tox_Proxy_Type proxy_type); +tox_non_null() +void tox_options_set_dht_announcements_enabled(struct Tox_Options *options, bool dht_announcements_enabled); -const char *tox_options_get_proxy_host(const Tox_Options *options); +tox_non_null() +Tox_Proxy_Type tox_options_get_proxy_type(const struct Tox_Options *options); -void tox_options_set_proxy_host(Tox_Options *options, const char *proxy_host); +tox_non_null() +void tox_options_set_proxy_type(struct Tox_Options *options, Tox_Proxy_Type proxy_type); -uint16_t tox_options_get_proxy_port(const Tox_Options *options); +tox_non_null() +const char *tox_options_get_proxy_host(const struct Tox_Options *options); -void tox_options_set_proxy_port(Tox_Options *options, uint16_t proxy_port); +tox_non_null() +void tox_options_set_proxy_host(struct Tox_Options *options, const char *proxy_host); -uint16_t tox_options_get_start_port(const Tox_Options *options); +tox_non_null() +uint16_t tox_options_get_proxy_port(const struct Tox_Options *options); -void tox_options_set_start_port(Tox_Options *options, uint16_t start_port); +tox_non_null() +void tox_options_set_proxy_port(struct Tox_Options *options, uint16_t proxy_port); -uint16_t tox_options_get_end_port(const Tox_Options *options); +tox_non_null() +uint16_t tox_options_get_start_port(const struct Tox_Options *options); -void tox_options_set_end_port(Tox_Options *options, uint16_t end_port); +tox_non_null() +void tox_options_set_start_port(struct Tox_Options *options, uint16_t start_port); -uint16_t tox_options_get_tcp_port(const Tox_Options *options); +tox_non_null() +uint16_t tox_options_get_end_port(const struct Tox_Options *options); -void tox_options_set_tcp_port(Tox_Options *options, uint16_t tcp_port); +tox_non_null() +void tox_options_set_end_port(struct Tox_Options *options, uint16_t end_port); -bool tox_options_get_hole_punching_enabled(const Tox_Options *options); +tox_non_null() +uint16_t tox_options_get_tcp_port(const struct Tox_Options *options); -void tox_options_set_hole_punching_enabled(Tox_Options *options, bool hole_punching_enabled); +tox_non_null() +void tox_options_set_tcp_port(struct Tox_Options *options, uint16_t tcp_port); -Tox_Savedata_Type tox_options_get_savedata_type(const Tox_Options *options); +tox_non_null() +bool tox_options_get_hole_punching_enabled(const struct Tox_Options *options); -void tox_options_set_savedata_type(Tox_Options *options, Tox_Savedata_Type savedata_type); +tox_non_null() +void tox_options_set_hole_punching_enabled(struct Tox_Options *options, bool hole_punching_enabled); -const uint8_t *tox_options_get_savedata_data(const Tox_Options *options); +tox_non_null() +Tox_Savedata_Type tox_options_get_savedata_type(const struct Tox_Options *options); -void tox_options_set_savedata_data(Tox_Options *options, const uint8_t savedata_data[], size_t length); +tox_non_null() +void tox_options_set_savedata_type(struct Tox_Options *options, Tox_Savedata_Type savedata_type); -size_t tox_options_get_savedata_length(const Tox_Options *options); +tox_non_null() +const uint8_t *tox_options_get_savedata_data(const struct Tox_Options *options); -void tox_options_set_savedata_length(Tox_Options *options, size_t savedata_length); +tox_non_null() +void tox_options_set_savedata_data(struct Tox_Options *options, const uint8_t savedata_data[], size_t length); -tox_log_cb *tox_options_get_log_callback(const Tox_Options *options); +tox_non_null() +size_t tox_options_get_savedata_length(const struct Tox_Options *options); -void tox_options_set_log_callback(Tox_Options *options, tox_log_cb *log_callback); +tox_non_null() +void tox_options_set_savedata_length(struct Tox_Options *options, size_t savedata_length); -void *tox_options_get_log_user_data(const Tox_Options *options); +tox_non_null() +tox_log_cb *tox_options_get_log_callback(const struct Tox_Options *options); -void tox_options_set_log_user_data(Tox_Options *options, void *log_user_data); +tox_non_null(1) tox_nullable(2) +void tox_options_set_log_callback(struct Tox_Options *options, tox_log_cb *log_callback); -bool tox_options_get_experimental_thread_safety(const Tox_Options *options); +tox_non_null() +void *tox_options_get_log_user_data(const struct Tox_Options *options); -void tox_options_set_experimental_thread_safety(Tox_Options *options, bool experimental_thread_safety); +tox_non_null(1) tox_nullable(2) +void tox_options_set_log_user_data(struct Tox_Options *options, void *log_user_data); -bool tox_options_get_experimental_groups_persistence(const Tox_Options *options); +tox_non_null() +bool tox_options_get_experimental_thread_safety(const struct Tox_Options *options); -void tox_options_set_experimental_groups_persistence(Tox_Options *options, bool experimental_groups_persistence); +tox_non_null() +void tox_options_set_experimental_thread_safety(struct Tox_Options *options, bool experimental_thread_safety); -/** - * @brief Initialises a Tox_Options object with the default options. - * - * The result of this function is independent of the original options. All - * values will be overwritten, no values will be read (so it is permissible - * to pass an uninitialised object). - * - * If options is NULL, this function has no effect. - * - * @param options An options object to be filled with default options. - */ -void tox_options_default(Tox_Options *options); +tox_non_null() +const Tox_System *tox_options_get_operating_system(const struct Tox_Options *options); -typedef enum Tox_Err_Options_New { +tox_non_null() +void tox_options_set_operating_system(struct Tox_Options *options, const Tox_System *operating_system); - /** - * The function returned successfully. - */ - TOX_ERR_OPTIONS_NEW_OK, +bool tox_options_get_experimental_groups_persistence(const struct Tox_Options *options); - /** - * The function failed to allocate enough memory for the options struct. - */ - TOX_ERR_OPTIONS_NEW_MALLOC, - -} Tox_Err_Options_New; - -const char *tox_err_options_new_to_string(Tox_Err_Options_New value); - -/** - * @brief Allocates a new Tox_Options object and initialises it with the default - * options. - * - * This function can be used to preserve long term ABI compatibility by - * giving the responsibility of allocation and deallocation to the Tox library. - * - * Objects returned from this function must be freed using the tox_options_free - * function. - * - * @return A new Tox_Options object with default options or NULL on failure. - */ -Tox_Options *tox_options_new(Tox_Err_Options_New *error); - -/** - * @brief Releases all resources associated with an options objects. - * - * Passing a pointer that was not returned by tox_options_new results in - * undefined behaviour. - */ -void tox_options_free(Tox_Options *options); +void tox_options_set_experimental_groups_persistence(struct Tox_Options *options, bool experimental_groups_persistence); /** @} */ @@ -877,7 +846,7 @@ const char *tox_err_new_to_string(Tox_Err_New value); * * @return A new Tox instance pointer on success or NULL on failure. */ -Tox *tox_new(const Tox_Options *options, Tox_Err_New *error); +Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error); /** * @brief Releases all resources associated with the Tox instance and diff --git a/toxcore/tox_api.c b/toxcore/tox_api.c index 18d861c18e..43ade35d02 100644 --- a/toxcore/tox_api.c +++ b/toxcore/tox_api.c @@ -1,20 +1,11 @@ /* SPDX-License-Identifier: GPL-3.0-or-later - * Copyright © 2016-2021 The TokTok team. + * Copyright © 2016-2023 The TokTok team. */ #include "tox.h" -#include - -#include "ccompat.h" +#include "tox_log.h" #include "tox_private.h" -#define SET_ERROR_PARAMETER(param, x) \ - do { \ - if (param != nullptr) { \ - *param = x; \ - } \ - } while (0) - uint32_t tox_version_major(void) { return TOX_VERSION_MAJOR; @@ -136,191 +127,6 @@ uint32_t tox_dht_node_public_key_size(void) return TOX_DHT_NODE_PUBLIC_KEY_SIZE; } -bool tox_options_get_ipv6_enabled(const Tox_Options *options) -{ - return options->ipv6_enabled; -} -void tox_options_set_ipv6_enabled(Tox_Options *options, bool ipv6_enabled) -{ - options->ipv6_enabled = ipv6_enabled; -} -bool tox_options_get_udp_enabled(const Tox_Options *options) -{ - return options->udp_enabled; -} -void tox_options_set_udp_enabled(Tox_Options *options, bool udp_enabled) -{ - options->udp_enabled = udp_enabled; -} -Tox_Proxy_Type tox_options_get_proxy_type(const Tox_Options *options) -{ - return options->proxy_type; -} -void tox_options_set_proxy_type(Tox_Options *options, Tox_Proxy_Type proxy_type) -{ - options->proxy_type = proxy_type; -} -const char *tox_options_get_proxy_host(const Tox_Options *options) -{ - return options->proxy_host; -} -void tox_options_set_proxy_host(Tox_Options *options, const char *proxy_host) -{ - options->proxy_host = proxy_host; -} -uint16_t tox_options_get_proxy_port(const Tox_Options *options) -{ - return options->proxy_port; -} -void tox_options_set_proxy_port(Tox_Options *options, uint16_t proxy_port) -{ - options->proxy_port = proxy_port; -} -uint16_t tox_options_get_start_port(const Tox_Options *options) -{ - return options->start_port; -} -void tox_options_set_start_port(Tox_Options *options, uint16_t start_port) -{ - options->start_port = start_port; -} -uint16_t tox_options_get_end_port(const Tox_Options *options) -{ - return options->end_port; -} -void tox_options_set_end_port(Tox_Options *options, uint16_t end_port) -{ - options->end_port = end_port; -} -uint16_t tox_options_get_tcp_port(const Tox_Options *options) -{ - return options->tcp_port; -} -void tox_options_set_tcp_port(Tox_Options *options, uint16_t tcp_port) -{ - options->tcp_port = tcp_port; -} -bool tox_options_get_hole_punching_enabled(const Tox_Options *options) -{ - return options->hole_punching_enabled; -} -void tox_options_set_hole_punching_enabled(Tox_Options *options, bool hole_punching_enabled) -{ - options->hole_punching_enabled = hole_punching_enabled; -} -Tox_Savedata_Type tox_options_get_savedata_type(const Tox_Options *options) -{ - return options->savedata_type; -} -void tox_options_set_savedata_type(Tox_Options *options, Tox_Savedata_Type savedata_type) -{ - options->savedata_type = savedata_type; -} -size_t tox_options_get_savedata_length(const Tox_Options *options) -{ - return options->savedata_length; -} -void tox_options_set_savedata_length(Tox_Options *options, size_t savedata_length) -{ - options->savedata_length = savedata_length; -} -tox_log_cb *tox_options_get_log_callback(const Tox_Options *options) -{ - return options->log_callback; -} -void tox_options_set_log_callback(Tox_Options *options, tox_log_cb *log_callback) -{ - options->log_callback = log_callback; -} -void *tox_options_get_log_user_data(const Tox_Options *options) -{ - return options->log_user_data; -} -void tox_options_set_log_user_data(Tox_Options *options, void *log_user_data) -{ - options->log_user_data = log_user_data; -} -bool tox_options_get_local_discovery_enabled(const Tox_Options *options) -{ - return options->local_discovery_enabled; -} -void tox_options_set_local_discovery_enabled(Tox_Options *options, bool local_discovery_enabled) -{ - options->local_discovery_enabled = local_discovery_enabled; -} -bool tox_options_get_dht_announcements_enabled(const Tox_Options *options) -{ - return options->dht_announcements_enabled; -} -void tox_options_set_dht_announcements_enabled(Tox_Options *options, bool dht_announcements_enabled) -{ - options->dht_announcements_enabled = dht_announcements_enabled; -} -bool tox_options_get_experimental_thread_safety(const Tox_Options *options) -{ - return options->experimental_thread_safety; -} -void tox_options_set_experimental_thread_safety( - Tox_Options *options, bool experimental_thread_safety) -{ - options->experimental_thread_safety = experimental_thread_safety; -} -bool tox_options_get_experimental_groups_persistence(const Tox_Options *options) -{ - return options->experimental_groups_persistence; -} -void tox_options_set_experimental_groups_persistence( - Tox_Options *options, bool experimental_groups_persistence) -{ - options->experimental_groups_persistence = experimental_groups_persistence; -} - -const uint8_t *tox_options_get_savedata_data(const Tox_Options *options) -{ - return options->savedata_data; -} - -void tox_options_set_savedata_data(Tox_Options *options, const uint8_t *savedata_data, size_t length) -{ - options->savedata_data = savedata_data; - options->savedata_length = length; -} - -void tox_options_default(Tox_Options *options) -{ - if (options != nullptr) { - const Tox_Options default_options = {false}; - *options = default_options; - tox_options_set_ipv6_enabled(options, true); - tox_options_set_udp_enabled(options, true); - tox_options_set_proxy_type(options, TOX_PROXY_TYPE_NONE); - tox_options_set_hole_punching_enabled(options, true); - tox_options_set_local_discovery_enabled(options, true); - tox_options_set_dht_announcements_enabled(options, true); - tox_options_set_experimental_thread_safety(options, false); - tox_options_set_experimental_groups_persistence(options, false); - } -} - -Tox_Options *tox_options_new(Tox_Err_Options_New *error) -{ - Tox_Options *options = (Tox_Options *)calloc(1, sizeof(Tox_Options)); - - if (options != nullptr) { - tox_options_default(options); - SET_ERROR_PARAMETER(error, TOX_ERR_OPTIONS_NEW_OK); - return options; - } - - SET_ERROR_PARAMETER(error, TOX_ERR_OPTIONS_NEW_MALLOC); - return nullptr; -} - -void tox_options_free(Tox_Options *options) -{ - free(options); -} - const char *tox_user_status_to_string(Tox_User_Status value) { switch (value) { @@ -378,27 +184,6 @@ const char *tox_savedata_type_to_string(Tox_Savedata_Type value) return ""; } -const char *tox_log_level_to_string(Tox_Log_Level value) -{ - switch (value) { - case TOX_LOG_LEVEL_TRACE: - return "TOX_LOG_LEVEL_TRACE"; - - case TOX_LOG_LEVEL_DEBUG: - return "TOX_LOG_LEVEL_DEBUG"; - - case TOX_LOG_LEVEL_INFO: - return "TOX_LOG_LEVEL_INFO"; - - case TOX_LOG_LEVEL_WARNING: - return "TOX_LOG_LEVEL_WARNING"; - - case TOX_LOG_LEVEL_ERROR: - return "TOX_LOG_LEVEL_ERROR"; - } - - return ""; -} const char *tox_err_options_new_to_string(Tox_Err_Options_New value) { switch (value) { diff --git a/toxcore/tox_attributes.h b/toxcore/tox_attributes.h new file mode 100644 index 0000000000..e9549f029d --- /dev/null +++ b/toxcore/tox_attributes.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2022-2023 The TokTok team. + */ + +/** + * nonnull attributes for GCC/Clang and Cimple. + * + * This file is a modified version of c-toxcore/toxcore/attributes.h with a + * `tox_` prefix added to the macros to avoid conflicts with client code. + */ +#ifndef C_TOXCORE_TOXCORE_TOX_ATTRIBUTES_H +#define C_TOXCORE_TOXCORE_TOX_ATTRIBUTES_H + +/* No declarations here. */ + +//!TOKSTYLE- + +#if defined(__GNUC__) && defined(_DEBUG) && !defined(__OPTIMIZE__) +#define tox_non_null(...) __attribute__((__nonnull__(__VA_ARGS__))) +#else +#define tox_non_null(...) +#endif + +#define tox_nullable(...) + +#ifdef SPARSE +#define tox_bitwise __attribute__((bitwise)) +#define tox_force __attribute__((force)) +#else +#define tox_bitwise +#define tox_force +#endif + +//!TOKSTYLE+ + +#endif /* C_TOXCORE_TOXCORE_TOX_ATTRIBUTES_H */ diff --git a/toxcore/tox_dispatch.c b/toxcore/tox_dispatch.c index 5383925bfa..2293edd20c 100644 --- a/toxcore/tox_dispatch.c +++ b/toxcore/tox_dispatch.c @@ -8,7 +8,7 @@ #include "attributes.h" #include "ccompat.h" -#include "events/events_alloc.h" // IWYU pragma: keep +#include "events/events_alloc.h" // IWYU pragma: keep #include "tox.h" #include "tox_event.h" #include "tox_events.h" diff --git a/toxcore/tox_event.h b/toxcore/tox_event.h index fa98aae229..21a2b4112d 100644 --- a/toxcore/tox_event.h +++ b/toxcore/tox_event.h @@ -5,10 +5,10 @@ #ifndef C_TOXCORE_TOXCORE_TOX_EVENT_H #define C_TOXCORE_TOXCORE_TOX_EVENT_H -#include "attributes.h" #include "bin_pack.h" #include "bin_unpack.h" #include "mem.h" +#include "tox_attributes.h" #include "tox_events.h" #include "tox_private.h" @@ -72,186 +72,186 @@ struct Tox_Event { /** * Constructor. */ -non_null() bool tox_event_construct(Tox_Event *event, Tox_Event_Type type, const Memory *mem); +tox_non_null() bool tox_event_construct(Tox_Event *event, Tox_Event_Type type, const Memory *mem); -non_null() Tox_Event_Conference_Connected *tox_event_conference_connected_new(const Memory *mem); -non_null() Tox_Event_Conference_Invite *tox_event_conference_invite_new(const Memory *mem); -non_null() Tox_Event_Conference_Message *tox_event_conference_message_new(const Memory *mem); -non_null() Tox_Event_Conference_Peer_List_Changed *tox_event_conference_peer_list_changed_new(const Memory *mem); -non_null() Tox_Event_Conference_Peer_Name *tox_event_conference_peer_name_new(const Memory *mem); -non_null() Tox_Event_Conference_Title *tox_event_conference_title_new(const Memory *mem); -non_null() Tox_Event_File_Chunk_Request *tox_event_file_chunk_request_new(const Memory *mem); -non_null() Tox_Event_File_Recv_Chunk *tox_event_file_recv_chunk_new(const Memory *mem); -non_null() Tox_Event_File_Recv_Control *tox_event_file_recv_control_new(const Memory *mem); -non_null() Tox_Event_File_Recv *tox_event_file_recv_new(const Memory *mem); -non_null() Tox_Event_Friend_Connection_Status *tox_event_friend_connection_status_new(const Memory *mem); -non_null() Tox_Event_Friend_Lossless_Packet *tox_event_friend_lossless_packet_new(const Memory *mem); -non_null() Tox_Event_Friend_Lossy_Packet *tox_event_friend_lossy_packet_new(const Memory *mem); -non_null() Tox_Event_Friend_Message *tox_event_friend_message_new(const Memory *mem); -non_null() Tox_Event_Friend_Name *tox_event_friend_name_new(const Memory *mem); -non_null() Tox_Event_Friend_Read_Receipt *tox_event_friend_read_receipt_new(const Memory *mem); -non_null() Tox_Event_Friend_Request *tox_event_friend_request_new(const Memory *mem); -non_null() Tox_Event_Friend_Status_Message *tox_event_friend_status_message_new(const Memory *mem); -non_null() Tox_Event_Friend_Status *tox_event_friend_status_new(const Memory *mem); -non_null() Tox_Event_Friend_Typing *tox_event_friend_typing_new(const Memory *mem); -non_null() Tox_Event_Self_Connection_Status *tox_event_self_connection_status_new(const Memory *mem); -non_null() Tox_Event_Group_Peer_Name *tox_event_group_peer_name_new(const Memory *mem); -non_null() Tox_Event_Group_Peer_Status *tox_event_group_peer_status_new(const Memory *mem); -non_null() Tox_Event_Group_Topic *tox_event_group_topic_new(const Memory *mem); -non_null() Tox_Event_Group_Privacy_State *tox_event_group_privacy_state_new(const Memory *mem); -non_null() Tox_Event_Group_Voice_State *tox_event_group_voice_state_new(const Memory *mem); -non_null() Tox_Event_Group_Topic_Lock *tox_event_group_topic_lock_new(const Memory *mem); -non_null() Tox_Event_Group_Peer_Limit *tox_event_group_peer_limit_new(const Memory *mem); -non_null() Tox_Event_Group_Password *tox_event_group_password_new(const Memory *mem); -non_null() Tox_Event_Group_Message *tox_event_group_message_new(const Memory *mem); -non_null() Tox_Event_Group_Private_Message *tox_event_group_private_message_new(const Memory *mem); -non_null() Tox_Event_Group_Custom_Packet *tox_event_group_custom_packet_new(const Memory *mem); -non_null() Tox_Event_Group_Custom_Private_Packet *tox_event_group_custom_private_packet_new(const Memory *mem); -non_null() Tox_Event_Group_Invite *tox_event_group_invite_new(const Memory *mem); -non_null() Tox_Event_Group_Peer_Join *tox_event_group_peer_join_new(const Memory *mem); -non_null() Tox_Event_Group_Peer_Exit *tox_event_group_peer_exit_new(const Memory *mem); -non_null() Tox_Event_Group_Self_Join *tox_event_group_self_join_new(const Memory *mem); -non_null() Tox_Event_Group_Join_Fail *tox_event_group_join_fail_new(const Memory *mem); -non_null() Tox_Event_Group_Moderation *tox_event_group_moderation_new(const Memory *mem); -non_null() Tox_Event_Dht_Get_Nodes_Response *tox_event_dht_get_nodes_response_new(const Memory *mem); +tox_non_null() Tox_Event_Conference_Connected *tox_event_conference_connected_new(const Memory *mem); +tox_non_null() Tox_Event_Conference_Invite *tox_event_conference_invite_new(const Memory *mem); +tox_non_null() Tox_Event_Conference_Message *tox_event_conference_message_new(const Memory *mem); +tox_non_null() Tox_Event_Conference_Peer_List_Changed *tox_event_conference_peer_list_changed_new(const Memory *mem); +tox_non_null() Tox_Event_Conference_Peer_Name *tox_event_conference_peer_name_new(const Memory *mem); +tox_non_null() Tox_Event_Conference_Title *tox_event_conference_title_new(const Memory *mem); +tox_non_null() Tox_Event_File_Chunk_Request *tox_event_file_chunk_request_new(const Memory *mem); +tox_non_null() Tox_Event_File_Recv_Chunk *tox_event_file_recv_chunk_new(const Memory *mem); +tox_non_null() Tox_Event_File_Recv_Control *tox_event_file_recv_control_new(const Memory *mem); +tox_non_null() Tox_Event_File_Recv *tox_event_file_recv_new(const Memory *mem); +tox_non_null() Tox_Event_Friend_Connection_Status *tox_event_friend_connection_status_new(const Memory *mem); +tox_non_null() Tox_Event_Friend_Lossless_Packet *tox_event_friend_lossless_packet_new(const Memory *mem); +tox_non_null() Tox_Event_Friend_Lossy_Packet *tox_event_friend_lossy_packet_new(const Memory *mem); +tox_non_null() Tox_Event_Friend_Message *tox_event_friend_message_new(const Memory *mem); +tox_non_null() Tox_Event_Friend_Name *tox_event_friend_name_new(const Memory *mem); +tox_non_null() Tox_Event_Friend_Read_Receipt *tox_event_friend_read_receipt_new(const Memory *mem); +tox_non_null() Tox_Event_Friend_Request *tox_event_friend_request_new(const Memory *mem); +tox_non_null() Tox_Event_Friend_Status_Message *tox_event_friend_status_message_new(const Memory *mem); +tox_non_null() Tox_Event_Friend_Status *tox_event_friend_status_new(const Memory *mem); +tox_non_null() Tox_Event_Friend_Typing *tox_event_friend_typing_new(const Memory *mem); +tox_non_null() Tox_Event_Self_Connection_Status *tox_event_self_connection_status_new(const Memory *mem); +tox_non_null() Tox_Event_Group_Peer_Name *tox_event_group_peer_name_new(const Memory *mem); +tox_non_null() Tox_Event_Group_Peer_Status *tox_event_group_peer_status_new(const Memory *mem); +tox_non_null() Tox_Event_Group_Topic *tox_event_group_topic_new(const Memory *mem); +tox_non_null() Tox_Event_Group_Privacy_State *tox_event_group_privacy_state_new(const Memory *mem); +tox_non_null() Tox_Event_Group_Voice_State *tox_event_group_voice_state_new(const Memory *mem); +tox_non_null() Tox_Event_Group_Topic_Lock *tox_event_group_topic_lock_new(const Memory *mem); +tox_non_null() Tox_Event_Group_Peer_Limit *tox_event_group_peer_limit_new(const Memory *mem); +tox_non_null() Tox_Event_Group_Password *tox_event_group_password_new(const Memory *mem); +tox_non_null() Tox_Event_Group_Message *tox_event_group_message_new(const Memory *mem); +tox_non_null() Tox_Event_Group_Private_Message *tox_event_group_private_message_new(const Memory *mem); +tox_non_null() Tox_Event_Group_Custom_Packet *tox_event_group_custom_packet_new(const Memory *mem); +tox_non_null() Tox_Event_Group_Custom_Private_Packet *tox_event_group_custom_private_packet_new(const Memory *mem); +tox_non_null() Tox_Event_Group_Invite *tox_event_group_invite_new(const Memory *mem); +tox_non_null() Tox_Event_Group_Peer_Join *tox_event_group_peer_join_new(const Memory *mem); +tox_non_null() Tox_Event_Group_Peer_Exit *tox_event_group_peer_exit_new(const Memory *mem); +tox_non_null() Tox_Event_Group_Self_Join *tox_event_group_self_join_new(const Memory *mem); +tox_non_null() Tox_Event_Group_Join_Fail *tox_event_group_join_fail_new(const Memory *mem); +tox_non_null() Tox_Event_Group_Moderation *tox_event_group_moderation_new(const Memory *mem); +tox_non_null() Tox_Event_Dht_Get_Nodes_Response *tox_event_dht_get_nodes_response_new(const Memory *mem); /** * Destructor. */ -non_null(2) nullable(1) void tox_event_destruct(Tox_Event *event, const Memory *mem); +tox_non_null(2) tox_nullable(1) void tox_event_destruct(Tox_Event *event, const Memory *mem); -non_null(2) nullable(1) void tox_event_conference_connected_free(Tox_Event_Conference_Connected *conference_connected, const Memory *mem); -non_null(2) nullable(1) void tox_event_conference_invite_free(Tox_Event_Conference_Invite *conference_invite, const Memory *mem); -non_null(2) nullable(1) void tox_event_conference_message_free(Tox_Event_Conference_Message *conference_message, const Memory *mem); -non_null(2) nullable(1) void tox_event_conference_peer_list_changed_free(Tox_Event_Conference_Peer_List_Changed *conference_peer_list_changed, const Memory *mem); -non_null(2) nullable(1) void tox_event_conference_peer_name_free(Tox_Event_Conference_Peer_Name *conference_peer_name, const Memory *mem); -non_null(2) nullable(1) void tox_event_conference_title_free(Tox_Event_Conference_Title *conference_title, const Memory *mem); -non_null(2) nullable(1) void tox_event_file_chunk_request_free(Tox_Event_File_Chunk_Request *file_chunk_request, const Memory *mem); -non_null(2) nullable(1) void tox_event_file_recv_chunk_free(Tox_Event_File_Recv_Chunk *file_recv_chunk, const Memory *mem); -non_null(2) nullable(1) void tox_event_file_recv_control_free(Tox_Event_File_Recv_Control *file_recv_control, const Memory *mem); -non_null(2) nullable(1) void tox_event_file_recv_free(Tox_Event_File_Recv *file_recv, const Memory *mem); -non_null(2) nullable(1) void tox_event_friend_connection_status_free(Tox_Event_Friend_Connection_Status *friend_connection_status, const Memory *mem); -non_null(2) nullable(1) void tox_event_friend_lossless_packet_free(Tox_Event_Friend_Lossless_Packet *friend_lossless_packet, const Memory *mem); -non_null(2) nullable(1) void tox_event_friend_lossy_packet_free(Tox_Event_Friend_Lossy_Packet *friend_lossy_packet, const Memory *mem); -non_null(2) nullable(1) void tox_event_friend_message_free(Tox_Event_Friend_Message *friend_message, const Memory *mem); -non_null(2) nullable(1) void tox_event_friend_name_free(Tox_Event_Friend_Name *friend_name, const Memory *mem); -non_null(2) nullable(1) void tox_event_friend_read_receipt_free(Tox_Event_Friend_Read_Receipt *friend_read_receipt, const Memory *mem); -non_null(2) nullable(1) void tox_event_friend_request_free(Tox_Event_Friend_Request *friend_request, const Memory *mem); -non_null(2) nullable(1) void tox_event_friend_status_message_free(Tox_Event_Friend_Status_Message *friend_status_message, const Memory *mem); -non_null(2) nullable(1) void tox_event_friend_status_free(Tox_Event_Friend_Status *friend_status, const Memory *mem); -non_null(2) nullable(1) void tox_event_friend_typing_free(Tox_Event_Friend_Typing *friend_typing, const Memory *mem); -non_null(2) nullable(1) void tox_event_self_connection_status_free(Tox_Event_Self_Connection_Status *self_connection_status, const Memory *mem); -non_null(2) nullable(1) void tox_event_group_peer_name_free(Tox_Event_Group_Peer_Name *group_peer_name, const Memory *mem); -non_null(2) nullable(1) void tox_event_group_peer_status_free(Tox_Event_Group_Peer_Status *group_peer_status, const Memory *mem); -non_null(2) nullable(1) void tox_event_group_topic_free(Tox_Event_Group_Topic *group_topic, const Memory *mem); -non_null(2) nullable(1) void tox_event_group_privacy_state_free(Tox_Event_Group_Privacy_State *group_privacy_state, const Memory *mem); -non_null(2) nullable(1) void tox_event_group_voice_state_free(Tox_Event_Group_Voice_State *group_voice_state, const Memory *mem); -non_null(2) nullable(1) void tox_event_group_topic_lock_free(Tox_Event_Group_Topic_Lock *group_topic_lock, const Memory *mem); -non_null(2) nullable(1) void tox_event_group_peer_limit_free(Tox_Event_Group_Peer_Limit *group_peer_limit, const Memory *mem); -non_null(2) nullable(1) void tox_event_group_password_free(Tox_Event_Group_Password *group_password, const Memory *mem); -non_null(2) nullable(1) void tox_event_group_message_free(Tox_Event_Group_Message *group_message, const Memory *mem); -non_null(2) nullable(1) void tox_event_group_private_message_free(Tox_Event_Group_Private_Message *group_private_message, const Memory *mem); -non_null(2) nullable(1) void tox_event_group_custom_packet_free(Tox_Event_Group_Custom_Packet *group_custom_packet, const Memory *mem); -non_null(2) nullable(1) void tox_event_group_custom_private_packet_free(Tox_Event_Group_Custom_Private_Packet *group_custom_private_packet, const Memory *mem); -non_null(2) nullable(1) void tox_event_group_invite_free(Tox_Event_Group_Invite *group_invite, const Memory *mem); -non_null(2) nullable(1) void tox_event_group_peer_join_free(Tox_Event_Group_Peer_Join *group_peer_join, const Memory *mem); -non_null(2) nullable(1) void tox_event_group_peer_exit_free(Tox_Event_Group_Peer_Exit *group_peer_exit, const Memory *mem); -non_null(2) nullable(1) void tox_event_group_self_join_free(Tox_Event_Group_Self_Join *group_self_join, const Memory *mem); -non_null(2) nullable(1) void tox_event_group_join_fail_free(Tox_Event_Group_Join_Fail *group_join_fail, const Memory *mem); -non_null(2) nullable(1) void tox_event_group_moderation_free(Tox_Event_Group_Moderation *group_moderation, const Memory *mem); -non_null(2) nullable(1) void tox_event_dht_get_nodes_response_free(Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response, const Memory *mem); +tox_non_null(2) tox_nullable(1) void tox_event_conference_connected_free(Tox_Event_Conference_Connected *conference_connected, const Memory *mem); +tox_non_null(2) tox_nullable(1) void tox_event_conference_invite_free(Tox_Event_Conference_Invite *conference_invite, const Memory *mem); +tox_non_null(2) tox_nullable(1) void tox_event_conference_message_free(Tox_Event_Conference_Message *conference_message, const Memory *mem); +tox_non_null(2) tox_nullable(1) void tox_event_conference_peer_list_changed_free(Tox_Event_Conference_Peer_List_Changed *conference_peer_list_changed, const Memory *mem); +tox_non_null(2) tox_nullable(1) void tox_event_conference_peer_name_free(Tox_Event_Conference_Peer_Name *conference_peer_name, const Memory *mem); +tox_non_null(2) tox_nullable(1) void tox_event_conference_title_free(Tox_Event_Conference_Title *conference_title, const Memory *mem); +tox_non_null(2) tox_nullable(1) void tox_event_file_chunk_request_free(Tox_Event_File_Chunk_Request *file_chunk_request, const Memory *mem); +tox_non_null(2) tox_nullable(1) void tox_event_file_recv_chunk_free(Tox_Event_File_Recv_Chunk *file_recv_chunk, const Memory *mem); +tox_non_null(2) tox_nullable(1) void tox_event_file_recv_control_free(Tox_Event_File_Recv_Control *file_recv_control, const Memory *mem); +tox_non_null(2) tox_nullable(1) void tox_event_file_recv_free(Tox_Event_File_Recv *file_recv, const Memory *mem); +tox_non_null(2) tox_nullable(1) void tox_event_friend_connection_status_free(Tox_Event_Friend_Connection_Status *friend_connection_status, const Memory *mem); +tox_non_null(2) tox_nullable(1) void tox_event_friend_lossless_packet_free(Tox_Event_Friend_Lossless_Packet *friend_lossless_packet, const Memory *mem); +tox_non_null(2) tox_nullable(1) void tox_event_friend_lossy_packet_free(Tox_Event_Friend_Lossy_Packet *friend_lossy_packet, const Memory *mem); +tox_non_null(2) tox_nullable(1) void tox_event_friend_message_free(Tox_Event_Friend_Message *friend_message, const Memory *mem); +tox_non_null(2) tox_nullable(1) void tox_event_friend_name_free(Tox_Event_Friend_Name *friend_name, const Memory *mem); +tox_non_null(2) tox_nullable(1) void tox_event_friend_read_receipt_free(Tox_Event_Friend_Read_Receipt *friend_read_receipt, const Memory *mem); +tox_non_null(2) tox_nullable(1) void tox_event_friend_request_free(Tox_Event_Friend_Request *friend_request, const Memory *mem); +tox_non_null(2) tox_nullable(1) void tox_event_friend_status_message_free(Tox_Event_Friend_Status_Message *friend_status_message, const Memory *mem); +tox_non_null(2) tox_nullable(1) void tox_event_friend_status_free(Tox_Event_Friend_Status *friend_status, const Memory *mem); +tox_non_null(2) tox_nullable(1) void tox_event_friend_typing_free(Tox_Event_Friend_Typing *friend_typing, const Memory *mem); +tox_non_null(2) tox_nullable(1) void tox_event_self_connection_status_free(Tox_Event_Self_Connection_Status *self_connection_status, const Memory *mem); +tox_non_null(2) tox_nullable(1) void tox_event_group_peer_name_free(Tox_Event_Group_Peer_Name *group_peer_name, const Memory *mem); +tox_non_null(2) tox_nullable(1) void tox_event_group_peer_status_free(Tox_Event_Group_Peer_Status *group_peer_status, const Memory *mem); +tox_non_null(2) tox_nullable(1) void tox_event_group_topic_free(Tox_Event_Group_Topic *group_topic, const Memory *mem); +tox_non_null(2) tox_nullable(1) void tox_event_group_privacy_state_free(Tox_Event_Group_Privacy_State *group_privacy_state, const Memory *mem); +tox_non_null(2) tox_nullable(1) void tox_event_group_voice_state_free(Tox_Event_Group_Voice_State *group_voice_state, const Memory *mem); +tox_non_null(2) tox_nullable(1) void tox_event_group_topic_lock_free(Tox_Event_Group_Topic_Lock *group_topic_lock, const Memory *mem); +tox_non_null(2) tox_nullable(1) void tox_event_group_peer_limit_free(Tox_Event_Group_Peer_Limit *group_peer_limit, const Memory *mem); +tox_non_null(2) tox_nullable(1) void tox_event_group_password_free(Tox_Event_Group_Password *group_password, const Memory *mem); +tox_non_null(2) tox_nullable(1) void tox_event_group_message_free(Tox_Event_Group_Message *group_message, const Memory *mem); +tox_non_null(2) tox_nullable(1) void tox_event_group_private_message_free(Tox_Event_Group_Private_Message *group_private_message, const Memory *mem); +tox_non_null(2) tox_nullable(1) void tox_event_group_custom_packet_free(Tox_Event_Group_Custom_Packet *group_custom_packet, const Memory *mem); +tox_non_null(2) tox_nullable(1) void tox_event_group_custom_private_packet_free(Tox_Event_Group_Custom_Private_Packet *group_custom_private_packet, const Memory *mem); +tox_non_null(2) tox_nullable(1) void tox_event_group_invite_free(Tox_Event_Group_Invite *group_invite, const Memory *mem); +tox_non_null(2) tox_nullable(1) void tox_event_group_peer_join_free(Tox_Event_Group_Peer_Join *group_peer_join, const Memory *mem); +tox_non_null(2) tox_nullable(1) void tox_event_group_peer_exit_free(Tox_Event_Group_Peer_Exit *group_peer_exit, const Memory *mem); +tox_non_null(2) tox_nullable(1) void tox_event_group_self_join_free(Tox_Event_Group_Self_Join *group_self_join, const Memory *mem); +tox_non_null(2) tox_nullable(1) void tox_event_group_join_fail_free(Tox_Event_Group_Join_Fail *group_join_fail, const Memory *mem); +tox_non_null(2) tox_nullable(1) void tox_event_group_moderation_free(Tox_Event_Group_Moderation *group_moderation, const Memory *mem); +tox_non_null(2) tox_nullable(1) void tox_event_dht_get_nodes_response_free(Tox_Event_Dht_Get_Nodes_Response *dht_get_nodes_response, const Memory *mem); /** * Pack into msgpack. */ -non_null() bool tox_event_pack(const Tox_Event *event, Bin_Pack *bp); +tox_non_null() bool tox_event_pack(const Tox_Event *event, Bin_Pack *bp); -non_null() bool tox_event_conference_connected_pack(const Tox_Event_Conference_Connected *event, Bin_Pack *bp); -non_null() bool tox_event_conference_invite_pack(const Tox_Event_Conference_Invite *event, Bin_Pack *bp); -non_null() bool tox_event_conference_message_pack(const Tox_Event_Conference_Message *event, Bin_Pack *bp); -non_null() bool tox_event_conference_peer_list_changed_pack(const Tox_Event_Conference_Peer_List_Changed *event, Bin_Pack *bp); -non_null() bool tox_event_conference_peer_name_pack(const Tox_Event_Conference_Peer_Name *event, Bin_Pack *bp); -non_null() bool tox_event_conference_title_pack(const Tox_Event_Conference_Title *event, Bin_Pack *bp); -non_null() bool tox_event_file_chunk_request_pack(const Tox_Event_File_Chunk_Request *event, Bin_Pack *bp); -non_null() bool tox_event_file_recv_chunk_pack(const Tox_Event_File_Recv_Chunk *event, Bin_Pack *bp); -non_null() bool tox_event_file_recv_control_pack(const Tox_Event_File_Recv_Control *event, Bin_Pack *bp); -non_null() bool tox_event_file_recv_pack(const Tox_Event_File_Recv *event, Bin_Pack *bp); -non_null() bool tox_event_friend_connection_status_pack(const Tox_Event_Friend_Connection_Status *event, Bin_Pack *bp); -non_null() bool tox_event_friend_lossless_packet_pack(const Tox_Event_Friend_Lossless_Packet *event, Bin_Pack *bp); -non_null() bool tox_event_friend_lossy_packet_pack(const Tox_Event_Friend_Lossy_Packet *event, Bin_Pack *bp); -non_null() bool tox_event_friend_message_pack(const Tox_Event_Friend_Message *event, Bin_Pack *bp); -non_null() bool tox_event_friend_name_pack(const Tox_Event_Friend_Name *event, Bin_Pack *bp); -non_null() bool tox_event_friend_read_receipt_pack(const Tox_Event_Friend_Read_Receipt *event, Bin_Pack *bp); -non_null() bool tox_event_friend_request_pack(const Tox_Event_Friend_Request *event, Bin_Pack *bp); -non_null() bool tox_event_friend_status_message_pack(const Tox_Event_Friend_Status_Message *event, Bin_Pack *bp); -non_null() bool tox_event_friend_status_pack(const Tox_Event_Friend_Status *event, Bin_Pack *bp); -non_null() bool tox_event_friend_typing_pack(const Tox_Event_Friend_Typing *event, Bin_Pack *bp); -non_null() bool tox_event_self_connection_status_pack(const Tox_Event_Self_Connection_Status *event, Bin_Pack *bp); -non_null() bool tox_event_group_peer_name_pack(const Tox_Event_Group_Peer_Name *event, Bin_Pack *bp); -non_null() bool tox_event_group_peer_status_pack(const Tox_Event_Group_Peer_Status *event, Bin_Pack *bp); -non_null() bool tox_event_group_topic_pack(const Tox_Event_Group_Topic *event, Bin_Pack *bp); -non_null() bool tox_event_group_privacy_state_pack(const Tox_Event_Group_Privacy_State *event, Bin_Pack *bp); -non_null() bool tox_event_group_voice_state_pack(const Tox_Event_Group_Voice_State *event, Bin_Pack *bp); -non_null() bool tox_event_group_topic_lock_pack(const Tox_Event_Group_Topic_Lock *event, Bin_Pack *bp); -non_null() bool tox_event_group_peer_limit_pack(const Tox_Event_Group_Peer_Limit *event, Bin_Pack *bp); -non_null() bool tox_event_group_password_pack(const Tox_Event_Group_Password *event, Bin_Pack *bp); -non_null() bool tox_event_group_message_pack(const Tox_Event_Group_Message *event, Bin_Pack *bp); -non_null() bool tox_event_group_private_message_pack(const Tox_Event_Group_Private_Message *event, Bin_Pack *bp); -non_null() bool tox_event_group_custom_packet_pack(const Tox_Event_Group_Custom_Packet *event, Bin_Pack *bp); -non_null() bool tox_event_group_custom_private_packet_pack(const Tox_Event_Group_Custom_Private_Packet *event, Bin_Pack *bp); -non_null() bool tox_event_group_invite_pack(const Tox_Event_Group_Invite *event, Bin_Pack *bp); -non_null() bool tox_event_group_peer_join_pack(const Tox_Event_Group_Peer_Join *event, Bin_Pack *bp); -non_null() bool tox_event_group_peer_exit_pack(const Tox_Event_Group_Peer_Exit *event, Bin_Pack *bp); -non_null() bool tox_event_group_self_join_pack(const Tox_Event_Group_Self_Join *event, Bin_Pack *bp); -non_null() bool tox_event_group_join_fail_pack(const Tox_Event_Group_Join_Fail *event, Bin_Pack *bp); -non_null() bool tox_event_group_moderation_pack(const Tox_Event_Group_Moderation *event, Bin_Pack *bp); -non_null() bool tox_event_dht_get_nodes_response_pack(const Tox_Event_Dht_Get_Nodes_Response *event, Bin_Pack *bp); +tox_non_null() bool tox_event_conference_connected_pack(const Tox_Event_Conference_Connected *event, Bin_Pack *bp); +tox_non_null() bool tox_event_conference_invite_pack(const Tox_Event_Conference_Invite *event, Bin_Pack *bp); +tox_non_null() bool tox_event_conference_message_pack(const Tox_Event_Conference_Message *event, Bin_Pack *bp); +tox_non_null() bool tox_event_conference_peer_list_changed_pack(const Tox_Event_Conference_Peer_List_Changed *event, Bin_Pack *bp); +tox_non_null() bool tox_event_conference_peer_name_pack(const Tox_Event_Conference_Peer_Name *event, Bin_Pack *bp); +tox_non_null() bool tox_event_conference_title_pack(const Tox_Event_Conference_Title *event, Bin_Pack *bp); +tox_non_null() bool tox_event_file_chunk_request_pack(const Tox_Event_File_Chunk_Request *event, Bin_Pack *bp); +tox_non_null() bool tox_event_file_recv_chunk_pack(const Tox_Event_File_Recv_Chunk *event, Bin_Pack *bp); +tox_non_null() bool tox_event_file_recv_control_pack(const Tox_Event_File_Recv_Control *event, Bin_Pack *bp); +tox_non_null() bool tox_event_file_recv_pack(const Tox_Event_File_Recv *event, Bin_Pack *bp); +tox_non_null() bool tox_event_friend_connection_status_pack(const Tox_Event_Friend_Connection_Status *event, Bin_Pack *bp); +tox_non_null() bool tox_event_friend_lossless_packet_pack(const Tox_Event_Friend_Lossless_Packet *event, Bin_Pack *bp); +tox_non_null() bool tox_event_friend_lossy_packet_pack(const Tox_Event_Friend_Lossy_Packet *event, Bin_Pack *bp); +tox_non_null() bool tox_event_friend_message_pack(const Tox_Event_Friend_Message *event, Bin_Pack *bp); +tox_non_null() bool tox_event_friend_name_pack(const Tox_Event_Friend_Name *event, Bin_Pack *bp); +tox_non_null() bool tox_event_friend_read_receipt_pack(const Tox_Event_Friend_Read_Receipt *event, Bin_Pack *bp); +tox_non_null() bool tox_event_friend_request_pack(const Tox_Event_Friend_Request *event, Bin_Pack *bp); +tox_non_null() bool tox_event_friend_status_message_pack(const Tox_Event_Friend_Status_Message *event, Bin_Pack *bp); +tox_non_null() bool tox_event_friend_status_pack(const Tox_Event_Friend_Status *event, Bin_Pack *bp); +tox_non_null() bool tox_event_friend_typing_pack(const Tox_Event_Friend_Typing *event, Bin_Pack *bp); +tox_non_null() bool tox_event_self_connection_status_pack(const Tox_Event_Self_Connection_Status *event, Bin_Pack *bp); +tox_non_null() bool tox_event_group_peer_name_pack(const Tox_Event_Group_Peer_Name *event, Bin_Pack *bp); +tox_non_null() bool tox_event_group_peer_status_pack(const Tox_Event_Group_Peer_Status *event, Bin_Pack *bp); +tox_non_null() bool tox_event_group_topic_pack(const Tox_Event_Group_Topic *event, Bin_Pack *bp); +tox_non_null() bool tox_event_group_privacy_state_pack(const Tox_Event_Group_Privacy_State *event, Bin_Pack *bp); +tox_non_null() bool tox_event_group_voice_state_pack(const Tox_Event_Group_Voice_State *event, Bin_Pack *bp); +tox_non_null() bool tox_event_group_topic_lock_pack(const Tox_Event_Group_Topic_Lock *event, Bin_Pack *bp); +tox_non_null() bool tox_event_group_peer_limit_pack(const Tox_Event_Group_Peer_Limit *event, Bin_Pack *bp); +tox_non_null() bool tox_event_group_password_pack(const Tox_Event_Group_Password *event, Bin_Pack *bp); +tox_non_null() bool tox_event_group_message_pack(const Tox_Event_Group_Message *event, Bin_Pack *bp); +tox_non_null() bool tox_event_group_private_message_pack(const Tox_Event_Group_Private_Message *event, Bin_Pack *bp); +tox_non_null() bool tox_event_group_custom_packet_pack(const Tox_Event_Group_Custom_Packet *event, Bin_Pack *bp); +tox_non_null() bool tox_event_group_custom_private_packet_pack(const Tox_Event_Group_Custom_Private_Packet *event, Bin_Pack *bp); +tox_non_null() bool tox_event_group_invite_pack(const Tox_Event_Group_Invite *event, Bin_Pack *bp); +tox_non_null() bool tox_event_group_peer_join_pack(const Tox_Event_Group_Peer_Join *event, Bin_Pack *bp); +tox_non_null() bool tox_event_group_peer_exit_pack(const Tox_Event_Group_Peer_Exit *event, Bin_Pack *bp); +tox_non_null() bool tox_event_group_self_join_pack(const Tox_Event_Group_Self_Join *event, Bin_Pack *bp); +tox_non_null() bool tox_event_group_join_fail_pack(const Tox_Event_Group_Join_Fail *event, Bin_Pack *bp); +tox_non_null() bool tox_event_group_moderation_pack(const Tox_Event_Group_Moderation *event, Bin_Pack *bp); +tox_non_null() bool tox_event_dht_get_nodes_response_pack(const Tox_Event_Dht_Get_Nodes_Response *event, Bin_Pack *bp); /** * Unpack from msgpack. */ -non_null() bool tox_event_unpack_into(Tox_Event *event, Bin_Unpack *bu, const Memory *mem); +tox_non_null() bool tox_event_unpack_into(Tox_Event *event, Bin_Unpack *bu, const Memory *mem); -non_null() bool tox_event_conference_connected_unpack(Tox_Event_Conference_Connected **event, Bin_Unpack *bu, const Memory *mem); -non_null() bool tox_event_conference_invite_unpack(Tox_Event_Conference_Invite **event, Bin_Unpack *bu, const Memory *mem); -non_null() bool tox_event_conference_message_unpack(Tox_Event_Conference_Message **event, Bin_Unpack *bu, const Memory *mem); -non_null() bool tox_event_conference_peer_list_changed_unpack(Tox_Event_Conference_Peer_List_Changed **event, Bin_Unpack *bu, const Memory *mem); -non_null() bool tox_event_conference_peer_name_unpack(Tox_Event_Conference_Peer_Name **event, Bin_Unpack *bu, const Memory *mem); -non_null() bool tox_event_conference_title_unpack(Tox_Event_Conference_Title **event, Bin_Unpack *bu, const Memory *mem); -non_null() bool tox_event_file_chunk_request_unpack(Tox_Event_File_Chunk_Request **event, Bin_Unpack *bu, const Memory *mem); -non_null() bool tox_event_file_recv_chunk_unpack(Tox_Event_File_Recv_Chunk **event, Bin_Unpack *bu, const Memory *mem); -non_null() bool tox_event_file_recv_control_unpack(Tox_Event_File_Recv_Control **event, Bin_Unpack *bu, const Memory *mem); -non_null() bool tox_event_file_recv_unpack(Tox_Event_File_Recv **event, Bin_Unpack *bu, const Memory *mem); -non_null() bool tox_event_friend_connection_status_unpack(Tox_Event_Friend_Connection_Status **event, Bin_Unpack *bu, const Memory *mem); -non_null() bool tox_event_friend_lossless_packet_unpack(Tox_Event_Friend_Lossless_Packet **event, Bin_Unpack *bu, const Memory *mem); -non_null() bool tox_event_friend_lossy_packet_unpack(Tox_Event_Friend_Lossy_Packet **event, Bin_Unpack *bu, const Memory *mem); -non_null() bool tox_event_friend_message_unpack(Tox_Event_Friend_Message **event, Bin_Unpack *bu, const Memory *mem); -non_null() bool tox_event_friend_name_unpack(Tox_Event_Friend_Name **event, Bin_Unpack *bu, const Memory *mem); -non_null() bool tox_event_friend_read_receipt_unpack(Tox_Event_Friend_Read_Receipt **event, Bin_Unpack *bu, const Memory *mem); -non_null() bool tox_event_friend_request_unpack(Tox_Event_Friend_Request **event, Bin_Unpack *bu, const Memory *mem); -non_null() bool tox_event_friend_status_message_unpack(Tox_Event_Friend_Status_Message **event, Bin_Unpack *bu, const Memory *mem); -non_null() bool tox_event_friend_status_unpack(Tox_Event_Friend_Status **event, Bin_Unpack *bu, const Memory *mem); -non_null() bool tox_event_friend_typing_unpack(Tox_Event_Friend_Typing **event, Bin_Unpack *bu, const Memory *mem); -non_null() bool tox_event_self_connection_status_unpack(Tox_Event_Self_Connection_Status **event, Bin_Unpack *bu, const Memory *mem); -non_null() bool tox_event_group_peer_name_unpack(Tox_Event_Group_Peer_Name **event, Bin_Unpack *bu, const Memory *mem); -non_null() bool tox_event_group_peer_status_unpack(Tox_Event_Group_Peer_Status **event, Bin_Unpack *bu, const Memory *mem); -non_null() bool tox_event_group_topic_unpack(Tox_Event_Group_Topic **event, Bin_Unpack *bu, const Memory *mem); -non_null() bool tox_event_group_privacy_state_unpack(Tox_Event_Group_Privacy_State **event, Bin_Unpack *bu, const Memory *mem); -non_null() bool tox_event_group_voice_state_unpack(Tox_Event_Group_Voice_State **event, Bin_Unpack *bu, const Memory *mem); -non_null() bool tox_event_group_topic_lock_unpack(Tox_Event_Group_Topic_Lock **event, Bin_Unpack *bu, const Memory *mem); -non_null() bool tox_event_group_peer_limit_unpack(Tox_Event_Group_Peer_Limit **event, Bin_Unpack *bu, const Memory *mem); -non_null() bool tox_event_group_password_unpack(Tox_Event_Group_Password **event, Bin_Unpack *bu, const Memory *mem); -non_null() bool tox_event_group_message_unpack(Tox_Event_Group_Message **event, Bin_Unpack *bu, const Memory *mem); -non_null() bool tox_event_group_private_message_unpack(Tox_Event_Group_Private_Message **event, Bin_Unpack *bu, const Memory *mem); -non_null() bool tox_event_group_custom_packet_unpack(Tox_Event_Group_Custom_Packet **event, Bin_Unpack *bu, const Memory *mem); -non_null() bool tox_event_group_custom_private_packet_unpack(Tox_Event_Group_Custom_Private_Packet **event, Bin_Unpack *bu, const Memory *mem); -non_null() bool tox_event_group_invite_unpack(Tox_Event_Group_Invite **event, Bin_Unpack *bu, const Memory *mem); -non_null() bool tox_event_group_peer_join_unpack(Tox_Event_Group_Peer_Join **event, Bin_Unpack *bu, const Memory *mem); -non_null() bool tox_event_group_peer_exit_unpack(Tox_Event_Group_Peer_Exit **event, Bin_Unpack *bu, const Memory *mem); -non_null() bool tox_event_group_self_join_unpack(Tox_Event_Group_Self_Join **event, Bin_Unpack *bu, const Memory *mem); -non_null() bool tox_event_group_join_fail_unpack(Tox_Event_Group_Join_Fail **event, Bin_Unpack *bu, const Memory *mem); -non_null() bool tox_event_group_moderation_unpack(Tox_Event_Group_Moderation **event, Bin_Unpack *bu, const Memory *mem); -non_null() bool tox_event_dht_get_nodes_response_unpack(Tox_Event_Dht_Get_Nodes_Response **event, Bin_Unpack *bu, const Memory *mem); +tox_non_null() bool tox_event_conference_connected_unpack(Tox_Event_Conference_Connected **event, Bin_Unpack *bu, const Memory *mem); +tox_non_null() bool tox_event_conference_invite_unpack(Tox_Event_Conference_Invite **event, Bin_Unpack *bu, const Memory *mem); +tox_non_null() bool tox_event_conference_message_unpack(Tox_Event_Conference_Message **event, Bin_Unpack *bu, const Memory *mem); +tox_non_null() bool tox_event_conference_peer_list_changed_unpack(Tox_Event_Conference_Peer_List_Changed **event, Bin_Unpack *bu, const Memory *mem); +tox_non_null() bool tox_event_conference_peer_name_unpack(Tox_Event_Conference_Peer_Name **event, Bin_Unpack *bu, const Memory *mem); +tox_non_null() bool tox_event_conference_title_unpack(Tox_Event_Conference_Title **event, Bin_Unpack *bu, const Memory *mem); +tox_non_null() bool tox_event_file_chunk_request_unpack(Tox_Event_File_Chunk_Request **event, Bin_Unpack *bu, const Memory *mem); +tox_non_null() bool tox_event_file_recv_chunk_unpack(Tox_Event_File_Recv_Chunk **event, Bin_Unpack *bu, const Memory *mem); +tox_non_null() bool tox_event_file_recv_control_unpack(Tox_Event_File_Recv_Control **event, Bin_Unpack *bu, const Memory *mem); +tox_non_null() bool tox_event_file_recv_unpack(Tox_Event_File_Recv **event, Bin_Unpack *bu, const Memory *mem); +tox_non_null() bool tox_event_friend_connection_status_unpack(Tox_Event_Friend_Connection_Status **event, Bin_Unpack *bu, const Memory *mem); +tox_non_null() bool tox_event_friend_lossless_packet_unpack(Tox_Event_Friend_Lossless_Packet **event, Bin_Unpack *bu, const Memory *mem); +tox_non_null() bool tox_event_friend_lossy_packet_unpack(Tox_Event_Friend_Lossy_Packet **event, Bin_Unpack *bu, const Memory *mem); +tox_non_null() bool tox_event_friend_message_unpack(Tox_Event_Friend_Message **event, Bin_Unpack *bu, const Memory *mem); +tox_non_null() bool tox_event_friend_name_unpack(Tox_Event_Friend_Name **event, Bin_Unpack *bu, const Memory *mem); +tox_non_null() bool tox_event_friend_read_receipt_unpack(Tox_Event_Friend_Read_Receipt **event, Bin_Unpack *bu, const Memory *mem); +tox_non_null() bool tox_event_friend_request_unpack(Tox_Event_Friend_Request **event, Bin_Unpack *bu, const Memory *mem); +tox_non_null() bool tox_event_friend_status_message_unpack(Tox_Event_Friend_Status_Message **event, Bin_Unpack *bu, const Memory *mem); +tox_non_null() bool tox_event_friend_status_unpack(Tox_Event_Friend_Status **event, Bin_Unpack *bu, const Memory *mem); +tox_non_null() bool tox_event_friend_typing_unpack(Tox_Event_Friend_Typing **event, Bin_Unpack *bu, const Memory *mem); +tox_non_null() bool tox_event_self_connection_status_unpack(Tox_Event_Self_Connection_Status **event, Bin_Unpack *bu, const Memory *mem); +tox_non_null() bool tox_event_group_peer_name_unpack(Tox_Event_Group_Peer_Name **event, Bin_Unpack *bu, const Memory *mem); +tox_non_null() bool tox_event_group_peer_status_unpack(Tox_Event_Group_Peer_Status **event, Bin_Unpack *bu, const Memory *mem); +tox_non_null() bool tox_event_group_topic_unpack(Tox_Event_Group_Topic **event, Bin_Unpack *bu, const Memory *mem); +tox_non_null() bool tox_event_group_privacy_state_unpack(Tox_Event_Group_Privacy_State **event, Bin_Unpack *bu, const Memory *mem); +tox_non_null() bool tox_event_group_voice_state_unpack(Tox_Event_Group_Voice_State **event, Bin_Unpack *bu, const Memory *mem); +tox_non_null() bool tox_event_group_topic_lock_unpack(Tox_Event_Group_Topic_Lock **event, Bin_Unpack *bu, const Memory *mem); +tox_non_null() bool tox_event_group_peer_limit_unpack(Tox_Event_Group_Peer_Limit **event, Bin_Unpack *bu, const Memory *mem); +tox_non_null() bool tox_event_group_password_unpack(Tox_Event_Group_Password **event, Bin_Unpack *bu, const Memory *mem); +tox_non_null() bool tox_event_group_message_unpack(Tox_Event_Group_Message **event, Bin_Unpack *bu, const Memory *mem); +tox_non_null() bool tox_event_group_private_message_unpack(Tox_Event_Group_Private_Message **event, Bin_Unpack *bu, const Memory *mem); +tox_non_null() bool tox_event_group_custom_packet_unpack(Tox_Event_Group_Custom_Packet **event, Bin_Unpack *bu, const Memory *mem); +tox_non_null() bool tox_event_group_custom_private_packet_unpack(Tox_Event_Group_Custom_Private_Packet **event, Bin_Unpack *bu, const Memory *mem); +tox_non_null() bool tox_event_group_invite_unpack(Tox_Event_Group_Invite **event, Bin_Unpack *bu, const Memory *mem); +tox_non_null() bool tox_event_group_peer_join_unpack(Tox_Event_Group_Peer_Join **event, Bin_Unpack *bu, const Memory *mem); +tox_non_null() bool tox_event_group_peer_exit_unpack(Tox_Event_Group_Peer_Exit **event, Bin_Unpack *bu, const Memory *mem); +tox_non_null() bool tox_event_group_self_join_unpack(Tox_Event_Group_Self_Join **event, Bin_Unpack *bu, const Memory *mem); +tox_non_null() bool tox_event_group_join_fail_unpack(Tox_Event_Group_Join_Fail **event, Bin_Unpack *bu, const Memory *mem); +tox_non_null() bool tox_event_group_moderation_unpack(Tox_Event_Group_Moderation **event, Bin_Unpack *bu, const Memory *mem); +tox_non_null() bool tox_event_dht_get_nodes_response_unpack(Tox_Event_Dht_Get_Nodes_Response **event, Bin_Unpack *bu, const Memory *mem); #ifdef __cplusplus } /* extern "C" */ diff --git a/toxcore/tox_events.c b/toxcore/tox_events.c index a5d995cf50..82e8c6ba5b 100644 --- a/toxcore/tox_events.c +++ b/toxcore/tox_events.c @@ -16,8 +16,10 @@ #include "mem.h" #include "tox.h" #include "tox_event.h" +#include "tox_impl.h" #include "tox_private.h" -#include "tox_struct.h" +#include "tox_system.h" +#include "tox_system_impl.h" /***************************************************** * @@ -173,7 +175,7 @@ Tox_Events *tox_events_load(const Tox_System *sys, const uint8_t *bytes, uint32_ }; events->mem = sys->mem; - if (!bin_unpack_obj(tox_events_unpack_handler, events, bytes, bytes_size)) { + if (!bin_unpack_obj(tox_events_unpack_handler, events, bytes, bytes_size, sys->mem)) { tox_events_free(events); return nullptr; } diff --git a/toxcore/tox_events.h b/toxcore/tox_events.h index 6bbf13e8ef..30d69eb496 100644 --- a/toxcore/tox_events.h +++ b/toxcore/tox_events.h @@ -577,11 +577,9 @@ void tox_events_free(Tox_Events *events); uint32_t tox_events_bytes_size(const Tox_Events *events); bool tox_events_get_bytes(const Tox_Events *events, uint8_t *bytes); -typedef struct Tox_System Tox_System; +Tox_Events *tox_events_load(const struct Tox_System *sys, 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_System *sys, const Tox_Events *a, const Tox_Events *b); +bool tox_events_equal(const struct Tox_System *sys, const Tox_Events *a, const Tox_Events *b); #ifdef __cplusplus } /* extern "C" */ diff --git a/toxcore/tox_events_test.cc b/toxcore/tox_events_test.cc index 749d6768f3..9352d324ad 100644 --- a/toxcore/tox_events_test.cc +++ b/toxcore/tox_events_test.cc @@ -6,32 +6,34 @@ #include #include "crypto_core.h" +#include "os_system.h" #include "tox_private.h" +#include "tox_system_impl.h" namespace { TEST(ToxEvents, UnpackRandomDataDoesntCrash) { - const Tox_System sys = tox_default_system(); - ASSERT_NE(sys.rng, nullptr); + const Tox_System *sys = os_system(); + ASSERT_NE(sys->rng, nullptr); std::array data; - random_bytes(sys.rng, data.data(), data.size()); - tox_events_free(tox_events_load(&sys, data.data(), data.size())); + random_bytes(sys->rng, data.data(), data.size()); + tox_events_free(tox_events_load(sys, data.data(), data.size())); } TEST(ToxEvents, UnpackEmptyDataFails) { - const Tox_System sys = tox_default_system(); + const Tox_System *sys = os_system(); std::array data; - Tox_Events *events = tox_events_load(&sys, data.end(), 0); + Tox_Events *events = tox_events_load(sys, data.end(), 0); EXPECT_EQ(events, nullptr); } TEST(ToxEvents, UnpackEmptyArrayCreatesEmptyEvents) { - const Tox_System sys = tox_default_system(); + const Tox_System *sys = os_system(); std::array data{0x90}; // empty msgpack array - Tox_Events *events = tox_events_load(&sys, data.data(), data.size()); + Tox_Events *events = tox_events_load(sys, data.data(), data.size()); ASSERT_NE(events, nullptr); EXPECT_EQ(tox_events_get_size(events), 0); tox_events_free(events); @@ -47,10 +49,10 @@ TEST(ToxEvents, NullEventsPacksToEmptyArray) TEST(ToxEvents, PackedEventsCanBeUnpacked) { - const Tox_System sys = tox_default_system(); + const Tox_System *sys = os_system(); // [[0, 1]] == Tox_Self_Connection_Status { .connection_status = TOX_CONNECTION_TCP } std::array packed{0x91, 0x92, 0xcc, 0x00, 0xcc, 0x01}; - Tox_Events *events = tox_events_load(&sys, packed.data(), packed.size()); + Tox_Events *events = tox_events_load(sys, packed.data(), packed.size()); ASSERT_NE(events, nullptr); std::array bytes; ASSERT_EQ(tox_events_bytes_size(events), bytes.size()); @@ -61,9 +63,9 @@ TEST(ToxEvents, PackedEventsCanBeUnpacked) TEST(ToxEvents, DealsWithHugeMsgpackArrays) { - const Tox_System sys = tox_default_system(); + const Tox_System *sys = os_system(); std::vector data{0xdd, 0xff, 0xff, 0xff, 0xff}; - EXPECT_EQ(tox_events_load(&sys, data.data(), data.size()), nullptr); + EXPECT_EQ(tox_events_load(sys, data.data(), data.size()), nullptr); } } // namespace diff --git a/toxcore/tox_struct.h b/toxcore/tox_impl.h similarity index 93% rename from toxcore/tox_struct.h rename to toxcore/tox_impl.h index bd42fcce8d..154f17c342 100644 --- a/toxcore/tox_struct.h +++ b/toxcore/tox_impl.h @@ -3,26 +3,27 @@ * Copyright © 2013 Tox project. */ -#ifndef C_TOXCORE_TOXCORE_TOX_STRUCT_H -#define C_TOXCORE_TOXCORE_TOX_STRUCT_H - -#include +#ifndef C_TOXCORE_TOXCORE_TOX_IMPL_H +#define C_TOXCORE_TOXCORE_TOX_IMPL_H #include "Messenger.h" #include "mem.h" #include "mono_time.h" #include "tox.h" #include "tox_private.h" +#include "tox_system_impl.h" #ifdef __cplusplus extern "C" { #endif +typedef struct Tox_Mutex Tox_Mutex; + struct Tox { Messenger *m; Mono_Time *mono_time; Tox_System sys; - pthread_mutex_t *mutex; + Tox_Mutex *mutex; tox_log_cb *log_callback; tox_self_connection_status_cb *self_connection_status_callback; @@ -73,4 +74,4 @@ struct Tox { } /* extern "C" */ #endif -#endif /* C_TOXCORE_TOXCORE_TOX_STRUCT_H */ +#endif /* C_TOXCORE_TOXCORE_TOX_IMPL_H */ diff --git a/toxcore/tox_log.c b/toxcore/tox_log.c new file mode 100644 index 0000000000..82e50f217b --- /dev/null +++ b/toxcore/tox_log.c @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2022-2023 The TokTok team. + */ +#include "tox_log.h" + +#include "ccompat.h" +#include "tox_log_impl.h" +#include "tox_memory.h" + +Tox_Log *tox_log_new(const Tox_Log_Funcs *funcs, void *user_data, const Tox_Memory *mem) +{ + Tox_Log *log = (Tox_Log *)tox_memory_alloc(mem, sizeof(Tox_Log)); + + if (log == nullptr) { + return nullptr; + } + + log->funcs = funcs; + log->user_data = user_data; + + log->mem = mem; + + return log; +} + +void tox_log_free(Tox_Log *log) +{ + if (log == nullptr || log->mem == nullptr) { + return; + } + tox_memory_dealloc(log->mem, log); +} + +void tox_log_log( + const Tox_Log *log, Tox_Log_Level level, + const char *file, uint32_t line, const char *func, + const char *message) +{ + log->funcs->log_callback(log->user_data, level, file, line, func, message); +} diff --git a/toxcore/tox_log.h b/toxcore/tox_log.h new file mode 100644 index 0000000000..464e9a1972 --- /dev/null +++ b/toxcore/tox_log.h @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2022-2023 The TokTok team. + */ + +#ifndef C_TOXCORE_TOXCORE_TOX_LOG_H +#define C_TOXCORE_TOXCORE_TOX_LOG_H + +#include // uint32_t + +#include "tox_attributes.h" +#include "tox_log_level.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef TOX_MEMORY_DEFINED +#define TOX_MEMORY_DEFINED +typedef struct Tox_Memory Tox_Memory; +#endif + +typedef struct Tox_Log_Funcs Tox_Log_Funcs; + +typedef struct Tox_Log Tox_Log; + +tox_non_null(1, 3) tox_nullable(2) +Tox_Log *tox_log_new(const Tox_Log_Funcs *funcs, void *user_data, const Tox_Memory *mem); + +tox_nullable(1) +void tox_log_free(Tox_Log *log); + +tox_non_null() +void tox_log_log( + const Tox_Log *log, Tox_Log_Level level, + const char *file, uint32_t line, const char *func, + const char *message); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* C_TOXCORE_TOXCORE_TOX_LOG_H */ diff --git a/toxcore/tox_log_impl.h b/toxcore/tox_log_impl.h new file mode 100644 index 0000000000..fbdcec7497 --- /dev/null +++ b/toxcore/tox_log_impl.h @@ -0,0 +1,54 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2022-2023 The TokTok team. + */ + +#ifndef C_TOXCORE_TOXCORE_TOX_LOG_IMPL_H +#define C_TOXCORE_TOXCORE_TOX_LOG_IMPL_H + +#include "tox_log.h" +#include "tox_memory.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief This event is triggered when the toxcore library logs a message. + * + * This is mostly useful for debugging. This callback can be called from any + * function, not just tox_iterate. This means the user data lifetime must at + * least extend between registering and unregistering it or tox_kill. + * + * Other toxcore modules such as toxav may concurrently call this callback at + * any time. Thus, user code must make sure it is equipped to handle concurrent + * execution, e.g. by employing appropriate mutex locking. + * + * @param self The user data pointer passed to `tox_log_new`. + * @param level The severity of the log message. + * @param file The source file from which the message originated. + * @param line The source line from which the message originated. + * @param func The function from which the message originated. + * @param message The log message. + */ +typedef void tox_log_log_cb( + void *self, Tox_Log_Level level, + const char *file, uint32_t line, const char *func, + const char *message); + + +struct Tox_Log_Funcs { + tox_log_log_cb *log_callback; +}; + +struct Tox_Log { + const Tox_Log_Funcs *funcs; + void *user_data; + + const Tox_Memory *mem; +}; + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* C_TOXCORE_TOXCORE_TOX_LOG_IMPL_H */ diff --git a/toxcore/tox_log_level.c b/toxcore/tox_log_level.c new file mode 100644 index 0000000000..145400e50d --- /dev/null +++ b/toxcore/tox_log_level.c @@ -0,0 +1,23 @@ +#include "tox_log_level.h" + +const char *tox_log_level_to_string(Tox_Log_Level value) +{ + switch (value) { + case TOX_LOG_LEVEL_TRACE: + return "TOX_LOG_LEVEL_TRACE"; + + case TOX_LOG_LEVEL_DEBUG: + return "TOX_LOG_LEVEL_DEBUG"; + + case TOX_LOG_LEVEL_INFO: + return "TOX_LOG_LEVEL_INFO"; + + case TOX_LOG_LEVEL_WARNING: + return "TOX_LOG_LEVEL_WARNING"; + + case TOX_LOG_LEVEL_ERROR: + return "TOX_LOG_LEVEL_ERROR"; + } + + return ""; +} diff --git a/toxcore/tox_log_level.h b/toxcore/tox_log_level.h new file mode 100644 index 0000000000..b10958da75 --- /dev/null +++ b/toxcore/tox_log_level.h @@ -0,0 +1,50 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2022-2024 The TokTok team. + */ + +#ifndef C_TOXCORE_TOXCORE_TOX_LOG_LEVEL_H +#define C_TOXCORE_TOXCORE_TOX_LOG_LEVEL_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Severity level of log messages. + */ +typedef enum Tox_Log_Level { + + /** + * Very detailed traces including all network activity. + */ + TOX_LOG_LEVEL_TRACE, + + /** + * Debug messages such as which port we bind to. + */ + TOX_LOG_LEVEL_DEBUG, + + /** + * Informational log messages such as video call status changes. + */ + TOX_LOG_LEVEL_INFO, + + /** + * Warnings about internal inconsistency or logic errors. + */ + TOX_LOG_LEVEL_WARNING, + + /** + * Severe unexpected errors caused by external or internal inconsistency. + */ + TOX_LOG_LEVEL_ERROR, + +} Tox_Log_Level; + +const char *tox_log_level_to_string(Tox_Log_Level value); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* C_TOXCORE_TOXCORE_TOX_LOG_LEVEL_H */ diff --git a/toxcore/tox_memory.c b/toxcore/tox_memory.c new file mode 100644 index 0000000000..9410094145 --- /dev/null +++ b/toxcore/tox_memory.c @@ -0,0 +1,60 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2018 The TokTok team. + * Copyright © 2013 Tox project. + */ +#include "tox_memory.h" + +#include + +#include "ccompat.h" +#include "tox_memory_impl.h" + +Tox_Memory *tox_memory_new(const Tox_Memory_Funcs *funcs, void *user_data) +{ + const Tox_Memory bootstrap = {funcs, user_data}; + + Tox_Memory *mem = (Tox_Memory *)tox_memory_alloc(&bootstrap, sizeof(Tox_Memory)); + + if (mem == nullptr) { + return nullptr; + } + + *mem = bootstrap; + + return mem; +} + +void tox_memory_free(Tox_Memory *mem) +{ + if (mem == nullptr) { + return; + } + + tox_memory_dealloc(mem, mem); +} + +void *tox_memory_malloc(const Tox_Memory *mem, uint32_t size) +{ + void *const ptr = mem->funcs->malloc_callback(mem->user_data, size); + return ptr; +} + +void *tox_memory_alloc(const Tox_Memory *mem, uint32_t size) +{ + void *const ptr = tox_memory_malloc(mem, size); + if (ptr != nullptr) { + memset(ptr, 0, size); + } + return ptr; +} + +void *tox_memory_realloc(const Tox_Memory *mem, void *ptr, uint32_t size) +{ + void *const new_ptr = mem->funcs->realloc_callback(mem->user_data, ptr, size); + return new_ptr; +} + +void tox_memory_dealloc(const Tox_Memory *mem, void *ptr) +{ + mem->funcs->dealloc_callback(mem->user_data, ptr); +} diff --git a/toxcore/tox_memory.h b/toxcore/tox_memory.h new file mode 100644 index 0000000000..b226709128 --- /dev/null +++ b/toxcore/tox_memory.h @@ -0,0 +1,84 @@ +/* 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_TOX_MEMORY_H +#define C_TOXCORE_TOXCORE_TOX_MEMORY_H + +#include // uint*_t + +#include "tox_attributes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief Functions wrapping standard C memory allocation functions. */ +typedef struct Tox_Memory_Funcs Tox_Memory_Funcs; + +/** + * @brief A dynamic memory allocator. + */ +#ifndef TOX_MEMORY_DEFINED +#define TOX_MEMORY_DEFINED +typedef struct Tox_Memory Tox_Memory; +#endif + +/** + * @brief Allocates a new allocator using itself to allocate its own memory. + * + * The passed `user_data` is stored and passed to allocator callbacks. It must + * outlive the `Tox_Memory` object, since it may be used by the callback invoked + * in `tox_memory_free`. + * + * @return NULL if allocation fails. + */ +tox_non_null(1) tox_nullable(2) +Tox_Memory *tox_memory_new(const Tox_Memory_Funcs *funcs, void *user_data); + +/** + * @brief Destroys the allocator using its own deallocation function. + * + * The stored `user_data` will not be deallocated. + */ +tox_nullable(1) +void tox_memory_free(Tox_Memory *mem); + +/** + * @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`. + */ +tox_non_null() +void *tox_memory_malloc(const Tox_Memory *mem, uint32_t size); + +/** + * @brief Allocate a single zero-initialised object. + * + * Always use as `(T *)tox_memory_alloc(mem, sizeof(T))`. Unlike `calloc`, this + * does not support allocating arrays. Use `malloc` and `memset` for that. + * + * @param mem The memory allocator. + * @param size Size in bytes of each element. + */ +tox_non_null() +void *tox_memory_alloc(const Tox_Memory *mem, uint32_t size); + +/** @brief Resize a memory chunk vector. */ +tox_non_null(1) tox_nullable(2) +void *tox_memory_realloc(const Tox_Memory *mem, void *ptr, uint32_t size); + +/** @brief Free an array, object, or object vector. */ +tox_non_null(1) tox_nullable(2) +void tox_memory_dealloc(const Tox_Memory *mem, void *ptr); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* C_TOXCORE_TOXCORE_TOX_MEMORY_H */ diff --git a/toxcore/tox_memory_impl.h b/toxcore/tox_memory_impl.h new file mode 100644 index 0000000000..e0b9961962 --- /dev/null +++ b/toxcore/tox_memory_impl.h @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2018 The TokTok team. + * Copyright © 2013 Tox project. + */ + +/** + * Datatypes, functions and includes for the core networking. + */ +#ifndef C_TOXCORE_TOXCORE_TOX_MEMORY_IMPL_H +#define C_TOXCORE_TOXCORE_TOX_MEMORY_IMPL_H + +#include // uint*_t + +#include "tox_memory.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief Allocate a byte array, similar to malloc. */ +typedef void *tox_memory_malloc_cb(void *self, uint32_t size); +/** @brief Reallocate a byte array, similar to realloc. */ +typedef void *tox_memory_realloc_cb(void *self, void *ptr, uint32_t size); +/** + * @brief Deallocate a byte or object array, similar to free. + * + * Note that `tox_memory_free` will use this callback to deallocate itself, so + * once the deallocation is done, the allocator data structures can no longer be + * referenced. + */ +typedef void tox_memory_dealloc_cb(void *self, void *ptr); + +/** @brief Functions wrapping standard C memory allocation functions. */ +struct Tox_Memory_Funcs { + tox_memory_malloc_cb *malloc_callback; + tox_memory_realloc_cb *realloc_callback; + tox_memory_dealloc_cb *dealloc_callback; +}; + +struct Tox_Memory { + const Tox_Memory_Funcs *funcs; + void *user_data; +}; + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* C_TOXCORE_TOXCORE_TOX_MEMORY_IMPL_H */ diff --git a/toxcore/tox_network.c b/toxcore/tox_network.c new file mode 100644 index 0000000000..1b892f6905 --- /dev/null +++ b/toxcore/tox_network.c @@ -0,0 +1,112 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2022-2023 The TokTok team. + */ +#include "tox_network.h" + +#include "ccompat.h" +#include "tox_memory.h" +#include "tox_network_impl.h" + +Tox_Network *tox_network_new(const Tox_Network_Funcs *funcs, void *user_data, const Tox_Memory *mem) +{ + Tox_Network *ns = (Tox_Network *)tox_memory_alloc(mem, sizeof(Tox_Network)); + + if (ns == nullptr) { + return nullptr; + } + + ns->funcs = funcs; + ns->user_data = user_data; + + ns->mem = mem; + + return ns; +} + +void tox_network_free(Tox_Network *ns) +{ + if (ns == nullptr || ns->mem == nullptr) { + return; + } + tox_memory_dealloc(ns->mem, ns); +} + +int tox_network_close(const Tox_Network *ns, Socket sock) +{ + return ns->funcs->close_callback(ns->user_data, sock); +} + +Socket tox_network_accept(const Tox_Network *ns, Socket sock) +{ + return ns->funcs->accept_callback(ns->user_data, sock); +} + +int tox_network_bind(const Tox_Network *ns, Socket sock, const Network_Addr *addr) +{ + return ns->funcs->bind_callback(ns->user_data, sock, addr); +} + +int tox_network_listen(const Tox_Network *ns, Socket sock, int backlog) +{ + return ns->funcs->listen_callback(ns->user_data, sock, backlog); +} + +int tox_network_connect(const Tox_Network *ns, Socket sock, const Network_Addr *addr) +{ + return ns->funcs->connect_callback(ns->user_data, sock, addr); +} + +int tox_network_recvbuf(const Tox_Network *ns, Socket sock) +{ + return ns->funcs->recvbuf_callback(ns->user_data, sock); +} + +int tox_network_recv(const Tox_Network *ns, Socket sock, uint8_t *buf, size_t len) +{ + return ns->funcs->recv_callback(ns->user_data, sock, buf, len); +} + +int tox_network_recvfrom(const Tox_Network *ns, Socket sock, uint8_t *buf, size_t len, Network_Addr *addr) +{ + return ns->funcs->recvfrom_callback(ns->user_data, sock, buf, len, addr); +} + +int tox_network_send(const Tox_Network *ns, Socket sock, const uint8_t *buf, size_t len) +{ + return ns->funcs->send_callback(ns->user_data, sock, buf, len); +} + +int tox_network_sendto(const Tox_Network *ns, Socket sock, const uint8_t *buf, size_t len, const Network_Addr *addr) +{ + return ns->funcs->sendto_callback(ns->user_data, sock, buf, len, addr); +} + +Socket tox_network_socket(const Tox_Network *ns, int domain, int type, int proto) +{ + return ns->funcs->socket_callback(ns->user_data, domain, type, proto); +} + +int tox_network_socket_nonblock(const Tox_Network *ns, Socket sock, bool nonblock) +{ + return ns->funcs->socket_nonblock_callback(ns->user_data, sock, nonblock); +} + +int tox_network_getsockopt(const Tox_Network *ns, Socket sock, int level, int optname, void *optval, size_t *optlen) +{ + return ns->funcs->getsockopt_callback(ns->user_data, sock, level, optname, optval, optlen); +} + +int tox_network_setsockopt(const Tox_Network *ns, Socket sock, int level, int optname, const void *optval, size_t optlen) +{ + return ns->funcs->setsockopt_callback(ns->user_data, sock, level, optname, optval, optlen); +} + +int tox_network_getaddrinfo(const Tox_Network *ns, int family, Network_Addr **addrs) +{ + return ns->funcs->getaddrinfo_callback(ns->user_data, family, addrs); +} + +int tox_network_freeaddrinfo(const Tox_Network *ns, Network_Addr *addrs) +{ + return ns->funcs->freeaddrinfo_callback(ns->user_data, addrs); +} diff --git a/toxcore/tox_network.h b/toxcore/tox_network.h new file mode 100644 index 0000000000..9351dc26e4 --- /dev/null +++ b/toxcore/tox_network.h @@ -0,0 +1,78 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2022-2023 The TokTok team. + */ + +#ifndef C_TOXCORE_TOXCORE_TOX_NETWORK_H +#define C_TOXCORE_TOXCORE_TOX_NETWORK_H + +#include +#include // size_t + +#include "tox_attributes.h" +#include "tox_memory.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct Tox_Network_Funcs Tox_Network_Funcs; + +typedef struct Tox_Network Tox_Network; + +tox_non_null(1, 3) tox_nullable(2) +Tox_Network *tox_network_new(const Tox_Network_Funcs *funcs, void *user_data, const Tox_Memory *mem); + +tox_nullable(1) +void tox_network_free(Tox_Network *ns); + +/** + * @brief Wrapper for sockaddr_storage and size. + */ +typedef struct Network_Addr Network_Addr; + +typedef tox_bitwise int Socket_Value; +typedef struct Socket { + Socket_Value value; +} Socket; + +int net_socket_to_native(Socket sock); +Socket net_socket_from_native(int sock); + +tox_non_null() +int tox_network_close(const Tox_Network *ns, Socket sock); +tox_non_null() +Socket tox_network_accept(const Tox_Network *ns, Socket sock); +tox_non_null() +int tox_network_bind(const Tox_Network *ns, Socket sock, const Network_Addr *addr); +tox_non_null() +int tox_network_listen(const Tox_Network *ns, Socket sock, int backlog); +tox_non_null() +int tox_network_connect(const Tox_Network *ns, Socket sock, const Network_Addr *addr); +tox_non_null() +int tox_network_recvbuf(const Tox_Network *ns, Socket sock); +tox_non_null() +int tox_network_recv(const Tox_Network *ns, Socket sock, uint8_t *buf, size_t len); +tox_non_null() +int tox_network_recvfrom(const Tox_Network *ns, Socket sock, uint8_t *buf, size_t len, Network_Addr *addr); +tox_non_null() +int tox_network_send(const Tox_Network *ns, Socket sock, const uint8_t *buf, size_t len); +tox_non_null() +int tox_network_sendto(const Tox_Network *ns, Socket sock, const uint8_t *buf, size_t len, const Network_Addr *addr); +tox_non_null() +Socket tox_network_socket(const Tox_Network *ns, int domain, int type, int proto); +tox_non_null() +int tox_network_socket_nonblock(const Tox_Network *ns, Socket sock, bool nonblock); +tox_non_null() +int tox_network_getsockopt(const Tox_Network *ns, Socket sock, int level, int optname, void *optval, size_t *optlen); +tox_non_null() +int tox_network_setsockopt(const Tox_Network *ns, Socket sock, int level, int optname, const void *optval, size_t optlen); +tox_non_null() +int tox_network_getaddrinfo(const Tox_Network *ns, int family, Network_Addr **addrs); +tox_non_null() +int tox_network_freeaddrinfo(const Tox_Network *ns, Network_Addr *addrs); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* C_TOXCORE_TOXCORE_TOX_NETWORK_H */ diff --git a/toxcore/tox_network_impl.h b/toxcore/tox_network_impl.h new file mode 100644 index 0000000000..1d2a8f5dc4 --- /dev/null +++ b/toxcore/tox_network_impl.h @@ -0,0 +1,67 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2022-2023 The TokTok team. + */ + +#ifndef C_TOXCORE_TOXCORE_TOX_NETWORK_IMPL_H +#define C_TOXCORE_TOXCORE_TOX_NETWORK_IMPL_H + +#include "tox_memory.h" +#include "tox_network.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef int tox_network_close_cb(void *self, Socket sock); +typedef Socket tox_network_accept_cb(void *self, Socket sock); +typedef int tox_network_bind_cb(void *self, Socket sock, const Network_Addr *addr); +typedef int tox_network_listen_cb(void *self, Socket sock, int backlog); +typedef int tox_network_connect_cb(void *self, Socket sock, const Network_Addr *addr); +typedef int tox_network_recvbuf_cb(void *self, Socket sock); +typedef int tox_network_recv_cb(void *self, Socket sock, uint8_t *buf, size_t len); +typedef int tox_network_recvfrom_cb(void *self, Socket sock, uint8_t *buf, size_t len, Network_Addr *addr); +typedef int tox_network_send_cb(void *self, Socket sock, const uint8_t *buf, size_t len); +typedef int tox_network_sendto_cb(void *self, Socket sock, const uint8_t *buf, size_t len, const Network_Addr *addr); +typedef Socket tox_network_socket_cb(void *self, int domain, int type, int proto); +typedef int tox_network_socket_nonblock_cb(void *self, Socket sock, bool nonblock); +typedef int tox_network_getsockopt_cb(void *self, Socket sock, int level, int optname, void *optval, size_t *optlen); +typedef int tox_network_setsockopt_cb(void *self, Socket sock, int level, int optname, const void *optval, size_t optlen); +typedef int tox_network_getaddrinfo_cb(void *self, int family, Network_Addr **addrs); +typedef int tox_network_freeaddrinfo_cb(void *self, Network_Addr *addrs); + +/** @brief Functions wrapping POSIX network functions. + * + * Refer to POSIX man pages for documentation of what these functions are + * expected to do when providing alternative Network implementations. + */ +struct Tox_Network_Funcs { + tox_network_close_cb *close_callback; + tox_network_accept_cb *accept_callback; + tox_network_bind_cb *bind_callback; + tox_network_listen_cb *listen_callback; + tox_network_connect_cb *connect_callback; + tox_network_recvbuf_cb *recvbuf_callback; + tox_network_recv_cb *recv_callback; + tox_network_recvfrom_cb *recvfrom_callback; + tox_network_send_cb *send_callback; + tox_network_sendto_cb *sendto_callback; + tox_network_socket_cb *socket_callback; + tox_network_socket_nonblock_cb *socket_nonblock_callback; + tox_network_getsockopt_cb *getsockopt_callback; + tox_network_setsockopt_cb *setsockopt_callback; + tox_network_getaddrinfo_cb *getaddrinfo_callback; + tox_network_freeaddrinfo_cb *freeaddrinfo_callback; +}; + +struct Tox_Network { + const Tox_Network_Funcs *funcs; + void *user_data; + + const Tox_Memory *mem; +}; + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* C_TOXCORE_TOXCORE_TOX_NETWORK_IMPL_H */ diff --git a/toxcore/tox_options.c b/toxcore/tox_options.c new file mode 100644 index 0000000000..41c7e8c5a3 --- /dev/null +++ b/toxcore/tox_options.c @@ -0,0 +1,208 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2021 The TokTok team. + */ +#include "tox_options.h" + +#include + +#include "ccompat.h" +#include "tox.h" +#include "tox_system.h" + +#define SET_ERROR_PARAMETER(param, x) \ + do { \ + if (param != nullptr) { \ + *param = x; \ + } \ + } while (0) + +bool tox_options_get_ipv6_enabled(const Tox_Options *options) +{ + return options->ipv6_enabled; +} +void tox_options_set_ipv6_enabled(Tox_Options *options, bool ipv6_enabled) +{ + options->ipv6_enabled = ipv6_enabled; +} +bool tox_options_get_udp_enabled(const Tox_Options *options) +{ + return options->udp_enabled; +} +void tox_options_set_udp_enabled(Tox_Options *options, bool udp_enabled) +{ + options->udp_enabled = udp_enabled; +} +Tox_Proxy_Type tox_options_get_proxy_type(const Tox_Options *options) +{ + return options->proxy_type; +} +void tox_options_set_proxy_type(Tox_Options *options, Tox_Proxy_Type proxy_type) +{ + options->proxy_type = proxy_type; +} +const char *tox_options_get_proxy_host(const Tox_Options *options) +{ + return options->proxy_host; +} +void tox_options_set_proxy_host(Tox_Options *options, const char *proxy_host) +{ + options->proxy_host = proxy_host; +} +uint16_t tox_options_get_proxy_port(const Tox_Options *options) +{ + return options->proxy_port; +} +void tox_options_set_proxy_port(Tox_Options *options, uint16_t proxy_port) +{ + options->proxy_port = proxy_port; +} +uint16_t tox_options_get_start_port(const Tox_Options *options) +{ + return options->start_port; +} +void tox_options_set_start_port(Tox_Options *options, uint16_t start_port) +{ + options->start_port = start_port; +} +uint16_t tox_options_get_end_port(const Tox_Options *options) +{ + return options->end_port; +} +void tox_options_set_end_port(Tox_Options *options, uint16_t end_port) +{ + options->end_port = end_port; +} +uint16_t tox_options_get_tcp_port(const Tox_Options *options) +{ + return options->tcp_port; +} +void tox_options_set_tcp_port(Tox_Options *options, uint16_t tcp_port) +{ + options->tcp_port = tcp_port; +} +bool tox_options_get_hole_punching_enabled(const Tox_Options *options) +{ + return options->hole_punching_enabled; +} +void tox_options_set_hole_punching_enabled(Tox_Options *options, bool hole_punching_enabled) +{ + options->hole_punching_enabled = hole_punching_enabled; +} +Tox_Savedata_Type tox_options_get_savedata_type(const Tox_Options *options) +{ + return options->savedata_type; +} +void tox_options_set_savedata_type(Tox_Options *options, Tox_Savedata_Type savedata_type) +{ + options->savedata_type = savedata_type; +} +size_t tox_options_get_savedata_length(const Tox_Options *options) +{ + return options->savedata_length; +} +void tox_options_set_savedata_length(Tox_Options *options, size_t savedata_length) +{ + options->savedata_length = savedata_length; +} +tox_log_cb *tox_options_get_log_callback(const Tox_Options *options) +{ + return options->log_callback; +} +void tox_options_set_log_callback(Tox_Options *options, tox_log_cb *log_callback) +{ + options->log_callback = log_callback; +} +void *tox_options_get_log_user_data(const Tox_Options *options) +{ + return options->log_user_data; +} +void tox_options_set_log_user_data(Tox_Options *options, void *log_user_data) +{ + options->log_user_data = log_user_data; +} +bool tox_options_get_local_discovery_enabled(const Tox_Options *options) +{ + return options->local_discovery_enabled; +} +void tox_options_set_local_discovery_enabled(Tox_Options *options, bool local_discovery_enabled) +{ + options->local_discovery_enabled = local_discovery_enabled; +} +bool tox_options_get_dht_announcements_enabled(const Tox_Options *options) +{ + return options->dht_announcements_enabled; +} +void tox_options_set_dht_announcements_enabled(Tox_Options *options, bool dht_announcements_enabled) +{ + options->dht_announcements_enabled = dht_announcements_enabled; +} +bool tox_options_get_experimental_thread_safety(const Tox_Options *options) +{ + return options->experimental_thread_safety; +} +void tox_options_set_experimental_thread_safety(Tox_Options *options, bool experimental_thread_safety) +{ + options->experimental_thread_safety = experimental_thread_safety; +} +const Tox_System *tox_options_get_operating_system(const Tox_Options *options) +{ + return options->operating_system; +} +void tox_options_set_operating_system(Tox_Options *options, const Tox_System *operating_system) +{ + options->operating_system = operating_system; +} +bool tox_options_get_experimental_groups_persistence(const Tox_Options *options) +{ + return options->experimental_groups_persistence; +} +void tox_options_set_experimental_groups_persistence( + Tox_Options *options, bool experimental_groups_persistence) +{ + options->experimental_groups_persistence = experimental_groups_persistence; +} + +const uint8_t *tox_options_get_savedata_data(const Tox_Options *options) +{ + return options->savedata_data; +} +void tox_options_set_savedata_data(Tox_Options *options, const uint8_t *savedata_data, size_t length) +{ + options->savedata_data = savedata_data; + options->savedata_length = length; +} + +void tox_options_default(Tox_Options *options) +{ + if (options != nullptr) { + const Tox_Options default_options = {false}; + *options = default_options; + tox_options_set_ipv6_enabled(options, true); + tox_options_set_udp_enabled(options, true); + tox_options_set_proxy_type(options, TOX_PROXY_TYPE_NONE); + tox_options_set_hole_punching_enabled(options, true); + tox_options_set_local_discovery_enabled(options, true); + tox_options_set_dht_announcements_enabled(options, true); + tox_options_set_experimental_thread_safety(options, false); + tox_options_set_experimental_groups_persistence(options, false); + } +} + +Tox_Options *tox_options_new(Tox_Err_Options_New *error) +{ + Tox_Options *options = (Tox_Options *)calloc(1, sizeof(Tox_Options)); + + if (options != nullptr) { + tox_options_default(options); + SET_ERROR_PARAMETER(error, TOX_ERR_OPTIONS_NEW_OK); + return options; + } + + SET_ERROR_PARAMETER(error, TOX_ERR_OPTIONS_NEW_MALLOC); + return nullptr; +} + +void tox_options_free(Tox_Options *options) +{ + free(options); +} diff --git a/toxcore/tox_options.h b/toxcore/tox_options.h new file mode 100644 index 0000000000..037473388c --- /dev/null +++ b/toxcore/tox_options.h @@ -0,0 +1,74 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2018 The TokTok team. + * Copyright © 2013 Tox project. + */ + +#ifndef C_TOXCORE_TOXCORE_TOX_OPTIONS_H +#define C_TOXCORE_TOXCORE_TOX_OPTIONS_H + +#include "tox_attributes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct Tox_Options Tox_Options; + +/** + * @brief Initialises a Tox_Options object with the default options. + * + * The result of this function is independent of the original options. All + * values will be overwritten, no values will be read (so it is permissible + * to pass an uninitialised object). + * + * If options is NULL, this function has no effect. + * + * @param options An options object to be filled with default options. + */ +tox_non_null() +void tox_options_default(Tox_Options *options); + +typedef enum Tox_Err_Options_New { + /** + * The function returned successfully. + */ + TOX_ERR_OPTIONS_NEW_OK, + + /** + * The function failed to allocate enough memory for the options struct. + */ + TOX_ERR_OPTIONS_NEW_MALLOC, +} Tox_Err_Options_New; + +const char *tox_err_options_new_to_string(Tox_Err_Options_New value); + + +/** + * @brief Allocates a new Tox_Options object and initialises it with the default + * options. + * + * This function can be used to preserve long term ABI compatibility by + * giving the responsibility of allocation and deallocation to the Tox library. + * + * Objects returned from this function must be freed using the tox_options_free + * function. + * + * @return A new Tox_Options object with default options or NULL on failure. + */ +tox_nullable(1) +Tox_Options *tox_options_new(Tox_Err_Options_New *error); + +/** + * @brief Releases all resources associated with an options objects. + * + * Passing a pointer that was not returned by tox_options_new results in + * undefined behaviour. + */ +tox_nullable(1) +void tox_options_free(Tox_Options *options); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* C_TOXCORE_TOXCORE_TOX_OPTIONS_H */ diff --git a/toxcore/tox_private.c b/toxcore/tox_private.c index 7b6050a9f8..6548df3cb8 100644 --- a/toxcore/tox_private.c +++ b/toxcore/tox_private.c @@ -11,16 +11,15 @@ #include #include "DHT.h" -#include "attributes.h" #include "ccompat.h" -#include "crypto_core.h" #include "group_chats.h" #include "group_common.h" -#include "mem.h" #include "net_crypto.h" #include "network.h" #include "tox.h" -#include "tox_struct.h" +#include "tox_attributes.h" +#include "tox_impl.h" +#include "tox_system.h" #define SET_ERROR_PARAMETER(param, x) \ do { \ @@ -29,32 +28,6 @@ } \ } while (0) -Tox_System tox_default_system(void) -{ - const Tox_System sys = { - nullptr, // mono_time_callback - nullptr, // mono_time_user_data - os_random(), - os_network(), - os_memory(), - }; - return sys; -} - -void tox_lock(const Tox *tox) -{ - if (tox->mutex != nullptr) { - pthread_mutex_lock(tox->mutex); - } -} - -void tox_unlock(const Tox *tox) -{ - if (tox->mutex != nullptr) { - pthread_mutex_unlock(tox->mutex); - } -} - void tox_callback_friend_lossy_packet_per_pktid(Tox *tox, tox_friend_lossy_packet_cb *callback, uint8_t pktid) { assert(tox != nullptr); diff --git a/toxcore/tox_private.h b/toxcore/tox_private.h index c872bfea47..1736c9dbff 100644 --- a/toxcore/tox_private.h +++ b/toxcore/tox_private.h @@ -11,39 +11,17 @@ #include #include "tox.h" +#include "tox_system.h" #ifdef __cplusplus extern "C" { #endif -typedef uint64_t tox_mono_time_cb(void *user_data); - -typedef struct Tox_System { - tox_mono_time_cb *mono_time_callback; - void *mono_time_user_data; - const struct Random *rng; - const struct Network *ns; - const struct Memory *mem; -} Tox_System; - -Tox_System tox_default_system(void); - -const Tox_System *tox_get_system(Tox *tox); - -typedef struct Tox_Options_Testing { - const struct Tox_System *operating_system; -} Tox_Options_Testing; - -typedef enum Tox_Err_New_Testing { - TOX_ERR_NEW_TESTING_OK, - TOX_ERR_NEW_TESTING_NULL, -} Tox_Err_New_Testing; - -Tox *tox_new_testing(const Tox_Options *options, Tox_Err_New *error, const Tox_Options_Testing *testing, Tox_Err_New_Testing *testing_error); - void tox_lock(const Tox *tox); void tox_unlock(const Tox *tox); +const Tox_System *tox_get_system(Tox *tox); + /** * Set the callback for the `friend_lossy_packet` event for a specific packet * ID. Pass NULL to unset. diff --git a/toxcore/tox_random.c b/toxcore/tox_random.c new file mode 100644 index 0000000000..848bd7f587 --- /dev/null +++ b/toxcore/tox_random.c @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2022-2023 The TokTok team. + */ +#include "tox_random.h" + +#include "ccompat.h" +#include "tox_memory.h" +#include "tox_random_impl.h" + +Tox_Random *tox_random_new(const Tox_Random_Funcs *funcs, void *user_data, const Tox_Memory *mem) +{ + Tox_Random *rng = (Tox_Random *)tox_memory_alloc(mem, sizeof(Tox_Random)); + + if (rng == nullptr) { + return nullptr; + } + + rng->funcs = funcs; + rng->user_data = user_data; + + rng->mem = mem; + + return rng; +} + +void tox_random_free(Tox_Random *rng) +{ + if (rng == nullptr || rng->mem == nullptr) { + return; + } + tox_memory_dealloc(rng->mem, rng); +} + +void tox_random_bytes(const Tox_Random *rng, uint8_t *bytes, uint32_t length) +{ + rng->funcs->bytes_callback(rng->user_data, bytes, length); +} + +uint32_t tox_random_uniform(const Tox_Random *rng, uint32_t upper_bound) +{ + return rng->funcs->uniform_callback(rng->user_data, upper_bound); +} diff --git a/toxcore/tox_random.h b/toxcore/tox_random.h new file mode 100644 index 0000000000..9c4dfd61d8 --- /dev/null +++ b/toxcore/tox_random.h @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2022-2023 The TokTok team. + */ + +#ifndef C_TOXCORE_TOXCORE_TOX_RANDOM_H +#define C_TOXCORE_TOXCORE_TOX_RANDOM_H + +#include +#include + +#include "tox_attributes.h" +#include "tox_memory.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct Tox_Random_Funcs Tox_Random_Funcs; + +typedef struct Tox_Random Tox_Random; + +tox_non_null(1, 3) tox_nullable(2) +Tox_Random *tox_random_new(const Tox_Random_Funcs *funcs, void *user_data, const Tox_Memory *mem); + +tox_nullable(1) +void tox_random_free(Tox_Random *rng); + +tox_non_null() +void tox_random_bytes(const Tox_Random *rng, uint8_t *bytes, uint32_t length); +tox_non_null() +uint32_t tox_random_uniform(const Tox_Random *rng, uint32_t upper_bound); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* C_TOXCORE_TOXCORE_TOX_RANDOM_H */ diff --git a/toxcore/tox_random_impl.h b/toxcore/tox_random_impl.h new file mode 100644 index 0000000000..2d88b91c00 --- /dev/null +++ b/toxcore/tox_random_impl.h @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2022-2023 The TokTok team. + */ + +#ifndef C_TOXCORE_TOXCORE_TOX_RANDOM_IMPL_H +#define C_TOXCORE_TOXCORE_TOX_RANDOM_IMPL_H + +#include "tox_memory.h" +#include "tox_random.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief Fill a byte array with random bytes. + * + * This is the key generator callback and as such must be a cryptographically + * secure pseudo-random number generator (CSPRNG). The security of Tox heavily + * depends on the security of this RNG. + */ +typedef void tox_random_bytes_cb(void *self, uint8_t *bytes, uint32_t length); + +/** @brief Generate a random integer between 0 and @p upper_bound. + * + * Should produce a uniform random distribution, but Tox security does not + * depend on this being correct. In principle, it could even be a non-CSPRNG. + */ +typedef uint32_t tox_random_uniform_cb(void *self, uint32_t upper_bound); + +/** @brief Virtual function table for Random. */ +struct Tox_Random_Funcs { + tox_random_bytes_cb *bytes_callback; + tox_random_uniform_cb *uniform_callback; +}; + +/** @brief Random number generator object. + * + * Can be used by test code and fuzzers to make toxcore behave in specific + * well-defined (non-random) ways. Production code ought to use libsodium's + * CSPRNG and use `os_random` below. + */ +struct Tox_Random { + const Tox_Random_Funcs *funcs; + void *user_data; + + const Tox_Memory *mem; +}; + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* C_TOXCORE_TOXCORE_TOX_RANDOM_IMPL_H */ diff --git a/toxcore/tox_system.c b/toxcore/tox_system.c new file mode 100644 index 0000000000..98a4b063f2 --- /dev/null +++ b/toxcore/tox_system.c @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2022-2023 The TokTok team. + */ +#include "tox_system.h" + +#include "ccompat.h" +#include "tox_log.h" +#include "tox_memory.h" +#include "tox_network.h" +#include "tox_random.h" +#include "tox_system_impl.h" +#include "tox_time.h" + +Tox_System *tox_system_new(const Tox_Log *log, const Tox_Memory *mem, const Tox_Network *ns, const Tox_Random *rng, const Tox_Time *tm) +{ + Tox_System *sys = (Tox_System *)tox_memory_alloc(mem, sizeof(Tox_System)); + + if (sys == nullptr) { + return nullptr; + } + + sys->log = log; + sys->mem = mem; + sys->ns = ns; + sys->rng = rng; + sys->tm = tm; + + return sys; +} + +void tox_system_free(Tox_System *sys) +{ + if (sys == nullptr || sys->mem == nullptr) { + return; + } + tox_memory_dealloc(sys->mem, sys); +} + +const Tox_Log *tox_system_get_log(const Tox_System *sys) +{ + return sys->log; +} + +const Tox_Memory *tox_system_get_memory(const Tox_System *sys) +{ + return sys->mem; +} + +const Tox_Network *tox_system_get_network(const Tox_System *sys) +{ + return sys->ns; +} + +const Tox_Random *tox_system_get_random(const Tox_System *sys) +{ + return sys->rng; +} + +const Tox_Time *tox_system_get_time(const Tox_System *sys) +{ + return sys->tm; +} diff --git a/toxcore/tox_system.h b/toxcore/tox_system.h new file mode 100644 index 0000000000..b06e24633f --- /dev/null +++ b/toxcore/tox_system.h @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2022-2023 The TokTok team. + */ + +#ifndef C_TOXCORE_TOXCORE_TOX_SYSTEM_H +#define C_TOXCORE_TOXCORE_TOX_SYSTEM_H + +#include "tox_attributes.h" +#include "tox_log.h" +#include "tox_memory.h" +#include "tox_network.h" +#include "tox_random.h" +#include "tox_time.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Operating system functions used by Tox. + * + * This struct is opaque and generally shouldn't be used in clients, but in + * combination with tox_system_impl.h, it allows tests to inject non-IO + * (hermetic) versions of low level network, RNG, and time keeping functions. + */ +typedef struct Tox_System Tox_System; + +tox_non_null() +Tox_System *tox_system_new(const Tox_Log *log, const Tox_Memory *mem, const Tox_Network *ns, const Tox_Random *rng, const Tox_Time *tm); + +tox_nullable(1) +void tox_system_free(Tox_System *sys); + +tox_non_null() +const Tox_Log *tox_system_get_log(const Tox_System *sys); + +tox_non_null() +const Tox_Memory *tox_system_get_memory(const Tox_System *sys); + +tox_non_null() +const Tox_Network *tox_system_get_network(const Tox_System *sys); + +tox_non_null() +const Tox_Random *tox_system_get_random(const Tox_System *sys); + +tox_non_null() +const Tox_Time *tox_system_get_time(const Tox_System *sys); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* C_TOXCORE_TOXCORE_TOX_SYSTEM_H */ diff --git a/toxcore/tox_system_impl.h b/toxcore/tox_system_impl.h new file mode 100644 index 0000000000..66bb1611e0 --- /dev/null +++ b/toxcore/tox_system_impl.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2022-2023 The TokTok team. + */ + +#ifndef C_TOXCORE_TOXCORE_TOX_SYSTEM_IMPL_H +#define C_TOXCORE_TOXCORE_TOX_SYSTEM_IMPL_H + +#include "tox_log.h" +#include "tox_memory.h" +#include "tox_network.h" +#include "tox_random.h" +#include "tox_system.h" +#include "tox_time.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct Tox_System { + const Tox_Log *log; + const Tox_Memory *mem; + const Tox_Network *ns; + const Tox_Random *rng; + const Tox_Time *tm; +}; + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* C_TOXCORE_TOXCORE_TOX_SYSTEM_IMPL_H */ diff --git a/toxcore/tox_test.cc b/toxcore/tox_test.cc index d3fe9bae8a..b9db902557 100644 --- a/toxcore/tox_test.cc +++ b/toxcore/tox_test.cc @@ -6,6 +6,8 @@ #include #include "crypto_core.h" +#include "os_random.h" +#include "tox_log.h" #include "tox_private.h" namespace { diff --git a/toxcore/tox_time.c b/toxcore/tox_time.c new file mode 100644 index 0000000000..4edba891b6 --- /dev/null +++ b/toxcore/tox_time.c @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2022-2023 The TokTok team. + */ +#include "tox_time.h" + +#include "ccompat.h" +#include "tox_memory.h" +#include "tox_time_impl.h" + +Tox_Time *tox_time_new(const Tox_Time_Funcs *funcs, void *user_data, const Tox_Memory *mem) +{ + Tox_Time *tm = (Tox_Time *)tox_memory_alloc(mem, sizeof(Tox_Time)); + + if (tm == nullptr) { + return nullptr; + } + + tm->funcs = funcs; + tm->user_data = user_data; + + tm->mem = mem; + + return tm; +} + +void tox_time_free(Tox_Time *tm) +{ + if (tm == nullptr || tm->mem == nullptr) { + return; + } + tox_memory_dealloc(tm->mem, tm); +} + +uint64_t tox_time_monotonic(const Tox_Time *tm) +{ + return tm->funcs->monotonic_callback(tm->user_data); +} diff --git a/toxcore/tox_time.h b/toxcore/tox_time.h new file mode 100644 index 0000000000..8daf97efc4 --- /dev/null +++ b/toxcore/tox_time.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2022-2023 The TokTok team. + */ + +#ifndef C_TOXCORE_TOXCORE_TOX_TIME_H +#define C_TOXCORE_TOXCORE_TOX_TIME_H + +#include +#include +#include + +#include "tox_attributes.h" +#include "tox_memory.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct Tox_Time_Funcs Tox_Time_Funcs; + +typedef struct Tox_Time Tox_Time; + +tox_non_null(1, 3) tox_nullable(2) +Tox_Time *tox_time_new(const Tox_Time_Funcs *funcs, void *user_data, const Tox_Memory *mem); + +tox_nullable(1) +void tox_time_free(Tox_Time *tm); + +tox_non_null() +uint64_t tox_time_monotonic(const Tox_Time *tm); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* C_TOXCORE_TOXCORE_TOX_TIME_H */ diff --git a/toxcore/tox_time_impl.h b/toxcore/tox_time_impl.h new file mode 100644 index 0000000000..7c0ad6a6a6 --- /dev/null +++ b/toxcore/tox_time_impl.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2022-2023 The TokTok team. + */ + +#ifndef C_TOXCORE_TOXCORE_TOX_TIME_IMPL_H +#define C_TOXCORE_TOXCORE_TOX_TIME_IMPL_H + +#include "tox_memory.h" +#include "tox_time.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef uint64_t tox_time_monotonic_cb(void *self); + +struct Tox_Time_Funcs { + tox_time_monotonic_cb *monotonic_callback; +}; + +struct Tox_Time { + const Tox_Time_Funcs *funcs; + void *user_data; + + const Tox_Memory *mem; +}; + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* C_TOXCORE_TOXCORE_TOX_TIME_IMPL_H */ diff --git a/toxcore/util.c b/toxcore/util.c index 1851e58a08..48a94a6977 100644 --- a/toxcore/util.c +++ b/toxcore/util.c @@ -13,6 +13,7 @@ #include "util.h" +#include #include #include diff --git a/toxencryptsave.h b/toxencryptsave.h new file mode 100644 index 0000000000..f5901d3cc3 --- /dev/null +++ b/toxencryptsave.h @@ -0,0 +1,5 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2022-2023 The TokTok team. + */ + +#include "toxencryptsave/toxencryptsave.h" diff --git a/toxencryptsave/BUILD.bazel b/toxencryptsave/BUILD.bazel index 917d9c007e..b2c46a3762 100644 --- a/toxencryptsave/BUILD.bazel +++ b/toxencryptsave/BUILD.bazel @@ -20,6 +20,8 @@ cc_library( ":defines", "//c-toxcore/toxcore:ccompat", "//c-toxcore/toxcore:crypto_core", + "//c-toxcore/toxcore:os_memory", + "//c-toxcore/toxcore:os_random", "@libsodium", ], ) @@ -34,6 +36,8 @@ cc_library( deps = [ "//c-toxcore/toxcore:ccompat", "//c-toxcore/toxcore:crypto_core", + "//c-toxcore/toxcore:os_memory", + "//c-toxcore/toxcore:os_random", "@libsodium", ], ) diff --git a/toxencryptsave/Makefile.inc b/toxencryptsave/Makefile.inc index 154c6744d0..25ecdda9e3 100644 --- a/toxencryptsave/Makefile.inc +++ b/toxencryptsave/Makefile.inc @@ -3,7 +3,7 @@ lib_LTLIBRARIES += libtoxencryptsave.la libtoxencryptsave_la_include_HEADERS = \ ../toxencryptsave/toxencryptsave.h -libtoxencryptsave_la_includedir = $(includedir)/tox +libtoxencryptsave_la_includedir = $(includedir)/tox/toxencryptsave libtoxencryptsave_la_SOURCES = ../toxencryptsave/toxencryptsave.h \ ../toxencryptsave/toxencryptsave.c \ diff --git a/toxencryptsave/toxencryptsave.c b/toxencryptsave/toxencryptsave.c index b785c26732..7156be0f16 100644 --- a/toxencryptsave/toxencryptsave.c +++ b/toxencryptsave/toxencryptsave.c @@ -15,6 +15,9 @@ #include "../toxcore/ccompat.h" #include "../toxcore/crypto_core.h" +#include "../toxcore/mem.h" +#include "../toxcore/os_memory.h" +#include "../toxcore/os_random.h" #include "defines.h" static_assert(TOX_PASS_SALT_LENGTH == crypto_pwhash_scryptsalsa208sha256_SALTBYTES, @@ -198,9 +201,10 @@ Tox_Pass_Key *tox_pass_key_derive_with_salt( bool tox_pass_key_encrypt(const Tox_Pass_Key *key, const uint8_t plaintext[], size_t plaintext_len, uint8_t ciphertext[], Tox_Err_Encryption *error) { + const Memory *mem = os_memory(); const Random *rng = os_random(); - if (rng == nullptr) { + if (mem == nullptr || rng == nullptr) { SET_ERROR_PARAMETER(error, TOX_ERR_ENCRYPTION_FAILED); return false; } @@ -231,7 +235,7 @@ bool tox_pass_key_encrypt(const Tox_Pass_Key *key, const uint8_t plaintext[], si ciphertext += crypto_box_NONCEBYTES; /* now encrypt */ - const int32_t encrypted_len = encrypt_data_symmetric(key->key, nonce, plaintext, plaintext_len, ciphertext); + const int32_t encrypted_len = encrypt_data_symmetric(key->key, nonce, plaintext, plaintext_len, ciphertext, mem); if (encrypted_len < 0 || (size_t)encrypted_len != plaintext_len + crypto_box_MACBYTES) { SET_ERROR_PARAMETER(error, TOX_ERR_ENCRYPTION_FAILED); return false; @@ -291,6 +295,13 @@ bool tox_pass_encrypt(const uint8_t plaintext[], size_t plaintext_len, const uin bool tox_pass_key_decrypt(const Tox_Pass_Key *key, const uint8_t ciphertext[], size_t ciphertext_len, uint8_t plaintext[], Tox_Err_Decryption *error) { + const Memory *mem = os_memory(); + + if (mem == nullptr) { + SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_FAILED); + return false; + } + if (ciphertext_len <= TOX_PASS_ENCRYPTION_EXTRA_LENGTH) { SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_INVALID_LENGTH); return false; @@ -316,7 +327,7 @@ bool tox_pass_key_decrypt(const Tox_Pass_Key *key, const uint8_t ciphertext[], s ciphertext += crypto_box_NONCEBYTES; /* decrypt the ciphertext */ - const int32_t decrypted_len = decrypt_data_symmetric(key->key, nonce, ciphertext, decrypt_length + crypto_box_MACBYTES, plaintext); + const int32_t decrypted_len = decrypt_data_symmetric(key->key, nonce, ciphertext, decrypt_length + crypto_box_MACBYTES, plaintext, mem); if (decrypted_len < 0 || (size_t)decrypted_len != decrypt_length) { SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_FAILED); return false; diff --git a/toxencryptsave/toxencryptsave.h b/toxencryptsave/toxencryptsave.h index e4cf116c97..b61bfe5fb1 100644 --- a/toxencryptsave/toxencryptsave.h +++ b/toxencryptsave/toxencryptsave.h @@ -220,10 +220,7 @@ bool tox_pass_decrypt(const uint8_t ciphertext[], size_t ciphertext_len, const u * using tox_pass_key_derive or tox_pass_key_derive_with_salt and must be * deallocated using tox_pass_key_free. */ -#ifndef TOX_PASS_KEY_DEFINED -#define TOX_PASS_KEY_DEFINED typedef struct Tox_Pass_Key Tox_Pass_Key; -#endif /* TOX_PASS_KEY_DEFINED */ /** * Deallocate a Tox_Pass_Key. This function behaves like `free()`, so NULL is an