From aa453e3134012c9a8b4d18b77f58733a5fda1dff Mon Sep 17 00:00:00 2001 From: iphydf Date: Tue, 29 Aug 2023 21:26:57 +0000 Subject: [PATCH] refactor: Move some OS-specifics into tox_system. --- .dockerignore | 2 + .github/scripts/flags.sh | 2 +- BUILD.bazel | 56 ++- CMakeLists.txt | 52 ++- auto_tests/BUILD.bazel | 5 + auto_tests/TCP_test.c | 79 ++-- auto_tests/announce_test.c | 17 +- auto_tests/auto_test_support.c | 16 +- auto_tests/auto_test_support.h | 1 + auto_tests/conference_av_test.c | 3 +- auto_tests/conference_test.c | 3 +- auto_tests/crypto_test.c | 57 ++- auto_tests/encryptsave_test.c | 3 +- auto_tests/forwarding_test.c | 19 +- auto_tests/group_message_test.c | 3 +- auto_tests/group_sync_test.c | 3 +- auto_tests/group_topic_test.c | 5 +- auto_tests/lan_discovery_test.c | 16 +- auto_tests/network_test.c | 3 +- auto_tests/onion_test.c | 49 +- auto_tests/reconnect_test.c | 3 +- auto_tests/save_friend_test.c | 3 +- auto_tests/save_load_test.c | 21 +- auto_tests/tox_dispatch_test.c | 6 +- auto_tests/tox_events_test.c | 15 +- auto_tests/tox_many_tcp_test.c | 5 +- auto_tests/tox_many_test.c | 3 +- auto_tests/toxav_many_test.c | 26 +- cmake/ModulePackage.cmake | 6 +- cmake/StrictAbi.cmake | 2 +- other/BUILD.bazel | 3 + other/DHT_bootstrap.c | 21 +- other/analysis/run-clang | 2 +- other/analysis/run-clang-analyze | 2 +- other/analysis/run-clang-tidy | 9 + other/analysis/run-gcc | 2 +- other/bootstrap_daemon/BUILD.bazel | 3 + other/bootstrap_daemon/docker/Dockerfile | 2 + .../docker/tox-bootstrapd.sha256 | 2 +- other/bootstrap_daemon/src/tox-bootstrapd.c | 20 +- testing/BUILD.bazel | 3 + testing/Messenger_test.c | 9 +- testing/fuzzing/BUILD.bazel | 6 + testing/fuzzing/bootstrap_harness.cc | 12 +- testing/fuzzing/e2e_fuzz_test.cc | 7 +- testing/fuzzing/fuzz_support.cc | 109 ++--- testing/fuzzing/fuzz_support.h | 14 +- testing/fuzzing/fuzz_tox.h | 3 +- tox.h | 5 + toxav.h | 5 + toxav/BUILD.bazel | 1 + toxav/Makefile.inc | 5 +- toxav/rtp_test.cc | 3 +- toxav/toxav.c | 2 +- toxcore/BUILD.bazel | 255 +++++++++- toxcore/DHT.c | 20 +- toxcore/DHT.h | 6 +- toxcore/DHT_fuzz_test.cc | 7 +- toxcore/DHT_test.cc | 31 +- toxcore/LAN_discovery.c | 52 ++- toxcore/LAN_discovery.h | 2 +- toxcore/Makefile.inc | 185 +++++--- toxcore/Messenger.c | 12 +- toxcore/TCP_client.c | 4 +- toxcore/TCP_common.c | 4 +- toxcore/TCP_server.c | 13 +- toxcore/announce.c | 27 +- toxcore/bin_pack.c | 14 +- toxcore/bin_pack.h | 5 +- toxcore/bin_pack_test.cc | 37 +- toxcore/bin_unpack.c | 21 +- toxcore/bin_unpack.h | 5 +- toxcore/ccompat.h | 2 +- toxcore/crypto_core.c | 108 ++--- toxcore/crypto_core.h | 32 +- toxcore/crypto_core_test.cc | 5 +- toxcore/events/events_alloc.h | 2 +- toxcore/forwarding.c | 8 +- toxcore/forwarding.h | 2 +- toxcore/forwarding_fuzz_test.cc | 10 +- toxcore/friend_connection.c | 16 +- toxcore/friend_connection.h | 2 +- toxcore/friend_requests.c | 16 +- toxcore/friend_requests.h | 3 +- toxcore/group.c | 62 +-- toxcore/group.h | 2 +- toxcore/group_announce.c | 20 +- toxcore/group_announce.h | 5 +- toxcore/group_announce_fuzz_test.cc | 25 +- toxcore/group_announce_test.cc | 23 +- toxcore/group_chats.c | 289 ++++++------ toxcore/group_chats.h | 5 +- toxcore/group_connection.c | 91 ++-- toxcore/group_connection.h | 8 +- toxcore/group_moderation.c | 50 +- toxcore/group_moderation_fuzz_test.cc | 3 +- toxcore/group_moderation_test.cc | 43 +- toxcore/group_onion_announce.c | 11 +- toxcore/group_onion_announce.h | 8 +- toxcore/group_pack.c | 24 +- toxcore/list.c | 12 +- toxcore/list.h | 7 +- toxcore/list_test.cc | 19 +- toxcore/logger.c | 22 +- toxcore/logger.h | 6 +- toxcore/mem.c | 61 +-- toxcore/mem.h | 31 +- toxcore/mem_test.cc | 12 +- toxcore/mono_time.c | 31 +- toxcore/mono_time.h | 14 +- toxcore/mono_time_test.cc | 27 +- toxcore/net_crypto.c | 36 +- toxcore/network.c | 305 ++++-------- toxcore/network.h | 56 +-- toxcore/onion.c | 32 +- toxcore/onion.h | 4 +- toxcore/onion_announce.c | 28 +- toxcore/onion_announce.h | 17 +- toxcore/onion_client.c | 41 +- toxcore/os_log.c | 28 ++ toxcore/os_log.h | 22 + toxcore/os_memory.c | 42 ++ toxcore/os_memory.h | 22 + toxcore/os_network.c | 288 ++++++++++++ toxcore/os_network.h | 22 + toxcore/os_network_impl.h | 34 ++ toxcore/os_random.c | 60 +++ toxcore/os_random.h | 22 + toxcore/os_system.c | 33 ++ toxcore/os_system.h | 29 ++ toxcore/ping.c | 13 +- toxcore/ping_array_test.cc | 42 +- toxcore/tox.c | 14 +- toxcore/tox.h | 426 +---------------- toxcore/tox_api.c | 89 +--- toxcore/tox_attributes.h | 31 ++ toxcore/tox_events.c | 4 +- toxcore/tox_events.h | 4 +- toxcore/tox_events_test.cc | 26 +- toxcore/tox_log.c | 39 ++ toxcore/tox_log.h | 67 +++ toxcore/tox_log_impl.h | 53 +++ toxcore/tox_memory.c | 60 +++ toxcore/tox_memory.h | 81 ++++ toxcore/tox_memory_impl.h | 49 ++ toxcore/tox_network.c | 106 +++++ toxcore/tox_network.h | 67 +++ toxcore/tox_network_impl.h | 64 +++ toxcore/tox_options.c | 196 ++++++++ toxcore/tox_options.h | 442 ++++++++++++++++++ toxcore/tox_private.c | 12 - toxcore/tox_private.h | 12 - toxcore/tox_random.c | 41 ++ toxcore/tox_random.h | 36 ++ toxcore/tox_random_impl.h | 33 ++ toxcore/tox_struct.h | 1 + toxcore/tox_system.c | 57 +++ toxcore/tox_system.h | 52 +++ toxcore/tox_system_impl.h | 26 ++ toxcore/tox_test.cc | 3 +- toxcore/tox_time.c | 36 ++ toxcore/tox_time.h | 35 ++ toxcore/tox_time_impl.h | 31 ++ toxcore/tox_unpack.h | 2 +- toxcore/util.h | 2 +- toxcore/util_test.cc | 5 +- toxencryptsave.h | 5 + toxencryptsave/BUILD.bazel | 4 + toxencryptsave/Makefile.inc | 2 +- toxencryptsave/toxencryptsave.c | 20 +- 170 files changed, 4044 insertions(+), 1916 deletions(-) create mode 100644 .dockerignore create mode 100644 tox.h create mode 100644 toxav.h create mode 100644 toxcore/os_log.c create mode 100644 toxcore/os_log.h create mode 100644 toxcore/os_memory.c create mode 100644 toxcore/os_memory.h create mode 100644 toxcore/os_network.c create mode 100644 toxcore/os_network.h create mode 100644 toxcore/os_network_impl.h create mode 100644 toxcore/os_random.c create mode 100644 toxcore/os_random.h create mode 100644 toxcore/os_system.c create mode 100644 toxcore/os_system.h create mode 100644 toxcore/tox_attributes.h create mode 100644 toxcore/tox_log.c create mode 100644 toxcore/tox_log.h create mode 100644 toxcore/tox_log_impl.h create mode 100644 toxcore/tox_memory.c create mode 100644 toxcore/tox_memory.h create mode 100644 toxcore/tox_memory_impl.h create mode 100644 toxcore/tox_network.c create mode 100644 toxcore/tox_network.h create mode 100644 toxcore/tox_network_impl.h create mode 100644 toxcore/tox_options.c create mode 100644 toxcore/tox_options.h create mode 100644 toxcore/tox_random.c create mode 100644 toxcore/tox_random.h create mode 100644 toxcore/tox_random_impl.h create mode 100644 toxcore/tox_system.c create mode 100644 toxcore/tox_system.h create mode 100644 toxcore/tox_system_impl.h create mode 100644 toxcore/tox_time.c create mode 100644 toxcore/tox_time.h create mode 100644 toxcore/tox_time_impl.h create mode 100644 toxencryptsave.h diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000000..3ad05109d47 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,2 @@ +_build +_install diff --git a/.github/scripts/flags.sh b/.github/scripts/flags.sh index 80a56c017df..d2af1292c48 100644 --- a/.github/scripts/flags.sh +++ b/.github/scripts/flags.sh @@ -29,7 +29,7 @@ add_flag -O3 -march=native # Warn on non-ISO C. add_c_flag -pedantic add_c_flag -std=c99 -add_cxx_flag -std=c++11 +add_cxx_flag -std=c++17 add_flag -g3 add_flag -ftrapv diff --git a/BUILD.bazel b/BUILD.bazel index 4d39dab3332..97693b0bfb6 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -5,29 +5,75 @@ package(features = ["layering_check"]) project() +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 = [ + "toxav.h", + "tox.h", + "toxencryptsave.h", "//c-toxcore/toxav:toxav.h", - "//c-toxcore/toxcore:tox.h", "//c-toxcore/toxencryptsave:toxencryptsave.h", ], outs = [ "tox/toxav.h", "tox/tox.h", "tox/toxencryptsave.h", + "tox/toxav/toxav.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/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 d3cabf06c66..fbd2d3026b1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -282,6 +282,17 @@ 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/ping_array.c toxcore/ping_array.h toxcore/ping.c @@ -302,11 +313,31 @@ 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_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_unpack.c @@ -316,9 +347,24 @@ set(toxcore_SOURCES set(toxcore_LINK_MODULES ${toxcore_LINK_MODULES} ${LIBSODIUM_LIBRARIES}) 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) + ${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) ################################################################################ # @@ -346,6 +392,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) set(toxcore_LINK_MODULES ${toxcore_LINK_MODULES} ${OPUS_LIBRARIES} ${VPX_LIBRARIES}) @@ -362,6 +409,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 babd3aca845..d5731890e78 100644 --- a/auto_tests/BUILD.bazel +++ b/auto_tests/BUILD.bazel @@ -19,6 +19,7 @@ cc_library( "//c-toxcore/toxcore:Messenger", "//c-toxcore/toxcore:mono_time", "//c-toxcore/toxcore:tox", + "//c-toxcore/toxcore:tox_time", ], ) @@ -61,9 +62,13 @@ flaky_tests = { "//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 f478f3c53f8..b4428bc7b3a 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" @@ -45,15 +48,15 @@ static uint16_t ports[NUM_PORTS] = {13215, 33445, 25643}; static void test_basic(void) { - const Random *rng = system_random(); + const Random *rng = os_random(); ck_assert(rng != nullptr); - const Network *ns = system_network(); + const Network *ns = os_network(); ck_assert(ns != nullptr); - const Memory *mem = system_memory(); + const Memory *mem = os_memory(); ck_assert(mem != nullptr); - Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); - Logger *logger = logger_new(); + Mono_Time *mono_time = mono_time_new(mem, nullptr); + Logger *logger = logger_new(mem); logger_callback_log(logger, print_debug_logger, nullptr, nullptr); // Attempt to create a new TCP_Server instance. @@ -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); @@ -270,7 +273,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 != (SIZEOF_VLA(packet) - sizeof(uint16_t))) { return -1; @@ -295,7 +298,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; @@ -303,15 +306,15 @@ static int read_packet_sec_tcp(const Logger *logger, struct sec_TCP_con *con, ui static void test_some(void) { - const Random *rng = system_random(); + const Random *rng = os_random(); ck_assert(rng != nullptr); - const Network *ns = system_network(); + const Network *ns = os_network(); ck_assert(ns != nullptr); - const Memory *mem = system_memory(); + const Memory *mem = os_memory(); ck_assert(mem != nullptr); - Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); - Logger *logger = logger_new(); + Mono_Time *mono_time = mono_time_new(mem, nullptr); + Logger *logger = logger_new(mem); uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE]; @@ -498,15 +501,15 @@ static int oob_data_callback(void *object, const uint8_t *public_key, const uint static void test_client(void) { - const Random *rng = system_random(); + const Random *rng = os_random(); ck_assert(rng != nullptr); - const Network *ns = system_network(); + const Network *ns = os_network(); ck_assert(ns != nullptr); - const Memory *mem = system_memory(); + const Memory *mem = os_memory(); ck_assert(mem != nullptr); - Logger *logger = logger_new(); - Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); + Logger *logger = logger_new(mem); + 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]; @@ -632,15 +635,15 @@ static void test_client(void) // Test how the client handles servers that don't respond. static void test_client_invalid(void) { - const Random *rng = system_random(); + const Random *rng = os_random(); ck_assert(rng != nullptr); - const Network *ns = system_network(); + const Network *ns = os_network(); ck_assert(ns != nullptr); - const Memory *mem = system_memory(); + const Memory *mem = os_memory(); ck_assert(mem != nullptr); - Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); - Logger *logger = logger_new(); + Mono_Time *mono_time = mono_time_new(mem, nullptr); + Logger *logger = logger_new(mem); uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE]; @@ -711,15 +714,15 @@ static int tcp_data_callback(void *object, int id, const uint8_t *data, uint16_t static void test_tcp_connection(void) { - const Random *rng = system_random(); + const Random *rng = os_random(); ck_assert(rng != nullptr); - const Network *ns = system_network(); + const Network *ns = os_network(); ck_assert(ns != nullptr); - const Memory *mem = system_memory(); + const Memory *mem = os_memory(); ck_assert(mem != nullptr); - Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); - Logger *logger = logger_new(); + Mono_Time *mono_time = mono_time_new(mem, nullptr); + Logger *logger = logger_new(mem); tcp_data_callback_called = 0; uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; @@ -824,15 +827,15 @@ static int tcp_oobdata_callback(void *object, const uint8_t *public_key, unsigne static void test_tcp_connection2(void) { - const Random *rng = system_random(); + const Random *rng = os_random(); ck_assert(rng != nullptr); - const Network *ns = system_network(); + const Network *ns = os_network(); ck_assert(ns != nullptr); - const Memory *mem = system_memory(); + const Memory *mem = os_memory(); ck_assert(mem != nullptr); - Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); - Logger *logger = logger_new(); + Mono_Time *mono_time = mono_time_new(mem, nullptr); + Logger *logger = logger_new(mem); tcp_oobdata_callback_called = 0; tcp_data_callback_called = 0; diff --git a/auto_tests/announce_test.c b/auto_tests/announce_test.c index f0929c757c6..78d91895ed1 100644 --- a/auto_tests/announce_test.c +++ b/auto_tests/announce_test.c @@ -7,13 +7,16 @@ #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" static void test_bucketnum(void) { - const Random *rng = system_random(); + const Random *rng = os_random(); ck_assert(rng != nullptr); uint8_t key1[CRYPTO_PUBLIC_KEY_SIZE], key2[CRYPTO_PUBLIC_KEY_SIZE]; random_bytes(rng, key1, sizeof(key1)); @@ -50,20 +53,20 @@ static void test_announce_data(void *object, const uint8_t *data, uint16_t lengt static void test_store_data(void) { - const Random *rng = system_random(); + const Random *rng = os_random(); ck_assert(rng != nullptr); - const Network *ns = system_network(); + const Network *ns = os_network(); ck_assert(ns != nullptr); - const Memory *mem = system_memory(); + const Memory *mem = os_memory(); ck_assert(mem != nullptr); - Logger *log = logger_new(); + 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); Networking_Core *net = new_networking_no_udp(log, mem, ns); DHT *dht = new_dht(log, mem, rng, ns, mono_time, net, true, true); - Forwarding *forwarding = new_forwarding(log, rng, mono_time, dht); + Forwarding *forwarding = new_forwarding(log, mem, rng, mono_time, dht); 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 320acc4bc70..604cc78c3cd 100644 --- a/auto_tests/auto_test_support.c +++ b/auto_tests/auto_test_support.c @@ -6,6 +6,7 @@ #include "../toxcore/Messenger.h" #include "../toxcore/mono_time.h" #include "../toxcore/tox_struct.h" +#include "../toxcore/tox_time_impl.h" #include "auto_test_support.h" @@ -159,15 +160,23 @@ 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; autotox->clock = current_time_monotonic(mono_time); - 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, nullptr); // set to default first + mono_time_set_current_time_callback(mono_time, autotox->tm); } void save_autotox(AutoTox *autotox) @@ -193,6 +202,8 @@ void kill_autotox(AutoTox *autotox) fprintf(stderr, "Killing #%u\n", autotox->index); autotox->alive = false; tox_kill(autotox->tox); + tox_time_free(autotox->tm); + autotox->tm = nullptr; } void reload(AutoTox *autotox) @@ -380,6 +391,7 @@ void run_auto_test(struct Tox_Options *options, uint32_t tox_count, void test(Au for (uint32_t i = 0; i < tox_count; ++i) { 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 eab121aa367..10a250a0ffa 100644 --- a/auto_tests/auto_test_support.h +++ b/auto_tests/auto_test_support.h @@ -10,6 +10,7 @@ typedef struct AutoTox { Tox *tox; + 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 c366be42dc4..248f1ddb8ec 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 @@ -291,7 +292,7 @@ static void do_audio(AutoTox *autotoxes, uint32_t iterations) static void run_conference_tests(AutoTox *autotoxes) { - const Random *rng = system_random(); + const Random *rng = os_random(); ck_assert(rng != nullptr); bool disabled[NUM_AV_GROUP_TOX] = {0}; diff --git a/auto_tests/conference_test.c b/auto_tests/conference_test.c index 66edddd85c7..d7e3fe6283c 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" @@ -192,7 +193,7 @@ static uint32_t random_false_index(const Random *rng, bool *list, const uint32_t static void run_conference_tests(AutoTox *autotoxes) { - const Random *rng = system_random(); + const Random *rng = os_random(); ck_assert(rng != nullptr); /* disabling name change propagation check for now, as it occasionally * fails due to disconnections too short to trigger freezing */ diff --git a/auto_tests/crypto_test.c b/auto_tests/crypto_test.c index 36da0413064..fc0c04360e2 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,7 +133,9 @@ static void test_fast_known(void) static void test_endtoend(void) { - const Random *rng = system_random(); + const Memory *mem = os_memory(); + ck_assert(mem != nullptr); + const Random *rng = os_random(); ck_assert(rng != nullptr); // Test 100 random messages and keypairs @@ -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,7 +202,9 @@ static void test_endtoend(void) static void test_large_data(void) { - const Random *rng = system_random(); + 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]; uint8_t n[CRYPTO_NONCE_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 Random *rng = system_random(); + 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"); @@ -292,7 +307,7 @@ static void increment_nonce_number_cmp(uint8_t *nonce, uint32_t num) static void test_increment_nonce(void) { - const Random *rng = system_random(); + const Random *rng = os_random(); ck_assert(rng != nullptr); uint8_t n[CRYPTO_NONCE_SIZE]; diff --git a/auto_tests/encryptsave_test.c b/auto_tests/encryptsave_test.c index fb49c4e2af2..cd56f65710b 100644 --- a/auto_tests/encryptsave_test.c +++ b/auto_tests/encryptsave_test.c @@ -9,6 +9,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" @@ -169,7 +170,7 @@ static void test_keys(void) ck_assert(encrypted2a != nullptr); uint8_t *in_plaintext2a = (uint8_t *)malloc(plaintext_length2a); ck_assert(in_plaintext2a != nullptr); - const Random *rng = system_random(); + const Random *rng = os_random(); ck_assert(rng != nullptr); random_bytes(rng, in_plaintext2a, plaintext_length2a); ret = tox_pass_encrypt(in_plaintext2a, plaintext_length2a, key_char, 12, encrypted2a, &encerr); diff --git a/auto_tests/forwarding_test.c b/auto_tests/forwarding_test.c index f9c82784f20..f7e9336e215 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" @@ -104,18 +107,18 @@ typedef struct Forwarding_Subtox { static Forwarding_Subtox *new_forwarding_subtox(const Memory *mem, bool no_udp, uint32_t *index, uint16_t port) { - const Random *rng = system_random(); + const Random *rng = os_random(); ck_assert(rng != nullptr); - const Network *ns = system_network(); + const Network *ns = os_network(); ck_assert(ns != nullptr); Forwarding_Subtox *subtox = (Forwarding_Subtox *)calloc(1, sizeof(Forwarding_Subtox)); ck_assert(subtox != nullptr); - subtox->log = logger_new(); + 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); @@ -152,11 +155,11 @@ static void kill_forwarding_subtox(const Memory *mem, Forwarding_Subtox *subtox) static void test_forwarding(void) { - const Memory *mem = system_memory(); + const Memory *mem = os_memory(); ck_assert(mem != nullptr); - const Random *rng = system_random(); + const Random *rng = os_random(); ck_assert(rng != nullptr); - const Network *ns = system_network(); + const Network *ns = os_network(); ck_assert(ns != nullptr); uint32_t index[NUM_FORWARDER]; diff --git a/auto_tests/group_message_test.c b/auto_tests/group_message_test.c index d7a00a9fee0..8d5d7cc64d3 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 { @@ -334,7 +335,7 @@ static void group_message_test(AutoTox *autotoxes) #ifndef VANILLA_NACL ck_assert_msg(NUM_GROUP_TOXES >= 2, "NUM_GROUP_TOXES is too small: %d", NUM_GROUP_TOXES); - const Random *rng = system_random(); + const Random *rng = os_random(); ck_assert(rng != nullptr); Tox *tox0 = autotoxes[0].tox; diff --git a/auto_tests/group_sync_test.c b/auto_tests/group_sync_test.c index 4d2bc1866dc..fdd895ed344 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" @@ -332,7 +333,7 @@ static void group_sync_test(AutoTox *autotoxes) { #ifndef VANILLA_NACL ck_assert(NUM_GROUP_TOXES >= 5); - const Random *rng = system_random(); + const Random *rng = os_random(); ck_assert(rng != nullptr); for (size_t i = 0; i < NUM_GROUP_TOXES; ++i) { diff --git a/auto_tests/group_topic_test.c b/auto_tests/group_topic_test.c index 26dafcb459a..00fff8555d8 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 @@ -206,7 +207,7 @@ static void group_topic_test(AutoTox *autotoxes) #ifndef VANILLA_NACL ck_assert_msg(NUM_GROUP_TOXES >= 3, "NUM_GROUP_TOXES is too small: %d", NUM_GROUP_TOXES); - const Random *rng = system_random(); + const Random *rng = os_random(); ck_assert(rng != nullptr); Tox *tox0 = autotoxes[0].tox; diff --git a/auto_tests/lan_discovery_test.c b/auto_tests/lan_discovery_test.c index d7bf594b2bf..8ea4e39764c 100644 --- a/auto_tests/lan_discovery_test.c +++ b/auto_tests/lan_discovery_test.c @@ -3,6 +3,8 @@ #include "../testing/misc_tools.h" #include "../toxcore/ccompat.h" +#include "../toxcore/os_memory.h" +#include "../toxcore/tox_time_impl.h" #include "../toxcore/tox_struct.h" #include "auto_test_support.h" @@ -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 df3b625a9e1..f96618385e2 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 @@ -20,7 +21,7 @@ static void test_addr_resolv_localhost(void) errno = 0; #endif - const Network *ns = system_network(); + const Network *ns = os_network(); ck_assert(ns != nullptr); const char localhost[] = "localhost"; diff --git a/auto_tests/onion_test.c b/auto_tests/onion_test.c index 6975c3ec300..f5cb93b98a7 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; @@ -148,7 +151,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; @@ -185,7 +188,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; @@ -204,10 +207,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"); } @@ -223,20 +226,20 @@ static Networking_Core *new_networking(const Logger *log, const Memory *mem, con static void test_basic(void) { uint32_t index[] = { 1, 2, 3 }; - const Network *ns = system_network(); + const Network *ns = os_network(); ck_assert(ns != nullptr); - const Memory *mem = system_memory(); + const Memory *mem = os_memory(); ck_assert(mem != nullptr); - const Random *rng = system_random(); + const Random *rng = os_random(); ck_assert(rng != nullptr); - Logger *log1 = logger_new(); + Logger *log1 = logger_new(mem); logger_callback_log(log1, print_debug_logger, nullptr, &index[0]); - Logger *log2 = logger_new(); + 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)); @@ -266,7 +269,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; @@ -293,7 +296,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(onion1->net, rng, &path, &nodes[3], + int ret = send_announce_request(onion1->net, rng, mem, &path, &nodes[3], dht_get_self_public_key(onion1->dht), dht_get_self_secret_key(onion1->dht), zeroes, @@ -315,7 +318,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(onion1->net, rng, &path, &nodes[3], + send_announce_request(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, @@ -331,16 +334,16 @@ static void test_basic(void) CRYPTO_PUBLIC_KEY_SIZE) != 0); c_sleep(1000); - Logger *log3 = logger_new(); + 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(onion3->net, rng, &path, &nodes[3].ip_port, + ret = send_data_request(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")); @@ -407,14 +410,14 @@ static Onions *new_onions(const Memory *mem, const Random *rng, uint16_t port, u { IP ip = get_loopback(); ip.ip.v6.uint8[15] = 1; - const Network *ns = system_network(); + const Network *ns = os_network(); Onions *on = (Onions *)malloc(sizeof(Onions)); if (!on) { return nullptr; } - on->log = logger_new(); + on->log = logger_new(mem); if (!on->log) { free(on); @@ -423,7 +426,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); @@ -576,9 +579,9 @@ static void test_announce(void) { uint32_t index[NUM_ONIONS]; Onions *onions[NUM_ONIONS]; - const Random *rng = system_random(); + const Random *rng = os_random(); ck_assert(rng != nullptr); - const Memory *mem = system_memory(); + const Memory *mem = os_memory(); ck_assert(mem != nullptr); for (uint32_t i = 0; i < NUM_ONIONS; ++i) { diff --git a/auto_tests/reconnect_test.c b/auto_tests/reconnect_test.c index 253f66b0c5c..ad6a021f227 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" @@ -51,7 +52,7 @@ static bool all_disconnected_from(uint32_t tox_count, AutoTox *autotoxes, uint32 static void test_reconnect(AutoTox *autotoxes) { - const Random *rng = system_random(); + const Random *rng = os_random(); ck_assert(rng != nullptr); const time_t test_start_time = time(nullptr); diff --git a/auto_tests/save_friend_test.c b/auto_tests/save_friend_test.c index 80a6ed037e8..4a546cc53c6 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" @@ -86,7 +87,7 @@ int main(void) ck_assert(reference_name != nullptr); ck_assert(reference_status != nullptr); - const Random *rng = system_random(); + const Random *rng = os_random(); ck_assert(rng != nullptr); set_random(tox1, rng, tox_self_set_name, tox_max_name_length()); set_random(tox2, rng, tox_self_set_name, tox_max_name_length()); diff --git a/auto_tests/save_load_test.c b/auto_tests/save_load_test.c index 97077735633..41ac2bb48bf 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_time_impl.h" #include "../toxcore/util.h" #include "auto_test_support.h" #include "check_compat.h" @@ -119,6 +121,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); @@ -126,10 +132,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) @@ -161,9 +167,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); @@ -257,6 +266,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 209e13788f2..c887176717b 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) } } -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); @@ -64,7 +64,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. @@ -103,7 +103,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 04549b2179c..9bc211fd33d 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_time_impl.h" #include "auto_test_support.h" #include "check_compat.h" @@ -43,6 +45,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) { @@ -59,13 +64,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); @@ -113,6 +122,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 0fda9181fe9..efa320471eb 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" @@ -41,7 +42,7 @@ static uint16_t tcp_relay_port = 33448; static void test_many_clients_tcp(void) { - const Random *rng = system_random(); + const Random *rng = os_random(); ck_assert(rng != nullptr); long long unsigned int cur_time = time(nullptr); Tox *toxes[NUM_TOXES_TCP]; @@ -143,7 +144,7 @@ static void test_many_clients_tcp(void) static void test_many_clients_tcp_b(void) { - const Random *rng = system_random(); + const Random *rng = os_random(); ck_assert(rng != nullptr); long long unsigned int cur_time = time(nullptr); Tox *toxes[NUM_TOXES_TCP]; diff --git a/auto_tests/tox_many_test.c b/auto_tests/tox_many_test.c index 8501b5c172a..da44f23c4e2 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" @@ -26,7 +27,7 @@ static void accept_friend_request(Tox *m, const uint8_t *public_key, const uint8 static void test_many_clients(void) { - const Random *rng = system_random(); + const Random *rng = os_random(); ck_assert(rng != nullptr); time_t cur_time = time(nullptr); Tox *toxes[TCP_TEST_NUM_TOXES]; diff --git a/auto_tests/toxav_many_test.c b/auto_tests/toxav_many_test.c index b1f2f9fa946..9220c6f7cc3 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_time_impl.h" #include "../toxcore/util.h" #include "auto_test_support.h" #include "check_compat.h" @@ -144,6 +146,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); @@ -151,10 +157,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) @@ -168,6 +174,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_Err_New error; @@ -175,23 +185,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(nullptr, &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(nullptr, &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(nullptr, &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(nullptr, &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); } printf("Created 5 instances of Tox\n"); @@ -367,6 +377,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 04dbf16d7a5..a5acbf34667 100644 --- a/cmake/ModulePackage.cmake +++ b/cmake/ModulePackage.cmake @@ -70,6 +70,7 @@ function(add_module lib) endfunction() function(install_module lib) + cmake_parse_arguments(INSTALL_MODULE "" "DESTINATION" "" ${ARGN}) if(ENABLE_SHARED) set_target_properties(${lib}_shared PROPERTIES VERSION ${SOVERSION} @@ -109,8 +110,11 @@ 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 22b1ca447af..0a17f561ded 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 '\\w+' | 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 1a8929a3758..4ed80ec49c4 100644 --- a/other/BUILD.bazel +++ b/other/BUILD.bazel @@ -28,6 +28,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", "//c-toxcore/toxcore:util", ], diff --git a/other/DHT_bootstrap.c b/other/DHT_bootstrap.c index cb469bfdce9..b5d2e6815c4 100644 --- a/other/DHT_bootstrap.c +++ b/other/DHT_bootstrap.c @@ -20,6 +20,9 @@ #include "../toxcore/group_onion_announce.h" #include "../toxcore/logger.h" #include "../toxcore/mono_time.h" +#include "../toxcore/os_memory.h" +#include "../toxcore/os_network.h" +#include "../toxcore/os_random.h" #include "../toxcore/tox.h" #include "../toxcore/util.h" @@ -132,23 +135,23 @@ int main(int argc, char *argv[]) IP ip; ip_init(&ip, ipv6enabled); - Logger *logger = logger_new(); + const Random *rng = os_random(); + const Network *ns = os_network(); + const Memory *mem = os_memory(); + + Logger *logger = logger_new(mem); if (MIN_LOGGER_LEVEL <= LOGGER_LEVEL_DEBUG) { logger_callback_log(logger, print_log, nullptr, nullptr); } - const Random *rng = system_random(); - const Network *ns = system_network(); - const Memory *mem = system_memory(); - - 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 @@ -224,7 +227,7 @@ int main(int argc, char *argv[]) int is_waiting_for_dht_connection = 1; uint64_t last_lan_discovery = 0; - const Broadcast_Info *broadcast = lan_discovery_init(ns); + const Broadcast_Info *broadcast = lan_discovery_init(mem, ns); while (1) { mono_time_update(mono_time); diff --git a/other/analysis/run-clang b/other/analysis/run-clang index c18464071e6..f5ec50f4a23 100755 --- a/other/analysis/run-clang +++ b/other/analysis/run-clang @@ -10,7 +10,7 @@ run() { "${CPPFLAGS[@]}" \ "${LDFLAGS[@]}" \ "$@" \ - -std=c++11 \ + -std=c++17 \ -Werror \ -Weverything \ -Wno-alloca \ diff --git a/other/analysis/run-clang-analyze b/other/analysis/run-clang-analyze index 05e94e78bd8..5ed9ff3041f 100755 --- a/other/analysis/run-clang-analyze +++ b/other/analysis/run-clang-analyze @@ -9,7 +9,7 @@ run() { clang++ --analyze amalgamation.cc \ "${CPPFLAGS[@]}" \ "$@" \ - -std=c++11 + -std=c++17 } . other/analysis/variants.sh diff --git a/other/analysis/run-clang-tidy b/other/analysis/run-clang-tidy index a87b517b31c..4341efbf4ee 100755 --- a/other/analysis/run-clang-tidy +++ b/other/analysis/run-clang-tidy @@ -10,6 +10,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-gcc b/other/analysis/run-gcc index ce3338c5567..8a49b32585c 100755 --- a/other/analysis/run-gcc +++ b/other/analysis/run-gcc @@ -11,7 +11,7 @@ run() { "${CPPFLAGS[@]}" \ "${LDFLAGS[@]}" \ "$@" \ - -std=c++11 \ + -std=c++17 \ -fdiagnostics-color=always \ -Wall \ -Wextra \ diff --git a/other/bootstrap_daemon/BUILD.bazel b/other/bootstrap_daemon/BUILD.bazel index e1a2e41f449..8e083558b77 100644 --- a/other/bootstrap_daemon/BUILD.bazel +++ b/other/bootstrap_daemon/BUILD.bazel @@ -19,6 +19,9 @@ cc_binary( "//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", "//c-toxcore/toxcore:util", "@libconfig", diff --git a/other/bootstrap_daemon/docker/Dockerfile b/other/bootstrap_daemon/docker/Dockerfile index a62a48827a8..4952e4645b9 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/docker/tox-bootstrapd.sha256 b/other/bootstrap_daemon/docker/tox-bootstrapd.sha256 index 61ec91a60b2..af860e014c9 100644 --- a/other/bootstrap_daemon/docker/tox-bootstrapd.sha256 +++ b/other/bootstrap_daemon/docker/tox-bootstrapd.sha256 @@ -1 +1 @@ -619d28e6ecd0dbfbf8727753d44aa7eb1d8baa53cfcd4067f426141b4c132784 /usr/local/bin/tox-bootstrapd +7a32a026ddb175110bfcb696074328e6b01a30c20123d2bcd76cb8b65ef7eeb2 /usr/local/bin/tox-bootstrapd diff --git a/other/bootstrap_daemon/src/tox-bootstrapd.c b/other/bootstrap_daemon/src/tox-bootstrapd.c index 8d0e31839aa..c5e7e160c9a 100644 --- a/other/bootstrap_daemon/src/tox-bootstrapd.c +++ b/other/bootstrap_daemon/src/tox-bootstrapd.c @@ -33,6 +33,9 @@ #include "../../../toxcore/logger.h" #include "../../../toxcore/mono_time.h" #include "../../../toxcore/onion_announce.h" +#include "../../../toxcore/os_memory.h" +#include "../../../toxcore/os_network.h" +#include "../../../toxcore/os_random.h" #include "../../../toxcore/util.h" // misc @@ -262,16 +265,17 @@ int main(int argc, char *argv[]) IP ip; ip_init(&ip, enable_ipv6); - Logger *logger = logger_new(); + const Memory *mem = os_memory(); + const Random *rng = os_random(); + const Network *ns = os_network(); + + Logger *logger = logger_new(mem); if (MIN_LOGGER_LEVEL <= LOGGER_LEVEL_DEBUG) { logger_callback_log(logger, toxcore_logger_callback, nullptr, nullptr); } const uint16_t end_port = start_port + (TOX_PORTRANGE_TO - TOX_PORTRANGE_FROM); - const Memory *mem = system_memory(); - const Random *rng = system_random(); - const Network *ns = system_network(); Networking_Core *net = new_networking_ex(logger, mem, ns, &ip, start_port, end_port, nullptr); if (net == nullptr) { @@ -299,7 +303,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"); @@ -326,7 +330,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"); @@ -355,7 +359,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"); @@ -540,7 +544,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/testing/BUILD.bazel b/testing/BUILD.bazel index 68e89a15918..b9c0f63f31d 100644 --- a/testing/BUILD.bazel +++ b/testing/BUILD.bazel @@ -57,5 +57,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 4c2c8f85ffb..a5548c86810 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, @@ -92,8 +95,8 @@ int main(int argc, char *argv[]) exit(0); } - const Memory *mem = system_memory(); - Mono_Time *const mono_time = mono_time_new(mem, nullptr, nullptr); + const Memory *mem = os_memory(); + Mono_Time *const mono_time = mono_time_new(mem, nullptr); if (mono_time == nullptr) { fputs("Failed to allocate monotonic timer datastructure\n", stderr); @@ -103,7 +106,7 @@ int main(int argc, char *argv[]) Messenger_Options options = {0}; options.ipv6enabled = ipv6enabled; Messenger_Error err; - m = new_messenger(mono_time, mem, system_random(), system_network(), &options, &err); + m = new_messenger(mono_time, mem, os_random(), os_network(), &options, &err); if (!m) { fprintf(stderr, "Failed to allocate messenger datastructure: %d\n", err); diff --git a/testing/fuzzing/BUILD.bazel b/testing/fuzzing/BUILD.bazel index 386516d72bf..68696f7ef09 100644 --- a/testing/fuzzing/BUILD.bazel +++ b/testing/fuzzing/BUILD.bazel @@ -15,7 +15,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_harness.cc b/testing/fuzzing/bootstrap_harness.cc index 9ffb69d1f1b..ee98f84608b 100644 --- a/testing/fuzzing/bootstrap_harness.cc +++ b/testing/fuzzing/bootstrap_harness.cc @@ -107,6 +107,9 @@ void setup_callbacks(Tox_Dispatch *dispatch) void TestBootstrap(Fuzz_Data &input) { + // Null system for regularly working memory allocations needed in + // tox_events_equal. + Null_System null_sys; Fuzz_System sys(input); Ptr opts(tox_options_new(nullptr), tox_options_free); @@ -154,11 +157,8 @@ void TestBootstrap(Fuzz_Data &input) uint8_t pub_key[TOX_PUBLIC_KEY_SIZE] = {0}; - const bool udp_success = tox_bootstrap(tox, "127.0.0.2", 33446, pub_key, nullptr); - assert(udp_success); - - const bool tcp_success = tox_add_tcp_relay(tox, "127.0.0.2", 33446, pub_key, nullptr); - assert(tcp_success); + tox_bootstrap(tox, "127.0.0.2", 33446, pub_key, nullptr); + tox_add_tcp_relay(tox, "127.0.0.2", 33446, pub_key, nullptr); tox_events_init(tox); @@ -169,7 +169,7 @@ void TestBootstrap(Fuzz_Data &input) while (input.size > 0) { Tox_Err_Events_Iterate error_iterate; Tox_Events *events = tox_events_iterate(tox, true, &error_iterate); - assert(tox_events_equal(sys.sys.get(), events, events)); + assert(tox_events_equal(null_sys.sys.get(), events, events)); tox_dispatch_invoke(dispatch, events, tox, nullptr); tox_events_free(events); // Move the clock forward a decent amount so all the time-based checks diff --git a/testing/fuzzing/e2e_fuzz_test.cc b/testing/fuzzing/e2e_fuzz_test.cc index f5258853e5c..868db2165db 100644 --- a/testing/fuzzing/e2e_fuzz_test.cc +++ b/testing/fuzzing/e2e_fuzz_test.cc @@ -155,12 +155,7 @@ void TestEndToEnd(Fuzz_Data &input) Tox_Err_New error_new; 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 - // might do things that make that I/O fail. - return; - } - + // tox_new never fails, because we execute a recorded successful trace. assert(error_new == TOX_ERR_NEW_OK); tox_events_init(tox); diff --git a/testing/fuzzing/fuzz_support.cc b/testing/fuzzing/fuzz_support.cc index 510a6563f33..6c9b14165ff 100644 --- a/testing/fuzzing/fuzz_support.cc +++ b/testing/fuzzing/fuzz_support.cc @@ -17,17 +17,16 @@ #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.h" const bool DEBUG = false; -// TODO(iphydf): Put this somewhere shared. -struct Network_Addr { - struct sockaddr_storage addr; - size_t size; -}; - System::~System() { } static int recv_common(Fuzz_Data &input, uint8_t *buf, size_t buf_len) @@ -72,15 +71,11 @@ static void *alloc_common(Fuzz_Data &data, F func) return func(); } -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(self->data, [=]() { return std::malloc(size); }); }, - /* .calloc = */ - ![](Fuzz_System *self, uint32_t nmemb, uint32_t size) { - return alloc_common(self->data, [=]() { return std::calloc(nmemb, size); }); - }, /* .realloc = */ ![](Fuzz_System *self, void *ptr, uint32_t size) { return alloc_common(self->data, [=]() { return std::realloc(ptr, size); }); @@ -89,7 +84,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, int sock) { return 0; }, /* .accept = */ ![](Fuzz_System *self, int sock) { return 1337; }, /* .bind = */ ![](Fuzz_System *self, int sock, const Network_Addr *addr) { return 0; }, @@ -109,16 +104,14 @@ static constexpr Network_Funcs fuzz_network_funcs = { /* .recvfrom = */ ![](Fuzz_System *self, int sock, uint8_t *buf, size_t len, Network_Addr *addr) { assert(sock == 42 || sock == 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); }, @@ -147,7 +140,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 @@ -165,7 +158,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; } @@ -173,34 +166,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 = ![](Fuzz_System *self) { return 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, int sock) { return 0; }, /* .accept = */ ![](Null_System *self, int sock) { return 1337; }, /* .bind = */ ![](Null_System *self, int sock, const Network_Addr *addr) { return 0; }, @@ -248,7 +244,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) { @@ -264,36 +260,27 @@ 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 = ![](Fuzz_System *self) { return 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 Tox_Memory_Funcs record_memory_funcs = null_memory_funcs; -static constexpr Memory_Funcs record_memory_funcs = null_memory_funcs; - -static constexpr Network_Funcs record_network_funcs = { +static constexpr Tox_Network_Funcs record_network_funcs = { /* .close = */ ![](Record_System *self, int sock) { return 0; }, /* .accept = */ ![](Record_System *self, int sock) { return 2; }, /* .bind = */ ![](Record_System *self, int 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; @@ -313,6 +300,7 @@ static constexpr Network_Funcs record_network_funcs = { /* .recvfrom = */ ![](Record_System *self, int sock, uint8_t *buf, size_t len, Network_Addr *addr) { assert(sock == 42); + assert(addr != nullptr); if (self->recvq.empty()) { self->recording.push_back(0xff); self->recording.push_back(0xff); @@ -327,15 +315,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->recording.push_back(recvlen >> 8); @@ -355,7 +341,8 @@ static constexpr Network_Funcs record_network_funcs = { /* .sendto = */ ![](Record_System *self, int sock, const uint8_t *buf, size_t len, const Network_Addr *addr) { assert(sock == 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); @@ -373,7 +360,7 @@ static constexpr Network_Funcs record_network_funcs = { }, }; -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) { @@ -386,7 +373,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) @@ -395,16 +382,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 = ![](Fuzz_System *self) { return 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.h b/testing/fuzzing/fuzz_support.h index a20d85b4f2e..e52e4cc7828 100644 --- a/testing/fuzzing/fuzz_support.h +++ b/testing/fuzzing/fuzz_support.h @@ -117,15 +117,17 @@ void fuzz_select_target(const uint8_t *data, std::size_t size, Args &&... args) return fuzz_select_target(selector, input, std::forward(args)...); } -struct Memory; -struct Network; -struct Random; +struct Tox_Memory; +struct Tox_Network; +struct Tox_Random; +struct Tox_Time; struct 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; // Not inline because sizeof of the above 2 structs is not known everywhere. ~System(); diff --git a/testing/fuzzing/fuzz_tox.h b/testing/fuzzing/fuzz_tox.h index b5864e78d3a..8ca359b18b1 100644 --- a/testing/fuzzing/fuzz_tox.h +++ b/testing/fuzzing/fuzz_tox.h @@ -11,6 +11,7 @@ #include "../../toxcore/DHT.h" #include "../../toxcore/logger.h" #include "../../toxcore/network.h" +#include "../../toxcore/os_memory.h" #include "fuzz_support.h" constexpr uint16_t SIZE_IP_PORT = SIZE_IP6 + sizeof(uint16_t); @@ -37,7 +38,7 @@ struct with { template void operator>>(F &&f) { - Ptr logger(logger_new(), logger_kill); + Ptr logger(logger_new(os_memory()), logger_kill); assert(logger != nullptr); f(std::move(logger)); } diff --git a/tox.h b/tox.h new file mode 100644 index 00000000000..4209883cf60 --- /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 00000000000..83e5daa8e64 --- /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/BUILD.bazel b/toxav/BUILD.bazel index ca88f1334aa..c3f3423a89a 100644 --- a/toxav/BUILD.bazel +++ b/toxav/BUILD.bazel @@ -81,6 +81,7 @@ cc_test( deps = [ ":rtp", "//c-toxcore/toxcore:crypto_core", + "//c-toxcore/toxcore:os_random", "@com_google_googletest//:gtest", "@com_google_googletest//:gtest_main", ], diff --git a/toxav/Makefile.inc b/toxav/Makefile.inc index 7b7881985c4..931d6445941 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/rtp_test.cc b/toxav/rtp_test.cc index b29c937ac91..24e5244804d 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 { @@ -29,7 +30,7 @@ RTPHeader random_header(const Random *rng) TEST(Rtp, Deserialisation) { - const Random *rng = system_random(); + const Random *rng = os_random(); ASSERT_NE(rng, nullptr); RTPHeader const header = random_header(rng); diff --git a/toxav/toxav.c b/toxav/toxav.c index bdec43b504a..c9a3d1db70a 100644 --- a/toxav/toxav.c +++ b/toxav/toxav.c @@ -181,7 +181,7 @@ ToxAV *toxav_new(Tox *tox, Toxav_Err_New *error) av->tox = tox; av->m = m; - av->toxav_mono_time = mono_time_new(tox->sys.mem, nullptr, nullptr); + av->toxav_mono_time = mono_time_new(tox->sys.mem, nullptr); av->msi = msi_new(av->m); if (av->msi == nullptr) { diff --git a/toxcore/BUILD.bazel b/toxcore/BUILD.bazel index 4701cf437d3..499dea04972 100644 --- a/toxcore/BUILD.bazel +++ b/toxcore/BUILD.bazel @@ -4,14 +4,38 @@ load("//tools:no_undefined.bzl", "cc_library") package(features = ["layering_check"]) -exports_files( - srcs = ["tox.h"], +sh_library( + name = "public", + srcs = [ + "os_log.h", + "os_memory.h", + "os_network.h", + "os_random.h", + "os_system.h", + "tox.h", + "tox_attributes.h", + "tox_dispatch.h", + "tox_events.h", + "tox_log.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:__pkg__"], ) cc_library( - name = "attributes", - hdrs = ["attributes.h"], + name = "tox_attributes", + hdrs = ["tox_attributes.h"], visibility = ["//c-toxcore:__subpackages__"], ) @@ -20,7 +44,163 @@ cc_library( srcs = ["ccompat.c"], hdrs = ["ccompat.h"], visibility = ["//c-toxcore:__subpackages__"], - deps = [":attributes"], + deps = [":tox_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", + srcs = ["tox_log.c"], + hdrs = [ + "tox_log.h", + "tox_log_impl.h", + ], + visibility = ["//c-toxcore:__subpackages__"], + deps = [ + ":ccompat", + ":tox_attributes", + ":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 = [ + ":ccompat", + ":tox_log", + ], +) + +cc_library( + name = "os_memory", + srcs = ["os_memory.c"], + hdrs = ["os_memory.h"], + visibility = ["//c-toxcore:__subpackages__"], + deps = [ + ":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 = [ + ":ccompat", + ":tox_network", + ], +) + +cc_library( + name = "os_random", + srcs = ["os_random.c"], + hdrs = ["os_random.h"], + visibility = ["//c-toxcore:__subpackages__"], + deps = [ + ":ccompat", + ":tox_random", + "@libsodium", + ], +) + +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", + ":tox_system", + ], ) cc_library( @@ -29,8 +209,9 @@ cc_library( hdrs = ["mem.h"], visibility = ["//c-toxcore:__subpackages__"], deps = [ - ":attributes", ":ccompat", + ":tox_attributes", + ":tox_memory", ], ) @@ -40,6 +221,7 @@ cc_test( srcs = ["mem_test.cc"], deps = [ ":mem", + ":os_memory", "@com_google_googletest//:gtest", "@com_google_googletest//:gtest_main", ], @@ -57,9 +239,9 @@ cc_library( "//c-toxcore/toxav:__pkg__", ], deps = [ - ":attributes", ":ccompat", ":mem", + ":tox_attributes", "@pthread", ], ) @@ -70,6 +252,7 @@ cc_test( srcs = ["util_test.cc"], deps = [ ":crypto_core", + ":os_random", ":util", "@com_google_googletest//:gtest", "@com_google_googletest//:gtest_main", @@ -82,8 +265,9 @@ cc_library( hdrs = ["bin_pack.h"], visibility = ["//c-toxcore:__subpackages__"], deps = [ - ":attributes", ":ccompat", + ":mem", + ":tox_attributes", "//c-toxcore/third_party:cmp", ], ) @@ -94,8 +278,9 @@ cc_library( hdrs = ["bin_unpack.h"], visibility = ["//c-toxcore:__subpackages__"], deps = [ - ":attributes", ":ccompat", + ":mem", + ":tox_attributes", "//c-toxcore/third_party:cmp", ], ) @@ -107,6 +292,7 @@ cc_test( deps = [ ":bin_pack", ":bin_unpack", + ":os_memory", "@com_google_googletest//:gtest", "@com_google_googletest//:gtest_main", ], @@ -118,8 +304,10 @@ cc_library( hdrs = ["crypto_core.h"], visibility = ["//c-toxcore:__subpackages__"], deps = [ - ":attributes", ":ccompat", + ":mem", + ":tox_attributes", + ":tox_random", "@libsodium", ], ) @@ -131,6 +319,7 @@ cc_test( flaky = True, deps = [ ":crypto_core", + ":os_random", ":util", "@com_google_googletest//:gtest", "@com_google_googletest//:gtest_main", @@ -142,8 +331,9 @@ cc_library( srcs = ["list.c"], hdrs = ["list.h"], deps = [ - ":attributes", ":ccompat", + ":mem", + ":tox_attributes", ], ) @@ -153,6 +343,7 @@ cc_test( srcs = ["list_test.cc"], deps = [ ":list", + ":os_memory", "@com_google_googletest//:gtest", "@com_google_googletest//:gtest_main", ], @@ -169,8 +360,9 @@ cc_library( "//c-toxcore/toxav:__pkg__", ], deps = [ - ":attributes", ":ccompat", + ":mem", + ":tox_attributes", ], ) @@ -196,9 +388,10 @@ cc_library( "//c-toxcore/toxav:__pkg__", ], deps = [ - ":attributes", ":ccompat", ":mem", + ":tox_attributes", + ":tox_time", "@pthread", ], ) @@ -209,6 +402,8 @@ cc_test( srcs = ["mono_time_test.cc"], deps = [ ":mono_time", + ":os_memory", + ":tox_time", "@com_google_googletest//:gtest", "@com_google_googletest//:gtest_main", ], @@ -250,6 +445,8 @@ cc_library( ":logger", ":mem", ":mono_time", + ":os_network", + ":tox_network", ":util", "@libsodium", "@psocket", @@ -298,6 +495,8 @@ cc_test( srcs = ["ping_array_test.cc"], deps = [ ":mono_time", + ":os_memory", + ":os_random", ":ping_array", "@com_google_googletest//:gtest", "@com_google_googletest//:gtest_main", @@ -338,7 +537,6 @@ cc_library( ], deps = [ ":LAN_discovery", - ":attributes", ":ccompat", ":crypto_core", ":logger", @@ -348,6 +546,7 @@ cc_library( ":ping_array", ":shared_key_cache", ":state", + ":tox_attributes", ":util", ], ) @@ -359,6 +558,9 @@ cc_test( deps = [ ":DHT", ":crypto_core", + ":os_memory", + ":os_network", + ":os_random", "@com_google_googletest//:gtest", "@com_google_googletest//:gtest_main", ], @@ -370,6 +572,7 @@ cc_fuzz_test( corpus = ["//tools/toktok-fuzzer/corpus:DHT_fuzz_test"], deps = [ ":DHT", + ":os_memory", "//c-toxcore/testing/fuzzing:fuzz_support", ], ) @@ -409,6 +612,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", ], @@ -438,11 +643,11 @@ cc_library( hdrs = ["TCP_common.h"], visibility = ["//c-toxcore/auto_tests:__pkg__"], deps = [ - ":attributes", ":ccompat", ":crypto_core", ":mem", ":network", + ":tox_attributes", ], ) @@ -580,6 +785,8 @@ cc_test( deps = [ ":group_announce", ":mono_time", + ":os_memory", + ":tox_time", "@com_google_googletest//:gtest", "@com_google_googletest//:gtest_main", ], @@ -607,6 +814,8 @@ cc_fuzz_test( #corpus = ["//tools/toktok-fuzzer/corpus:group_announce_fuzz_test"], deps = [ ":group_announce", + ":os_memory", + ":tox_time", "//c-toxcore/testing/fuzzing:fuzz_support", ], ) @@ -698,6 +907,8 @@ cc_test( ":crypto_core", ":group_moderation", ":logger", + ":os_memory", + ":os_random", ":util", "@com_google_googletest//:gtest", "@com_google_googletest//:gtest_main", @@ -710,6 +921,7 @@ cc_fuzz_test( corpus = ["//tools/toktok-fuzzer/corpus:group_moderation_fuzz_test"], deps = [ ":group_moderation", + ":os_memory", "//c-toxcore/testing/fuzzing:fuzz_support", ], ) @@ -781,10 +993,12 @@ cc_library( srcs = [ "tox.c", "tox_api.c", + "tox_options.c", "tox_private.c", ], hdrs = [ "tox.h", + "tox_options.h", "tox_private.h", "tox_struct.h", ], @@ -798,6 +1012,9 @@ cc_library( ":mem", ":mono_time", ":network", + ":os_system", + ":tox_log", + ":tox_system", "//c-toxcore/toxencryptsave:defines", ], ) @@ -808,6 +1025,7 @@ cc_test( srcs = ["tox_test.cc"], deps = [ ":crypto_core", + ":os_random", ":tox", "@com_google_googletest//:gtest", "@com_google_googletest//:gtest_main", @@ -820,10 +1038,10 @@ cc_library( hdrs = ["tox_unpack.h"], visibility = ["//c-toxcore:__subpackages__"], deps = [ - ":attributes", ":bin_unpack", ":ccompat", ":tox", + ":tox_attributes", ], ) @@ -836,12 +1054,13 @@ cc_library( hdrs = ["tox_events.h"], visibility = ["//c-toxcore:__subpackages__"], deps = [ - ":attributes", ":bin_pack", ":bin_unpack", ":ccompat", ":mem", ":tox", + ":tox_attributes", + ":tox_system", ":tox_unpack", "//c-toxcore/third_party:cmp", ], @@ -853,8 +1072,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 75907645d6f..0f46db8d8a2 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c @@ -277,7 +277,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; @@ -293,7 +293,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); @@ -309,7 +309,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) { @@ -328,7 +328,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); @@ -430,7 +430,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 == -1) { mem_delete(mem, encrypted); @@ -970,7 +970,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; } @@ -1479,7 +1479,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; @@ -1539,7 +1539,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 ((unsigned int)len != SIZEOF_VLA(plain)) { return false; @@ -2219,7 +2219,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; @@ -2553,7 +2553,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 d4fc33dc4d5..3725a40d90c 100644 --- a/toxcore/DHT.h +++ b/toxcore/DHT.h @@ -11,7 +11,7 @@ #include -#include "attributes.h" +#include "tox_attributes.h" #include "crypto_core.h" #include "logger.h" #include "mem.h" @@ -115,7 +115,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. @@ -142,7 +142,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 e9673ae0ee5..7588ad2af3a 100644 --- a/toxcore/DHT_fuzz_test.cc +++ b/toxcore/DHT_fuzz_test.cc @@ -4,6 +4,7 @@ #include #include "../testing/fuzzing/fuzz_support.h" +#include "os_memory.h" namespace { @@ -15,8 +16,8 @@ void TestHandleRequest(Fuzz_Data &input) uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; 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); + handle_request(self_public_key, self_secret_key, public_key, request, &request_id, input.data, + input.size, os_memory()); } void TestUnpackNodes(Fuzz_Data &input) @@ -29,7 +30,7 @@ void TestUnpackNodes(Fuzz_Data &input) const int packed_count = unpack_nodes(nodes, node_count, &processed_data_len, input.data, input.size, tcp_enabled); if (packed_count > 0) { - Logger *logger = logger_new(); + Logger *logger = logger_new(os_memory()); std::vector packed(packed_count * PACKED_NODE_SIZE_IP6); const int packed_size = pack_nodes(logger, packed.data(), packed.size(), nodes, packed_count); diff --git a/toxcore/DHT_test.cc b/toxcore/DHT_test.cc index 84d3b9820a1..9f456e86e2f 100644 --- a/toxcore/DHT_test.cc +++ b/toxcore/DHT_test.cc @@ -6,6 +6,9 @@ #include #include "crypto_core.h" +#include "os_memory.h" +#include "os_network.h" +#include "os_random.h" namespace { @@ -36,7 +39,7 @@ PublicKey random_pk(const Random *rng) TEST(IdClosest, IdenticalKeysAreSameDistance) { - const Random *rng = system_random(); + const Random *rng = os_random(); ASSERT_NE(rng, nullptr); PublicKey pk0 = random_pk(rng); @@ -48,7 +51,7 @@ TEST(IdClosest, IdenticalKeysAreSameDistance) TEST(IdClosest, DistanceIsCommutative) { - const Random *rng = system_random(); + const Random *rng = os_random(); ASSERT_NE(rng, nullptr); for (uint32_t i = 0; i < 100; ++i) { @@ -130,7 +133,9 @@ TEST(AddToList, OverridesKeysWithCloserKeys) TEST(Request, CreateAndParse) { - const Random *rng = system_random(); + const Memory *mem = os_memory(); + ASSERT_NE(mem, nullptr); + const Random *rng = os_random(); ASSERT_NE(rng, nullptr); // Peers. @@ -151,31 +156,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( @@ -187,12 +192,12 @@ TEST(Request, CreateAndParse) TEST(AnnounceNodes, SetAndTest) { - const Random *rng = system_random(); - const Network *ns = system_network(); - const Memory *mem = system_memory(); + const Random *rng = os_random(); + const Network *ns = os_network(); + const Memory *mem = os_memory(); - Logger *log = logger_new(); - Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); + Logger *log = logger_new(mem); + Mono_Time *mono_time = mono_time_new(mem, nullptr); Networking_Core *net = new_networking_no_udp(log, mem, ns); DHT *dht = new_dht(log, mem, rng, ns, mono_time, net, true, true); ASSERT_NE(dht, nullptr); diff --git a/toxcore/LAN_discovery.c b/toxcore/LAN_discovery.c index ef44d3b5525..a1f1cf56a60 100644 --- a/toxcore/LAN_discovery.c +++ b/toxcore/LAN_discovery.c @@ -47,6 +47,8 @@ struct Broadcast_Info { + const Memory *mem; + uint32_t count; IP ips[MAX_INTERFACES]; }; @@ -54,28 +56,30 @@ 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 *pAdapterInfo = (IP_ADAPTER_INFO *)malloc(sizeof(IP_ADAPTER_INFO)); + broadcast->mem = mem; + + IP_ADAPTER_INFO *pAdapterInfo = (IP_ADAPTER_INFO *)mem_balloc(mem, sizeof(IP_ADAPTER_INFO)); unsigned long ulOutBufLen = sizeof(IP_ADAPTER_INFO); if (pAdapterInfo == nullptr) { - free(broadcast); + mem_delete(mem, broadcast); return nullptr; } if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) { - free(pAdapterInfo); - pAdapterInfo = (IP_ADAPTER_INFO *)malloc(ulOutBufLen); + mem_delete(mem, pAdapterInfo); + pAdapterInfo = (IP_ADAPTER_INFO *)mem_balloc(mem, ulOutBufLen); if (pAdapterInfo == nullptr) { - free(broadcast); + mem_delete(mem, broadcast); return nullptr; } } @@ -111,7 +115,7 @@ static Broadcast_Info *fetch_broadcast_info(const Network *ns) } if (pAdapterInfo != nullptr) { - free(pAdapterInfo); + mem_delete(mem, pAdapterInfo); } return broadcast; @@ -120,14 +124,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... @@ -135,7 +141,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; } @@ -149,7 +155,7 @@ static Broadcast_Info *fetch_broadcast_info(const Network *ns) if (ioctl(sock.sock, SIOCGIFCONF, &ifc) < 0) { kill_sock(ns, sock); - free(broadcast); + mem_delete(mem, broadcast); return nullptr; } @@ -196,9 +202,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 @@ -376,12 +390,16 @@ bool lan_discovery_send(const Networking_Core *net, const Broadcast_Info *broadc } -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 5d9c83335b6..b97da637758 100644 --- a/toxcore/LAN_discovery.h +++ b/toxcore/LAN_discovery.h @@ -31,7 +31,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 70df82b39e6..71e1ffe787a 100644 --- a/toxcore/Makefile.inc +++ b/toxcore/Makefile.inc @@ -1,25 +1,42 @@ 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/attributes.h \ + ../toxcore/announce.c \ + ../toxcore/announce.h \ ../toxcore/bin_pack.c \ ../toxcore/bin_pack.h \ ../toxcore/bin_unpack.c \ ../toxcore/bin_unpack.h \ ../toxcore/ccompat.c \ ../toxcore/ccompat.h \ + ../toxcore/crypto_core.c \ + ../toxcore/crypto_core.h \ + ../toxcore/DHT.c \ + ../toxcore/DHT.h \ ../toxcore/events/conference_connected.c \ ../toxcore/events/conference_invite.c \ ../toxcore/events/conference_message.c \ ../toxcore/events/conference_peer_list_changed.c \ ../toxcore/events/conference_peer_name.c \ ../toxcore/events/conference_title.c \ + ../toxcore/events/events_alloc.c \ + ../toxcore/events/events_alloc.h \ ../toxcore/events/file_chunk_request.c \ ../toxcore/events/file_recv.c \ ../toxcore/events/file_recv_chunk.c \ @@ -34,90 +51,114 @@ 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/events_alloc.c \ - ../toxcore/events/events_alloc.h \ ../toxcore/events/self_connection_status.c \ - ../toxcore/DHT.h \ - ../toxcore/DHT.c \ - ../toxcore/mem.h \ - ../toxcore/mem.c \ - ../toxcore/mono_time.h \ - ../toxcore/mono_time.c \ - ../toxcore/network.h \ - ../toxcore/network.c \ - ../toxcore/crypto_core.h \ - ../toxcore/crypto_core.c \ - ../toxcore/timed_auth.h \ - ../toxcore/timed_auth.c \ - ../toxcore/ping_array.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/forwarding.c \ + ../toxcore/forwarding.h \ ../toxcore/friend_connection.c \ - ../toxcore/Messenger.h \ - ../toxcore/Messenger.c \ - ../toxcore/ping.h \ - ../toxcore/ping.c \ - ../toxcore/shared_key_cache.h \ - ../toxcore/shared_key_cache.c \ - ../toxcore/state.h \ - ../toxcore/state.c \ - ../toxcore/tox.h \ - ../toxcore/tox.c \ - ../toxcore/tox_dispatch.h \ - ../toxcore/tox_dispatch.c \ - ../toxcore/tox_events.h \ - ../toxcore/tox_events.c \ - ../toxcore/tox_unpack.h \ - ../toxcore/tox_unpack.c \ - ../toxcore/tox_private.c \ - ../toxcore/tox_private.h \ - ../toxcore/tox_struct.h \ - ../toxcore/tox_api.c \ - ../toxcore/util.h \ - ../toxcore/util.c \ - ../toxcore/group.h \ - ../toxcore/group.c \ - ../toxcore/group_announce.h \ + ../toxcore/friend_connection.h \ + ../toxcore/friend_requests.c \ + ../toxcore/friend_requests.h \ ../toxcore/group_announce.c \ - ../toxcore/group_onion_announce.c \ - ../toxcore/group_onion_announce.h \ - ../toxcore/group_chats.h \ + ../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_pack.c \ - ../toxcore/group_pack.h \ + ../toxcore/group.h \ ../toxcore/group_moderation.c \ ../toxcore/group_moderation.h \ - ../toxcore/onion.h \ - ../toxcore/onion.c \ - ../toxcore/logger.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/onion_announce.h \ + ../toxcore/logger.h \ + ../toxcore/mem.c \ + ../toxcore/mem.h \ + ../toxcore/Messenger.c \ + ../toxcore/Messenger.h \ + ../toxcore/mono_time.c \ + ../toxcore/mono_time.h \ + ../toxcore/net_crypto.c \ + ../toxcore/net_crypto.h \ + ../toxcore/network.c \ + ../toxcore/network.h \ ../toxcore/onion_announce.c \ - ../toxcore/onion_client.h \ + ../toxcore/onion_announce.h \ + ../toxcore/onion.c \ ../toxcore/onion_client.c \ - ../toxcore/announce.h \ - ../toxcore/announce.c \ - ../toxcore/forwarding.h \ - ../toxcore/forwarding.c \ - ../toxcore/TCP_client.h \ + ../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/ping_array.c \ + ../toxcore/ping_array.h \ + ../toxcore/ping.c \ + ../toxcore/ping.h \ + ../toxcore/shared_key_cache.c \ + ../toxcore/shared_key_cache.h \ + ../toxcore/state.c \ + ../toxcore/state.h \ ../toxcore/TCP_client.c \ - ../toxcore/TCP_common.h \ + ../toxcore/TCP_client.h \ ../toxcore/TCP_common.c \ - ../toxcore/TCP_server.h \ - ../toxcore/TCP_server.c \ - ../toxcore/TCP_connection.h \ + ../toxcore/TCP_common.h \ ../toxcore/TCP_connection.c \ - ../toxcore/list.c \ - ../toxcore/list.h + ../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.c \ + ../toxcore/tox_dispatch.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_private.c \ + ../toxcore/tox_private.h \ + ../toxcore/tox_random.c \ + ../toxcore/tox_random.h \ + ../toxcore/tox_random_impl.h \ + ../toxcore/tox_struct.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/util.h libtoxcore_la_CFLAGS = -I$(top_srcdir) \ -I$(top_srcdir)/toxcore \ diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index fc28e0c069b..1e56272aa65 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c @@ -3199,7 +3199,7 @@ static uint8_t *groups_save(const Messenger *m, uint8_t *data) non_null() static State_Load_Status groups_load(Messenger *m, const uint8_t *data, uint32_t length) { - Bin_Unpack *bu = bin_unpack_new(data, length); + Bin_Unpack *bu = bin_unpack_new(data, length, m->mem); if (bu == nullptr) { LOGGER_ERROR(m->log, "failed to allocate binary unpacker"); return STATE_LOAD_STATUS_ERROR; @@ -3525,14 +3525,14 @@ 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); return nullptr; } - m->log = logger_new(); + m->log = logger_new(mem); if (m->log == nullptr) { friendreq_kill(m->fr); @@ -3592,7 +3592,7 @@ Messenger *new_messenger(Mono_Time *mono_time, const Memory *mem, const Random * } #ifndef VANILLA_NACL - m->group_announce = new_gca_list(); + m->group_announce = new_gca_list(m->mem); if (m->group_announce == nullptr) { kill_net_crypto(m->net_crypto); @@ -3607,7 +3607,7 @@ Messenger *new_messenger(Mono_Time *mono_time, const Memory *mem, const Random * #endif /* VANILLA_NACL */ 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); m->announce = new_announcements(m->log, m->mem, m->rng, m->mono_time, m->forwarding); } else { m->forwarding = nullptr; @@ -3617,7 +3617,7 @@ Messenger *new_messenger(Mono_Time *mono_time, const Memory *mem, const Random * m->onion = new_onion(m->log, m->mem, m->mono_time, m->rng, m->dht); m->onion_a = new_onion_announce(m->log, m->mem, m->rng, m->mono_time, m->dht); m->onion_c = new_onion_client(m->log, m->mem, m->rng, m->mono_time, m->net_crypto); - m->fr_c = new_friend_connections(m->log, m->mono_time, m->ns, m->onion_c, options->local_discovery_enabled); + 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)) || m->onion == nullptr || m->onion_a == nullptr || m->onion_c == nullptr || m->fr_c == nullptr) { diff --git a/toxcore/TCP_client.c b/toxcore/TCP_client.c index aeb722f660e..20a7d106b45 100644 --- a/toxcore/TCP_client.c +++ b/toxcore/TCP_client.c @@ -306,7 +306,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; @@ -328,7 +328,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_common.c b/toxcore/TCP_common.c index 5d0019486c0..7b0904ec2d2 100644 --- a/toxcore/TCP_common.c +++ b/toxcore/TCP_common.c @@ -150,7 +150,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 != (SIZEOF_VLA(packet) - sizeof(uint16_t))) { return -1; @@ -294,7 +294,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_server.c b/toxcore/TCP_server.c index 905d2bb4341..ba056ff9b52 100644 --- a/toxcore/TCP_server.c +++ b/toxcore/TCP_server.c @@ -319,7 +319,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); @@ -339,7 +340,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)); @@ -903,7 +904,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); @@ -922,7 +923,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()); @@ -986,7 +987,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; @@ -1027,7 +1028,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); + bs_list_init(&temp->accepted_key_list, CRYPTO_PUBLIC_KEY_SIZE, 8, mem); return temp; } diff --git a/toxcore/announce.c b/toxcore/announce.c index fbbb2350c60..376948a27e8 100644 --- a/toxcore/announce.c +++ b/toxcore/announce.c @@ -233,10 +233,10 @@ bool announce_store_data(Announcements *announce, const uint8_t *data_public_key assert(data != nullptr); if (entry->data != nullptr) { - free(entry->data); + mem_delete(announce->mem, entry->data); } - entry->data = (uint8_t *)malloc(length); + entry->data = (uint8_t *)mem_balloc(announce->mem, length); if (entry->data == nullptr) { return false; @@ -447,7 +447,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; } @@ -545,11 +545,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); @@ -564,7 +565,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; } @@ -609,7 +610,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; @@ -628,7 +630,8 @@ static int handle_dht_announce_request(void *object, const IP_Port *source, const int len = create_reply(announce, source, nullptr, 0, - data, length, reply, sizeof(reply)); + data, length, reply, sizeof(reply), + announce->mem); if (len == -1) { return -1; @@ -644,7 +647,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; @@ -662,7 +665,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(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; } @@ -694,9 +697,9 @@ void kill_announcements(Announcements *announce) for (uint32_t i = 0; i < ANNOUNCE_BUCKETS * ANNOUNCE_BUCKET_SIZE; ++i) { if (announce->entries[i].data != nullptr) { - 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 3575803aedd..00e7ea87c56 100644 --- a/toxcore/bin_pack.c +++ b/toxcore/bin_pack.c @@ -12,6 +12,8 @@ #include "ccompat.h" struct Bin_Pack { + const Memory *mem; + uint8_t *bytes; uint32_t bytes_size; uint32_t bytes_pos; @@ -56,6 +58,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; @@ -77,19 +80,24 @@ uint32_t bin_pack_obj_size(bin_pack_cb *callback, const void *obj) return bp.bytes_pos; } -Bin_Pack *bin_pack_new(uint8_t *buf, uint32_t buf_size) +Bin_Pack *bin_pack_new(uint8_t *buf, uint32_t buf_size, const Memory *mem) { - Bin_Pack *bp = (Bin_Pack *)calloc(1, sizeof(Bin_Pack)); + Bin_Pack *bp = (Bin_Pack *)mem_alloc(mem, sizeof(Bin_Pack)); if (bp == nullptr) { return nullptr; } bin_pack_init(bp, buf, buf_size); + bp->mem = mem; return bp; } void bin_pack_free(Bin_Pack *bp) { - free(bp); + if (bp == nullptr) { + return; + } + + mem_delete(bp->mem, bp); } bool bin_pack_array(Bin_Pack *bp, uint32_t size) diff --git a/toxcore/bin_pack.h b/toxcore/bin_pack.h index 51646c088a5..0160b1e19d4 100644 --- a/toxcore/bin_pack.h +++ b/toxcore/bin_pack.h @@ -7,7 +7,8 @@ #include #include -#include "attributes.h" +#include "mem.h" +#include "tox_attributes.h" #ifdef __cplusplus extern "C" { @@ -64,7 +65,7 @@ bool bin_pack_obj(bin_pack_cb *callback, const void *obj, uint8_t *buf, uint32_t * @retval nullptr on allocation failure. */ non_null() -Bin_Pack *bin_pack_new(uint8_t *buf, uint32_t buf_size); +Bin_Pack *bin_pack_new(uint8_t *buf, uint32_t buf_size, const Memory *mem); /** @brief Deallocates a packer object. * diff --git a/toxcore/bin_pack_test.cc b/toxcore/bin_pack_test.cc index 05140146dfe..43aa4e61feb 100644 --- a/toxcore/bin_pack_test.cc +++ b/toxcore/bin_pack_test.cc @@ -7,6 +7,7 @@ #include #include "bin_unpack.h" +#include "os_memory.h" namespace { @@ -24,20 +25,22 @@ using Bin_Unpack_Ptr = std::unique_ptr; TEST(BinPack, TooSmallBufferIsNotExceeded) { + const Memory *mem = os_memory(); std::array buf; - Bin_Pack_Ptr bp(bin_pack_new(buf.data(), buf.size())); + Bin_Pack_Ptr bp(bin_pack_new(buf.data(), buf.size(), mem)); ASSERT_NE(bp, nullptr); EXPECT_FALSE(bin_pack_u64_b(bp.get(), 1234567812345678LL)); } TEST(BinPack, PackedUint64CanBeUnpacked) { + const Memory *mem = os_memory(); std::array buf; - Bin_Pack_Ptr bp(bin_pack_new(buf.data(), buf.size())); + Bin_Pack_Ptr bp(bin_pack_new(buf.data(), buf.size(), mem)); ASSERT_NE(bp, nullptr); ASSERT_TRUE(bin_pack_u64_b(bp.get(), 1234567812345678LL)); - Bin_Unpack_Ptr bu(bin_unpack_new(buf.data(), buf.size())); + Bin_Unpack_Ptr bu(bin_unpack_new(buf.data(), buf.size(), mem)); ASSERT_NE(bu, nullptr); uint64_t val; ASSERT_TRUE(bin_unpack_u64_b(bu.get(), &val)); @@ -46,12 +49,13 @@ TEST(BinPack, PackedUint64CanBeUnpacked) TEST(BinPack, MsgPackedUint8CanBeUnpackedAsUint32) { + const Memory *mem = os_memory(); std::array buf; - Bin_Pack_Ptr bp(bin_pack_new(buf.data(), buf.size())); + Bin_Pack_Ptr bp(bin_pack_new(buf.data(), buf.size(), mem)); ASSERT_NE(bp, nullptr); ASSERT_TRUE(bin_pack_u08(bp.get(), 123)); - Bin_Unpack_Ptr bu(bin_unpack_new(buf.data(), buf.size())); + Bin_Unpack_Ptr bu(bin_unpack_new(buf.data(), buf.size(), mem)); ASSERT_NE(bu, nullptr); uint32_t val; ASSERT_TRUE(bin_unpack_u32(bu.get(), &val)); @@ -60,12 +64,13 @@ TEST(BinPack, MsgPackedUint8CanBeUnpackedAsUint32) TEST(BinPack, MsgPackedUint32CanBeUnpackedAsUint8IfSmallEnough) { + const Memory *mem = os_memory(); std::array buf; - Bin_Pack_Ptr bp(bin_pack_new(buf.data(), buf.size())); + Bin_Pack_Ptr bp(bin_pack_new(buf.data(), buf.size(), mem)); ASSERT_NE(bp, nullptr); ASSERT_TRUE(bin_pack_u32(bp.get(), 123)); - Bin_Unpack_Ptr bu(bin_unpack_new(buf.data(), buf.size())); + Bin_Unpack_Ptr bu(bin_unpack_new(buf.data(), buf.size(), mem)); ASSERT_NE(bu, nullptr); uint8_t val; ASSERT_TRUE(bin_unpack_u08(bu.get(), &val)); @@ -74,12 +79,13 @@ TEST(BinPack, MsgPackedUint32CanBeUnpackedAsUint8IfSmallEnough) TEST(BinPack, LargeMsgPackedUint32CannotBeUnpackedAsUint8) { + const Memory *mem = os_memory(); std::array buf; - Bin_Pack_Ptr bp(bin_pack_new(buf.data(), buf.size())); + Bin_Pack_Ptr bp(bin_pack_new(buf.data(), buf.size(), mem)); ASSERT_NE(bp, nullptr); ASSERT_TRUE(bin_pack_u32(bp.get(), 1234567)); - Bin_Unpack_Ptr bu(bin_unpack_new(buf.data(), buf.size())); + Bin_Unpack_Ptr bu(bin_unpack_new(buf.data(), buf.size(), mem)); ASSERT_NE(bu, nullptr); uint8_t val; EXPECT_FALSE(bin_unpack_u08(bu.get(), &val)); @@ -87,14 +93,15 @@ TEST(BinPack, LargeMsgPackedUint32CannotBeUnpackedAsUint8) TEST(BinPack, BinCanHoldPackedInts) { + const Memory *mem = os_memory(); std::array buf; - Bin_Pack_Ptr bp(bin_pack_new(buf.data(), buf.size())); + Bin_Pack_Ptr bp(bin_pack_new(buf.data(), buf.size(), mem)); ASSERT_NE(bp, nullptr); ASSERT_TRUE(bin_pack_bin_marker(bp.get(), 8)); ASSERT_TRUE(bin_pack_u64_b(bp.get(), 1234567812345678LL)); ASSERT_TRUE(bin_pack_u16_b(bp.get(), 54321)); - Bin_Unpack_Ptr bu(bin_unpack_new(buf.data(), buf.size())); + Bin_Unpack_Ptr bu(bin_unpack_new(buf.data(), buf.size(), mem)); ASSERT_NE(bu, nullptr); uint32_t size; EXPECT_TRUE(bin_unpack_bin_size(bu.get(), &size)); @@ -109,13 +116,14 @@ TEST(BinPack, BinCanHoldPackedInts) TEST(BinPack, BinCanHoldArbitraryData) { + const Memory *mem = os_memory(); std::array buf; - Bin_Pack_Ptr bp(bin_pack_new(buf.data(), buf.size())); + Bin_Pack_Ptr bp(bin_pack_new(buf.data(), buf.size(), mem)); ASSERT_NE(bp, nullptr); ASSERT_TRUE(bin_pack_bin_marker(bp.get(), 5)); ASSERT_TRUE(bin_pack_bin_b(bp.get(), reinterpret_cast("hello"), 5)); - Bin_Unpack_Ptr bu(bin_unpack_new(buf.data(), buf.size())); + Bin_Unpack_Ptr bu(bin_unpack_new(buf.data(), buf.size(), mem)); ASSERT_NE(bu, nullptr); std::array str; EXPECT_TRUE(bin_unpack_bin_fixed(bu.get(), str.data(), str.size())); @@ -124,9 +132,10 @@ TEST(BinPack, BinCanHoldArbitraryData) TEST(BinPack, OversizedArrayFailsUnpack) { + const Memory *mem = os_memory(); std::array buf = {0x91}; - Bin_Unpack_Ptr bu(bin_unpack_new(buf.data(), buf.size())); + Bin_Unpack_Ptr bu(bin_unpack_new(buf.data(), buf.size(), mem)); uint32_t size; EXPECT_FALSE(bin_unpack_array(bu.get(), &size)); } diff --git a/toxcore/bin_unpack.c b/toxcore/bin_unpack.c index ff591ca87ad..1799e7517fe 100644 --- a/toxcore/bin_unpack.c +++ b/toxcore/bin_unpack.c @@ -12,6 +12,8 @@ #include "ccompat.h" struct Bin_Unpack { + const Memory *mem; + const uint8_t *bytes; uint32_t bytes_size; cmp_ctx_t ctx; @@ -51,12 +53,13 @@ static size_t null_writer(cmp_ctx_t *ctx, const void *data, size_t count) return 0; } -Bin_Unpack *bin_unpack_new(const uint8_t *buf, uint32_t buf_size) +Bin_Unpack *bin_unpack_new(const uint8_t *buf, uint32_t buf_size, const Memory *mem) { - Bin_Unpack *bu = (Bin_Unpack *)calloc(1, sizeof(Bin_Unpack)); + Bin_Unpack *bu = (Bin_Unpack *)mem_alloc(mem, sizeof(Bin_Unpack)); if (bu == nullptr) { return nullptr; } + bu->mem = mem; bu->bytes = buf; bu->bytes_size = buf_size; cmp_init(&bu->ctx, bu, buf_reader, buf_skipper, null_writer); @@ -65,7 +68,11 @@ Bin_Unpack *bin_unpack_new(const uint8_t *buf, uint32_t buf_size) void bin_unpack_free(Bin_Unpack *bu) { - free(bu); + if (bu == nullptr) { + return; + } + + mem_delete(bu->mem, bu); } bool bin_unpack_array(Bin_Unpack *bu, uint32_t *size) @@ -116,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 bd4d8785c1f..b37a407b91f 100644 --- a/toxcore/bin_unpack.h +++ b/toxcore/bin_unpack.h @@ -8,7 +8,8 @@ #include #include -#include "attributes.h" +#include "mem.h" +#include "tox_attributes.h" #ifdef __cplusplus extern "C" { @@ -27,7 +28,7 @@ typedef struct Bin_Unpack Bin_Unpack; * @retval nullptr on allocation failure. */ non_null() -Bin_Unpack *bin_unpack_new(const uint8_t *buf, uint32_t buf_size); +Bin_Unpack *bin_unpack_new(const uint8_t *buf, uint32_t buf_size, const Memory *mem); /** @brief Deallocates an unpacker object. * diff --git a/toxcore/ccompat.h b/toxcore/ccompat.h index 9ea6739a7d3..05525ef6691 100644 --- a/toxcore/ccompat.h +++ b/toxcore/ccompat.h @@ -10,7 +10,7 @@ #include // NULL, size_t -#include "attributes.h" +#include "tox_attributes.h" //!TOKSTYLE- diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index 14025252c41..85c20fcce60 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -29,6 +29,7 @@ #endif #include "ccompat.h" +#include "tox_random_impl.h" #ifndef crypto_box_MACBYTES #define crypto_box_MACBYTES (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES) @@ -116,9 +117,10 @@ const uint8_t *get_chat_id(const uint8_t *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); @@ -127,15 +129,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) @@ -245,7 +247,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, const uint8_t *message, uint64_t message_length, @@ -286,7 +288,8 @@ int32_t encrypt_precompute(const uint8_t *public_key, const uint8_t *secret_key, } int32_t encrypt_data_symmetric(const uint8_t *shared_key, const uint8_t *nonce, - 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; @@ -302,12 +305,12 @@ int32_t encrypt_data_symmetric(const uint8_t *shared_key, const uint8_t *nonce, 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; } @@ -322,23 +325,24 @@ int32_t encrypt_data_symmetric(const uint8_t *shared_key, const uint8_t *nonce, 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 assert(length < INT32_MAX - crypto_box_MACBYTES); return (int32_t)(length + crypto_box_MACBYTES); } int32_t decrypt_data_symmetric(const uint8_t *shared_key, const uint8_t *nonce, - 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) { @@ -353,12 +357,12 @@ int32_t decrypt_data_symmetric(const uint8_t *shared_key, const uint8_t *nonce, 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; } @@ -373,15 +377,15 @@ int32_t decrypt_data_symmetric(const uint8_t *shared_key, const uint8_t *nonce, 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 assert(length > crypto_box_MACBYTES); assert(length < INT32_MAX); @@ -389,7 +393,7 @@ int32_t decrypt_data_symmetric(const uint8_t *shared_key, const uint8_t *nonce, } int32_t encrypt_data(const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *nonce, - 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; @@ -397,13 +401,13 @@ int32_t encrypt_data(const uint8_t *public_key, const uint8_t *secret_key, const 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; } int32_t decrypt_data(const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *nonce, - 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; @@ -411,7 +415,7 @@ int32_t decrypt_data(const uint8_t *public_key, const uint8_t *secret_key, const 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; } @@ -530,53 +534,7 @@ void crypto_sha512(uint8_t *hash, const uint8_t *data, size_t length) #endif } -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) -{ -#ifdef VANILLA_NACL - if (upper_bound == 0) { - return 0; - } - - uint32_t randnum; - sys_random_bytes(obj, (uint8_t *)&randnum, sizeof(randnum)); - return randnum % upper_bound; -#else - return randombytes_uniform(upper_bound); -#endif -} - -static const Random_Funcs system_random_funcs = { - sys_random_bytes, - sys_random_uniform, -}; - -static const Random system_random_obj = {&system_random_funcs}; - -const Random *system_random(void) -{ -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - if ((true)) { - return nullptr; - } -#endif -#ifndef VANILLA_NACL - // 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; - } -#endif - return &system_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 3b9f27d677c..59a412698a5 100644 --- a/toxcore/crypto_core.h +++ b/toxcore/crypto_core.h @@ -13,7 +13,9 @@ #include #include -#include "attributes.h" +#include "mem.h" +#include "tox_attributes.h" +#include "tox_random.h" #ifdef __cplusplus extern "C" { @@ -75,21 +77,6 @@ extern "C" { */ #define CRYPTO_SHA512_SIZE 64 -typedef void crypto_random_bytes_cb(void *obj, uint8_t *bytes, size_t length); -typedef uint32_t crypto_random_uniform_cb(void *obj, uint32_t upper_bound); - -typedef struct Random_Funcs { - crypto_random_bytes_cb *random_bytes; - crypto_random_uniform_cb *random_uniform; -} Random_Funcs; - -typedef struct Random { - const Random_Funcs *funcs; - void *obj; -} Random; - -const Random *system_random(void); - /** * @brief The number of bytes in an encryption public key used by DHT group chats. */ @@ -208,6 +195,11 @@ bool crypto_sha512_eq(const uint8_t *cksum1, const uint8_t *cksum2); non_null() bool crypto_sha256_eq(const uint8_t *cksum1, const uint8_t *cksum2); +/** + * @brief Shorter internal name for the RNG type. + */ +typedef Tox_Random Random; + /** * @brief Return a random 8 bit integer. */ @@ -338,7 +330,7 @@ void crypto_derive_public_key(uint8_t *public_key, const uint8_t *secret_key); */ non_null() int32_t encrypt_data(const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *nonce, const uint8_t *plain, - size_t length, uint8_t *encrypted); + size_t length, uint8_t *encrypted, const Memory *mem); /** * @brief Decrypt message from public key to secret key. @@ -353,7 +345,7 @@ int32_t encrypt_data(const uint8_t *public_key, const uint8_t *secret_key, const */ non_null() int32_t decrypt_data(const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *nonce, - 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. @@ -377,7 +369,7 @@ int32_t encrypt_precompute(const uint8_t *public_key, const uint8_t *secret_key, */ non_null() int32_t encrypt_data_symmetric(const uint8_t *shared_key, const uint8_t *nonce, const uint8_t *plain, size_t length, - uint8_t *encrypted); + uint8_t *encrypted, const Memory *mem); /** * @brief Decrypt message with precomputed shared key. @@ -391,7 +383,7 @@ int32_t encrypt_data_symmetric(const uint8_t *shared_key, const uint8_t *nonce, */ non_null() int32_t decrypt_data_symmetric(const uint8_t *shared_key, const uint8_t *nonce, const uint8_t *encrypted, size_t length, - uint8_t *plain); + uint8_t *plain, const Memory *mem); /** * @brief Increment the given nonce by 1 in big endian (rightmost byte incremented diff --git a/toxcore/crypto_core_test.cc b/toxcore/crypto_core_test.cc index 4f2a9f3085b..bde7ec7bac8 100644 --- a/toxcore/crypto_core_test.cc +++ b/toxcore/crypto_core_test.cc @@ -6,6 +6,7 @@ #include #include +#include "os_random.h" #include "util.h" namespace { @@ -52,7 +53,7 @@ TEST(CryptoCore, IncrementNonceNumber) TEST(CryptoCore, Signatures) { - const Random *rng = system_random(); + const Random *rng = os_random(); ASSERT_NE(rng, nullptr); ExtPublicKey pk; @@ -76,7 +77,7 @@ TEST(CryptoCore, Signatures) TEST(CryptoCore, Hmac) { - const Random *rng = system_random(); + const Random *rng = os_random(); ASSERT_NE(rng, nullptr); HmacKey sk; diff --git a/toxcore/events/events_alloc.h b/toxcore/events/events_alloc.h index 6c5a7abd4f7..06a24942763 100644 --- a/toxcore/events/events_alloc.h +++ b/toxcore/events/events_alloc.h @@ -5,7 +5,7 @@ #ifndef C_TOXCORE_TOXCORE_TOX_EVENTS_INTERNAL_H #define C_TOXCORE_TOXCORE_TOX_EVENTS_INTERNAL_H -#include "../attributes.h" +#include "../tox_attributes.h" #include "../bin_pack.h" #include "../bin_unpack.h" #include "../tox_events.h" diff --git a/toxcore/forwarding.c b/toxcore/forwarding.c index 5e885abd211..be98ecf24e7 100644 --- a/toxcore/forwarding.c +++ b/toxcore/forwarding.c @@ -14,6 +14,7 @@ struct Forwarding { const Logger *log; + const Memory *mem; const Random *rng; DHT *dht; const Mono_Time *mono_time; @@ -352,19 +353,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; @@ -391,5 +393,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 36ce8ad8943..4cc47e528c3 100644 --- a/toxcore/forwarding.h +++ b/toxcore/forwarding.h @@ -113,7 +113,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 ce263f1e6fd..a6c5581aa51 100644 --- a/toxcore/forwarding_fuzz_test.cc +++ b/toxcore/forwarding_fuzz_test.cc @@ -5,14 +5,16 @@ #include "../testing/fuzzing/fuzz_support.h" #include "../testing/fuzzing/fuzz_tox.h" +#include "os_memory.h" +#include "os_network.h" namespace { void TestSendForwardRequest(Fuzz_Data &input) { - const Network *ns = system_network(); // TODO(iphydf): fuzz_network + const Network *ns = os_network(); // TODO(iphydf): fuzz_network assert(ns != nullptr); - const Memory *mem = system_memory(); // TODO(iphydf): fuzz_memory + const Memory *mem = os_memory(); // TODO(iphydf): fuzz_memory assert(mem != nullptr); with{} >> with{input, ns, mem} >> [&input](Ptr net) { @@ -29,9 +31,9 @@ void TestSendForwardRequest(Fuzz_Data &input) void TestForwardReply(Fuzz_Data &input) { - const Network *ns = system_network(); // TODO(iphydf): fuzz_network + const Network *ns = os_network(); // TODO(iphydf): fuzz_network assert(ns != nullptr); - const Memory *mem = system_memory(); // TODO(iphydf): fuzz_memory + const Memory *mem = os_memory(); // TODO(iphydf): fuzz_memory assert(mem != nullptr); with{} >> with{input, ns, mem} >> [&input](Ptr net) { diff --git a/toxcore/friend_connection.c b/toxcore/friend_connection.c index 49fed514657..c7aaa49a287 100644 --- a/toxcore/friend_connection.c +++ b/toxcore/friend_connection.c @@ -60,6 +60,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; @@ -111,19 +112,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; @@ -898,14 +899,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; @@ -913,6 +914,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; @@ -923,7 +925,7 @@ Friend_Connections *new_friend_connections( new_connection_handler(temp->net_crypto, &handle_new_connections, temp); 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"); @@ -1021,5 +1023,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 93bd5113ac5..1555ff3d4c3 100644 --- a/toxcore/friend_connection.h +++ b/toxcore/friend_connection.h @@ -156,7 +156,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 7f18b1ff026..30a4363c644 100644 --- a/toxcore/friend_requests.c +++ b/toxcore/friend_requests.c @@ -26,6 +26,8 @@ struct Received_Requests { }; struct Friend_Requests { + const Memory *mem; + uint32_t nospam; fr_friend_request_cb *handle_friendrequest; uint8_t handle_friendrequest_isset; @@ -160,12 +162,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 26145271636..0524c648f14 100644 --- a/toxcore/friend_requests.h +++ b/toxcore/friend_requests.h @@ -46,7 +46,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 0e851b1e348..c5703bfb306 100644 --- a/toxcore/group.c +++ b/toxcore/group.c @@ -138,6 +138,7 @@ typedef struct Group_c { } Group_c; struct Group_Chats { + const Memory *mem; const Mono_Time *mono_time; Messenger *m; @@ -238,19 +239,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; @@ -292,10 +293,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)); } @@ -310,7 +311,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; @@ -660,7 +661,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; @@ -669,14 +670,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, sizeof(Group_Peer) * g->numfrozen); + Group_Peer *const frozen_temp = (Group_Peer *)mem_vrealloc(mem, g->frozen, g->numfrozen, sizeof(Group_Peer)); if (frozen_temp == nullptr) { return false; @@ -693,8 +694,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); @@ -717,7 +718,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, sizeof(Group_Peer) * (g->numpeers + 1)); + Group_Peer *temp = (Group_Peer *)mem_vrealloc(mem, g->group, g->numpeers + 1, sizeof(Group_Peer)); if (temp == nullptr) { return -1; @@ -734,7 +735,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); @@ -770,7 +771,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); } } @@ -797,7 +798,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) { @@ -829,7 +830,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, sizeof(Group_Peer) * (g->numpeers + 1)); + Group_Peer *temp = (Group_Peer *)mem_vrealloc(g_c->mem, g->group, g->numpeers + 1, sizeof(Group_Peer)); if (temp == nullptr) { return -1; @@ -920,14 +921,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, sizeof(Group_Peer) * g->numpeers); + Group_Peer *temp = (Group_Peer *)mem_vrealloc(g_c->mem, g->group, g->numpeers, sizeof(Group_Peer)); if (temp == nullptr) { return false; @@ -971,14 +972,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; @@ -986,7 +987,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, sizeof(Group_Peer) * g->maxfrozen); + Group_Peer *temp = (Group_Peer *)mem_vrealloc(mem, g->frozen, g->maxfrozen, sizeof(Group_Peer)); if (temp == nullptr) { return false; @@ -1011,7 +1012,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, sizeof(Group_Peer) * (g->numfrozen + 1)); + Group_Peer *temp = (Group_Peer *)mem_vrealloc(g_c->mem, g->frozen, g->numfrozen + 1, sizeof(Group_Peer)); if (temp == nullptr) { return false; @@ -1029,7 +1030,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; } @@ -1518,7 +1519,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; } @@ -2857,7 +2858,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) { @@ -3610,7 +3611,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 @@ -3748,18 +3749,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; @@ -3811,7 +3813,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 e6f6c447333..a1a664adb69 100644 --- a/toxcore/group.h +++ b/toxcore/group.h @@ -385,7 +385,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 896b043dbd1..8c6d35e283e 100644 --- a/toxcore/group_announce.c +++ b/toxcore/group_announce.c @@ -5,7 +5,6 @@ #include "group_announce.h" -#include #include #include "LAN_discovery.h" @@ -33,7 +32,7 @@ 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); } /** @@ -349,7 +348,7 @@ GC_Peer_Announce *gca_add_announce(const Mono_Time *mono_time, GC_Announces_List // No entry for this chat_id exists so we create one if (announces == nullptr) { - announces = (GC_Announces *)calloc(1, sizeof(GC_Announces)); + announces = (GC_Announces *)mem_alloc(gc_announces_list->mem, sizeof(GC_Announces)); if (announces == nullptr) { return nullptr; @@ -393,9 +392,16 @@ 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) { - GC_Announces_List *announces_list = (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; } @@ -409,11 +415,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. */ diff --git a/toxcore/group_announce.h b/toxcore/group_announce.h index 801363d6b2d..887b1d47b55 100644 --- a/toxcore/group_announce.h +++ b/toxcore/group_announce.h @@ -73,6 +73,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; }; @@ -82,7 +84,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 6728e712840..ef68b678f72 100644 --- a/toxcore/group_announce_fuzz_test.cc +++ b/toxcore/group_announce_fuzz_test.cc @@ -6,6 +6,8 @@ #include #include "../testing/fuzzing/fuzz_support.h" +#include "os_memory.h" +#include "tox_time_impl.h" namespace { @@ -17,7 +19,7 @@ void TestUnpackAnnouncesList(Fuzz_Data &input) // TODO(iphydf): How do we know the packed size? CONSUME1_OR_RETURN(const uint16_t packed_size, input); - Logger *logger = logger_new(); + Logger *logger = logger_new(os_memory()); if (gca_unpack_announces_list(logger, input.data, input.size, announces.data(), max_count) != -1) { std::vector packed(packed_size); @@ -35,7 +37,7 @@ void TestUnpackPublicAnnounce(Fuzz_Data &input) // TODO(iphydf): How do we know the packed size? CONSUME1_OR_RETURN(const uint16_t packed_size, input); - Logger *logger = logger_new(); + Logger *logger = logger_new(os_memory()); if (gca_unpack_public_announce(logger, input.data, input.size, &public_announce) != -1) { std::vector packed(packed_size); gca_pack_public_announce(logger, packed.data(), packed.size(), &public_announce); @@ -45,16 +47,19 @@ void TestUnpackPublicAnnounce(Fuzz_Data &input) void TestDoGca(Fuzz_Data &input) { - const Memory *mem = system_memory(); - std::unique_ptr logger(logger_new(), logger_kill); + const Memory *mem = os_memory(); + std::unique_ptr logger(logger_new(os_memory()), 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, nullptr, nullptr), [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); - uint64_t clock = 1; - mono_time_set_current_time_callback( - mono_time.get(), [](void *user_data) { return *static_cast(user_data); }, - &clock); - std::unique_ptr gca(new_gca_list(), kill_gca); + std::unique_ptr gca( + new_gca_list(mem), kill_gca); assert(gca != nullptr); while (input.size > 0) { diff --git a/toxcore/group_announce_test.cc b/toxcore/group_announce_test.cc index d3d5d715817..7dae423cd09 100644 --- a/toxcore/group_announce_test.cc +++ b/toxcore/group_announce_test.cc @@ -3,12 +3,18 @@ #include #include "mono_time.h" +#include "os_memory.h" +#include "tox_time_impl.h" namespace { struct Announces : ::testing::Test { protected: - const Memory *mem_ = system_memory(); + const Memory *mem_ = os_memory(); + static constexpr Tox_Time_Funcs mock_time_funcs = { + [](void *user_data) { return *static_cast(user_data); }, + }; + Tox_Time *tm_; uint64_t clock_ = 0; Mono_Time *mono_time_ = nullptr; GC_Announces_List *gca_ = nullptr; @@ -17,12 +23,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); } @@ -30,6 +36,7 @@ struct Announces : ::testing::Test { { kill_gca(gca_); mono_time_free(mem_, mono_time_); + tox_time_free(tm_); } void advance_clock(uint64_t increment) @@ -108,12 +115,14 @@ TEST_F(Announces, AnnouncesGetAndCleanup) struct AnnouncesPack : ::testing::Test { protected: + const Memory *mem_ = os_memory(); std::vector announces_; Logger *logger_ = nullptr; void SetUp() override { - logger_ = logger_new(); + ASSERT_NE(mem_, nullptr); + logger_ = logger_new(mem_); ASSERT_NE(logger_, nullptr); // Add an announce without TCP relay. diff --git a/toxcore/group_chats.c b/toxcore/group_chats.c index 23eca0a909f..d2f53176012 100644 --- a/toxcore/group_chats.c +++ b/toxcore/group_chats.c @@ -1412,8 +1412,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) { if (length <= CRYPTO_NONCE_SIZE) { @@ -1421,7 +1422,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"); @@ -1429,10 +1430,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; } @@ -1446,7 +1447,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; } } @@ -1463,13 +1464,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, uint8_t net_packet_type) { @@ -1488,7 +1490,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; @@ -1516,20 +1518,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; } @@ -1538,7 +1540,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; } @@ -1562,25 +1564,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, gconn->session_shared_key, packet, + chat->log, chat->mem, chat->rng, chat->self_public_key, 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; } @@ -1819,7 +1821,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; @@ -1859,7 +1861,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 @@ -2293,7 +2295,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; @@ -2303,7 +2305,7 @@ static bool send_gc_broadcast_message(const GC_Chat *chat, const uint8_t *data, send_gc_lossless_packet_all_peers(chat, packet, packet_len, GP_BROADCAST); - free(packet); + mem_delete(chat->mem, packet); return true; } @@ -2538,7 +2540,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; @@ -2547,10 +2549,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; } @@ -2567,17 +2569,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; } @@ -2643,7 +2645,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, @@ -2688,7 +2690,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; @@ -2696,17 +2698,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; @@ -3090,7 +3092,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; @@ -3101,25 +3103,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; } @@ -3156,7 +3158,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; @@ -3165,7 +3167,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; @@ -3180,7 +3182,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; @@ -3189,13 +3191,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; } @@ -3239,7 +3241,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; @@ -3248,13 +3250,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; } @@ -3269,7 +3271,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; @@ -3278,13 +3280,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; } send_gc_lossless_packet_all_peers(chat, packet, (uint16_t)packet_len, GP_SANCTIONS_LIST); - free(packet); + mem_delete(chat->mem, packet); return true; } @@ -3315,7 +3317,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; @@ -3324,13 +3326,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; } send_gc_lossless_packet_all_peers(chat, packet, length, GP_MOD_LIST); - free(packet); + mem_delete(chat->mem, packet); return true; } @@ -3551,7 +3553,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; @@ -3560,16 +3562,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; } @@ -3619,7 +3621,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; @@ -3628,13 +3630,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; } send_gc_lossless_packet_all_peers(chat, packet, packet_buf_size, GP_TOPIC); - free(packet); + mem_delete(chat->mem, packet); return true; } @@ -3684,7 +3686,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; @@ -3711,13 +3713,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; } @@ -3964,7 +3966,7 @@ int gc_founder_set_password(GC_Chat *chat, const uint8_t *password, uint16_t pas const uint16_t oldlen = chat->shared_state.password_length; if (oldlen > 0) { - oldpasswd = (uint8_t *)malloc(oldlen); + oldpasswd = (uint8_t *)mem_balloc(chat->mem, oldlen); if (oldpasswd == nullptr) { return -4; @@ -3974,17 +3976,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; @@ -4109,7 +4111,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; @@ -4120,11 +4122,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; } @@ -4313,7 +4315,7 @@ static bool send_gc_set_observer(const GC_Chat *chat, const uint8_t *target_ext_ uint16_t length, bool add_obs) { const uint16_t packet_len = 1 + EXT_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; @@ -4325,11 +4327,11 @@ static bool send_gc_set_observer(const GC_Chat *chat, const uint8_t *target_ext_ memcpy(packet + 1 + EXT_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; } @@ -4746,7 +4748,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; @@ -4758,7 +4760,7 @@ 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; } @@ -4766,7 +4768,7 @@ int gc_send_message(const GC_Chat *chat, const uint8_t *message, uint16_t length *message_id = pseudo_msg_id; } - free(message_raw); + mem_delete(chat->mem, message_raw); return 0; } @@ -4832,7 +4834,7 @@ int gc_send_private_message(const GC_Chat *chat, uint32_t peer_id, uint8_t type, return -5; } - uint8_t *message_with_type = (uint8_t *)malloc(length + 1); + uint8_t *message_with_type = (uint8_t *)mem_balloc(chat->mem, length + 1); if (message_with_type == nullptr) { return -6; @@ -4841,23 +4843,23 @@ int gc_send_private_message(const GC_Chat *chat, uint32_t peer_id, uint8_t type, message_with_type[0] = type; memcpy(message_with_type + 1, message, length); - uint8_t *packet = (uint8_t *)malloc(length + 1 + GC_BROADCAST_ENC_HEADER_SIZE); + uint8_t *packet = (uint8_t *)mem_balloc(chat->mem, length + 1 + 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, length + 1, 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); return 0; } @@ -5192,7 +5194,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; } @@ -5371,7 +5373,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); @@ -5379,7 +5381,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); @@ -5396,12 +5398,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) { @@ -5414,17 +5417,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; } @@ -5434,7 +5437,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; } @@ -5484,7 +5487,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, chat->self_secret_key, + chat->log, chat->mem, chat->rng, chat->self_public_key, chat->self_secret_key, gconn->addr.public_key, packet, (uint16_t)packet_size, data, length); if (enc_len != GC_MIN_ENCRYPTED_HS_PAYLOAD_SIZE + nodes_size) { @@ -5809,18 +5812,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, 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; } @@ -5836,11 +5839,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); @@ -6035,7 +6038,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"); @@ -6045,19 +6048,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; } @@ -6067,28 +6070,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); } @@ -6096,7 +6099,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); } @@ -6104,13 +6107,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; @@ -6156,7 +6159,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"); @@ -6165,13 +6168,13 @@ 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; } @@ -6206,12 +6209,12 @@ static bool handle_gc_lossy_packet(const GC_Session *c, GC_Chat *chat, const uin default: { LOGGER_WARNING(chat->log, "Warning: handling invalid lossy group packet type 0x%02x", packet_type); - free(data); + mem_delete(chat->mem, data); return false; } } - 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, @@ -6585,7 +6588,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; @@ -6597,7 +6600,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; @@ -6673,8 +6676,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"); @@ -6683,22 +6686,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; } @@ -6914,7 +6917,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; @@ -6960,11 +6963,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 true; } - free(data); + mem_delete(chat->mem, data); return false; } @@ -7176,12 +7179,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; @@ -7230,7 +7233,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; @@ -7242,7 +7245,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() @@ -7483,6 +7486,10 @@ int gc_group_load(GC_Session *c, Bin_Unpack *bu) chat->last_ping_interval = tm; chat->friend_connection_id = -1; + // Initialise these first, because we may need to log/dealloc things on cleanup. + chat->moderation.log = m->log; + chat->moderation.mem = m->mem; + if (!gc_load_unpack_group(chat, bu)) { LOGGER_ERROR(chat->log, "Failed to unpack group"); return -1; @@ -7706,7 +7713,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; @@ -7728,11 +7735,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; @@ -7801,7 +7808,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; @@ -7813,11 +7820,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; } @@ -8079,7 +8086,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; @@ -8110,7 +8117,7 @@ static void group_cleanup(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; } @@ -8183,8 +8190,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 821e629a641..37661378b7b 100644 --- a/toxcore/group_chats.h +++ b/toxcore/group_chats.h @@ -138,9 +138,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, uint8_t net_packet_type); diff --git a/toxcore/group_connection.c b/toxcore/group_connection.c index 86c353c00c0..669dfaef12e 100644 --- a/toxcore/group_connection.c +++ b/toxcore/group_connection.c @@ -37,10 +37,10 @@ static bool array_entry_is_empty(const GC_Message_Array_Entry *array_entry) /** @brief Clears an array entry. */ non_null() -static void clear_array_entry(GC_Message_Array_Entry *const array_entry) +static void clear_array_entry(GC_Message_Array_Entry *const array_entry, const Memory *mem) { if (array_entry->data != nullptr) { - free(array_entry->data); + mem_delete(mem, array_entry->data); } *array_entry = (GC_Message_Array_Entry) { @@ -54,14 +54,14 @@ static void clear_array_entry(GC_Message_Array_Entry *const array_entry) * to `start_id`. */ non_null() -static void clear_send_queue_id_range(GC_Connection *gconn, uint64_t start_id, uint64_t end_id) +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; @@ -87,16 +87,16 @@ void gcc_set_recv_message_id(GC_Connection *gconn, uint64_t id) * * Return true on success. */ -non_null(1, 2) nullable(3) +non_null(1, 2, 7) nullable(3) static bool create_array_entry(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) + uint16_t length, uint8_t packet_type, uint64_t message_id, const Memory *mem) { if (length > 0) { if (data == nullptr) { return false; } - array_entry->data = (uint8_t *)malloc(sizeof(uint8_t) * length); + array_entry->data = (uint8_t *)mem_balloc(mem, sizeof(uint8_t) * length); if (array_entry->data == nullptr) { return false; @@ -120,9 +120,9 @@ static bool create_array_entry(const Mono_Time *mono_time, GC_Message_Array_Entr * * Returns true on success and increments gconn's send_message_id. */ -non_null(1, 2, 3) nullable(4) +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) + 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)) { @@ -138,7 +138,7 @@ static bool add_to_send_array(const Logger *log, const Mono_Time *mono_time, GC_ return false; } - if (!create_array_entry(mono_time, array_entry, data, length, packet_type, gconn->send_message_id)) { + if (!create_array_entry(mono_time, array_entry, data, length, packet_type, gconn->send_message_id, mem)) { LOGGER_WARNING(log, "Failed to create array entry"); return false; } @@ -153,7 +153,7 @@ int gcc_send_lossless_packet(const GC_Chat *chat, GC_Connection *gconn, const ui { const uint64_t message_id = gconn->send_message_id; - if (!add_to_send_array(chat->log, chat->mono_time, gconn, data, length, packet_type)) { + 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; } @@ -182,7 +182,7 @@ 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; } @@ -195,15 +195,15 @@ 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; } @@ -227,7 +227,7 @@ bool gcc_send_lossless_packet_fragments(const GC_Chat *chat, GC_Connection *gcon 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]; @@ -241,7 +241,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) { @@ -322,10 +322,11 @@ 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) +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) + 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]; @@ -335,7 +336,7 @@ static bool store_in_recv_array(const Logger *log, const Mono_Time *mono_time, G return false; } - if (!create_array_entry(mono_time, ary_entry, data, length, packet_type, message_id)) { + if (!create_array_entry(mono_time, ary_entry, data, length, packet_type, message_id, mem)) { LOGGER_WARNING(log, "Failed to create array entry"); return false; } @@ -354,8 +355,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; @@ -392,7 +393,7 @@ static uint16_t reassemble_packet(const Logger *log, GC_Connection *gconn, uint8 } assert(*payload == nullptr); - *payload = (uint8_t *)malloc(packet_length); + *payload = (uint8_t *)mem_balloc(mem, packet_length); if (*payload == nullptr) { LOGGER_ERROR(log, "Failed to allocate %u bytes for payload buffer", packet_length); @@ -411,7 +412,7 @@ static uint16_t reassemble_packet(const Logger *log, GC_Connection *gconn, uint8 memcpy(*payload + processed, entry->data, entry->data_length); processed += entry->data_length; - clear_array_entry(entry); + clear_array_entry(entry, mem); } return processed; @@ -422,7 +423,7 @@ 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; } @@ -436,15 +437,15 @@ 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); + mem_delete(chat->mem, payload); return -1; } @@ -459,14 +460,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); @@ -483,7 +484,7 @@ int gcc_handle_received_message(const Logger *log, const Mono_Time *mono_time, G /* 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; } @@ -515,7 +516,7 @@ static bool process_recv_array_entry(const GC_Session *c, GC_Chat *chat, GC_Conn 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; @@ -614,7 +615,7 @@ bool gcc_encrypt_and_send_lossless_packet(const GC_Chat *chat, const GC_Connecti 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"); @@ -622,22 +623,22 @@ bool gcc_encrypt_and_send_lossless_packet(const GC_Chat *chat, const GC_Connecti } const int enc_len = group_packet_wrap( - chat->log, chat->rng, chat->self_public_key, gconn->session_shared_key, packet, - packet_size, data, length, message_id, packet_type, NET_PACKET_GC_LOSSLESS); + chat->log, chat->mem, chat->rng, chat->self_public_key, 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 false; } 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 false; } - free(packet); + mem_delete(chat->mem, packet); return true; } @@ -679,15 +680,15 @@ void gcc_mark_for_deletion(GC_Connection *gconn, TCP_Connections *tcp_conn, Grou } } -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)); @@ -700,7 +701,7 @@ 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 2202c7ab36e..9ee58155444 100644 --- a/toxcore/group_connection.h +++ b/toxcore/group_connection.h @@ -28,10 +28,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. * @@ -56,7 +56,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`. * @@ -180,7 +180,7 @@ bool gcc_encrypt_and_send_lossless_packet(const GC_Chat *chat, const GC_Connecti /** @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 eeed26d00eb..c3b0e591182 100644 --- a/toxcore/group_moderation.c +++ b/toxcore/group_moderation.c @@ -49,7 +49,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; @@ -58,7 +58,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) { - tmp_list[i] = (uint8_t *)malloc(sizeof(uint8_t) * MOD_LIST_ENTRY_SIZE); + tmp_list[i] = (uint8_t *)mem_balloc(moderation->mem, MOD_LIST_ENTRY_SIZE); if (tmp_list[i] == nullptr) { free_uint8_t_pointer_array(moderation->mem, tmp_list, i); @@ -98,7 +98,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; @@ -108,7 +108,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; } @@ -162,10 +162,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; @@ -199,7 +199,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; @@ -207,7 +207,7 @@ bool mod_list_add_entry(Moderation *moderation, const uint8_t *mod_data) moderation->mod_list = tmp_list; - tmp_list[moderation->num_mods] = (uint8_t *)malloc(sizeof(uint8_t) * MOD_LIST_ENTRY_SIZE); + tmp_list[moderation->num_mods] = (uint8_t *)mem_balloc(moderation->mem, MOD_LIST_ENTRY_SIZE); if (tmp_list[moderation->num_mods] == nullptr) { return false; @@ -400,9 +400,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) { memset(hash, 0, MOD_SANCTION_HASH_SIZE); @@ -417,7 +417,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; @@ -430,7 +430,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; } @@ -488,7 +488,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; } @@ -528,7 +528,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; } @@ -607,9 +607,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; @@ -650,7 +650,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; @@ -660,15 +660,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; } @@ -748,7 +748,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; @@ -756,17 +756,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; } @@ -860,7 +860,7 @@ uint16_t sanctions_list_replace_sig(Moderation *moderation, const uint8_t *publi void sanctions_list_cleanup(Moderation *moderation) { if (moderation->sanctions != nullptr) { - free(moderation->sanctions); + mem_delete(moderation->mem, moderation->sanctions); } moderation->sanctions = nullptr; diff --git a/toxcore/group_moderation_fuzz_test.cc b/toxcore/group_moderation_fuzz_test.cc index c5f46f3417c..dc4fbed76a1 100644 --- a/toxcore/group_moderation_fuzz_test.cc +++ b/toxcore/group_moderation_fuzz_test.cc @@ -1,13 +1,14 @@ #include "group_moderation.h" #include "../testing/fuzzing/fuzz_support.h" +#include "os_memory.h" namespace { void TestModListUnpack(Fuzz_Data &input) { CONSUME1_OR_RETURN(const uint16_t num_mods, input); - Moderation mods{system_memory()}; + Moderation mods{os_memory()}; mod_list_unpack(&mods, input.data, input.size, num_mods); mod_list_cleanup(&mods); } diff --git a/toxcore/group_moderation_test.cc b/toxcore/group_moderation_test.cc index e55122896ad..d007866a410 100644 --- a/toxcore/group_moderation_test.cc +++ b/toxcore/group_moderation_test.cc @@ -8,6 +8,8 @@ #include "crypto_core.h" #include "logger.h" +#include "os_memory.h" +#include "os_random.h" #include "util.h" namespace { @@ -18,7 +20,7 @@ using ModerationHash = std::array; TEST(ModList, PackedSizeOfEmptyModListIsZero) { - Moderation mods{system_memory()}; + Moderation mods{os_memory()}; EXPECT_EQ(mod_list_packed_size(&mods), 0); uint8_t byte = 1; @@ -28,14 +30,14 @@ TEST(ModList, PackedSizeOfEmptyModListIsZero) TEST(ModList, UnpackingZeroSizeArrayIsNoop) { - Moderation mods{system_memory()}; + Moderation mods{os_memory()}; const uint8_t byte = 1; EXPECT_EQ(mod_list_unpack(&mods, &byte, 0, 0), 0); } TEST(ModList, AddRemoveMultipleMods) { - Moderation mods{system_memory()}; + Moderation mods{os_memory()}; uint8_t sig_pk1[32] = {1}; uint8_t sig_pk2[32] = {2}; EXPECT_TRUE(mod_list_add_entry(&mods, sig_pk1)); @@ -47,7 +49,7 @@ TEST(ModList, AddRemoveMultipleMods) TEST(ModList, PackingAndUnpackingList) { using ModListEntry = std::array; - Moderation mods{system_memory()}; + Moderation mods{os_memory()}; EXPECT_TRUE(mod_list_add_entry(&mods, ModListEntry{}.data())); std::vector packed(mod_list_packed_size(&mods)); @@ -55,7 +57,7 @@ TEST(ModList, PackingAndUnpackingList) EXPECT_TRUE(mod_list_remove_entry(&mods, ModListEntry{}.data())); - Moderation mods2{system_memory()}; + Moderation mods2{os_memory()}; EXPECT_EQ(mod_list_unpack(&mods2, packed.data(), packed.size(), 1), packed.size()); EXPECT_TRUE(mod_list_remove_entry(&mods2, ModListEntry{}.data())); } @@ -63,13 +65,13 @@ TEST(ModList, PackingAndUnpackingList) TEST(ModList, UnpackingTooManyModsFails) { using ModListEntry = std::array; - Moderation mods{system_memory()}; + Moderation mods{os_memory()}; EXPECT_TRUE(mod_list_add_entry(&mods, ModListEntry{}.data())); std::vector packed(mod_list_packed_size(&mods)); mod_list_pack(&mods, packed.data()); - Moderation mods2{system_memory()}; + Moderation mods2{os_memory()}; EXPECT_EQ(mod_list_unpack(&mods2, packed.data(), packed.size(), 2), -1); EXPECT_TRUE(mod_list_remove_entry(&mods, ModListEntry{}.data())); } @@ -78,16 +80,16 @@ TEST(ModList, UnpackingFromEmptyBufferFails) { std::vector packed(1); - Moderation mods{system_memory()}; + Moderation mods{os_memory()}; EXPECT_EQ(mod_list_unpack(&mods, packed.end().base(), 0, 1), -1); } TEST(ModList, HashOfEmptyModListZeroesOutBuffer) { - const Random *rng = system_random(); + const Random *rng = os_random(); ASSERT_NE(rng, nullptr); - Moderation mods{system_memory()}; + Moderation mods{os_memory()}; // Fill with random data, check that it's zeroed. ModerationHash hash; @@ -98,21 +100,21 @@ TEST(ModList, HashOfEmptyModListZeroesOutBuffer) TEST(ModList, RemoveIndexFromEmptyModListFails) { - Moderation mods{system_memory()}; + Moderation mods{os_memory()}; EXPECT_FALSE(mod_list_remove_index(&mods, 0)); EXPECT_FALSE(mod_list_remove_index(&mods, UINT16_MAX)); } TEST(ModList, RemoveEntryFromEmptyModListFails) { - Moderation mods{system_memory()}; + Moderation mods{os_memory()}; uint8_t sig_pk[32] = {0}; EXPECT_FALSE(mod_list_remove_entry(&mods, sig_pk)); } TEST(ModList, ModListRemoveIndex) { - Moderation mods{system_memory()}; + Moderation mods{os_memory()}; uint8_t sig_pk[32] = {1}; EXPECT_TRUE(mod_list_add_entry(&mods, sig_pk)); EXPECT_TRUE(mod_list_remove_index(&mods, 0)); @@ -120,20 +122,20 @@ TEST(ModList, ModListRemoveIndex) TEST(ModList, CleanupOnEmptyModsIsNoop) { - Moderation mods{system_memory()}; + Moderation mods{os_memory()}; mod_list_cleanup(&mods); } TEST(ModList, EmptyModListCannotVerifyAnySigPk) { - Moderation mods{system_memory()}; + Moderation mods{os_memory()}; uint8_t sig_pk[32] = {1}; EXPECT_FALSE(mod_list_verify_sig_pk(&mods, sig_pk)); } TEST(ModList, ModListAddVerifyRemoveSigPK) { - Moderation mods{system_memory()}; + Moderation mods{os_memory()}; uint8_t sig_pk[32] = {1}; EXPECT_TRUE(mod_list_add_entry(&mods, sig_pk)); EXPECT_TRUE(mod_list_verify_sig_pk(&mods, sig_pk)); @@ -143,7 +145,7 @@ TEST(ModList, ModListAddVerifyRemoveSigPK) TEST(ModList, ModListHashCheck) { - Moderation mods1{system_memory()}; + Moderation mods1{os_memory()}; uint8_t sig_pk1[32] = {1}; std::array hash1; @@ -165,7 +167,7 @@ TEST(SanctionsList, PackingIntoUndersizedBufferFails) TEST(SanctionsList, PackUnpackSanctionsCreds) { - Moderation mod{system_memory()}; + Moderation mod{os_memory()}; std::array packed; EXPECT_EQ(sanctions_creds_pack(&mod.sanctions_creds, packed.data()), MOD_SANCTIONS_CREDS_SIZE); EXPECT_EQ( @@ -176,8 +178,9 @@ struct SanctionsListMod : ::testing::Test { protected: ExtPublicKey pk; ExtSecretKey sk; - Logger *log = logger_new(); - Moderation mod{system_memory()}; + const Memory *mem = os_memory(); + Logger *log = logger_new(mem); + Moderation mod{os_memory()}; Mod_Sanction sanctions[2] = {}; const uint8_t sanctioned_pk1[32] = {1}; diff --git a/toxcore/group_onion_announce.c b/toxcore/group_onion_announce.c index b797770e520..8a2f8398d98 100644 --- a/toxcore/group_onion_announce.c +++ b/toxcore/group_onion_announce.c @@ -69,10 +69,10 @@ void gca_onion_init(GC_Announces_List *group_announce, Onion_Announce *onion_a) #ifndef VANILLA_NACL 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; @@ -102,7 +102,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 5c6d64ec594..6c566bd4066 100644 --- a/toxcore/group_onion_announce.h +++ b/toxcore/group_onion_announce.h @@ -14,9 +14,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 ecdd965610c..eb6391f5372 100644 --- a/toxcore/group_pack.c +++ b/toxcore/group_pack.c @@ -119,7 +119,7 @@ static bool load_unpack_mod_list(GC_Chat *chat, Bin_Unpack *bu) return false; } - 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"); @@ -130,17 +130,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; } @@ -232,7 +232,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"); @@ -241,7 +241,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; } @@ -249,7 +249,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; } @@ -322,7 +322,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) { @@ -340,7 +340,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() @@ -374,7 +374,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) { @@ -395,13 +395,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 e3674873804..448e4f5510c 100644 --- a/toxcore/list.c +++ b/toxcore/list.c @@ -114,7 +114,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; @@ -122,7 +122,7 @@ static bool resize(BS_List *list, uint32_t new_size) list->data = data; - int *ids = (int *)realloc(list->ids, sizeof(int) * new_size); + 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) } -int bs_list_init(BS_List *list, uint32_t element_size, uint32_t initial_capacity) +int bs_list_init(BS_List *list, uint32_t element_size, uint32_t initial_capacity, const Memory *mem) { + list->mem = mem; + // set initial values list->n = 0; list->element_size = element_size; @@ -161,10 +163,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 a7c0e56c061..5d04dfa74db 100644 --- a/toxcore/list.h +++ b/toxcore/list.h @@ -14,13 +14,16 @@ #include #include -#include "attributes.h" +#include "mem.h" +#include "tox_attributes.h" #ifdef __cplusplus extern "C" { #endif 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 @@ -37,7 +40,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); +int bs_list_init(BS_List *list, uint32_t element_size, uint32_t initial_capacity, 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 5bffb8a1433..8d39433948d 100644 --- a/toxcore/list_test.cc +++ b/toxcore/list_test.cc @@ -2,26 +2,33 @@ #include +#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); + bs_list_init(&list, sizeof(int), 10, mem_); bs_list_free(&list); } -TEST(List, CreateAndDestroyWithZeroSize) +TEST_F(List, CreateAndDestroyWithZeroSize) { BS_List list; - bs_list_init(&list, sizeof(int), 0); + bs_list_init(&list, sizeof(int), 0, mem_); bs_list_free(&list); } -TEST(List, DeleteFromEmptyList) +TEST_F(List, DeleteFromEmptyList) { BS_List list; - bs_list_init(&list, sizeof(int), 0); + bs_list_init(&list, sizeof(int), 0, 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 d281a66085a..a0754637503 100644 --- a/toxcore/logger.c +++ b/toxcore/logger.c @@ -17,6 +17,8 @@ #include "ccompat.h" struct Logger { + const Memory *mem; + logger_cb *callback; void *context; void *userdata; @@ -59,6 +61,7 @@ static void logger_stderr_handler(void *context, Logger_Level level, const char } static const Logger logger_stderr = { + nullptr, logger_stderr_handler, nullptr, nullptr, @@ -68,18 +71,31 @@ static const Logger logger_stderr = { * Public Functions */ -Logger *logger_new(void) +Logger *logger_new(const Memory *mem) { - return (Logger *)calloc(1, sizeof(Logger)); + Logger *log = (Logger *)mem_alloc(mem, sizeof(Logger)); + + if (log == nullptr) { + return nullptr; + } + + log->mem = mem; + + return log; } void logger_kill(Logger *log) { - free(log); + if (log == nullptr) { + return; + } + + mem_delete(log->mem, 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/logger.h b/toxcore/logger.h index ee5838ae734..b3fe80c80f3 100644 --- a/toxcore/logger.h +++ b/toxcore/logger.h @@ -11,7 +11,8 @@ #include -#include "attributes.h" +#include "mem.h" +#include "tox_attributes.h" #ifdef __cplusplus extern "C" { @@ -38,7 +39,8 @@ typedef void logger_cb(void *context, Logger_Level level, const char *file, int /** * Creates a new logger with logging disabled (callback is NULL) by default. */ -Logger *logger_new(void); +non_null() +Logger *logger_new(const Memory *mem); /** * Frees all resources associated with the logger. diff --git a/toxcore/mem.c b/toxcore/mem.c index a15b9728df6..f7295a7eb2f 100644 --- a/toxcore/mem.c +++ b/toxcore/mem.c @@ -1,60 +1,32 @@ /* 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 "ccompat.h" -nullable(1) -static void *sys_malloc(void *obj, uint32_t size) -{ - return malloc(size); -} - -nullable(1) -static void *sys_calloc(void *obj, uint32_t nmemb, uint32_t size) -{ - return calloc(nmemb, size); -} - -nullable(1, 2) -static void *sys_realloc(void *obj, void *ptr, uint32_t size) -{ - return realloc(ptr, size); -} - -nullable(1, 2) -static void sys_free(void *obj, void *ptr) -{ - free(ptr); -} - -static const Memory_Funcs system_memory_funcs = { - sys_malloc, - sys_calloc, - sys_realloc, - sys_free, -}; -static const Memory system_memory_obj = {&system_memory_funcs}; - -const Memory *system_memory(void) +void *mem_balloc(const Memory *mem, uint32_t size) { - return &system_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; } @@ -66,7 +38,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; } @@ -78,11 +53,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 a9d9e1d2c9a..11555ef0d69 100644 --- a/toxcore/mem.h +++ b/toxcore/mem.h @@ -11,31 +11,14 @@ #include // uint*_t -#include "attributes.h" +#include "tox_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 *system_memory(void); +typedef Tox_Memory Memory; /** * @brief Allocate an array of a given size for built-in types. @@ -45,6 +28,14 @@ const Memory *system_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 f787036616c..bdd567cf07e 100644 --- a/toxcore/mem_test.cc +++ b/toxcore/mem_test.cc @@ -2,6 +2,8 @@ #include +#include "os_memory.h" + namespace { TEST(Mem, AllocLarge) @@ -9,7 +11,7 @@ TEST(Mem, AllocLarge) // Mebi prefix: https://en.wikipedia.org/wiki/Binary_prefix. constexpr uint32_t MI = 1024 * 1024; - const Memory *mem = system_memory(); + const Memory *mem = os_memory(); void *ptr = mem_valloc(mem, 4, MI); EXPECT_NE(ptr, nullptr); @@ -22,18 +24,18 @@ TEST(Mem, AllocOverflow) // Gibi prefix. constexpr uint32_t GI = 1024 * 1024 * 1024; - const Memory *mem = system_memory(); + 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/mono_time.c b/toxcore/mono_time.c index 418deec494b..75bb9ea2bcd 100644 --- a/toxcore/mono_time.c +++ b/toxcore/mono_time.c @@ -32,6 +32,7 @@ #include #include "ccompat.h" +#include "tox_time_impl.h" /** don't call into system billions of times for no reason */ struct Mono_Time { @@ -49,8 +50,8 @@ struct Mono_Time { pthread_rwlock_t *time_update_lock; #endif - mono_time_current_time_cb *current_time_callback; - void *user_data; + const Tox_Time *tm; + Tox_Time default_tm; }; #ifdef OS_WIN32 @@ -121,8 +122,12 @@ static uint64_t current_time_monotonic_default(void *user_data) #endif // !__APPLE__ #endif // !OS_WIN32 +static const Tox_Time_Funcs os_time_funcs = { + current_time_monotonic_default, +}; + -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)); @@ -145,7 +150,10 @@ Mono_Time *mono_time_new(const Memory *mem, mono_time_current_time_cb *current_t } #endif - mono_time_set_current_time_callback(mono_time, current_time_callback, user_data); + mono_time->default_tm.funcs = &os_time_funcs; + mono_time->default_tm.user_data = mono_time; + + mono_time_set_current_time_callback(mono_time, tm); #ifdef OS_WIN32 @@ -196,7 +204,7 @@ void mono_time_update(Mono_Time *mono_time) pthread_mutex_lock(&mono_time->last_clock_lock); mono_time->last_clock_update = true; #endif - cur_time = mono_time->current_time_callback(mono_time->user_data) / 1000ULL; + cur_time = tox_time_monotonic(mono_time->tm) / 1000ULL; cur_time += mono_time->base_time; #ifdef OS_WIN32 pthread_mutex_unlock(&mono_time->last_clock_lock); @@ -233,16 +241,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 : &mono_time->default_tm; } /** @@ -257,7 +258,7 @@ uint64_t current_time_monotonic(Mono_Time *mono_time) * but must protect against other threads */ pthread_mutex_lock(&mono_time->last_clock_lock); #endif - const uint64_t cur_time = mono_time->current_time_callback(mono_time->user_data); + const uint64_t cur_time = tox_time_monotonic(mono_time->tm); #ifdef OS_WIN32 pthread_mutex_unlock(&mono_time->last_clock_lock); #endif diff --git a/toxcore/mono_time.h b/toxcore/mono_time.h index fa1df840e0c..b98bcf971ae 100644 --- a/toxcore/mono_time.h +++ b/toxcore/mono_time.h @@ -8,8 +8,9 @@ #include #include -#include "attributes.h" #include "mem.h" +#include "tox_attributes.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); @@ -86,9 +85,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 } diff --git a/toxcore/mono_time_test.cc b/toxcore/mono_time_test.cc index 379b606c8e5..6544dbac162 100644 --- a/toxcore/mono_time_test.cc +++ b/toxcore/mono_time_test.cc @@ -2,12 +2,16 @@ #include +#include "os_memory.h" +#include "tox_time_impl.h" + namespace { TEST(MonoTime, UnixTimeIncreasesOverTime) { - const Memory *mem = system_memory(); - Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); + const Memory *mem = os_memory(); + ASSERT_NE(mem, nullptr); + Mono_Time *mono_time = mono_time_new(mem, nullptr); ASSERT_NE(mono_time, nullptr); mono_time_update(mono_time); @@ -25,8 +29,9 @@ TEST(MonoTime, UnixTimeIncreasesOverTime) TEST(MonoTime, IsTimeout) { - const Memory *mem = system_memory(); - Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); + const Memory *mem = os_memory(); + ASSERT_NE(mem, nullptr); + Mono_Time *mono_time = mono_time_new(mem, nullptr); ASSERT_NE(mono_time, nullptr); uint64_t const start = mono_time_get(mono_time); @@ -43,14 +48,19 @@ TEST(MonoTime, IsTimeout) TEST(MonoTime, CustomTime) { - const Memory *mem = system_memory(); - Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); + const Memory *mem = os_memory(); + ASSERT_NE(mem, 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); @@ -65,6 +75,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 4d2aaac1b01..fbc46d2bcf8 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -232,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; @@ -247,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]; @@ -255,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; @@ -270,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; @@ -310,14 +310,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; @@ -346,7 +346,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; @@ -443,7 +443,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; @@ -451,7 +451,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; @@ -483,14 +483,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; @@ -530,7 +530,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; } @@ -544,7 +544,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; @@ -1100,7 +1100,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); @@ -1275,7 +1275,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; @@ -1696,7 +1696,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; } @@ -3155,7 +3155,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); + bs_list_init(&temp->ip_port_list, sizeof(IP_Port), 8, mem); return temp; } diff --git a/toxcore/network.c b/toxcore/network.c index 90b3d2d919a..ef3a4102210 100644 --- a/toxcore/network.c +++ b/toxcore/network.c @@ -37,12 +37,6 @@ #include "network.h" -#ifdef PLAN9 -#include // Plan 9 requires this is imported first -// Comment line here to avoid reordering by source code formatters. -#include -#endif - #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 @@ -53,11 +47,6 @@ #include #endif -#ifdef __APPLE__ -#include -#include -#endif - #if !defined(OS_WIN32) #include #include @@ -87,21 +76,12 @@ #include #include -#ifndef VANILLA_NACL -// Used for sodium_init() -#include -#endif - #include "ccompat.h" #include "logger.h" #include "mono_time.h" +#include "os_network_impl.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 - #ifndef IPV6_ADD_MEMBERSHIP #ifdef IPV6_JOIN_GROUP #define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP @@ -472,147 +452,9 @@ bool sock_valid(Socket sock) return sock.sock != net_invalid_socket.sock; } -struct Network_Addr { - struct sockaddr_storage addr; - size_t size; -}; - -non_null() -static int sys_close(void *obj, int sock) -{ -#if defined(OS_WIN32) - return closesocket(sock); -#else // !OS_WIN32 - return close(sock); -#endif -} - -non_null() -static int sys_accept(void *obj, int sock) -{ - return accept(sock, nullptr, nullptr); -} - -non_null() -static int sys_bind(void *obj, int sock, const Network_Addr *addr) -{ - return bind(sock, (const struct sockaddr *)&addr->addr, addr->size); -} - -non_null() -static int sys_listen(void *obj, int sock, int backlog) -{ - return listen(sock, backlog); -} - -non_null() -static int sys_recvbuf(void *obj, int sock) -{ -#ifdef OS_WIN32 - u_long count = 0; - ioctlsocket(sock, FIONREAD, &count); -#else - int count = 0; - ioctl(sock, FIONREAD, &count); -#endif - - return count; -} - -non_null() -static int sys_recv(void *obj, int sock, uint8_t *buf, size_t len) -{ - return recv(sock, (char *)buf, len, MSG_NOSIGNAL); -} - -non_null() -static int sys_send(void *obj, int sock, const uint8_t *buf, size_t len) -{ - return send(sock, (const char *)buf, len, MSG_NOSIGNAL); -} - -non_null() -static int sys_sendto(void *obj, int sock, const uint8_t *buf, size_t len, const Network_Addr *addr) { - return sendto(sock, (const char *)buf, len, 0, (const struct sockaddr *)&addr->addr, addr->size); -} - -non_null() -static int sys_recvfrom(void *obj, int sock, uint8_t *buf, size_t len, Network_Addr *addr) { - socklen_t size = addr->size; - const int ret = recvfrom(sock, (char *)buf, len, 0, (struct sockaddr *)&addr->addr, &size); - addr->size = size; - return ret; -} - -non_null() -static int sys_socket(void *obj, int domain, int type, int proto) -{ - return (int)socket(domain, type, proto); -} - -non_null() -static int sys_socket_nonblock(void *obj, int sock, bool nonblock) -{ -#ifdef OS_WIN32 - u_long mode = nonblock ? 1 : 0; - return ioctlsocket(sock, FIONBIO, &mode); -#else - return fcntl(sock, F_SETFL, O_NONBLOCK, nonblock ? 1 : 0); -#endif /* OS_WIN32 */ -} - -non_null() -static int sys_getsockopt(void *obj, int sock, int level, int optname, void *optval, size_t *optlen) -{ - socklen_t len = *optlen; - const int ret = getsockopt(sock, level, optname, optval, &len); - *optlen = len; - return ret; -} - -non_null() -static int sys_setsockopt(void *obj, int sock, int level, int optname, const void *optval, size_t optlen) -{ - return setsockopt(sock, level, optname, optval, optlen); -} - -static const Network_Funcs system_network_funcs = { - sys_close, - sys_accept, - sys_bind, - sys_listen, - sys_recvbuf, - sys_recv, - sys_recvfrom, - sys_send, - sys_sendto, - sys_socket, - sys_socket_nonblock, - sys_getsockopt, - sys_setsockopt, -}; -static const Network system_network_obj = {&system_network_funcs}; - -const Network *system_network(void) -{ -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - if ((true)) { - return nullptr; - } -#endif -#ifdef OS_WIN32 - WSADATA wsaData; - - if (WSAStartup(MAKEWORD(2, 2), &wsaData) != NO_ERROR) { - return nullptr; - } -#endif - return &system_network_obj; -} - #if 0 -/* TODO(iphydf): Call this from functions that use `system_network()`. */ -void system_network_deinit(const Network *ns) +/* TODO(iphydf): Call this from functions that use `os_network()`. */ +void os_network_deinit(const Network *ns) { #ifdef OS_WIN32 WSACleanup(); @@ -623,13 +465,13 @@ void system_network_deinit(const Network *ns) 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.sock, level, optname, optval, optlen); + return tox_network_setsockopt(ns, sock.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.sock, level, optname, optval, optlen); + return tox_network_getsockopt(ns, sock.sock, level, optname, optval, optlen); } non_null() @@ -804,7 +646,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.sock, buf, len); + const int res = tox_network_send(ns, sock.sock, buf, len); loglogdata(log, "T=>", buf, len, ip_port, res); return res; } @@ -814,13 +656,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.sock, buf, len, addr); + return tox_network_sendto(ns, sock.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.sock, buf, len); + const int res = tox_network_recv(ns, sock.sock, buf, len); loglogdata(log, "=>T", buf, len, ip_port, res); return res; } @@ -829,35 +671,35 @@ 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.sock, buf, len, addr); + return tox_network_recvfrom(ns, sock.sock, buf, len, addr); } int net_listen(const Network *ns, Socket sock, int backlog) { - return ns->funcs->listen(ns->obj, sock.sock, backlog); + return tox_network_listen(ns, sock.sock, backlog); } non_null() static int net_bind(const Network *ns, Socket sock, const Network_Addr *addr) { - return ns->funcs->bind(ns->obj, sock.sock, addr); + return tox_network_bind(ns, sock.sock, addr); } Socket net_accept(const Network *ns, Socket sock) { - const Socket newsock = {ns->funcs->accept(ns->obj, sock.sock)}; + const Socket newsock = {tox_network_accept(ns, sock.sock)}; return newsock; } /** Close the socket. */ void kill_sock(const Network *ns, Socket sock) { - ns->funcs->close(ns->obj, sock.sock); + tox_network_close(ns, sock.sock); } bool set_socket_nonblock(const Network *ns, Socket sock) { - return ns->funcs->socket_nonblock(ns->obj, sock.sock, true) == 0; + return tox_network_socket_nonblock(ns, sock.sock, true) == 0; } bool set_socket_nosigpipe(const Network *ns, Socket sock) @@ -962,34 +804,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; } @@ -1013,11 +862,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(); @@ -1028,30 +880,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; } @@ -1064,11 +919,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; } @@ -1222,23 +1079,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; + Network_Addr *addr = net_addr_new(nullptr, 0, mem); - memset(&addr.addr, 0, sizeof(struct sockaddr_storage)); + 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); @@ -1249,6 +1114,7 @@ Networking_Core *new_networking_ex( portptr = &addr6->sin6_port; } else { mem_delete(mem, temp); + net_addr_free(addr, mem); return nullptr; } @@ -1305,7 +1171,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; @@ -1325,6 +1191,7 @@ Networking_Core *new_networking_ex( *error = 0; } + net_addr_free(addr, mem); return temp; } @@ -1349,6 +1216,7 @@ Networking_Core *new_networking_ex( *error = 1; } + net_addr_free(addr, mem); return nullptr; } @@ -1777,6 +1645,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; } @@ -1788,7 +1657,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)) { *res = (IP_Port *)mem_alloc(mem, sizeof(IP_Port)); - assert(*res != nullptr); + + if (*res == nullptr) { + return -1; + } + IP_Port *ip_port = *res; ip_port->ip.ip.v4.uint32 = net_htonl(0x7F000003); // 127.0.0.3 ip_port->ip.family = *make_tox_family(AF_INET); @@ -1877,27 +1750,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) @@ -1905,13 +1782,13 @@ 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); - const Socket sock = {ns->funcs->socket(ns->obj, platform_domain, platform_type, platform_prot)}; + const Socket sock = {tox_network_socket(ns, platform_domain, platform_type, platform_prot)}; return sock; } uint16_t net_socket_data_recv_buffer(const Network *ns, Socket sock) { - const int count = ns->funcs->recvbuf(ns->obj, sock.sock); + const int count = tox_network_recvbuf(ns, sock.sock); return (uint16_t)max_s32(0, min_s32(count, UINT16_MAX)); } diff --git a/toxcore/network.h b/toxcore/network.h index 2f518c1d910..59b4a10a019 100644 --- a/toxcore/network.h +++ b/toxcore/network.h @@ -15,62 +15,12 @@ #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 int net_close_cb(void *obj, int sock); -typedef int net_accept_cb(void *obj, int sock); -typedef int net_bind_cb(void *obj, int sock, const Network_Addr *addr); -typedef int net_listen_cb(void *obj, int sock, int backlog); -typedef int net_recvbuf_cb(void *obj, int sock); -typedef int net_recv_cb(void *obj, int sock, uint8_t *buf, size_t len); -typedef int net_recvfrom_cb(void *obj, int sock, uint8_t *buf, size_t len, Network_Addr *addr); -typedef int net_send_cb(void *obj, int sock, const uint8_t *buf, size_t len); -typedef int net_sendto_cb(void *obj, int sock, const uint8_t *buf, size_t len, const Network_Addr *addr); -typedef int net_socket_cb(void *obj, int domain, int type, int proto); -typedef int net_socket_nonblock_cb(void *obj, int sock, bool nonblock); -typedef int net_getsockopt_cb(void *obj, int sock, int level, int optname, void *optval, size_t *optlen); -typedef int net_setsockopt_cb(void *obj, int 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_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 *system_network(void); - typedef struct Family { uint8_t value; } Family; @@ -267,6 +217,8 @@ typedef struct Socket { int sock; } Socket; +typedef Tox_Network Network; + non_null() Socket net_socket(const Network *ns, Family domain, int type, int protocol); @@ -560,7 +512,7 @@ void net_freeipport(const Memory *mem, IP_Port *ip_ports); * @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/onion.c b/toxcore/onion.c index d7ec8bfd788..ecfbae86594 100644 --- a/toxcore/onion.c +++ b/toxcore/onion.c @@ -178,7 +178,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; @@ -197,7 +197,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, SIZEOF_VLA(step1), - 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; @@ -207,7 +207,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, SIZEOF_VLA(step2), - 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; @@ -218,7 +218,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, SIZEOF_VLA(step3), - 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; @@ -238,7 +238,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; @@ -257,7 +257,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, SIZEOF_VLA(step1), - 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; @@ -266,7 +266,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, SIZEOF_VLA(step2), - 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; @@ -328,7 +328,7 @@ static int handle_send_initial(void *object, const IP_Port *source, const uint8_ } const int len = decrypt_data_symmetric(shared_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE, - length - (1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE), plain); + length - (1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE), plain, onion->mem); if (len != length - (1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE)) { return 1; @@ -364,7 +364,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; @@ -404,7 +404,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; @@ -427,7 +427,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; @@ -467,7 +467,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; @@ -497,7 +497,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; @@ -537,7 +537,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; @@ -586,7 +586,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; @@ -635,7 +635,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 7f71c2493d3..a3691a5e4e1 100644 --- a/toxcore/onion.h +++ b/toxcore/onion.h @@ -103,7 +103,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. @@ -118,7 +118,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 551e7b1fae9..99f66f2dfa3 100644 --- a/toxcore/onion_announce.c +++ b/toxcore/onion_announce.c @@ -97,7 +97,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) { @@ -117,7 +117,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; @@ -140,8 +140,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; @@ -162,7 +163,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) { @@ -186,14 +187,14 @@ int create_data_request(const Random *rng, uint8_t *packet, uint16_t max_packet_ * return -1 on failure. * return 0 on success. */ -int send_announce_request(const Networking_Core *net, const Random *rng, +int send_announce_request(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)) { @@ -201,7 +202,7 @@ int send_announce_request(const Networking_Core *net, const Random *rng, } 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; @@ -230,19 +231,20 @@ int send_announce_request(const Networking_Core *net, const Random *rng, * return -1 on failure. * return 0 on success. */ -int send_data_request(const Networking_Core *net, const Random *rng, const Onion_Path *path, const IP_Port *dest, +int send_data_request(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; @@ -448,7 +450,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); @@ -535,7 +537,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 857f4706ace..95a637c1613 100644 --- a/toxcore/onion_announce.h +++ b/toxcore/onion_announce.h @@ -59,9 +59,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. * @@ -76,8 +77,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. * @@ -94,7 +96,7 @@ int create_data_request(const Random *rng, uint8_t *packet, uint16_t max_packet_ * return 0 on success. */ non_null() -int send_announce_request(const Networking_Core *net, const Random *rng, +int send_announce_request(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, @@ -117,7 +119,8 @@ int send_announce_request(const Networking_Core *net, const Random *rng, * return 0 on success. */ non_null() -int send_data_request(const Networking_Core *net, const Random *rng, const Onion_Path *path, const IP_Port *dest, +int send_data_request(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 c15eb555642..e3f91773eb8 100644 --- a/toxcore/onion_client.c +++ b/toxcore/onion_client.c @@ -526,7 +526,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; @@ -543,7 +543,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; @@ -655,7 +655,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 { @@ -663,7 +663,7 @@ 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 @@ -671,7 +671,7 @@ static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, con 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); @@ -954,7 +954,8 @@ static int handle_announce_response(void *object, const IP_Port *source, const u len = decrypt_data(public_key, nc_get_self_secret_key(onion_c->c), packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH, packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE, - length - (1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE), plain); + length - (1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE), plain, + onion_c->mem); } else { if (!onion_c->friends_list[num - 1].is_valid) { return 1; @@ -963,7 +964,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 + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH, packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE, - length - (1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE), plain); + length - (1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE), plain, + onion_c->mem); } if ((uint32_t)len != plain_size) { @@ -1044,7 +1046,8 @@ static int handle_announce_response_old(void *object, const IP_Port *source, con len = decrypt_data(public_key, nc_get_self_secret_key(onion_c->c), packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH, packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE, - length - (1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE), plain); + length - (1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE), plain, + onion_c->mem); } else { if (!onion_c->friends_list[num - 1].is_valid) { return 1; @@ -1053,7 +1056,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 + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH, packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE, - length - (1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE), plain); + length - (1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE), plain, + onion_c->mem); } if ((uint32_t)len != SIZEOF_VLA(plain)) { @@ -1103,7 +1107,8 @@ static int handle_data_response(void *object, const IP_Port *source, const uint8 VLA(uint8_t, temp_plain, length - ONION_DATA_RESPONSE_MIN_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 != SIZEOF_VLA(temp_plain)) { return 1; @@ -1112,7 +1117,8 @@ static int handle_data_response(void *object, const IP_Port *source, const uint8 VLA(uint8_t, plain, SIZEOF_VLA(temp_plain) - DATA_IN_RESPONSE_MIN_SIZE); len = decrypt_data(temp_plain, nc_get_self_secret_key(onion_c->c), packet + 1, temp_plain + CRYPTO_PUBLIC_KEY_SIZE, - SIZEOF_VLA(temp_plain) - CRYPTO_PUBLIC_KEY_SIZE, plain); + SIZEOF_VLA(temp_plain) - CRYPTO_PUBLIC_KEY_SIZE, plain, + onion_c->mem); if ((uint32_t)len != SIZEOF_VLA(plain)) { return 1; @@ -1270,7 +1276,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 != SIZEOF_VLA(packet)) { return -1; @@ -1287,7 +1294,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, SIZEOF_VLA(packet)); if (len == -1) { @@ -1328,7 +1335,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 != SIZEOF_VLA(temp)) { return -1; @@ -1337,7 +1345,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, SIZEOF_VLA(temp), CRYPTO_PACKET_DHTPK); + onion_c->friends_list[friend_num].dht_public_key, temp, SIZEOF_VLA(temp), CRYPTO_PACKET_DHTPK, onion_c->mem); assert(len <= UINT16_MAX); const Packet packet = {packet_data, (uint16_t)len}; @@ -1366,7 +1374,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 00000000000..a9866b9ec84 --- /dev/null +++ b/toxcore/os_log.c @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2022-2023 The TokTok team. + */ +#include "os_log.h" + +#include "ccompat.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 00000000000..85e4b82efa0 --- /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 +} +#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 00000000000..d393b1e72cf --- /dev/null +++ b/toxcore/os_memory.c @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2022-2023 The TokTok team. + */ +#include "os_memory.h" + +#include + +#include "ccompat.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 00000000000..29b04868c36 --- /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 +} +#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 00000000000..dbfec602e93 --- /dev/null +++ b/toxcore/os_network.c @@ -0,0 +1,288 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2022-2023 The TokTok team. + */ +#ifdef __APPLE__ +#define _DARWIN_C_SOURCE +#endif + +// For Solaris. +#ifdef __sun +#define __EXTENSIONS__ 1 +#endif + +// For Linux (and some BSDs). +#ifndef _XOPEN_SOURCE +#define _XOPEN_SOURCE 700 +#endif + +#if defined(_WIN32) && _WIN32_WINNT >= _WIN32_WINNT_WINXP +#undef _WIN32_WINNT +#define _WIN32_WINNT 0x501 +#endif + +#if !defined(OS_WIN32) && (defined(_WIN32) || defined(__WIN32__) || defined(WIN32)) +#define OS_WIN32 +#endif + +#if defined(OS_WIN32) && !defined(WINVER) +// Windows XP +#define WINVER 0x0501 +#endif + +#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 + +#if !defined(OS_WIN32) +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __sun +#include +#include +#endif + +#else +#ifndef IPV6_V6ONLY +#define IPV6_V6ONLY 27 +#endif +#endif + +#include +#include // memcpy + +#include "ccompat.h" +#include "os_network_impl.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 + +non_null() +static int os_close(void *self, int sock) +{ +#if defined(OS_WIN32) + return closesocket(sock); +#else // !OS_WIN32 + return close(sock); +#endif +} + +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 int os_accept(void *self, int sock) +{ + return accept(sock, nullptr, nullptr); +} + +non_null() +static int os_bind(void *self, int sock, const Network_Addr *addr) +{ + return bind(sock, (const struct sockaddr *)net_addr_get_addr(addr), net_addr_get_size(addr)); +} + +non_null() +static int os_listen(void *self, int sock, int backlog) +{ + return listen(sock, backlog); +} + +non_null() +static int os_recvbuf(void *self, int sock) +{ +#ifdef OS_WIN32 + u_long count = 0; + ioctlsocket(sock, FIONREAD, &count); +#else + int count = 0; + ioctl(sock, FIONREAD, &count); +#endif + + return count; +} + +non_null() +static int os_recv(void *self, int sock, uint8_t *buf, size_t len) +{ + return recv(sock, (char *)buf, len, MSG_NOSIGNAL); +} + +non_null() +static int os_send(void *self, int sock, const uint8_t *buf, size_t len) +{ + return send(sock, (const char *)buf, len, MSG_NOSIGNAL); +} + +non_null() +static int os_sendto(void *self, int sock, const uint8_t *buf, size_t len, const Network_Addr *addr) { + return sendto(sock, (const char *)buf, len, 0, (const struct sockaddr *)&addr->addr, addr->size); +} + +non_null() +static int os_recvfrom(void *self, int sock, uint8_t *buf, size_t len, Network_Addr *addr) { + socklen_t size = addr->size; + const int ret = recvfrom(sock, (char *)buf, len, 0, (struct sockaddr *)&addr->addr, &size); + addr->size = size; + return ret; +} + +non_null() +static int os_socket(void *self, int domain, int type, int proto) +{ + return (int)socket(domain, type, proto); +} + +non_null() +static int os_socket_nonblock(void *self, int sock, bool nonblock) +{ +#ifdef OS_WIN32 + u_long mode = nonblock ? 1 : 0; + return ioctlsocket(sock, FIONBIO, &mode); +#else + return fcntl(sock, F_SETFL, O_NONBLOCK, nonblock ? 1 : 0); +#endif /* OS_WIN32 */ +} + +non_null() +static int os_getsockopt(void *self, int sock, int level, int optname, void *optval, size_t *optlen) +{ + socklen_t len = *optlen; + const int ret = getsockopt(sock, level, optname, optval, &len); + *optlen = len; + return ret; +} + +non_null() +static int os_setsockopt(void *self, int sock, int level, int optname, const void *optval, size_t optlen) +{ + return setsockopt(sock, level, optname, optval, optlen); +} + +static const Tox_Network_Funcs os_network_funcs = { + os_close, + os_accept, + os_bind, + os_listen, + 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}; + +const Tox_Network *os_network(void) +{ +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + if ((true)) { + return nullptr; + } +#endif +#ifdef OS_WIN32 + WSADATA wsaData; + + if (WSAStartup(MAKEWORD(2, 2), &wsaData) != NO_ERROR) { + return nullptr; + } +#endif + return &os_network_obj; +} diff --git a/toxcore/os_network.h b/toxcore/os_network.h new file mode 100644 index 00000000000..2e49e52ba2b --- /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 +} +#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 00000000000..26cacf6b410 --- /dev/null +++ b/toxcore/os_network_impl.h @@ -0,0 +1,34 @@ +/* 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 "tox_network.h" + +#ifdef __cplusplus +extern "C" { +#endif + +non_null() Network_Addr *net_addr_new(const void *data, size_t size, const Tox_Memory *mem); +non_null() 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 +} +#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 00000000000..0ebf55636ce --- /dev/null +++ b/toxcore/os_random.c @@ -0,0 +1,60 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2022-2023 The TokTok team. + */ +#include "os_random.h" + +#ifndef VANILLA_NACL +// We use libsodium by default. +#include +#else +#include +#endif + +#include "ccompat.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) +{ +#ifdef VANILLA_NACL + if (upper_bound == 0) { + return 0; + } + + uint32_t randnum; + os_random_bytes(self, (uint8_t *)&randnum, sizeof(randnum)); + return randnum % upper_bound; +#else + return randombytes_uniform(upper_bound); +#endif +} + +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 +#ifndef VANILLA_NACL + // 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; + } +#endif + return &os_random_obj; +} diff --git a/toxcore/os_random.h b/toxcore/os_random.h new file mode 100644 index 00000000000..99c430318cf --- /dev/null +++ b/toxcore/os_random.h @@ -0,0 +1,22 @@ +/* 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; + +const Tox_Random *os_random(void); + +#ifdef __cplusplus +} +#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 00000000000..b5fb67626a0 --- /dev/null +++ b/toxcore/os_system.c @@ -0,0 +1,33 @@ +/* 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_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 00000000000..f74864a228a --- /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 +} +#endif + +#endif // C_TOXCORE_TOXCORE_OS_SYSTEM_H diff --git a/toxcore/ping.c b/toxcore/ping.c index f8a96edfb96..63cd30882c9 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; @@ -78,7 +79,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; @@ -110,7 +112,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; @@ -144,7 +147,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; @@ -189,7 +193,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; @@ -353,6 +357,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 8ce557092e4..1924de0f39d 100644 --- a/toxcore/ping_array_test.cc +++ b/toxcore/ping_array_test.cc @@ -5,6 +5,8 @@ #include #include "mono_time.h" +#include "os_memory.h" +#include "os_random.h" namespace { @@ -29,21 +31,21 @@ using Mono_Time_Ptr = std::unique_ptr; TEST(PingArray, MinimumTimeoutIsOne) { - const Memory *mem = system_memory(); + const Memory *mem = os_memory(); EXPECT_EQ(ping_array_new(mem, 1, 0), nullptr); EXPECT_NE(Ping_Array_Ptr(ping_array_new(mem, 1, 1)), nullptr); } TEST(PingArray, MinimumArraySizeIsOne) { - const Memory *mem = system_memory(); + const Memory *mem = os_memory(); EXPECT_EQ(ping_array_new(mem, 0, 1), nullptr); EXPECT_NE(Ping_Array_Ptr(ping_array_new(mem, 1, 1)), nullptr); } TEST(PingArray, ArraySizeMustBePowerOfTwo) { - const Memory *mem = system_memory(); + const Memory *mem = os_memory(); Ping_Array_Ptr arr; arr.reset(ping_array_new(mem, 2, 1)); @@ -59,12 +61,12 @@ TEST(PingArray, ArraySizeMustBePowerOfTwo) TEST(PingArray, StoredDataCanBeRetrieved) { - const Memory *mem = system_memory(); + const Memory *mem = os_memory(); Ping_Array_Ptr const arr(ping_array_new(mem, 2, 1)); - Mono_Time_Ptr const mono_time(mono_time_new(mem, nullptr, nullptr), mem); + Mono_Time_Ptr const mono_time(mono_time_new(mem, nullptr), mem); ASSERT_NE(mono_time, nullptr); - const Random *rng = system_random(); + const Random *rng = os_random(); ASSERT_NE(rng, nullptr); uint64_t const ping_id = ping_array_add( @@ -78,12 +80,12 @@ TEST(PingArray, StoredDataCanBeRetrieved) TEST(PingArray, RetrievingDataWithTooSmallOutputBufferHasNoEffect) { - const Memory *mem = system_memory(); + const Memory *mem = os_memory(); Ping_Array_Ptr const arr(ping_array_new(mem, 2, 1)); - Mono_Time_Ptr const mono_time(mono_time_new(mem, nullptr, nullptr), mem); + Mono_Time_Ptr const mono_time(mono_time_new(mem, nullptr), mem); ASSERT_NE(mono_time, nullptr); - const Random *rng = system_random(); + const Random *rng = os_random(); ASSERT_NE(rng, nullptr); uint64_t const ping_id = ping_array_add( @@ -101,12 +103,12 @@ TEST(PingArray, RetrievingDataWithTooSmallOutputBufferHasNoEffect) TEST(PingArray, ZeroLengthDataCanBeAdded) { - const Memory *mem = system_memory(); + const Memory *mem = os_memory(); Ping_Array_Ptr const arr(ping_array_new(mem, 2, 1)); - Mono_Time_Ptr const mono_time(mono_time_new(mem, nullptr, nullptr), mem); + Mono_Time_Ptr const mono_time(mono_time_new(mem, nullptr), mem); ASSERT_NE(mono_time, nullptr); - const Random *rng = system_random(); + const Random *rng = os_random(); ASSERT_NE(rng, nullptr); uint8_t c = 0; @@ -118,10 +120,10 @@ TEST(PingArray, ZeroLengthDataCanBeAdded) TEST(PingArray, PingId0IsInvalid) { - const Memory *mem = system_memory(); + const Memory *mem = os_memory(); Ping_Array_Ptr const arr(ping_array_new(mem, 2, 1)); - Mono_Time_Ptr const mono_time(mono_time_new(mem, nullptr, nullptr), mem); + Mono_Time_Ptr const mono_time(mono_time_new(mem, nullptr), mem); ASSERT_NE(mono_time, nullptr); uint8_t c = 0; @@ -131,12 +133,12 @@ TEST(PingArray, PingId0IsInvalid) // Protection against replay attacks. TEST(PingArray, DataCanOnlyBeRetrievedOnce) { - const Memory *mem = system_memory(); + const Memory *mem = os_memory(); Ping_Array_Ptr const arr(ping_array_new(mem, 2, 1)); - Mono_Time_Ptr const mono_time(mono_time_new(mem, nullptr, nullptr), mem); + Mono_Time_Ptr const mono_time(mono_time_new(mem, nullptr), mem); ASSERT_NE(mono_time, nullptr); - const Random *rng = system_random(); + const Random *rng = os_random(); ASSERT_NE(rng, nullptr); uint8_t c = 0; @@ -149,12 +151,12 @@ TEST(PingArray, DataCanOnlyBeRetrievedOnce) TEST(PingArray, PingIdMustMatchOnCheck) { - const Memory *mem = system_memory(); + const Memory *mem = os_memory(); Ping_Array_Ptr const arr(ping_array_new(mem, 1, 1)); - Mono_Time_Ptr const mono_time(mono_time_new(mem, nullptr, nullptr), mem); + Mono_Time_Ptr const mono_time(mono_time_new(mem, nullptr), mem); ASSERT_NE(mono_time, nullptr); - const Random *rng = system_random(); + const Random *rng = os_random(); ASSERT_NE(rng, nullptr); uint8_t c = 0; diff --git a/toxcore/tox.c b/toxcore/tox.c index 4053b87392d..82f55528ffa 100644 --- a/toxcore/tox.c +++ b/toxcore/tox.c @@ -25,6 +25,7 @@ #include "mem.h" #include "mono_time.h" #include "network.h" +#include "os_system.h" #include "tox_private.h" #include "tox_struct.h" @@ -649,10 +650,9 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error) assert(opts != nullptr); const Tox_System *sys = tox_options_get_operating_system(opts); - const Tox_System default_system = tox_default_system(); if (sys == nullptr) { - sys = &default_system; + sys = os_system(); } if (sys->rng == nullptr || sys->ns == nullptr || sys->mem == nullptr) { @@ -777,7 +777,7 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error) m_options.proxy_info.ip_port.port = net_htons(tox_options_get_proxy_port(opts)); } - tox->mono_time = mono_time_new(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); @@ -838,7 +838,7 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error) return nullptr; } - if (new_groupchats(tox->mono_time, tox->m) == nullptr) { + if (new_groupchats(tox->mono_time, sys->mem, tox->m) == nullptr) { kill_messenger(tox->m); mono_time_free(tox->sys.mem, tox->mono_time); @@ -4583,3 +4583,9 @@ const Tox_System *tox_get_system(Tox *tox) assert(tox != nullptr); return &tox->sys; } + +const Tox_System *tox_new_default_system(void) +{ + const Tox_System *default_system = os_system(); + return tox_system_new(default_system->log, default_system->mem, default_system->ns, default_system->rng, default_system->tm); +} diff --git a/toxcore/tox.h b/toxcore/tox.h index d03e2b19b9b..8586615093b 100644 --- a/toxcore/tox.h +++ b/toxcore/tox.h @@ -104,6 +104,9 @@ #include #include +#include "tox_options.h" +#include "tox_system.h" + #ifdef __cplusplus extern "C" { #endif @@ -396,427 +399,6 @@ typedef enum Tox_Message_Type { /** @} */ -/** @{ - * @name Startup options - */ - -/** - * @brief Type of proxy used to connect to TCP relays. - */ -typedef enum Tox_Proxy_Type { - - /** - * Don't use a proxy. - */ - TOX_PROXY_TYPE_NONE, - - /** - * HTTP proxy using CONNECT. - */ - TOX_PROXY_TYPE_HTTP, - - /** - * SOCKS proxy for simple socket pipes. - */ - TOX_PROXY_TYPE_SOCKS5, - -} Tox_Proxy_Type; - - -/** - * @brief Type of savedata to create the Tox instance from. - */ -typedef enum Tox_Savedata_Type { - - /** - * No savedata. - */ - TOX_SAVEDATA_TYPE_NONE, - - /** - * Savedata is one that was obtained from tox_get_savedata. - */ - TOX_SAVEDATA_TYPE_TOX_SAVE, - - /** - * Savedata is a secret key of length TOX_SECRET_KEY_SIZE. - */ - TOX_SAVEDATA_TYPE_SECRET_KEY, - -} Tox_Savedata_Type; - - -/** - * @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 events_alloc inconsistency or logic errors. - */ - TOX_LOG_LEVEL_WARNING, - - /** - * Severe unexpected errors caused by external or events_alloc inconsistency. - */ - TOX_LOG_LEVEL_ERROR, - -} Tox_Log_Level; - - -/** - * @brief This event is triggered when the toxcore library logs an events_alloc 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 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. - * @param user_data The user data pointer passed to tox_new in options. - */ -typedef void tox_log_cb(Tox *tox, Tox_Log_Level level, const char *file, uint32_t line, const char *func, - const char *message, void *user_data); - - -/** - * @brief Operating system functions used by Tox. - * - * This struct is opaque and generally shouldn't be used in clients, but in - * combination with tox_private.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; - - -/** - * @brief This struct contains all the startup options for Tox. - * - * You must tox_options_new to allocate an object of this type. - * - * WARNING: Although this struct happens to be visible in the API, it is - * effectively private. Do not allocate this yourself or access members - * directly, as it *will* break binary compatibility frequently. - * - * @deprecated The memory layout of this struct (size, alignment, and field - * order) is not part of the ABI. To remain compatible, prefer to use - * tox_options_new to allocate the object and accessor functions to set the - * members. The struct will become opaque (i.e. the definition will become - * private) in v0.3.0. - */ -struct Tox_Options { - - /** - * The type of socket to create. - * - * If this is set to false, an IPv4 socket is created, which subsequently - * only allows IPv4 communication. - * If it is set to true, an IPv6 socket is created, allowing both IPv4 and - * IPv6 communication. - */ - bool ipv6_enabled; - - - /** - * Enable the use of UDP communication when available. - * - * Setting this to false will force Tox to use TCP only. Communications will - * need to be relayed through a TCP relay node, potentially slowing them down. - * - * If a proxy is enabled, UDP will be disabled if either toxcore or the - * proxy don't support proxying UDP messages. - */ - bool udp_enabled; - - - /** - * Enable local network peer discovery. - * - * Disabling this will cause Tox to not look for peers on the local network. - */ - bool local_discovery_enabled; - - - /** - * Enable storing DHT announcements and forwarding corresponding requests. - * - * Disabling this will cause Tox to ignore the relevant packets. - */ - bool dht_announcements_enabled; - - /** - * Pass communications through a proxy. - */ - Tox_Proxy_Type proxy_type; - - - /** - * The IP address or DNS name of the proxy to be used. - * - * If used, this must be non-NULL and be a valid DNS name. The name must not - * exceed TOX_MAX_HOSTNAME_LENGTH characters, and be in a NUL-terminated C string - * format (TOX_MAX_HOSTNAME_LENGTH includes the NUL byte). - * - * This member is ignored (it can be NULL) if proxy_type is TOX_PROXY_TYPE_NONE. - * - * The data pointed at by this member is owned by the user, so must - * outlive the options object. - */ - const char *proxy_host; - - - /** - * The port to use to connect to the proxy server. - * - * Ports must be in the range (1, 65535). The value is ignored if - * proxy_type is TOX_PROXY_TYPE_NONE. - */ - uint16_t proxy_port; - - - /** - * The start port of the inclusive port range to attempt to use. - * - * If both start_port and end_port are 0, the default port range will be - * used: `[33445, 33545]`. - * - * If either start_port or end_port is 0 while the other is non-zero, the - * non-zero port will be the only port in the range. - * - * Having start_port > end_port will yield the same behavior as if start_port - * and end_port were swapped. - */ - uint16_t start_port; - - - /** - * The end port of the inclusive port range to attempt to use. - */ - uint16_t end_port; - - - /** - * The port to use for the TCP server (relay). If 0, the TCP server is - * disabled. - * - * Enabling it is not required for Tox to function properly. - * - * When enabled, your Tox instance can act as a TCP relay for other Tox - * instance. This leads to increased traffic, thus when writing a client - * it is recommended to enable TCP server only if the user has an option - * to disable it. - */ - uint16_t tcp_port; - - - /** - * Enables or disables UDP hole-punching in toxcore. (Default: enabled). - */ - bool hole_punching_enabled; - - - /** - * The type of savedata to load from. - */ - Tox_Savedata_Type savedata_type; - - - /** - * The savedata. - * - * The data pointed at by this member is owned by the user, so must - * outlive the options object. - */ - const uint8_t *savedata_data; - - - /** - * The length of the savedata. - */ - size_t savedata_length; - - - /** - * Logging callback for the new tox instance. - */ - tox_log_cb *log_callback; - - - /** - * User data pointer passed to the logging callback. - */ - void *log_user_data; - - - /** - * These options are experimental, so avoid writing code that depends on - * them. Options marked "experimental" may change their behaviour or go away - * entirely in the future, or may be renamed to something non-experimental - * if they become part of the supported API. - */ - /** - * Make public API functions thread-safe using a per-instance lock. - * - * Default: false. - */ - bool experimental_thread_safety; - - /** - * Low level operating system functionality such as send/recv, random - * number generation, and memory allocation. - */ - const Tox_System *operating_system; - -}; - - -bool tox_options_get_ipv6_enabled(const struct Tox_Options *options); - -void tox_options_set_ipv6_enabled(struct Tox_Options *options, bool ipv6_enabled); - -bool tox_options_get_udp_enabled(const struct Tox_Options *options); - -void tox_options_set_udp_enabled(struct Tox_Options *options, bool udp_enabled); - -bool tox_options_get_local_discovery_enabled(const struct Tox_Options *options); - -void tox_options_set_local_discovery_enabled(struct Tox_Options *options, bool local_discovery_enabled); - -bool tox_options_get_dht_announcements_enabled(const struct Tox_Options *options); - -void tox_options_set_dht_announcements_enabled(struct Tox_Options *options, bool dht_announcements_enabled); - -Tox_Proxy_Type tox_options_get_proxy_type(const struct Tox_Options *options); - -void tox_options_set_proxy_type(struct Tox_Options *options, Tox_Proxy_Type type); - -const char *tox_options_get_proxy_host(const struct Tox_Options *options); - -void tox_options_set_proxy_host(struct Tox_Options *options, const char *host); - -uint16_t tox_options_get_proxy_port(const struct Tox_Options *options); - -void tox_options_set_proxy_port(struct Tox_Options *options, uint16_t port); - -uint16_t tox_options_get_start_port(const struct Tox_Options *options); - -void tox_options_set_start_port(struct Tox_Options *options, uint16_t start_port); - -uint16_t tox_options_get_end_port(const struct Tox_Options *options); - -void tox_options_set_end_port(struct Tox_Options *options, uint16_t end_port); - -uint16_t tox_options_get_tcp_port(const struct Tox_Options *options); - -void tox_options_set_tcp_port(struct Tox_Options *options, uint16_t tcp_port); - -bool tox_options_get_hole_punching_enabled(const struct Tox_Options *options); - -void tox_options_set_hole_punching_enabled(struct Tox_Options *options, bool hole_punching_enabled); - -Tox_Savedata_Type tox_options_get_savedata_type(const struct Tox_Options *options); - -void tox_options_set_savedata_type(struct Tox_Options *options, Tox_Savedata_Type type); - -const uint8_t *tox_options_get_savedata_data(const struct Tox_Options *options); - -void tox_options_set_savedata_data(struct Tox_Options *options, const uint8_t *data, size_t length); - -size_t tox_options_get_savedata_length(const struct Tox_Options *options); - -void tox_options_set_savedata_length(struct Tox_Options *options, size_t length); - -tox_log_cb *tox_options_get_log_callback(const struct Tox_Options *options); - -void tox_options_set_log_callback(struct Tox_Options *options, tox_log_cb *callback); - -void *tox_options_get_log_user_data(const struct Tox_Options *options); - -void tox_options_set_log_user_data(struct Tox_Options *options, void *user_data); - -bool tox_options_get_experimental_thread_safety(const struct Tox_Options *options); - -void tox_options_set_experimental_thread_safety(struct Tox_Options *options, bool experimental_thread_safety); - -const Tox_System *tox_options_get_operating_system(const struct Tox_Options *options); - -void tox_options_set_operating_system(struct Tox_Options *options, const Tox_System *operating_system); - -/** - * @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(struct 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; - - -/** - * @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. - */ -struct 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(struct Tox_Options *options); - -/** @} */ - - /** @{ * @name Creation and destruction */ @@ -911,6 +493,8 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error); */ void tox_kill(Tox *tox); +const Tox_System *tox_new_default_system(void); + const Tox_System *tox_get_system(Tox *tox); /** diff --git a/toxcore/tox_api.c b/toxcore/tox_api.c index 61c248c30d7..207bb54230c 100644 --- a/toxcore/tox_api.c +++ b/toxcore/tox_api.c @@ -1,21 +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 - #include "ccompat.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; @@ -132,80 +122,3 @@ uint32_t tox_dht_node_public_key_size(void) { return TOX_DHT_NODE_PUBLIC_KEY_SIZE; } - -//!TOKSTYLE- - -#define ACCESSORS(type, ns, name) \ -type tox_options_get_##ns##name(const struct Tox_Options *options) \ -{ \ - return options->ns##name; \ -} \ -void tox_options_set_##ns##name(struct Tox_Options *options, type name) \ -{ \ - options->ns##name = name; \ -} - -ACCESSORS(bool,, ipv6_enabled) -ACCESSORS(bool,, udp_enabled) -ACCESSORS(Tox_Proxy_Type, proxy_, type) -ACCESSORS(const char *, proxy_, host) -ACCESSORS(uint16_t, proxy_, port) -ACCESSORS(uint16_t,, start_port) -ACCESSORS(uint16_t,, end_port) -ACCESSORS(uint16_t,, tcp_port) -ACCESSORS(bool,, hole_punching_enabled) -ACCESSORS(Tox_Savedata_Type, savedata_, type) -ACCESSORS(size_t, savedata_, length) -ACCESSORS(tox_log_cb *, log_, callback) -ACCESSORS(void *, log_, user_data) -ACCESSORS(bool,, local_discovery_enabled) -ACCESSORS(bool,, dht_announcements_enabled) -ACCESSORS(bool,, experimental_thread_safety) -ACCESSORS(const Tox_System *,, operating_system) - -//!TOKSTYLE+ - -const uint8_t *tox_options_get_savedata_data(const struct Tox_Options *options) -{ - return options->savedata_data; -} - -void tox_options_set_savedata_data(struct Tox_Options *options, const uint8_t *data, size_t length) -{ - options->savedata_data = data; - options->savedata_length = length; -} - -void tox_options_default(struct Tox_Options *options) -{ - if (options != nullptr) { - const struct Tox_Options default_options = {0}; - *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); - } -} - -struct Tox_Options *tox_options_new(Tox_Err_Options_New *error) -{ - struct Tox_Options *options = (struct Tox_Options *)calloc(1, sizeof(struct 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(struct Tox_Options *options) -{ - free(options); -} diff --git a/toxcore/tox_attributes.h b/toxcore/tox_attributes.h new file mode 100644 index 00000000000..7200763a883 --- /dev/null +++ b/toxcore/tox_attributes.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2022-2023 The TokTok team. + */ + +/** + * printf and nonnull attributes for GCC/Clang and Cimple. + */ +#ifndef C_TOXCORE_TOXCORE_TOX_ATTRIBUTES_H +#define C_TOXCORE_TOXCORE_TOX_ATTRIBUTES_H + +/* No declarations here. */ + +//!TOKSTYLE- + +#ifdef __GNUC__ +#define GNU_PRINTF(f, a) __attribute__((__format__(__printf__, f, a))) +#else +#define GNU_PRINTF(f, a) +#endif + +#if defined(__GNUC__) && defined(_DEBUG) && !defined(__OPTIMIZE__) +#define non_null(...) __attribute__((__nonnull__(__VA_ARGS__))) +#else +#define non_null(...) +#endif + +#define nullable(...) + +//!TOKSTYLE+ + +#endif // C_TOXCORE_TOXCORE_TOX_ATTRIBUTES_H diff --git a/toxcore/tox_events.c b/toxcore/tox_events.c index cae662e58ef..f500a6661fe 100644 --- a/toxcore/tox_events.c +++ b/toxcore/tox_events.c @@ -14,7 +14,7 @@ #include "events/events_alloc.h" #include "mem.h" #include "tox.h" -#include "tox_private.h" +#include "tox_system_impl.h" /***************************************************** @@ -236,7 +236,7 @@ void tox_events_get_bytes(const Tox_Events *events, uint8_t *bytes) Tox_Events *tox_events_load(const Tox_System *sys, const uint8_t *bytes, uint32_t bytes_size) { - Bin_Unpack *bu = bin_unpack_new(bytes, bytes_size); + Bin_Unpack *bu = bin_unpack_new(bytes, bytes_size, sys->mem); if (bu == nullptr) { return nullptr; diff --git a/toxcore/tox_events.h b/toxcore/tox_events.h index e868d89098a..8a0cd8a7d8d 100644 --- a/toxcore/tox_events.h +++ b/toxcore/tox_events.h @@ -343,9 +343,9 @@ void tox_events_free(Tox_Events *events); uint32_t tox_events_bytes_size(const Tox_Events *events); void tox_events_get_bytes(const Tox_Events *events, uint8_t *bytes); -Tox_Events *tox_events_load(const Tox_System *sys, const uint8_t *bytes, uint32_t bytes_size); +Tox_Events *tox_events_load(const struct 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 } diff --git a/toxcore/tox_events_test.cc b/toxcore/tox_events_test.cc index 5de29b5e483..0e381131011 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_conference_connected_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_log.c b/toxcore/tox_log.c new file mode 100644 index 00000000000..d247e28fc39 --- /dev/null +++ b/toxcore/tox_log.c @@ -0,0 +1,39 @@ +/* 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" + +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 00000000000..c2c29069da3 --- /dev/null +++ b/toxcore/tox_log.h @@ -0,0 +1,67 @@ +/* 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 "tox_memory.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 events_alloc inconsistency or logic errors. + */ + TOX_LOG_LEVEL_WARNING, + + /** + * Severe unexpected errors caused by external or events_alloc inconsistency. + */ + TOX_LOG_LEVEL_ERROR, + +} Tox_Log_Level; + + +typedef struct Tox_Log_Funcs Tox_Log_Funcs; + +typedef struct Tox_Log Tox_Log; + +non_null(1, 3) nullable(2) +Tox_Log *tox_log_new(const Tox_Log_Funcs *funcs, void *user_data, const Tox_Memory *mem); + +nullable(1) +void tox_log_free(Tox_Log *log); + +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 +} +#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 00000000000..efbcc07092c --- /dev/null +++ b/toxcore/tox_log_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_LOGGER_IMPL_H +#define C_TOXCORE_TOXCORE_TOX_LOGGER_IMPL_H + +#include "tox_log.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 +} +#endif + +#endif // C_TOXCORE_TOXCORE_TOX_LOGGER_IMPL_H diff --git a/toxcore/tox_memory.c b/toxcore/tox_memory.c new file mode 100644 index 00000000000..9410094145a --- /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 00000000000..4447b5df52a --- /dev/null +++ b/toxcore/tox_memory.h @@ -0,0 +1,81 @@ +/* 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. + */ +typedef struct Tox_Memory Tox_Memory; + +/** + * @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. + */ +non_null(1) 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. + */ +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`. + */ +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. + */ +non_null() +void *tox_memory_alloc(const Tox_Memory *mem, uint32_t size); + +/** @brief Resize a memory chunk vector. */ +non_null(1) nullable(2) +void *tox_memory_realloc(const Tox_Memory *mem, void *ptr, uint32_t size); + +/** @brief Free an array, object, or object vector. */ +non_null(1) 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 00000000000..e317fa46d2a --- /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 00000000000..010e288e189 --- /dev/null +++ b/toxcore/tox_network.c @@ -0,0 +1,106 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2022-2023 The TokTok team. + */ +#include "tox_network.h" + +#include "ccompat.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, int sock) +{ + return ns->funcs->close_callback(ns->user_data, sock); +} + +int tox_network_accept(const Tox_Network *ns, int sock) +{ + return ns->funcs->accept_callback(ns->user_data, sock); +} + +int tox_network_bind(const Tox_Network *ns, int sock, const Network_Addr *addr) +{ + return ns->funcs->bind_callback(ns->user_data, sock, addr); +} + +int tox_network_listen(const Tox_Network *ns, int sock, int backlog) +{ + return ns->funcs->listen_callback(ns->user_data, sock, backlog); +} + +int tox_network_recvbuf(const Tox_Network *ns, int sock) +{ + return ns->funcs->recvbuf_callback(ns->user_data, sock); +} + +int tox_network_recv(const Tox_Network *ns, int 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, int 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, int 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, int sock, const uint8_t *buf, size_t len, const Network_Addr *addr) +{ + return ns->funcs->sendto_callback(ns->user_data, sock, buf, len, addr); +} + +int 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, int sock, bool nonblock) +{ + return ns->funcs->socket_nonblock_callback(ns->user_data, sock, nonblock); +} + +int tox_network_getsockopt(const Tox_Network *ns, int 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, int 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 00000000000..0f711201438 --- /dev/null +++ b/toxcore/tox_network.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_H +#define C_TOXCORE_TOXCORE_TOX_NETWORK_H + +#include +#include // size_t + +#include "tox_memory.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct Tox_Network_Funcs Tox_Network_Funcs; + +typedef struct Tox_Network Tox_Network; + +non_null(1, 3) nullable(2) +Tox_Network *tox_network_new(const Tox_Network_Funcs *funcs, void *user_data, const Tox_Memory *mem); + +nullable(1) +void tox_network_free(Tox_Network *ns); + +/** + * @brief Wrapper for sockaddr_storage and size. + */ +typedef struct Network_Addr Network_Addr; + +non_null() +int tox_network_close(const Tox_Network *ns, int sock); +non_null() +int tox_network_accept(const Tox_Network *ns, int sock); +non_null() +int tox_network_bind(const Tox_Network *ns, int sock, const Network_Addr *addr); +non_null() +int tox_network_listen(const Tox_Network *ns, int sock, int backlog); +non_null() +int tox_network_recvbuf(const Tox_Network *ns, int sock); +non_null() +int tox_network_recv(const Tox_Network *ns, int sock, uint8_t *buf, size_t len); +non_null() +int tox_network_recvfrom(const Tox_Network *ns, int sock, uint8_t *buf, size_t len, Network_Addr *addr); +non_null() +int tox_network_send(const Tox_Network *ns, int sock, const uint8_t *buf, size_t len); +non_null() +int tox_network_sendto(const Tox_Network *ns, int sock, const uint8_t *buf, size_t len, const Network_Addr *addr); +non_null() +int tox_network_socket(const Tox_Network *ns, int domain, int type, int proto); +non_null() +int tox_network_socket_nonblock(const Tox_Network *ns, int sock, bool nonblock); +non_null() +int tox_network_getsockopt(const Tox_Network *ns, int sock, int level, int optname, void *optval, size_t *optlen); +non_null() +int tox_network_setsockopt(const Tox_Network *ns, int sock, int level, int optname, const void *optval, size_t optlen); +non_null() +int tox_network_getaddrinfo(const Tox_Network *ns, int family, Network_Addr **addrs); +non_null() +int tox_network_freeaddrinfo(const Tox_Network *ns, Network_Addr *addrs); + +#ifdef __cplusplus +} +#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 00000000000..bc0217b7210 --- /dev/null +++ b/toxcore/tox_network_impl.h @@ -0,0 +1,64 @@ +/* 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_network.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef int tox_network_close_cb(void *self, int sock); +typedef int tox_network_accept_cb(void *self, int sock); +typedef int tox_network_bind_cb(void *self, int sock, const Network_Addr *addr); +typedef int tox_network_listen_cb(void *self, int sock, int backlog); +typedef int tox_network_recvbuf_cb(void *self, int sock); +typedef int tox_network_recv_cb(void *self, int sock, uint8_t *buf, size_t len); +typedef int tox_network_recvfrom_cb(void *self, int sock, uint8_t *buf, size_t len, Network_Addr *addr); +typedef int tox_network_send_cb(void *self, int sock, const uint8_t *buf, size_t len); +typedef int tox_network_sendto_cb(void *self, int sock, const uint8_t *buf, size_t len, const Network_Addr *addr); +typedef int tox_network_socket_cb(void *self, int domain, int type, int proto); +typedef int tox_network_socket_nonblock_cb(void *self, int sock, bool nonblock); +typedef int tox_network_getsockopt_cb(void *self, int sock, int level, int optname, void *optval, size_t *optlen); +typedef int tox_network_setsockopt_cb(void *self, int 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_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 +} +#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 00000000000..6a214768a73 --- /dev/null +++ b/toxcore/tox_options.c @@ -0,0 +1,196 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2021 The TokTok team. + */ +#include "tox_options.h" + +#include + +#include "ccompat.h" + +#define SET_ERROR_PARAMETER(param, x) \ + do { \ + if (param != nullptr) { \ + *param = x; \ + } \ + } while (0) + +bool tox_options_get_ipv6_enabled(const struct Tox_Options *options) +{ + return options->ipv6_enabled; +} +void tox_options_set_ipv6_enabled(struct Tox_Options *options, bool ipv6_enabled) +{ + options->ipv6_enabled = ipv6_enabled; +} +bool tox_options_get_udp_enabled(const struct Tox_Options *options) +{ + return options->udp_enabled; +} +void tox_options_set_udp_enabled(struct Tox_Options *options, bool udp_enabled) +{ + options->udp_enabled = udp_enabled; +} +Tox_Proxy_Type tox_options_get_proxy_type(const struct Tox_Options *options) +{ + return options->proxy_type; +} +void tox_options_set_proxy_type(struct Tox_Options *options, Tox_Proxy_Type type) +{ + options->proxy_type = type; +} +const char *tox_options_get_proxy_host(const struct Tox_Options *options) +{ + return options->proxy_host; +} +void tox_options_set_proxy_host(struct Tox_Options *options, const char *host) +{ + options->proxy_host = host; +} +uint16_t tox_options_get_proxy_port(const struct Tox_Options *options) +{ + return options->proxy_port; +} +void tox_options_set_proxy_port(struct Tox_Options *options, uint16_t port) +{ + options->proxy_port = port; +} +uint16_t tox_options_get_start_port(const struct Tox_Options *options) +{ + return options->start_port; +} +void tox_options_set_start_port(struct Tox_Options *options, uint16_t start_port) +{ + options->start_port = start_port; +} +uint16_t tox_options_get_end_port(const struct Tox_Options *options) +{ + return options->end_port; +} +void tox_options_set_end_port(struct Tox_Options *options, uint16_t end_port) +{ + options->end_port = end_port; +} +uint16_t tox_options_get_tcp_port(const struct Tox_Options *options) +{ + return options->tcp_port; +} +void tox_options_set_tcp_port(struct Tox_Options *options, uint16_t tcp_port) +{ + options->tcp_port = tcp_port; +} +bool tox_options_get_hole_punching_enabled(const struct Tox_Options *options) +{ + return options->hole_punching_enabled; +} +void tox_options_set_hole_punching_enabled(struct Tox_Options *options, bool hole_punching_enabled) +{ + options->hole_punching_enabled = hole_punching_enabled; +} +Tox_Savedata_Type tox_options_get_savedata_type(const struct Tox_Options *options) +{ + return options->savedata_type; +} +void tox_options_set_savedata_type(struct Tox_Options *options, Tox_Savedata_Type type) +{ + options->savedata_type = type; +} +size_t tox_options_get_savedata_length(const struct Tox_Options *options) +{ + return options->savedata_length; +} +void tox_options_set_savedata_length(struct Tox_Options *options, size_t length) +{ + options->savedata_length = length; +} +tox_log_cb *tox_options_get_log_callback(const struct Tox_Options *options) +{ + return options->log_callback; +} +void tox_options_set_log_callback(struct Tox_Options *options, tox_log_cb *callback) +{ + options->log_callback = callback; +} +void *tox_options_get_log_user_data(const struct Tox_Options *options) +{ + return options->log_user_data; +} +void tox_options_set_log_user_data(struct Tox_Options *options, void *user_data) +{ + options->log_user_data = user_data; +} +bool tox_options_get_local_discovery_enabled(const struct Tox_Options *options) +{ + return options->local_discovery_enabled; +} +void tox_options_set_local_discovery_enabled(struct Tox_Options *options, bool local_discovery_enabled) +{ + options->local_discovery_enabled = local_discovery_enabled; +} +bool tox_options_get_dht_announcements_enabled(const struct Tox_Options *options) +{ + return options->dht_announcements_enabled; +} +void tox_options_set_dht_announcements_enabled(struct Tox_Options *options, bool dht_announcements_enabled) +{ + options->dht_announcements_enabled = dht_announcements_enabled; +} +bool tox_options_get_experimental_thread_safety(const struct Tox_Options *options) +{ + return options->experimental_thread_safety; +} +void tox_options_set_experimental_thread_safety(struct Tox_Options *options, bool experimental_thread_safety) +{ + options->experimental_thread_safety = experimental_thread_safety; +} +const Tox_System *tox_options_get_operating_system(const struct Tox_Options *options) +{ + return options->operating_system; +} +void tox_options_set_operating_system(struct Tox_Options *options, const Tox_System *operating_system) +{ + options->operating_system = operating_system; +} + +const uint8_t *tox_options_get_savedata_data(const struct Tox_Options *options) +{ + return options->savedata_data; +} +void tox_options_set_savedata_data(struct Tox_Options *options, const uint8_t *data, size_t length) +{ + options->savedata_data = data; + options->savedata_length = length; +} + +void tox_options_default(struct Tox_Options *options) +{ + if (options != nullptr) { + const struct Tox_Options default_options = {0}; + *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); + } +} + +struct Tox_Options *tox_options_new(Tox_Err_Options_New *error) +{ + struct Tox_Options *options = (struct Tox_Options *)calloc(1, sizeof(struct 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(struct Tox_Options *options) +{ + free(options); +} diff --git a/toxcore/tox_options.h b/toxcore/tox_options.h new file mode 100644 index 00000000000..7a83a538719 --- /dev/null +++ b/toxcore/tox_options.h @@ -0,0 +1,442 @@ +/* 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 +#include +#include + +#include "tox_system.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef TOX_DEFINED +#define TOX_DEFINED +typedef struct Tox Tox; +#endif /* TOX_DEFINED */ + +/** @{ + * @name Startup options + */ + +/** + * @brief Type of proxy used to connect to TCP relays. + */ +typedef enum Tox_Proxy_Type { + + /** + * Don't use a proxy. + */ + TOX_PROXY_TYPE_NONE, + + /** + * HTTP proxy using CONNECT. + */ + TOX_PROXY_TYPE_HTTP, + + /** + * SOCKS proxy for simple socket pipes. + */ + TOX_PROXY_TYPE_SOCKS5, + +} Tox_Proxy_Type; + + +/** + * @brief Type of savedata to create the Tox instance from. + */ +typedef enum Tox_Savedata_Type { + + /** + * No savedata. + */ + TOX_SAVEDATA_TYPE_NONE, + + /** + * Savedata is one that was obtained from tox_get_savedata. + */ + TOX_SAVEDATA_TYPE_TOX_SAVE, + + /** + * Savedata is a secret key of length TOX_SECRET_KEY_SIZE. + */ + TOX_SAVEDATA_TYPE_SECRET_KEY, + +} Tox_Savedata_Type; + +/** + * @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 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. + * @param user_data The user data pointer passed to tox_new in options. + */ +typedef void tox_log_cb(Tox *tox, Tox_Log_Level level, const char *file, uint32_t line, const char *func, + const char *message, void *user_data); + +/** + * @brief This struct contains all the startup options for Tox. + * + * You must tox_options_new to allocate an object of this type. + * + * WARNING: Although this struct happens to be visible in the API, it is + * effectively private. Do not allocate this yourself or access members + * directly, as it *will* break binary compatibility frequently. + * + * @deprecated The memory layout of this struct (size, alignment, and field + * order) is not part of the ABI. To remain compatible, prefer to use + * tox_options_new to allocate the object and accessor functions to set the + * members. The struct will become opaque (i.e. the definition will become + * private) in v0.3.0. + */ +struct Tox_Options { + + /** + * The type of socket to create. + * + * If this is set to false, an IPv4 socket is created, which subsequently + * only allows IPv4 communication. + * If it is set to true, an IPv6 socket is created, allowing both IPv4 and + * IPv6 communication. + */ + bool ipv6_enabled; + + + /** + * Enable the use of UDP communication when available. + * + * Setting this to false will force Tox to use TCP only. Communications will + * need to be relayed through a TCP relay node, potentially slowing them down. + * + * If a proxy is enabled, UDP will be disabled if either toxcore or the + * proxy don't support proxying UDP messages. + */ + bool udp_enabled; + + + /** + * Enable local network peer discovery. + * + * Disabling this will cause Tox to not look for peers on the local network. + */ + bool local_discovery_enabled; + + + /** + * Enable storing DHT announcements and forwarding corresponding requests. + * + * Disabling this will cause Tox to ignore the relevant packets. + */ + bool dht_announcements_enabled; + + /** + * Pass communications through a proxy. + */ + Tox_Proxy_Type proxy_type; + + + /** + * The IP address or DNS name of the proxy to be used. + * + * If used, this must be non-NULL and be a valid DNS name. The name must not + * exceed TOX_MAX_HOSTNAME_LENGTH characters, and be in a NUL-terminated C string + * format (TOX_MAX_HOSTNAME_LENGTH includes the NUL byte). + * + * This member is ignored (it can be NULL) if proxy_type is TOX_PROXY_TYPE_NONE. + * + * The data pointed at by this member is owned by the user, so must + * outlive the options object. + */ + const char *proxy_host; + + + /** + * The port to use to connect to the proxy server. + * + * Ports must be in the range (1, 65535). The value is ignored if + * proxy_type is TOX_PROXY_TYPE_NONE. + */ + uint16_t proxy_port; + + + /** + * The start port of the inclusive port range to attempt to use. + * + * If both start_port and end_port are 0, the default port range will be + * used: `[33445, 33545]`. + * + * If either start_port or end_port is 0 while the other is non-zero, the + * non-zero port will be the only port in the range. + * + * Having start_port > end_port will yield the same behavior as if start_port + * and end_port were swapped. + */ + uint16_t start_port; + + + /** + * The end port of the inclusive port range to attempt to use. + */ + uint16_t end_port; + + + /** + * The port to use for the TCP server (relay). If 0, the TCP server is + * disabled. + * + * Enabling it is not required for Tox to function properly. + * + * When enabled, your Tox instance can act as a TCP relay for other Tox + * instance. This leads to increased traffic, thus when writing a client + * it is recommended to enable TCP server only if the user has an option + * to disable it. + */ + uint16_t tcp_port; + + + /** + * Enables or disables UDP hole-punching in toxcore. (Default: enabled). + */ + bool hole_punching_enabled; + + + /** + * The type of savedata to load from. + */ + Tox_Savedata_Type savedata_type; + + + /** + * The savedata. + * + * The data pointed at by this member is owned by the user, so must + * outlive the options object. + */ + const uint8_t *savedata_data; + + + /** + * The length of the savedata. + */ + size_t savedata_length; + + + /** + * Logging callback for the new tox instance. + */ + tox_log_cb *log_callback; + + + /** + * User data pointer passed to the logging callback. + */ + void *log_user_data; + + + /** + * These options are experimental, so avoid writing code that depends on + * them. Options marked "experimental" may change their behaviour or go away + * entirely in the future, or may be renamed to something non-experimental + * if they become part of the supported API. + */ + /** + * Make public API functions thread-safe using a per-instance lock. + * + * Default: false. + */ + bool experimental_thread_safety; + + /** + * Low level operating system functionality such as send/recv, random + * number generation, and memory allocation. + */ + const Tox_System *operating_system; + +}; + + +non_null() +bool tox_options_get_ipv6_enabled(const struct Tox_Options *options); + +non_null() +void tox_options_set_ipv6_enabled(struct Tox_Options *options, bool ipv6_enabled); + +non_null() +bool tox_options_get_udp_enabled(const struct Tox_Options *options); + +non_null() +void tox_options_set_udp_enabled(struct Tox_Options *options, bool udp_enabled); + +non_null() +bool tox_options_get_local_discovery_enabled(const struct Tox_Options *options); + +non_null() +void tox_options_set_local_discovery_enabled(struct Tox_Options *options, bool local_discovery_enabled); + +non_null() +bool tox_options_get_dht_announcements_enabled(const struct Tox_Options *options); + +non_null() +void tox_options_set_dht_announcements_enabled(struct Tox_Options *options, bool dht_announcements_enabled); + +non_null() +Tox_Proxy_Type tox_options_get_proxy_type(const struct Tox_Options *options); + +non_null() +void tox_options_set_proxy_type(struct Tox_Options *options, Tox_Proxy_Type type); + +non_null() +const char *tox_options_get_proxy_host(const struct Tox_Options *options); + +non_null() +void tox_options_set_proxy_host(struct Tox_Options *options, const char *host); + +non_null() +uint16_t tox_options_get_proxy_port(const struct Tox_Options *options); + +non_null() +void tox_options_set_proxy_port(struct Tox_Options *options, uint16_t port); + +non_null() +uint16_t tox_options_get_start_port(const struct Tox_Options *options); + +non_null() +void tox_options_set_start_port(struct Tox_Options *options, uint16_t start_port); + +non_null() +uint16_t tox_options_get_end_port(const struct Tox_Options *options); + +non_null() +void tox_options_set_end_port(struct Tox_Options *options, uint16_t end_port); + +non_null() +uint16_t tox_options_get_tcp_port(const struct Tox_Options *options); + +non_null() +void tox_options_set_tcp_port(struct Tox_Options *options, uint16_t tcp_port); + +non_null() +bool tox_options_get_hole_punching_enabled(const struct Tox_Options *options); + +non_null() +void tox_options_set_hole_punching_enabled(struct Tox_Options *options, bool hole_punching_enabled); + +non_null() +Tox_Savedata_Type tox_options_get_savedata_type(const struct Tox_Options *options); + +non_null() +void tox_options_set_savedata_type(struct Tox_Options *options, Tox_Savedata_Type type); + +non_null() +const uint8_t *tox_options_get_savedata_data(const struct Tox_Options *options); + +non_null() +void tox_options_set_savedata_data(struct Tox_Options *options, const uint8_t *data, size_t length); + +non_null() +size_t tox_options_get_savedata_length(const struct Tox_Options *options); + +non_null() +void tox_options_set_savedata_length(struct Tox_Options *options, size_t length); + +non_null() +tox_log_cb *tox_options_get_log_callback(const struct Tox_Options *options); + +non_null() +void tox_options_set_log_callback(struct Tox_Options *options, tox_log_cb *callback); + +non_null() +void *tox_options_get_log_user_data(const struct Tox_Options *options); + +non_null() +void tox_options_set_log_user_data(struct Tox_Options *options, void *user_data); + +non_null() +bool tox_options_get_experimental_thread_safety(const struct Tox_Options *options); + +non_null() +void tox_options_set_experimental_thread_safety(struct Tox_Options *options, bool experimental_thread_safety); + +non_null() +const Tox_System *tox_options_get_operating_system(const struct Tox_Options *options); + +non_null() +void tox_options_set_operating_system(struct Tox_Options *options, const Tox_System *operating_system); + +/** + * @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. + */ +non_null() +void tox_options_default(struct 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; + + +/** + * @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. + */ +nullable(1) +struct 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. + */ +nullable(1) +void tox_options_free(struct Tox_Options *options); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif // C_TOXCORE_TOXCORE_TOX_OPTIONS_H diff --git a/toxcore/tox_private.c b/toxcore/tox_private.c index 72a93358a5b..cebdd502fd3 100644 --- a/toxcore/tox_private.c +++ b/toxcore/tox_private.c @@ -22,18 +22,6 @@ } \ } while (0) -Tox_System tox_default_system(void) -{ - const Tox_System sys = { - nullptr, // mono_time_callback - nullptr, // mono_time_user_data - system_random(), - system_network(), - system_memory(), - }; - return sys; -} - void tox_lock(const Tox *tox) { if (tox->mutex != nullptr) { diff --git a/toxcore/tox_private.h b/toxcore/tox_private.h index c82357170e6..ba6c8a27eb7 100644 --- a/toxcore/tox_private.h +++ b/toxcore/tox_private.h @@ -16,18 +16,6 @@ extern "C" { #endif -typedef uint64_t tox_mono_time_cb(void *user_data); - -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_default_system(void); - void tox_lock(const Tox *tox); void tox_unlock(const Tox *tox); diff --git a/toxcore/tox_random.c b/toxcore/tox_random.c new file mode 100644 index 00000000000..18483f46523 --- /dev/null +++ b/toxcore/tox_random.c @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2022-2023 The TokTok team. + */ +#include "tox_random.h" + +#include "ccompat.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 00000000000..7345f886816 --- /dev/null +++ b/toxcore/tox_random.h @@ -0,0 +1,36 @@ +/* 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_memory.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct Tox_Random_Funcs Tox_Random_Funcs; + +typedef struct Tox_Random Tox_Random; + +non_null(1, 3) nullable(2) +Tox_Random *tox_random_new(const Tox_Random_Funcs *funcs, void *user_data, const Tox_Memory *mem); + +nullable(1) +void tox_random_free(Tox_Random *rng); + +non_null() +void tox_random_bytes(const Tox_Random *rng, uint8_t *bytes, uint32_t length); +non_null() +uint32_t tox_random_uniform(const Tox_Random *rng, uint32_t upper_bound); + +#ifdef __cplusplus +} +#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 00000000000..f11d2f26d6a --- /dev/null +++ b/toxcore/tox_random_impl.h @@ -0,0 +1,33 @@ +/* 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_random.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void tox_random_bytes_cb(void *self, uint8_t *bytes, uint32_t length); +typedef uint32_t tox_random_uniform_cb(void *self, uint32_t upper_bound); + +struct Tox_Random_Funcs { + tox_random_bytes_cb *bytes_callback; + tox_random_uniform_cb *uniform_callback; +}; + +struct Tox_Random { + const Tox_Random_Funcs *funcs; + void *user_data; + + const Tox_Memory *mem; +}; + +#ifdef __cplusplus +} +#endif + +#endif // C_TOXCORE_TOXCORE_TOX_RANDOM_IMPL_H diff --git a/toxcore/tox_struct.h b/toxcore/tox_struct.h index b298269af95..ec1db247a7c 100644 --- a/toxcore/tox_struct.h +++ b/toxcore/tox_struct.h @@ -10,6 +10,7 @@ #include "mem.h" #include "tox.h" #include "tox_private.h" +#include "tox_system_impl.h" #ifdef __cplusplus extern "C" { diff --git a/toxcore/tox_system.c b/toxcore/tox_system.c new file mode 100644 index 00000000000..eddcf493ffa --- /dev/null +++ b/toxcore/tox_system.c @@ -0,0 +1,57 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2022-2023 The TokTok team. + */ +#include "tox_system.h" + +#include "ccompat.h" +#include "tox_system_impl.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 00000000000..fb8f40a97db --- /dev/null +++ b/toxcore/tox_system.h @@ -0,0 +1,52 @@ +/* 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_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_private.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; + +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); + +nullable(1) +void tox_system_free(Tox_System *sys); + +non_null() +const Tox_Log *tox_system_get_log(const Tox_System *sys); + +non_null() +const Tox_Memory *tox_system_get_memory(const Tox_System *sys); + +non_null() +const Tox_Network *tox_system_get_network(const Tox_System *sys); + +non_null() +const Tox_Random *tox_system_get_random(const Tox_System *sys); + +non_null() +const Tox_Time *tox_system_get_time(const Tox_System *sys); + +#ifdef __cplusplus +} +#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 00000000000..5353ea4e1bd --- /dev/null +++ b/toxcore/tox_system_impl.h @@ -0,0 +1,26 @@ +/* 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_system.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 +} +#endif + +#endif // C_TOXCORE_TOXCORE_TOX_SYSTEM_IMPL_H diff --git a/toxcore/tox_test.cc b/toxcore/tox_test.cc index 530c1390a1f..2848a4fa2e6 100644 --- a/toxcore/tox_test.cc +++ b/toxcore/tox_test.cc @@ -6,6 +6,7 @@ #include #include "crypto_core.h" +#include "os_random.h" #include "tox_private.h" namespace { @@ -94,7 +95,7 @@ TEST(Tox, OneTest) Tox *tox1 = tox_new(options, nullptr); ASSERT_NE(tox1, nullptr); - const Random *rng = system_random(); + const Random *rng = os_random(); ASSERT_NE(rng, nullptr); set_random_name_and_status_message(tox1, rng, name.data(), status_message.data()); Tox *tox2 = tox_new(options, nullptr); diff --git a/toxcore/tox_time.c b/toxcore/tox_time.c new file mode 100644 index 00000000000..c13c1caec6f --- /dev/null +++ b/toxcore/tox_time.c @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2022-2023 The TokTok team. + */ +#include "tox_time.h" + +#include "ccompat.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 00000000000..7fbd0cf3ea8 --- /dev/null +++ b/toxcore/tox_time.h @@ -0,0 +1,35 @@ +/* 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_memory.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct Tox_Time_Funcs Tox_Time_Funcs; + +typedef struct Tox_Time Tox_Time; + +non_null(1, 3) nullable(2) +Tox_Time *tox_time_new(const Tox_Time_Funcs *funcs, void *user_data, const Tox_Memory *mem); + +nullable(1) +void tox_time_free(Tox_Time *tm); + +non_null() +uint64_t tox_time_monotonic(const Tox_Time *tm); + +#ifdef __cplusplus +} +#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 00000000000..300bc12b1f8 --- /dev/null +++ b/toxcore/tox_time_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_TIME_IMPL_H +#define C_TOXCORE_TOXCORE_TOX_TIME_IMPL_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 +} +#endif + +#endif // C_TOXCORE_TOXCORE_TOX_TIME_IMPL_H diff --git a/toxcore/tox_unpack.h b/toxcore/tox_unpack.h index 5f0b18ad1b8..c07fe49445d 100644 --- a/toxcore/tox_unpack.h +++ b/toxcore/tox_unpack.h @@ -5,7 +5,7 @@ #ifndef C_TOXCORE_TOXCORE_TOX_UNPACK_H #define C_TOXCORE_TOXCORE_TOX_UNPACK_H -#include "attributes.h" +#include "tox_attributes.h" #include "bin_unpack.h" #include "tox.h" diff --git a/toxcore/util.h b/toxcore/util.h index 44091b36227..e8067dbf77b 100644 --- a/toxcore/util.h +++ b/toxcore/util.h @@ -15,7 +15,7 @@ #include #include -#include "attributes.h" +#include "tox_attributes.h" #include "mem.h" #ifdef __cplusplus diff --git a/toxcore/util_test.cc b/toxcore/util_test.cc index 47bf258766b..3a31ce39363 100644 --- a/toxcore/util_test.cc +++ b/toxcore/util_test.cc @@ -3,12 +3,13 @@ #include #include "crypto_core.h" +#include "os_random.h" namespace { TEST(Util, TwoRandomIdsAreNotEqual) { - const Random *rng = system_random(); + const Random *rng = os_random(); ASSERT_NE(rng, nullptr); uint8_t pk1[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t sk1[CRYPTO_SECRET_KEY_SIZE]; @@ -23,7 +24,7 @@ TEST(Util, TwoRandomIdsAreNotEqual) TEST(Util, IdCopyMakesKeysEqual) { - const Random *rng = system_random(); + const Random *rng = os_random(); ASSERT_NE(rng, nullptr); uint8_t pk1[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t sk1[CRYPTO_SECRET_KEY_SIZE]; diff --git a/toxencryptsave.h b/toxencryptsave.h new file mode 100644 index 00000000000..f5901d3cc32 --- /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 bbd5e0ee88c..9cb631ac049 100644 --- a/toxencryptsave/BUILD.bazel +++ b/toxencryptsave/BUILD.bazel @@ -22,6 +22,8 @@ cc_library( ":defines", "//c-toxcore/toxcore:ccompat", "//c-toxcore/toxcore:crypto_core", + "//c-toxcore/toxcore:os_memory", + "//c-toxcore/toxcore:os_random", "@libsodium", ], ) @@ -36,6 +38,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 4b517a19f6d..716ed1b7ed0 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 if !WITH_NACL libtoxencryptsave_la_SOURCES = ../toxencryptsave/toxencryptsave.h \ diff --git a/toxencryptsave/toxencryptsave.c b/toxencryptsave/toxencryptsave.c index 45003055f42..81ec450d308 100644 --- a/toxencryptsave/toxencryptsave.c +++ b/toxencryptsave/toxencryptsave.c @@ -15,6 +15,8 @@ #include "../toxcore/ccompat.h" #include "../toxcore/crypto_core.h" +#include "../toxcore/os_memory.h" +#include "../toxcore/os_random.h" #include "defines.h" static_assert(TOX_PASS_SALT_LENGTH == crypto_pwhash_scryptsalsa208sha256_SALTBYTES, @@ -115,7 +117,7 @@ bool tox_get_salt(const uint8_t *ciphertext, uint8_t *salt, Tox_Err_Get_Salt *er Tox_Pass_Key *tox_pass_key_derive(const uint8_t *passphrase, size_t passphrase_len, Tox_Err_Key_Derivation *error) { - const Random *rng = system_random(); + const Random *rng = os_random(); if (rng == nullptr) { SET_ERROR_PARAMETER(error, TOX_ERR_KEY_DERIVATION_FAILED); @@ -192,9 +194,10 @@ Tox_Pass_Key *tox_pass_key_derive_with_salt(const uint8_t *passphrase, size_t pa 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 Random *rng = system_random(); + 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; } @@ -225,7 +228,7 @@ bool tox_pass_key_encrypt(const Tox_Pass_Key *key, const uint8_t *plaintext, siz ciphertext += crypto_box_NONCEBYTES; /* now encrypt */ - if (encrypt_data_symmetric(key->key, nonce, plaintext, plaintext_len, ciphertext) + if (encrypt_data_symmetric(key->key, nonce, plaintext, plaintext_len, ciphertext, mem) != plaintext_len + crypto_box_MACBYTES) { SET_ERROR_PARAMETER(error, TOX_ERR_ENCRYPTION_FAILED); return false; @@ -284,6 +287,13 @@ bool tox_pass_encrypt(const uint8_t *plaintext, size_t plaintext_len, const uint 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; @@ -309,7 +319,7 @@ bool tox_pass_key_decrypt(const Tox_Pass_Key *key, const uint8_t *ciphertext, si ciphertext += crypto_box_NONCEBYTES; /* decrypt the ciphertext */ - if (decrypt_data_symmetric(key->key, nonce, ciphertext, decrypt_length + crypto_box_MACBYTES, plaintext) + if (decrypt_data_symmetric(key->key, nonce, ciphertext, decrypt_length + crypto_box_MACBYTES, plaintext, mem) != decrypt_length) { SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_FAILED); return false;