Squashed 'external/toxcore/c-toxcore/' changes from c9cdae001..9ed2fa80d

9ed2fa80d fix(toxav): remove extra copy of video frame on encode
de30cf3ad docs: Add new file kinds, that should be useful to all clients.
d5b5e879d fix(DHT): Correct node skipping logic timed out nodes.
30e71fe97 refactor: Generate event dispatch functions and add tox_events_dispatch.
8fdbb0b50 style: Format parameter lists in event handlers.
d00dee12b refactor: Add warning logs when losing chat invites.
b144e8db1 feat: Add a way to look up a file number by ID.
849281ea0 feat: Add a way to fetch groups by chat ID.
a2c177396 refactor: Harden event system and improve type safety.
8f5caa656 refactor: Add MessagePack string support to bin_pack.
34e8d5ad5 chore: Add GitHub CodeQL workflow and local Docker runner.
f7b068010 refactor: Add nullability annotations to event headers.
788abe651 refactor(toxav): Use system allocator for mutexes.
2e4b423eb refactor: Use specific typedefs for public API arrays.
2baf34775 docs(toxav): update idle iteration interval see 679444751876fa3882a717772918ebdc8f083354
2f87ac67b feat: Add Event Loop abstraction (Ev).
f8dfc38d8 test: Fix data race in ToxScenario virtual_clock.
38313921e test(TCP): Add regression test for TCP priority queue integrity.
f94a50d9a refactor(toxav): Replace mutable_mutex with dynamically allocated mutex.
ad054511e refactor: Internalize DHT structs and add debug helpers.
8b467cc96 fix: Prevent potential integer overflow in group chat handshake.
4962bdbb8 test: Improve TCP simulation and add tests
5f0227093 refactor: Allow nullable data in group chat handlers.
e97b18ea9 chore: Improve Windows Docker support.
b14943bbd refactor: Move Logger out of Messenger into Tox.
dd3136250 cleanup: Apply nullability qualifiers to C++ codebase.
1849f70fc refactor: Extract low-level networking code to net and os_network.
8fec75421 refactor: Delete tox_random, align on rng and os_random.
a03ae8051 refactor: Delete tox_memory, align on mem and os_memory.
4c88fed2c refactor: Use `std::` prefixes more consistently in C++ code.
72452f2ae test: Add some more tests for onion and shared key cache.
d5a51b09a cleanup: Use tox_attributes.h in tox_private.h and install it.
b6f5b9fc5 test: Add some benchmarks for various high level things.
8a8d02785 test(support): Introduce threaded Tox runner and simulation barrier
d68d1d095 perf(toxav): optimize audio and video intermediate buffers by keeping them around
REVERT: c9cdae001 fix(toxav): remove extra copy of video frame on encode

git-subtree-dir: external/toxcore/c-toxcore
git-subtree-split: 9ed2fa80d582c714d6bdde6a7648220a92cddff8
This commit is contained in:
Green Sky
2026-02-01 14:26:52 +01:00
parent 565efa4f39
commit 9b36dd9d99
274 changed files with 11891 additions and 4292 deletions

View File

@@ -4,6 +4,7 @@ load("@rules_fuzzing//fuzzing:cc_defs.bzl", "cc_fuzz_test")
exports_files(
srcs = [
"tox.h",
"tox_attributes.h",
"tox_dispatch.h",
"tox_events.h",
"tox_log_level.h",
@@ -18,6 +19,9 @@ cc_library(
testonly = True,
srcs = ["test_util.cc"],
hdrs = ["test_util.hh"],
deps = [
":attributes",
],
)
cc_test(
@@ -54,16 +58,13 @@ cc_library(
)
cc_library(
name = "tox_memory",
srcs = ["tox_memory.c"],
hdrs = [
"tox_memory.h",
"tox_memory_impl.h",
],
name = "mem",
srcs = ["mem.c"],
hdrs = ["mem.h"],
visibility = ["//c-toxcore:__subpackages__"],
deps = [
":attributes",
":ccompat",
":tox_attributes",
],
)
@@ -74,22 +75,7 @@ cc_library(
visibility = ["//c-toxcore:__subpackages__"],
deps = [
":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",
":mem",
],
)
@@ -101,20 +87,90 @@ cc_library(
deps = [
":attributes",
":ccompat",
":tox_random",
":rng",
"@libsodium",
],
)
cc_library(
name = "mem",
srcs = ["mem.c"],
hdrs = ["mem.h"],
name = "rng",
srcs = ["rng.c"],
hdrs = ["rng.h"],
visibility = ["//c-toxcore:__subpackages__"],
deps = [
":attributes",
],
)
cc_library(
name = "ev",
srcs = ["ev.c"],
hdrs = ["ev.h"],
visibility = ["//c-toxcore:__subpackages__"],
deps = [
":attributes",
":ccompat",
":tox_memory",
":net",
],
)
cc_library(
name = "os_event",
srcs = ["os_event.c"],
hdrs = ["os_event.h"],
copts = select({
"//tools/config:linux": ["-DEV_USE_EPOLL=1"],
"//conditions:default": [],
}),
visibility = ["//c-toxcore:__subpackages__"],
deps = [
":ccompat",
":ev",
":logger",
":mem",
":net",
":os_network",
],
)
cc_library(
name = "ev_test_util",
testonly = True,
srcs = ["ev_test_util.cc"],
hdrs = ["ev_test_util.hh"],
deps = [":net"],
)
cc_test(
name = "ev_test",
size = "small",
srcs = ["ev_test.cc"],
deps = [
":ev",
":ev_test_util",
":logger",
":net",
":os_event",
":os_memory",
":os_network",
"@com_google_googletest//:gtest",
"@com_google_googletest//:gtest_main",
],
)
cc_binary(
name = "ev_bench",
testonly = True,
srcs = ["ev_bench.cc"],
deps = [
":ev",
":ev_test_util",
":logger",
":net",
":os_event",
":os_memory",
":os_network",
"@benchmark",
],
)
@@ -123,6 +179,7 @@ cc_test(
size = "small",
srcs = ["mem_test.cc"],
deps = [
":attributes",
":mem",
":os_memory",
"@com_google_googletest//:gtest",
@@ -177,6 +234,7 @@ cc_library(
srcs = ["sort_test_util.cc"],
hdrs = ["sort_test_util.hh"],
deps = [
":attributes",
":sort",
":util",
],
@@ -199,6 +257,7 @@ cc_binary(
testonly = True,
srcs = ["sort_bench.cc"],
deps = [
":attributes",
":mem",
":sort",
":sort_test_util",
@@ -254,11 +313,13 @@ cc_test(
size = "small",
srcs = ["bin_pack_test.cc"],
deps = [
":attributes",
":bin_pack",
":bin_unpack",
":logger",
":mem",
":os_memory",
":test_util",
"@com_google_googletest//:gtest",
"@com_google_googletest//:gtest_main",
],
@@ -273,7 +334,7 @@ cc_library(
":attributes",
":ccompat",
":mem",
":tox_random",
":rng",
":util",
"@libsodium",
],
@@ -299,9 +360,10 @@ cc_library(
srcs = ["crypto_core_test_util.cc"],
hdrs = ["crypto_core_test_util.hh"],
deps = [
":attributes",
":crypto_core",
":rng",
":test_util",
":tox_random",
],
)
@@ -381,6 +443,7 @@ cc_library(
srcs = ["mono_time_test_util.cc"],
hdrs = ["mono_time_test_util.hh"],
deps = [
":attributes",
":mono_time",
"//c-toxcore/testing/support",
],
@@ -391,6 +454,7 @@ cc_test(
size = "small",
srcs = ["mono_time_test.cc"],
deps = [
":attributes",
":mono_time",
":mono_time_test_util",
"//c-toxcore/testing/support",
@@ -420,6 +484,25 @@ cc_library(
],
)
cc_test(
name = "shared_key_cache_test",
size = "small",
srcs = ["shared_key_cache_test.cc"],
deps = [
":attributes",
":crypto_core_test_util",
":logger",
":mono_time",
":mono_time_test_util",
":os_memory",
":rng",
":shared_key_cache",
"//c-toxcore/testing/support",
"@com_google_googletest//:gtest",
"@com_google_googletest//:gtest_main",
],
)
cc_library(
name = "net_profile",
srcs = ["net_profile.c"],
@@ -436,6 +519,30 @@ cc_library(
],
)
cc_library(
name = "net",
srcs = ["net.c"],
hdrs = ["net.h"],
visibility = ["//c-toxcore:__subpackages__"],
deps = [
":attributes",
":mem",
],
)
cc_library(
name = "os_network",
srcs = ["os_network.c"],
hdrs = ["os_network.h"],
visibility = ["//c-toxcore:__subpackages__"],
deps = [
":attributes",
":ccompat",
":mem",
":net",
],
)
cc_library(
name = "network",
srcs = [
@@ -450,6 +557,7 @@ cc_library(
"//c-toxcore/auto_tests:__subpackages__",
"//c-toxcore/other:__pkg__",
"//c-toxcore/other/bootstrap_daemon:__pkg__",
"//c-toxcore/testing/bench:__pkg__",
"//c-toxcore/testing/fuzzing:__pkg__",
"//c-toxcore/testing/support:__pkg__",
"//c-toxcore/toxav:__pkg__",
@@ -459,10 +567,13 @@ cc_library(
":bin_pack",
":ccompat",
":crypto_core",
":ev",
":logger",
":mem",
":mono_time",
":net",
":net_profile",
":os_network",
":util",
"@libsodium",
"@psocket",
@@ -476,9 +587,12 @@ cc_library(
srcs = ["network_test_util.cc"],
hdrs = ["network_test_util.hh"],
deps = [
":attributes",
":crypto_core",
":mem",
":net",
":network",
":rng",
":test_util",
],
)
@@ -518,6 +632,7 @@ cc_library(
":crypto_core",
":mem",
":mono_time",
":rng",
":util",
],
)
@@ -527,9 +642,14 @@ cc_test(
size = "small",
srcs = ["ping_array_test.cc"],
deps = [
":attributes",
":crypto_core_test_util",
":logger",
":mono_time",
":mono_time_test_util",
":os_memory",
":ping_array",
":rng",
"//c-toxcore/testing/support",
"@com_google_googletest//:gtest",
"@com_google_googletest//:gtest_main",
@@ -550,6 +670,7 @@ cc_library(
":ccompat",
":crypto_core",
":mem",
":net",
":network",
":util",
"@psocket",
@@ -567,6 +688,7 @@ cc_library(
"ping.h",
],
visibility = [
"//c-toxcore/auto_tests:__pkg__",
"//c-toxcore/other:__pkg__",
"//c-toxcore/other/bootstrap_daemon:__pkg__",
"//c-toxcore/testing:__pkg__",
@@ -580,8 +702,10 @@ cc_library(
":logger",
":mem",
":mono_time",
":net",
":network",
":ping_array",
":rng",
":shared_key_cache",
":sort",
":state",
@@ -596,13 +720,18 @@ cc_library(
hdrs = ["DHT_test_util.hh"],
deps = [
":DHT",
":attributes",
":crypto_core",
":crypto_core_test_util",
":ev",
":logger",
":mono_time",
":net",
":net_crypto",
":network",
":network_test_util",
":os_event",
":rng",
":test_util",
"//c-toxcore/testing/support",
],
@@ -615,12 +744,15 @@ cc_test(
deps = [
":DHT",
":DHT_test_util",
":attributes",
":crypto_core",
":crypto_core_test_util",
":ev",
":logger",
":mono_time",
":network",
":network_test_util",
":os_event",
":test_util",
"//c-toxcore/testing/support",
"@com_google_googletest//:gtest",
@@ -658,7 +790,9 @@ cc_library(
":logger",
":mem",
":mono_time",
":net",
":network",
":rng",
":shared_key_cache",
":util",
],
@@ -681,7 +815,9 @@ cc_library(
":logger",
":mem",
":mono_time",
":net",
":network",
":rng",
":timed_auth",
],
)
@@ -692,7 +828,9 @@ cc_fuzz_test(
srcs = ["forwarding_fuzz_test.cc"],
corpus = ["//tools/toktok-fuzzer/corpus:forwarding_fuzz_test"],
deps = [
":ev",
":forwarding",
":os_event",
"//c-toxcore/testing/support",
],
)
@@ -716,6 +854,7 @@ cc_library(
":mem",
":mono_time",
":network",
":rng",
":shared_key_cache",
":timed_auth",
":util",
@@ -733,8 +872,10 @@ cc_library(
":crypto_core",
":logger",
":mem",
":net",
":net_profile",
":network",
":rng",
],
)
@@ -742,10 +883,6 @@ cc_library(
name = "TCP_server",
srcs = ["TCP_server.c"],
hdrs = ["TCP_server.h"],
copts = select({
"//tools/config:linux": ["-DTCP_SERVER_USE_EPOLL=1"],
"//conditions:default": [],
}),
visibility = [
"//c-toxcore/auto_tests:__pkg__",
"//c-toxcore/other:__pkg__",
@@ -756,14 +893,17 @@ cc_library(
":attributes",
":ccompat",
":crypto_core",
":ev",
":forwarding",
":list",
":logger",
":mem",
":mono_time",
":net",
":net_profile",
":network",
":onion",
":rng",
":util",
"@psocket",
],
@@ -783,8 +923,10 @@ cc_library(
":logger",
":mem",
":mono_time",
":net",
":net_profile",
":network",
":rng",
":util",
],
)
@@ -806,9 +948,11 @@ cc_library(
":logger",
":mem",
":mono_time",
":net",
":net_profile",
":network",
":onion",
":rng",
":util",
],
)
@@ -831,11 +975,16 @@ cc_test(
deps = [
":TCP_client",
":TCP_common",
":attributes",
":crypto_core",
":logger",
":mono_time",
":net_profile",
":network",
":os_event",
":os_memory",
":rng",
":test_util",
":util",
"//c-toxcore/testing/support",
"@com_google_googletest//:gtest",
@@ -843,6 +992,21 @@ cc_test(
],
)
cc_test(
name = "TCP_common_test",
size = "small",
srcs = ["TCP_common_test.cc"],
deps = [
":TCP_common",
":crypto_core",
":logger",
":os_memory",
":os_random",
"@com_google_googletest//:gtest",
"@com_google_googletest//:gtest_main",
],
)
cc_library(
name = "net_crypto",
srcs = ["net_crypto.c"],
@@ -863,8 +1027,10 @@ cc_library(
":logger",
":mem",
":mono_time",
":net",
":net_profile",
":network",
":rng",
":util",
"@pthread",
],
@@ -876,12 +1042,14 @@ cc_test(
srcs = ["net_crypto_test.cc"],
deps = [
":DHT_test_util",
":attributes",
":crypto_core",
":logger",
":mono_time",
":net_crypto",
":net_profile",
":network",
":test_util",
"//c-toxcore/testing/support",
"@com_google_googletest//:gtest",
"@com_google_googletest//:gtest_main",
@@ -894,6 +1062,7 @@ cc_test(
srcs = ["friend_connection_test.cc"],
deps = [
":DHT_test_util",
":attributes",
":crypto_core",
":friend_connection",
":logger",
@@ -902,6 +1071,7 @@ cc_test(
":net_profile",
":network",
":onion_client",
":test_util",
"//c-toxcore/testing/support",
"@com_google_googletest//:gtest",
"@com_google_googletest//:gtest_main",
@@ -911,15 +1081,17 @@ cc_test(
cc_fuzz_test(
name = "net_crypto_fuzz_test",
size = "small",
testonly = True,
srcs = ["net_crypto_fuzz_test.cc"],
corpus = ["//tools/toktok-fuzzer/corpus:net_crypto_fuzz_test"],
copts = ["-UNDEBUG"],
deps = [
":DHT",
":TCP_client",
":attributes",
":ev",
":net_crypto",
":net_profile",
":network",
":os_event",
"//c-toxcore/testing/support",
],
)
@@ -942,8 +1114,10 @@ cc_library(
":logger",
":mem",
":mono_time",
":net",
":network",
":onion",
":rng",
":shared_key_cache",
":sort",
":timed_auth",
@@ -969,6 +1143,7 @@ cc_library(
":logger",
":mem",
":mono_time",
":net",
":network",
":util",
],
@@ -980,6 +1155,7 @@ cc_test(
srcs = ["group_announce_test.cc"],
deps = [
":DHT",
":attributes",
":crypto_core",
":group_announce",
":logger",
@@ -995,10 +1171,10 @@ cc_test(
cc_fuzz_test(
name = "group_announce_fuzz_test",
size = "small",
testonly = True,
srcs = ["group_announce_fuzz_test.cc"],
corpus = ["//tools/toktok-fuzzer/corpus:group_announce_fuzz_test"],
copts = ["-UNDEBUG"],
deps = [
":attributes",
":group_announce",
"//c-toxcore/testing/support",
],
@@ -1024,6 +1200,7 @@ cc_library(
":mono_time",
":network",
":onion_announce",
":rng",
":timed_auth",
],
)
@@ -1046,11 +1223,13 @@ cc_library(
":logger",
":mem",
":mono_time",
":net",
":net_crypto",
":network",
":onion",
":onion_announce",
":ping_array",
":rng",
":sort",
":timed_auth",
":util",
@@ -1059,10 +1238,11 @@ cc_library(
cc_test(
name = "onion_client_test",
size = "small",
size = "medium",
srcs = ["onion_client_test.cc"],
deps = [
":DHT_test_util",
":attributes",
":crypto_core",
":logger",
":mono_time",
@@ -1083,12 +1263,17 @@ cc_fuzz_test(
size = "small",
testonly = True,
srcs = ["onion_client_fuzz_test.cc"],
# corpus = ["//tools/toktok-fuzzer/corpus:onion_client_fuzz_test"],
copts = ["-UNDEBUG"],
deps = [
":DHT",
":attributes",
":ev",
":net_crypto",
":net_profile",
":network",
":onion_client",
":os_event",
":test_util",
"//c-toxcore/testing/support",
],
)
@@ -1108,11 +1293,13 @@ cc_library(
":logger",
":mem",
":mono_time",
":net",
":net_crypto",
":network",
":onion",
":onion_announce",
":onion_client",
":rng",
":util",
],
)
@@ -1136,6 +1323,7 @@ cc_library(
":onion",
":onion_announce",
":onion_client",
":rng",
":util",
],
)
@@ -1221,6 +1409,7 @@ cc_library(
":ccompat",
":crypto_core",
":crypto_core_pack",
":ev",
":forwarding",
":friend_connection",
":friend_requests",
@@ -1230,12 +1419,14 @@ cc_library(
":logger",
":mem",
":mono_time",
":net",
":net_crypto",
":net_profile",
":network",
":onion",
":onion_announce",
":onion_client",
":rng",
":state",
":util",
"@libsodium",
@@ -1259,6 +1450,7 @@ cc_library(
":mono_time",
":net_crypto",
":network",
":rng",
":sort",
":state",
":util",
@@ -1305,19 +1497,24 @@ cc_library(
":attributes",
":ccompat",
":crypto_core",
":ev",
":friend_requests",
":group",
":group_moderation",
":logger",
":mem",
":mono_time",
":net",
":net_crypto",
":net_profile",
":network",
":onion_client",
":os_event",
":os_memory",
":os_network",
":os_random",
":state",
":tox_attributes",
":tox_log_level",
":tox_options",
":util",
@@ -1331,6 +1528,7 @@ cc_test(
size = "small",
srcs = ["tox_test.cc"],
deps = [
":attributes",
":crypto_core",
":os_random",
":tox",
@@ -1390,6 +1588,7 @@ cc_library(
":logger",
":mem",
":tox",
":tox_attributes",
":tox_pack",
":tox_unpack",
"//c-toxcore/third_party:cmp",

View File

@@ -55,6 +55,19 @@
#define MAX_KEYS_PER_SLOT 4
#define KEYS_TIMEOUT 600
typedef struct NAT {
/* true if currently hole punching */
bool hole_punching;
uint32_t punching_index;
uint32_t tries;
uint32_t punching_index2;
uint64_t punching_timestamp;
uint64_t recv_nat_ping_timestamp;
uint64_t nat_ping_id;
uint64_t nat_ping_timestamp;
} NAT;
typedef struct DHT_Friend_Callback {
dht_ip_cb *_Nullable ip_callback;
void *_Nullable data;
@@ -2002,7 +2015,7 @@ static uint32_t foreach_ip_port(const DHT *_Nonnull dht, const DHT_Friend *_Nonn
/* If ip is not zero and node is good. */
if (!ip_isset(&assoc->ret_ip_port.ip)
&& !mono_time_is_timeout(dht->mono_time, assoc->ret_timestamp, BAD_NODE_TIMEOUT)) {
|| mono_time_is_timeout(dht->mono_time, assoc->ret_timestamp, BAD_NODE_TIMEOUT)) {
continue;
}

View File

@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright © 2016-2025 The TokTok team.
* Copyright © 2016-2026 The TokTok team.
* Copyright © 2013 Tox project.
*/
@@ -10,14 +10,17 @@
#define C_TOXCORE_TOXCORE_DHT_H
#include <stdbool.h>
#include <stdint.h>
#include "attributes.h"
#include "crypto_core.h"
#include "logger.h"
#include "mem.h"
#include "mono_time.h"
#include "net.h"
#include "network.h"
#include "ping_array.h"
#include "rng.h"
#ifdef __cplusplus
extern "C" {
@@ -156,19 +159,6 @@ typedef struct Client_data {
/*----------------------------------------------------------------------------------*/
typedef struct NAT {
/* true if currently hole punching */
bool hole_punching;
uint32_t punching_index;
uint32_t tries;
uint32_t punching_index2;
uint64_t punching_timestamp;
uint64_t recv_nat_ping_timestamp;
uint64_t nat_ping_id;
uint64_t nat_ping_timestamp;
} NAT;
typedef struct Node_format {
uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE];
IP_Port ip_port;

View File

@@ -16,14 +16,14 @@ using tox::test::SimulatedEnvironment;
void TestHandleRequest(Fuzz_Data &input)
{
SimulatedEnvironment env;
auto c_mem = env.fake_memory().get_c_memory();
auto c_mem = env.fake_memory().c_memory();
CONSUME_OR_RETURN(const uint8_t *self_public_key, input, CRYPTO_PUBLIC_KEY_SIZE);
CONSUME_OR_RETURN(const uint8_t *self_secret_key, input, CRYPTO_SECRET_KEY_SIZE);
CONSUME_OR_RETURN(const std::uint8_t *self_public_key, input, CRYPTO_PUBLIC_KEY_SIZE);
CONSUME_OR_RETURN(const std::uint8_t *self_secret_key, input, CRYPTO_SECRET_KEY_SIZE);
uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE];
uint8_t request[MAX_CRYPTO_REQUEST_SIZE];
uint8_t request_id;
std::uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE];
std::uint8_t request[MAX_CRYPTO_REQUEST_SIZE];
std::uint8_t request_id;
handle_request(&c_mem, self_public_key, self_secret_key, public_key, request, &request_id,
input.data(), input.size());
}
@@ -32,16 +32,16 @@ void TestUnpackNodes(Fuzz_Data &input)
{
CONSUME1_OR_RETURN(const bool, tcp_enabled, input);
const uint16_t node_count = 5;
const std::uint16_t node_count = 5;
Node_format nodes[node_count];
uint16_t processed_data_len;
std::uint16_t processed_data_len;
const int packed_count = unpack_nodes(
nodes, node_count, &processed_data_len, input.data(), input.size(), tcp_enabled);
if (packed_count > 0) {
SimulatedEnvironment env;
auto c_mem = env.fake_memory().get_c_memory();
auto c_mem = env.fake_memory().c_memory();
Logger *logger = logger_new(&c_mem);
std::vector<uint8_t> packed(packed_count * PACKED_NODE_SIZE_IP6);
std::vector<std::uint8_t> packed(packed_count * PACKED_NODE_SIZE_IP6);
const int packed_size
= pack_nodes(logger, packed.data(), packed.size(), nodes, packed_count);
LOGGER_ASSERT(logger, packed_size == processed_data_len,
@@ -51,7 +51,7 @@ void TestUnpackNodes(Fuzz_Data &input)
// Check that packed nodes can be unpacked again and result in the
// original unpacked nodes.
Node_format nodes2[node_count];
uint16_t processed_data_len2;
std::uint16_t processed_data_len2;
const int packed_count2 = unpack_nodes(
nodes2, node_count, &processed_data_len2, packed.data(), packed.size(), tcp_enabled);
(void)packed_count2;
@@ -59,14 +59,14 @@ void TestUnpackNodes(Fuzz_Data &input)
assert(processed_data_len2 == processed_data_len);
assert(packed_count2 == packed_count);
#endif
assert(memcmp(nodes, nodes2, sizeof(Node_format) * packed_count) == 0);
assert(std::memcmp(nodes, nodes2, sizeof(Node_format) * packed_count) == 0);
}
}
} // namespace
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t *data, std::size_t size);
extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t *data, std::size_t size)
{
tox::test::fuzz_select_target<TestHandleRequest, TestUnpackNodes>(data, size);
return 0;

View File

@@ -10,6 +10,7 @@
#include "../testing/support/public/simulated_environment.hh"
#include "DHT_test_util.hh"
#include "attributes.h"
#include "crypto_core.h"
#include "crypto_core_test_util.hh"
#include "logger.h"
@@ -27,19 +28,19 @@ using ::testing::PrintToString;
using ::testing::UnorderedElementsAre;
using namespace tox::test;
using SecretKey = std::array<uint8_t, CRYPTO_SECRET_KEY_SIZE>;
using SecretKey = std::array<std::uint8_t, CRYPTO_SECRET_KEY_SIZE>;
struct KeyPair {
PublicKey pk;
SecretKey sk;
explicit KeyPair(const Random *rng) { crypto_new_keypair(rng, pk.data(), sk.data()); }
explicit KeyPair(const Random *_Nonnull rng) { crypto_new_keypair(rng, pk.data(), sk.data()); }
};
TEST(IdClosest, KeyIsClosestToItself)
{
SimulatedEnvironment env;
auto c_rng = env.fake_random().get_c_random();
auto c_rng = env.fake_random().c_random();
PublicKey pk0 = random_pk(&c_rng);
PublicKey pk1;
@@ -54,7 +55,7 @@ TEST(IdClosest, KeyIsClosestToItself)
TEST(IdClosest, IdenticalKeysAreSameDistance)
{
SimulatedEnvironment env;
auto c_rng = env.fake_random().get_c_random();
auto c_rng = env.fake_random().c_random();
PublicKey pk0 = random_pk(&c_rng);
PublicKey pk1 = random_pk(&c_rng);
@@ -65,7 +66,7 @@ TEST(IdClosest, IdenticalKeysAreSameDistance)
TEST(IdClosest, DistanceIsCommutative)
{
SimulatedEnvironment env;
auto c_rng = env.fake_random().get_c_random();
auto c_rng = env.fake_random().c_random();
PublicKey pk0 = random_pk(&c_rng);
PublicKey pk1 = random_pk(&c_rng);
@@ -100,7 +101,7 @@ TEST(IdClosest, DistinctKeysCannotHaveTheSameDistance)
PublicKey const pk1 = {0x00};
PublicKey pk2 = {0x00};
for (uint8_t i = 1; i < 0xff; ++i) {
for (std::uint8_t i = 1; i < 0xff; ++i) {
pk2[0] = i;
EXPECT_NE(id_closest(pk0.data(), pk1.data(), pk2.data()), 0);
}
@@ -152,7 +153,7 @@ Node_format fill(Node_format v, PublicKey const &pk, IP_Port const &ip_port)
TEST(AddToList, AddsFirstKeysInOrder)
{
SimulatedEnvironment env;
auto c_rng = env.fake_random().get_c_random();
auto c_rng = env.fake_random().c_random();
// Make cmp_key the furthest away from 00000... as possible, so all initial inserts succeed.
PublicKey const cmp_pk{0xff, 0xff, 0xff, 0xff};
@@ -255,7 +256,7 @@ TEST(AddToList, AddsFirstKeysInOrder)
TEST(AddToList, KeepsKeysInOrder)
{
SimulatedEnvironment env;
auto c_rng = env.fake_random().get_c_random();
auto c_rng = env.fake_random().c_random();
// Any random cmp_pk should work, as well as the smallest or (approximately) largest pk.
for (PublicKey const cmp_pk : {random_pk(&c_rng), PublicKey{0x00}, PublicKey{0xff, 0xff}}) {
@@ -281,24 +282,24 @@ TEST(AddToList, KeepsKeysInOrder)
TEST(Request, CreateAndParse)
{
SimulatedEnvironment env;
auto c_mem = env.fake_memory().get_c_memory();
auto c_rng = env.fake_random().get_c_random();
auto c_mem = env.fake_memory().c_memory();
auto c_rng = env.fake_random().c_random();
// Peers.
const KeyPair sender(&c_rng);
const KeyPair receiver(&c_rng);
const uint8_t sent_pkt_id = CRYPTO_PACKET_FRIEND_REQ;
const std::uint8_t sent_pkt_id = CRYPTO_PACKET_FRIEND_REQ;
// Encoded packet.
std::array<uint8_t, MAX_CRYPTO_REQUEST_SIZE> packet;
std::array<std::uint8_t, MAX_CRYPTO_REQUEST_SIZE> packet;
// Received components.
PublicKey pk;
std::array<uint8_t, MAX_CRYPTO_REQUEST_SIZE> incoming;
uint8_t recvd_pkt_id;
std::array<std::uint8_t, MAX_CRYPTO_REQUEST_SIZE> incoming;
std::uint8_t recvd_pkt_id;
// Request data: maximum payload is 918 bytes, so create a payload 1 byte larger than max.
std::vector<uint8_t> outgoing(919);
std::vector<std::uint8_t> outgoing(919);
random_bytes(&c_rng, outgoing.data(), outgoing.size());
EXPECT_LT(create_request(&c_mem, &c_rng, sender.pk.data(), sender.sk.data(), packet.data(),
@@ -330,7 +331,7 @@ TEST(Request, CreateAndParse)
ASSERT_GE(recvd_length, 0);
EXPECT_EQ(
std::vector<uint8_t>(incoming.begin(), incoming.begin() + recvd_length), outgoing);
std::vector<std::uint8_t>(incoming.begin(), incoming.begin() + recvd_length), outgoing);
outgoing.pop_back();
}
@@ -339,8 +340,8 @@ TEST(Request, CreateAndParse)
TEST(AnnounceNodes, SetAndTest)
{
SimulatedEnvironment env;
auto c_mem = env.fake_memory().get_c_memory();
auto c_rng = env.fake_random().get_c_random();
auto c_mem = env.fake_memory().c_memory();
auto c_rng = env.fake_random().c_random();
// Use FakeNetwork instead of Test_Network (which wrapped os_network)
// Create endpoint bound to virtual port
@@ -356,7 +357,7 @@ TEST(AnnounceNodes, SetAndTest)
// Hook up simulation clock to mono_time
mono_time_set_current_time_callback(
mono_time,
[](void *user_data) -> uint64_t {
[](void *user_data) -> std::uint64_t {
auto *clock = static_cast<FakeClock *>(user_data);
return clock->current_time_ms();
},
@@ -367,8 +368,8 @@ TEST(AnnounceNodes, SetAndTest)
Ptr<DHT> dht(new_dht(log, &c_mem, &c_rng, &net_struct, mono_time, net.get(), true, true));
ASSERT_NE(dht, nullptr);
uint8_t pk_data[CRYPTO_PUBLIC_KEY_SIZE];
memcpy(pk_data, dht_get_self_public_key(dht.get()), sizeof(pk_data));
std::uint8_t pk_data[CRYPTO_PUBLIC_KEY_SIZE];
std::memcpy(pk_data, dht_get_self_public_key(dht.get()), sizeof(pk_data));
PublicKey self_pk(to_array(pk_data));
PublicKey pk1 = random_pk(&c_rng);

View File

@@ -3,6 +3,7 @@
#include <cassert>
#include <cstring>
#include <iomanip>
#include <ostream>
#include "../testing/support/public/simulated_environment.hh"
#include "DHT.h"
@@ -15,11 +16,14 @@ using tox::test::FakeClock;
// --- Mock DHT Implementation ---
MockDHT::MockDHT(const Random *rng) { crypto_new_keypair(rng, self_public_key, self_secret_key); }
const uint8_t *MockDHT::get_shared_key(const uint8_t *pk)
MockDHT::MockDHT(const Random *_Nonnull rng)
{
std::array<uint8_t, CRYPTO_PUBLIC_KEY_SIZE> pk_arr;
crypto_new_keypair(rng, self_public_key, self_secret_key);
}
const std::uint8_t *_Nullable MockDHT::get_shared_key(const std::uint8_t *_Nonnull pk)
{
std::array<std::uint8_t, CRYPTO_PUBLIC_KEY_SIZE> pk_arr;
std::copy(pk, pk + CRYPTO_PUBLIC_KEY_SIZE, pk_arr.begin());
auto it = shared_keys.find(pk_arr);
if (it != shared_keys.end()) {
@@ -29,28 +33,28 @@ const uint8_t *MockDHT::get_shared_key(const uint8_t *pk)
++computation_count;
// Compute new shared key
std::array<uint8_t, CRYPTO_SHARED_KEY_SIZE> sk;
std::array<std::uint8_t, CRYPTO_SHARED_KEY_SIZE> sk;
encrypt_precompute(pk, self_secret_key, sk.data());
shared_keys[pk_arr] = sk;
return shared_keys[pk_arr].data();
}
const Net_Crypto_DHT_Funcs MockDHT::funcs = {
[](void *obj, const uint8_t *public_key) {
[](void *_Nonnull obj, const std::uint8_t *_Nonnull public_key) {
return static_cast<MockDHT *>(obj)->get_shared_key(public_key);
},
[](const void *obj) { return static_cast<const MockDHT *>(obj)->self_public_key; },
[](const void *obj) { return static_cast<const MockDHT *>(obj)->self_secret_key; },
[](const void *_Nonnull obj) { return static_cast<const MockDHT *>(obj)->self_public_key; },
[](const void *_Nonnull obj) { return static_cast<const MockDHT *>(obj)->self_secret_key; },
};
// --- WrappedMockDHT Implementation ---
WrappedMockDHT::WrappedMockDHT(tox::test::SimulatedEnvironment &env, uint16_t port)
WrappedMockDHT::WrappedMockDHT(tox::test::SimulatedEnvironment &env, std::uint16_t port)
: node_(env.create_node(0))
, logger_(logger_new(&node_->c_memory), [](Logger *l) { logger_kill(l); })
, mono_time_(mono_time_new(
&node_->c_memory,
[](void *ud) -> uint64_t {
[](void *_Nullable ud) -> std::uint64_t {
return static_cast<tox::test::FakeClock *>(ud)->current_time_ms();
},
&env.fake_clock()),
@@ -91,14 +95,15 @@ const Net_Crypto_DHT_Funcs WrappedMockDHT::funcs = MockDHT::funcs;
// --- WrappedDHT Implementation ---
WrappedDHT::WrappedDHT(tox::test::SimulatedEnvironment &env, uint16_t port)
WrappedDHT::WrappedDHT(tox::test::SimulatedEnvironment &env, std::uint16_t port)
: node_(env.create_node(0))
, logger_(logger_new(&node_->c_memory), [](Logger *l) { logger_kill(l); })
, mono_time_(
mono_time_new(
&node_->c_memory,
[](void *ud) -> uint64_t { return static_cast<FakeClock *>(ud)->current_time_ms(); },
&env.fake_clock()),
, mono_time_(mono_time_new(
&node_->c_memory,
[](void *_Nullable ud) -> std::uint64_t {
return static_cast<FakeClock *>(ud)->current_time_ms();
},
&env.fake_clock()),
[mem = &node_->c_memory](Mono_Time *t) { mono_time_free(mem, t); })
, networking_(nullptr, [](Networking_Core *n) { kill_networking(n); })
, dht_(nullptr, [](DHT *d) { kill_dht(d); })
@@ -122,9 +127,15 @@ WrappedDHT::WrappedDHT(tox::test::SimulatedEnvironment &env, uint16_t port)
WrappedDHT::~WrappedDHT() = default;
const uint8_t *WrappedDHT::dht_public_key() const { return dht_get_self_public_key(dht_.get()); }
const std::uint8_t *WrappedDHT::dht_public_key() const
{
return dht_get_self_public_key(dht_.get());
}
const uint8_t *WrappedDHT::dht_secret_key() const { return dht_get_self_secret_key(dht_.get()); }
const std::uint8_t *WrappedDHT::dht_secret_key() const
{
return dht_get_self_secret_key(dht_.get());
}
IP_Port WrappedDHT::get_ip_port() const
{
@@ -142,16 +153,16 @@ void WrappedDHT::poll()
}
const Net_Crypto_DHT_Funcs WrappedDHT::funcs = {
[](void *obj, const uint8_t *public_key) {
[](void *_Nonnull obj, const std::uint8_t *_Nonnull public_key) {
return dht_get_shared_key_sent(static_cast<DHT *>(obj), public_key);
},
[](const void *obj) { return dht_get_self_public_key(static_cast<const DHT *>(obj)); },
[](const void *obj) { return dht_get_self_secret_key(static_cast<const DHT *>(obj)); },
[](const void *_Nonnull obj) { return dht_get_self_public_key(static_cast<const DHT *>(obj)); },
[](const void *_Nonnull obj) { return dht_get_self_secret_key(static_cast<const DHT *>(obj)); },
};
// --- Test Util Functions ---
Node_format random_node_format(const Random *rng)
Node_format random_node_format(const Random *_Nonnull rng)
{
Node_format node;
auto const pk = random_pk(rng);

View File

@@ -2,6 +2,7 @@
#define C_TOXCORE_TOXCORE_DHT_TEST_UTIL_H
#include <array>
#include <cstdint>
#include <functional>
#include <iosfwd>
#include <map>
@@ -9,10 +10,13 @@
#include <vector>
#include "DHT.h"
#include "attributes.h"
#include "crypto_core.h"
#include "logger.h"
#include "mono_time.h"
#include "net.h"
#include "net_crypto.h"
#include "rng.h"
#include "test_util.hh"
namespace tox::test {
@@ -27,21 +31,21 @@ bool operator==(Node_format const &a, Node_format const &b);
std::ostream &operator<<(std::ostream &out, Node_format const &v);
Node_format random_node_format(const Random *rng);
Node_format random_node_format(const Random *_Nonnull rng);
// --- Mock DHT ---
struct MockDHT {
uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE];
uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE];
std::uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE];
std::uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE];
// Cache for shared keys: Public Key -> Shared Key
std::map<std::array<uint8_t, CRYPTO_PUBLIC_KEY_SIZE>,
std::array<uint8_t, CRYPTO_SHARED_KEY_SIZE>>
std::map<std::array<std::uint8_t, CRYPTO_PUBLIC_KEY_SIZE>,
std::array<std::uint8_t, CRYPTO_SHARED_KEY_SIZE>>
shared_keys;
int computation_count = 0;
explicit MockDHT(const Random *rng);
explicit MockDHT(const Random *_Nonnull rng);
const uint8_t *get_shared_key(const uint8_t *pk);
const std::uint8_t *_Nullable get_shared_key(const std::uint8_t *_Nonnull pk);
static const Net_Crypto_DHT_Funcs funcs;
};
@@ -50,11 +54,11 @@ struct MockDHT {
// Wraps a MockDHT instance and its dependencies (networking, etc.) within a SimulatedEnvironment
class WrappedMockDHT {
public:
WrappedMockDHT(tox::test::SimulatedEnvironment &env, uint16_t port);
WrappedMockDHT(tox::test::SimulatedEnvironment &env, std::uint16_t port);
MockDHT *get_dht() { return &dht_; }
const uint8_t *dht_public_key() const { return dht_.self_public_key; }
const uint8_t *dht_secret_key() const { return dht_.self_secret_key; }
MockDHT *_Nonnull get_dht() { return &dht_; }
const std::uint8_t *_Nonnull dht_public_key() const { return dht_.self_public_key; }
const std::uint8_t *_Nonnull dht_secret_key() const { return dht_.self_secret_key; }
int dht_computation_count() const { return dht_.computation_count; }
// Returns a valid IP_Port for this node in the simulation (Localhost IPv6)
@@ -64,9 +68,9 @@ public:
tox::test::ScopedToxSystem &node() { return *node_; }
const tox::test::ScopedToxSystem &node() const { return *node_; }
Networking_Core *networking() { return networking_.get(); }
Mono_Time *mono_time() { return mono_time_.get(); }
Logger *logger() { return logger_.get(); }
Networking_Core *_Nonnull networking() { return networking_.get(); }
Mono_Time *_Nonnull mono_time() { return mono_time_.get(); }
Logger *_Nonnull logger() { return logger_.get(); }
~WrappedMockDHT();
@@ -74,9 +78,9 @@ public:
private:
std::unique_ptr<tox::test::ScopedToxSystem> node_;
std::unique_ptr<Logger, void (*)(Logger *)> logger_;
std::unique_ptr<Mono_Time, std::function<void(Mono_Time *)>> mono_time_;
std::unique_ptr<Networking_Core, void (*)(Networking_Core *)> networking_;
std::unique_ptr<Logger, void (*_Nonnull)(Logger *_Nullable)> logger_;
std::unique_ptr<Mono_Time, std::function<void(Mono_Time *_Nullable)>> mono_time_;
std::unique_ptr<Networking_Core, void (*_Nonnull)(Networking_Core *_Nullable)> networking_;
MockDHT dht_;
};
@@ -84,11 +88,11 @@ private:
// Wraps a DHT instance and its dependencies within a SimulatedEnvironment
class WrappedDHT {
public:
WrappedDHT(tox::test::SimulatedEnvironment &env, uint16_t port);
WrappedDHT(tox::test::SimulatedEnvironment &env, std::uint16_t port);
DHT *get_dht() { return dht_.get(); }
const uint8_t *dht_public_key() const;
const uint8_t *dht_secret_key() const;
DHT *_Nonnull get_dht() { return dht_.get(); }
const std::uint8_t *_Nonnull dht_public_key() const;
const std::uint8_t *_Nonnull dht_secret_key() const;
// Returns a valid IP_Port for this node in the simulation (Localhost IPv6)
IP_Port get_ip_port() const;
@@ -97,9 +101,9 @@ public:
tox::test::ScopedToxSystem &node() { return *node_; }
const tox::test::ScopedToxSystem &node() const { return *node_; }
Networking_Core *networking() { return networking_.get(); }
Mono_Time *mono_time() { return mono_time_.get(); }
Logger *logger() { return logger_.get(); }
Networking_Core *_Nonnull networking() { return networking_.get(); }
Mono_Time *_Nonnull mono_time() { return mono_time_.get(); }
Logger *_Nonnull logger() { return logger_.get(); }
~WrappedDHT();
@@ -107,10 +111,10 @@ public:
private:
std::unique_ptr<tox::test::ScopedToxSystem> node_;
std::unique_ptr<Logger, void (*)(Logger *)> logger_;
std::unique_ptr<Mono_Time, std::function<void(Mono_Time *)>> mono_time_;
std::unique_ptr<Networking_Core, void (*)(Networking_Core *)> networking_;
std::unique_ptr<DHT, void (*)(DHT *)> dht_;
std::unique_ptr<Logger, void (*_Nonnull)(Logger *_Nullable)> logger_;
std::unique_ptr<Mono_Time, std::function<void(Mono_Time *_Nullable)>> mono_time_;
std::unique_ptr<Networking_Core, void (*_Nonnull)(Networking_Core *_Nullable)> networking_;
std::unique_ptr<DHT, void (*_Nonnull)(DHT *_Nullable)> dht_;
};
#endif // C_TOXCORE_TOXCORE_DHT_TEST_UTIL_H

View File

@@ -9,8 +9,12 @@
#ifndef C_TOXCORE_TOXCORE_LAN_DISCOVERY_H
#define C_TOXCORE_TOXCORE_LAN_DISCOVERY_H
#include <stdbool.h>
#include <stdint.h>
#include "attributes.h"
#include "mem.h"
#include "net.h"
#include "network.h"
/**

View File

@@ -66,6 +66,8 @@ libtoxcore_la_SOURCES = ../third_party/cmp/cmp.c \
../toxcore/crypto_core.h \
../toxcore/DHT.c \
../toxcore/DHT.h \
../toxcore/ev.c \
../toxcore/ev.h \
../toxcore/forwarding.c \
../toxcore/forwarding.h \
../toxcore/friend_connection.c \
@@ -105,6 +107,8 @@ libtoxcore_la_SOURCES = ../third_party/cmp/cmp.c \
../toxcore/net_log.h \
../toxcore/net_profile.c \
../toxcore/net_profile.h \
../toxcore/net.c \
../toxcore/net.h \
../toxcore/network.c \
../toxcore/network.h \
../toxcore/onion_announce.c \
@@ -113,14 +117,20 @@ libtoxcore_la_SOURCES = ../third_party/cmp/cmp.c \
../toxcore/onion_client.h \
../toxcore/onion.c \
../toxcore/onion.h \
../toxcore/os_event.c \
../toxcore/os_event.h \
../toxcore/os_memory.c \
../toxcore/os_memory.h \
../toxcore/os_network.c \
../toxcore/os_network.h \
../toxcore/os_random.c \
../toxcore/os_random.h \
../toxcore/ping_array.c \
../toxcore/ping_array.h \
../toxcore/ping.c \
../toxcore/ping.h \
../toxcore/rng.c \
../toxcore/rng.h \
../toxcore/shared_key_cache.c \
../toxcore/shared_key_cache.h \
../toxcore/sort.c \
@@ -147,18 +157,12 @@ libtoxcore_la_SOURCES = ../third_party/cmp/cmp.c \
../toxcore/tox_events.h \
../toxcore/tox_log_level.c \
../toxcore/tox_log_level.h \
../toxcore/tox_memory.c \
../toxcore/tox_memory.h \
../toxcore/tox_memory_impl.h \
../toxcore/tox_options.c \
../toxcore/tox_options.h \
../toxcore/tox_pack.c \
../toxcore/tox_pack.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_unpack.c \
../toxcore/tox_unpack.h \

View File

@@ -1184,6 +1184,29 @@ int file_get_id(const Messenger *m, int32_t friendnumber, uint32_t filenumber, u
return 0;
}
int32_t file_by_id(const Messenger *m, uint32_t friendnumber, const uint8_t *file_id)
{
if (friendnumber >= m->numfriends || m->friendlist[friendnumber].status == 0) {
return -1;
}
for (uint32_t j = 0; j < MAX_CONCURRENT_FILE_PIPES; ++j) {
if (m->friendlist[friendnumber].file_sending[j].status != FILESTATUS_NONE) {
if (memcmp(m->friendlist[friendnumber].file_sending[j].id, file_id, FILE_ID_LENGTH) == 0) {
return (int32_t)j;
}
}
if (m->friendlist[friendnumber].file_receiving[j].status != FILESTATUS_NONE) {
if (memcmp(m->friendlist[friendnumber].file_receiving[j].id, file_id, FILE_ID_LENGTH) == 0) {
return (int32_t)((j + 1) << 16);
}
}
}
return -2;
}
/** @brief Send a file send request.
* Maximum filename length is 255 bytes.
* @retval 1 on success
@@ -3394,6 +3417,7 @@ Messenger *new_messenger(Mono_Time *mono_time, const Memory *mem, const Random *
return nullptr;
}
m->log = options->log;
m->mono_time = mono_time;
m->mem = mem;
m->rng = rng;
@@ -3409,16 +3433,6 @@ Messenger *new_messenger(Mono_Time *mono_time, const Memory *mem, const Random *
}
m->fr = fr;
Logger *log = logger_new(mem);
if (log == nullptr) {
friendreq_kill(m->fr);
mem_delete(mem, m);
return nullptr;
}
m->log = log;
logger_callback_log(m->log, options->log_callback, options->log_context, options->log_user_data);
unsigned int net_err = 0;
if (!options->udp_disabled && options->proxy_info.proxy_type != TCP_PROXY_NONE) {
@@ -3444,7 +3458,6 @@ Messenger *new_messenger(Mono_Time *mono_time, const Memory *mem, const Random *
*error = MESSENGER_ERROR_PORT;
}
logger_kill(m->log);
mem_delete(mem, m);
return nullptr;
}
@@ -3454,7 +3467,6 @@ Messenger *new_messenger(Mono_Time *mono_time, const Memory *mem, const Random *
if (dht == nullptr) {
kill_networking(m->net);
friendreq_kill(m->fr);
logger_kill(m->log);
mem_delete(mem, m);
return nullptr;
}
@@ -3466,7 +3478,6 @@ Messenger *new_messenger(Mono_Time *mono_time, const Memory *mem, const Random *
kill_dht(m->dht);
kill_networking(m->net);
friendreq_kill(m->fr);
logger_kill(m->log);
mem_delete(mem, m);
return nullptr;
}
@@ -3481,7 +3492,6 @@ Messenger *new_messenger(Mono_Time *mono_time, const Memory *mem, const Random *
kill_dht(m->dht);
kill_networking(m->net);
friendreq_kill(m->fr);
logger_kill(m->log);
mem_delete(mem, m);
return nullptr;
}
@@ -3496,7 +3506,6 @@ Messenger *new_messenger(Mono_Time *mono_time, const Memory *mem, const Random *
kill_dht(m->dht);
kill_networking(m->net);
friendreq_kill(m->fr);
logger_kill(m->log);
mem_delete(mem, m);
return nullptr;
}
@@ -3534,7 +3543,6 @@ Messenger *new_messenger(Mono_Time *mono_time, const Memory *mem, const Random *
kill_dht(m->dht);
kill_networking(m->net);
friendreq_kill(m->fr);
logger_kill(m->log);
mem_delete(mem, m);
return nullptr;
}
@@ -3561,7 +3569,6 @@ Messenger *new_messenger(Mono_Time *mono_time, const Memory *mem, const Random *
kill_dht(m->dht);
kill_networking(m->net);
friendreq_kill(m->fr);
logger_kill(m->log);
mem_delete(mem, m);
return nullptr;
}
@@ -3588,7 +3595,6 @@ Messenger *new_messenger(Mono_Time *mono_time, const Memory *mem, const Random *
kill_dht(m->dht);
kill_networking(m->net);
friendreq_kill(m->fr);
logger_kill(m->log);
mem_delete(mem, m);
if (error != nullptr) {
@@ -3652,7 +3658,6 @@ void kill_messenger(Messenger *m)
friendreq_kill(m->fr);
mem_delete(m->mem, m->options.state_plugins);
logger_kill(m->log);
mem_delete(m->mem, m);
}

View File

@@ -10,6 +10,9 @@
#ifndef C_TOXCORE_TOXCORE_MESSENGER_H
#define C_TOXCORE_TOXCORE_MESSENGER_H
#include <stdbool.h>
#include <stdint.h>
#include "DHT.h"
#include "TCP_client.h"
#include "TCP_server.h"
@@ -24,6 +27,7 @@
#include "logger.h"
#include "mem.h"
#include "mono_time.h"
#include "net.h"
#include "net_crypto.h"
#include "net_profile.h"
#include "network.h"
@@ -70,6 +74,8 @@ typedef struct Messenger_State_Plugin {
} Messenger_State_Plugin;
typedef struct Messenger_Options {
Logger *_Nonnull log;
bool ipv6enabled;
bool udp_disabled;
TCP_Proxy_Info proxy_info;
@@ -81,10 +87,6 @@ typedef struct Messenger_Options {
bool dht_announcements_enabled;
bool groups_persistence_enabled;
logger_cb *_Nullable log_callback;
void *_Nullable log_context;
void *_Nullable log_user_data;
Messenger_State_Plugin *_Nullable state_plugins;
uint8_t state_plugins_length;
@@ -626,6 +628,7 @@ void callback_file_reqchunk(Messenger *_Nonnull m, m_file_chunk_request_cb *_Non
* @retval -2 if filenumber not valid
*/
int file_get_id(const Messenger *_Nonnull m, int32_t friendnumber, uint32_t filenumber, uint8_t *_Nonnull file_id);
int32_t file_by_id(const Messenger *_Nonnull m, uint32_t friendnumber, const uint8_t *_Nonnull file_id);
/** @brief Send a file send request.
*

View File

@@ -9,14 +9,18 @@
#ifndef C_TOXCORE_TOXCORE_TCP_CLIENT_H
#define C_TOXCORE_TOXCORE_TCP_CLIENT_H
#include <stdint.h>
#include "attributes.h"
#include "crypto_core.h"
#include "forwarding.h"
#include "logger.h"
#include "mem.h"
#include "mono_time.h"
#include "net.h"
#include "net_profile.h"
#include "network.h"
#include "rng.h"
#ifdef __cplusplus
extern "C" {

View File

@@ -5,14 +5,18 @@
#include <gtest/gtest.h>
#include <cstdio>
#include <cstring>
#include <vector>
#include "TCP_common.h"
#include "attributes.h"
#include "crypto_core.h"
#include "logger.h"
#include "mono_time.h"
#include "net_profile.h"
#include "network.h"
#include "test_util.hh"
#include "util.h"
namespace {
@@ -23,12 +27,12 @@ class TCPClientTest : public ::testing::Test {
protected:
SimulatedEnvironment env;
Mono_Time *create_mono_time(const Memory *mem)
Mono_Time *_Nonnull create_mono_time(const Memory *_Nonnull mem)
{
Mono_Time *mt = mono_time_new(mem, nullptr, nullptr);
Mono_Time *_Nonnull mt = REQUIRE_NOT_NULL(mono_time_new(mem, nullptr, nullptr));
mono_time_set_current_time_callback(
mt,
[](void *user_data) -> uint64_t {
[](void *_Nullable user_data) -> std::uint64_t {
auto *clock = static_cast<FakeClock *>(user_data);
return clock->current_time_ms();
},
@@ -36,15 +40,19 @@ protected:
return mt;
}
static void log_cb(void *context, Logger_Level level, const char *file, uint32_t line,
const char *func, const char *message, void *userdata)
static void log_cb(void *_Nullable context, Logger_Level level, const char *_Nonnull file,
std::uint32_t line, const char *_Nonnull func, const char *_Nonnull message,
void *_Nullable userdata)
{
if (level > LOGGER_LEVEL_TRACE) {
fprintf(stderr, "[%d] %s:%u %s: %s\n", level, file, line, func, message);
}
}
static void net_profile_deleter(Net_Profile *p, const Memory *mem) { netprof_kill(mem, p); }
static void net_profile_deleter(Net_Profile *_Nullable p, const Memory *_Nonnull mem)
{
netprof_kill(mem, p);
}
};
TEST_F(TCPClientTest, ConnectsToRelay)
@@ -68,13 +76,13 @@ TEST_F(TCPClientTest, ConnectsToRelay)
ASSERT_EQ(0, net_listen(&server_node->c_network, server_sock, 5));
// Server Keys
uint8_t server_pk[CRYPTO_PUBLIC_KEY_SIZE];
uint8_t server_sk[CRYPTO_SECRET_KEY_SIZE];
std::uint8_t server_pk[CRYPTO_PUBLIC_KEY_SIZE];
std::uint8_t server_sk[CRYPTO_SECRET_KEY_SIZE];
crypto_new_keypair(&server_node->c_random, server_pk, server_sk);
// Client Keys
uint8_t client_pk[CRYPTO_PUBLIC_KEY_SIZE];
uint8_t client_sk[CRYPTO_SECRET_KEY_SIZE];
std::uint8_t client_pk[CRYPTO_PUBLIC_KEY_SIZE];
std::uint8_t client_sk[CRYPTO_SECRET_KEY_SIZE];
crypto_new_keypair(&client_node->c_random, client_pk, client_sk);
Net_Profile *client_profile = netprof_new(client_log, &client_node->c_memory);
@@ -92,7 +100,7 @@ TEST_F(TCPClientTest, ConnectsToRelay)
// 3. Simulation Loop
bool connected = false;
Socket accepted_sock = net_invalid_socket();
uint64_t start_time = env.clock().current_time_ms();
std::uint64_t start_time = env.clock().current_time_ms();
while (env.clock().current_time_ms() - start_time < 5000) {
env.advance_time(10);
@@ -109,7 +117,7 @@ TEST_F(TCPClientTest, ConnectsToRelay)
// Server handles handshake
if (sock_valid(accepted_sock)) {
uint8_t buf[TCP_CLIENT_HANDSHAKE_SIZE];
std::uint8_t buf[TCP_CLIENT_HANDSHAKE_SIZE];
IP_Port remote = {{{0}}};
int len = net_recv(
&server_node->c_network, server_log, accepted_sock, buf, sizeof(buf), &remote);
@@ -120,15 +128,16 @@ TEST_F(TCPClientTest, ConnectsToRelay)
if (len == TCP_CLIENT_HANDSHAKE_SIZE) {
// Verify client PK
EXPECT_EQ(0, memcmp(buf, client_pk, CRYPTO_PUBLIC_KEY_SIZE));
EXPECT_EQ(0, std::memcmp(buf, client_pk, CRYPTO_PUBLIC_KEY_SIZE));
// Decrypt
uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE];
std::uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE];
encrypt_precompute(client_pk, server_sk, shared_key);
uint8_t plain[TCP_HANDSHAKE_PLAIN_SIZE];
const uint8_t *nonce_ptr = buf + CRYPTO_PUBLIC_KEY_SIZE;
const uint8_t *ciphertext_ptr = buf + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE;
std::uint8_t plain[TCP_HANDSHAKE_PLAIN_SIZE];
const std::uint8_t *nonce_ptr = buf + CRYPTO_PUBLIC_KEY_SIZE;
const std::uint8_t *ciphertext_ptr
= buf + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE;
int res = decrypt_data_symmetric(&server_node->c_memory, shared_key, nonce_ptr,
ciphertext_ptr,
@@ -143,19 +152,19 @@ TEST_F(TCPClientTest, ConnectsToRelay)
// Generate Response
// [Nonce (24)] [Encrypted (PK(32)+Nonce(24)+MAC(16))]
uint8_t resp_nonce[CRYPTO_NONCE_SIZE];
std::uint8_t resp_nonce[CRYPTO_NONCE_SIZE];
random_nonce(&server_node->c_random, resp_nonce);
uint8_t temp_pk[CRYPTO_PUBLIC_KEY_SIZE];
uint8_t temp_sk[CRYPTO_SECRET_KEY_SIZE];
std::uint8_t temp_pk[CRYPTO_PUBLIC_KEY_SIZE];
std::uint8_t temp_sk[CRYPTO_SECRET_KEY_SIZE];
crypto_new_keypair(&server_node->c_random, temp_pk, temp_sk);
uint8_t resp_plain[TCP_HANDSHAKE_PLAIN_SIZE];
memcpy(resp_plain, temp_pk, CRYPTO_PUBLIC_KEY_SIZE);
std::uint8_t resp_plain[TCP_HANDSHAKE_PLAIN_SIZE];
std::memcpy(resp_plain, temp_pk, CRYPTO_PUBLIC_KEY_SIZE);
random_nonce(&server_node->c_random, resp_plain + CRYPTO_PUBLIC_KEY_SIZE);
uint8_t response[TCP_SERVER_HANDSHAKE_SIZE];
memcpy(response, resp_nonce, CRYPTO_NONCE_SIZE);
std::uint8_t response[TCP_SERVER_HANDSHAKE_SIZE];
std::memcpy(response, resp_nonce, CRYPTO_NONCE_SIZE);
encrypt_data_symmetric(&server_node->c_memory, shared_key,
resp_nonce, // nonce
@@ -209,12 +218,12 @@ TEST_F(TCPClientTest, SendDataIntegerOverflow)
ASSERT_TRUE(bind_to_port(&server_node->c_network, server_sock, net_family_ipv4(), 33446));
ASSERT_EQ(0, net_listen(&server_node->c_network, server_sock, 5));
uint8_t server_pk[CRYPTO_PUBLIC_KEY_SIZE];
uint8_t server_sk[CRYPTO_SECRET_KEY_SIZE];
std::uint8_t server_pk[CRYPTO_PUBLIC_KEY_SIZE];
std::uint8_t server_sk[CRYPTO_SECRET_KEY_SIZE];
crypto_new_keypair(&server_node->c_random, server_pk, server_sk);
uint8_t client_pk[CRYPTO_PUBLIC_KEY_SIZE];
uint8_t client_sk[CRYPTO_SECRET_KEY_SIZE];
std::uint8_t client_pk[CRYPTO_PUBLIC_KEY_SIZE];
std::uint8_t client_sk[CRYPTO_SECRET_KEY_SIZE];
crypto_new_keypair(&client_node->c_random, client_pk, client_sk);
Net_Profile *client_profile = netprof_new(client_log, &client_node->c_memory);
@@ -230,20 +239,20 @@ TEST_F(TCPClientTest, SendDataIntegerOverflow)
bool connected = false;
Socket accepted_sock = net_invalid_socket();
uint64_t start_time = env.clock().current_time_ms();
uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE];
uint8_t sent_nonce[CRYPTO_NONCE_SIZE] = {0};
uint8_t recv_nonce[CRYPTO_NONCE_SIZE] = {0};
std::uint64_t start_time = env.clock().current_time_ms();
std::uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE];
std::uint8_t sent_nonce[CRYPTO_NONCE_SIZE] = {0};
std::uint8_t recv_nonce[CRYPTO_NONCE_SIZE] = {0};
// Helper to send encrypted packet from server to client
auto server_send_packet = [&](const uint8_t *data, uint16_t length) {
uint16_t packet_size = sizeof(uint16_t) + length + CRYPTO_MAC_SIZE;
std::vector<uint8_t> packet(packet_size);
uint16_t c_length = net_htons(length + CRYPTO_MAC_SIZE);
memcpy(packet.data(), &c_length, sizeof(uint16_t));
auto server_send_packet = [&](const std::uint8_t *data, std::uint16_t length) {
std::uint16_t packet_size = sizeof(std::uint16_t) + length + CRYPTO_MAC_SIZE;
std::vector<std::uint8_t> packet(packet_size);
std::uint16_t c_length = net_htons(length + CRYPTO_MAC_SIZE);
std::memcpy(packet.data(), &c_length, sizeof(std::uint16_t));
encrypt_data_symmetric(&server_node->c_memory, shared_key, sent_nonce, data, length,
packet.data() + sizeof(uint16_t));
packet.data() + sizeof(std::uint16_t));
increment_nonce(sent_nonce);
IP_Port remote = {{{0}}};
@@ -263,39 +272,39 @@ TEST_F(TCPClientTest, SendDataIntegerOverflow)
}
if (sock_valid(accepted_sock) && !connected) {
uint8_t buf[TCP_CLIENT_HANDSHAKE_SIZE];
std::uint8_t buf[TCP_CLIENT_HANDSHAKE_SIZE];
IP_Port remote = {{{0}}};
int len = net_recv(
&server_node->c_network, server_log, accepted_sock, buf, sizeof(buf), &remote);
if (len == TCP_CLIENT_HANDSHAKE_SIZE) {
encrypt_precompute(client_pk, server_sk, shared_key);
uint8_t plain[TCP_HANDSHAKE_PLAIN_SIZE];
std::uint8_t plain[TCP_HANDSHAKE_PLAIN_SIZE];
if (decrypt_data_symmetric(&server_node->c_memory, shared_key,
buf + CRYPTO_PUBLIC_KEY_SIZE,
buf + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE,
TCP_CLIENT_HANDSHAKE_SIZE - (CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE),
plain)
== TCP_HANDSHAKE_PLAIN_SIZE) {
memcpy(recv_nonce, plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_NONCE_SIZE);
std::memcpy(recv_nonce, plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_NONCE_SIZE);
uint8_t resp_nonce[CRYPTO_NONCE_SIZE];
std::uint8_t resp_nonce[CRYPTO_NONCE_SIZE];
random_nonce(&server_node->c_random, resp_nonce);
memcpy(sent_nonce, resp_nonce, CRYPTO_NONCE_SIZE);
std::memcpy(sent_nonce, resp_nonce, CRYPTO_NONCE_SIZE);
uint8_t temp_pk[CRYPTO_PUBLIC_KEY_SIZE];
uint8_t temp_sk[CRYPTO_SECRET_KEY_SIZE];
std::uint8_t temp_pk[CRYPTO_PUBLIC_KEY_SIZE];
std::uint8_t temp_sk[CRYPTO_SECRET_KEY_SIZE];
crypto_new_keypair(&server_node->c_random, temp_pk, temp_sk);
uint8_t resp_plain[TCP_HANDSHAKE_PLAIN_SIZE];
memcpy(resp_plain, temp_pk, CRYPTO_PUBLIC_KEY_SIZE);
std::uint8_t resp_plain[TCP_HANDSHAKE_PLAIN_SIZE];
std::memcpy(resp_plain, temp_pk, CRYPTO_PUBLIC_KEY_SIZE);
random_nonce(&server_node->c_random, resp_plain + CRYPTO_PUBLIC_KEY_SIZE);
// FIX: Save the nonce that client will use for receiving
memcpy(sent_nonce, resp_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_NONCE_SIZE);
std::memcpy(sent_nonce, resp_plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_NONCE_SIZE);
uint8_t response[TCP_SERVER_HANDSHAKE_SIZE];
memcpy(response, resp_nonce, CRYPTO_NONCE_SIZE);
std::uint8_t response[TCP_SERVER_HANDSHAKE_SIZE];
std::memcpy(response, resp_nonce, CRYPTO_NONCE_SIZE);
encrypt_data_symmetric(&server_node->c_memory, shared_key, resp_nonce,
resp_plain, TCP_HANDSHAKE_PLAIN_SIZE, response + CRYPTO_NONCE_SIZE);
net_send(&server_node->c_network, server_log, accepted_sock, response,
@@ -315,14 +324,14 @@ TEST_F(TCPClientTest, SendDataIntegerOverflow)
ASSERT_TRUE(connected);
// Establish sub-connection 0
uint8_t con_id = 0;
uint8_t other_pk[CRYPTO_PUBLIC_KEY_SIZE] = {0}; // Dummy PK
std::uint8_t con_id = 0;
std::uint8_t other_pk[CRYPTO_PUBLIC_KEY_SIZE] = {0}; // Dummy PK
// 1. Send Routing Response to set status=1
{
uint8_t packet[1 + 1 + CRYPTO_PUBLIC_KEY_SIZE];
std::uint8_t packet[1 + 1 + CRYPTO_PUBLIC_KEY_SIZE];
packet[0] = TCP_PACKET_ROUTING_RESPONSE;
packet[1] = con_id + NUM_RESERVED_PORTS;
memcpy(packet + 2, other_pk, CRYPTO_PUBLIC_KEY_SIZE);
std::memcpy(packet + 2, other_pk, CRYPTO_PUBLIC_KEY_SIZE);
server_send_packet(packet, sizeof(packet));
}
@@ -334,7 +343,7 @@ TEST_F(TCPClientTest, SendDataIntegerOverflow)
// 2. Send Connection Notification to set status=2
{
uint8_t packet[1 + 1];
std::uint8_t packet[1 + 1];
packet[0] = TCP_PACKET_CONNECTION_NOTIFICATION;
packet[1] = con_id + NUM_RESERVED_PORTS;
server_send_packet(packet, sizeof(packet));
@@ -347,7 +356,7 @@ TEST_F(TCPClientTest, SendDataIntegerOverflow)
}
// Now call send_data with 65535 bytes
std::vector<uint8_t> large_data(65535);
std::vector<std::uint8_t> large_data(65535);
// This should trigger integer overflow: 1 + 65535 = 0. VLA(0). packet[0] write -> Crash/UB
send_data(client_log, client_conn, con_id, large_data.data(), 65535);

View File

@@ -316,3 +316,69 @@ int read_packet_tcp_secure_connection(
return len;
}
const char *tcp_packet_type_to_string(Tcp_Packet type)
{
switch (type) {
case TCP_PACKET_ROUTING_REQUEST:
return "TCP_PACKET_ROUTING_REQUEST";
case TCP_PACKET_ROUTING_RESPONSE:
return "TCP_PACKET_ROUTING_RESPONSE";
case TCP_PACKET_CONNECTION_NOTIFICATION:
return "TCP_PACKET_CONNECTION_NOTIFICATION";
case TCP_PACKET_DISCONNECT_NOTIFICATION:
return "TCP_PACKET_DISCONNECT_NOTIFICATION";
case TCP_PACKET_PING:
return "TCP_PACKET_PING";
case TCP_PACKET_PONG:
return "TCP_PACKET_PONG";
case TCP_PACKET_OOB_SEND:
return "TCP_PACKET_OOB_SEND";
case TCP_PACKET_OOB_RECV:
return "TCP_PACKET_OOB_RECV";
case TCP_PACKET_ONION_REQUEST:
return "TCP_PACKET_ONION_REQUEST";
case TCP_PACKET_ONION_RESPONSE:
return "TCP_PACKET_ONION_RESPONSE";
case TCP_PACKET_FORWARD_REQUEST:
return "TCP_PACKET_FORWARD_REQUEST";
case TCP_PACKET_FORWARDING:
return "TCP_PACKET_FORWARDING";
}
return "<invalid Tcp_Packet>";
}
bool tcp_packet_from_int(uint32_t value, Tcp_Packet *_Nonnull out_enum)
{
switch (value) {
case TCP_PACKET_ROUTING_REQUEST:
case TCP_PACKET_ROUTING_RESPONSE:
case TCP_PACKET_CONNECTION_NOTIFICATION:
case TCP_PACKET_DISCONNECT_NOTIFICATION:
case TCP_PACKET_PING:
case TCP_PACKET_PONG:
case TCP_PACKET_OOB_SEND:
case TCP_PACKET_OOB_RECV:
case TCP_PACKET_ONION_REQUEST:
case TCP_PACKET_ONION_RESPONSE:
case TCP_PACKET_FORWARD_REQUEST:
case TCP_PACKET_FORWARDING: {
*out_enum = (Tcp_Packet)value;
return true;
}
}
return false;
}

View File

@@ -6,12 +6,21 @@
#ifndef C_TOXCORE_TOXCORE_TCP_COMMON_H
#define C_TOXCORE_TOXCORE_TCP_COMMON_H
#include <stdbool.h>
#include <stdint.h>
#include "attributes.h"
#include "crypto_core.h"
#include "logger.h"
#include "mem.h"
#include "net.h"
#include "net_profile.h"
#include "network.h"
#include "rng.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct TCP_Priority_List TCP_Priority_List;
struct TCP_Priority_List {
@@ -40,6 +49,9 @@ typedef enum Tcp_Packet {
TCP_PACKET_FORWARDING = 11,
} Tcp_Packet;
const char *_Nonnull tcp_packet_type_to_string(Tcp_Packet type);
bool tcp_packet_from_int(uint32_t value, Tcp_Packet *_Nonnull out_enum);
#define TCP_HANDSHAKE_PLAIN_SIZE (CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE)
#define TCP_SERVER_HANDSHAKE_SIZE (CRYPTO_NONCE_SIZE + TCP_HANDSHAKE_PLAIN_SIZE + CRYPTO_MAC_SIZE)
#define TCP_CLIENT_HANDSHAKE_SIZE (CRYPTO_PUBLIC_KEY_SIZE + TCP_SERVER_HANDSHAKE_SIZE)
@@ -106,4 +118,8 @@ int read_tcp_packet(const Logger *_Nonnull logger, const Memory *_Nonnull mem, c
int read_packet_tcp_secure_connection(const Logger *_Nonnull logger, const Memory *_Nonnull mem, const Network *_Nonnull ns, Socket sock, uint16_t *_Nonnull next_packet_length,
const uint8_t *_Nonnull shared_key, uint8_t *_Nonnull recv_nonce, uint8_t *_Nonnull data, uint16_t max_len, const IP_Port *_Nonnull ip_port);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* C_TOXCORE_TOXCORE_TCP_COMMON_H */

View File

@@ -0,0 +1,98 @@
#include "TCP_common.h"
#include <gtest/gtest.h>
#include "logger.h"
#include "os_memory.h"
#include "os_random.h"
namespace {
TEST(TCP_common, PriorityQueueOrderingAndIntegrity)
{
constexpr Network_Funcs mock_funcs = {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
// Mock net_send to simulate a full buffer (returns 0)
// This forces packets into the priority queue.
[](void *obj, Socket sock, const uint8_t *buf, size_t len) {
(void)obj;
(void)sock;
(void)buf;
(void)len;
return 0;
},
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
};
TCP_Connection con;
memset(&con, 0, sizeof(con));
con.mem = os_memory();
con.rng = os_random();
Network ns = {&mock_funcs, nullptr};
con.ns = &ns;
Logger *logger = logger_new(con.mem);
ASSERT_NE(logger, nullptr);
// Minimal initialization to make write_packet_tcp_secure_connection happy
// It calls encrypt_data_symmetric which needs shared_key and sent_nonce
memset(con.shared_key, 0x42, sizeof(con.shared_key));
memset(con.sent_nonce, 0x12, sizeof(con.sent_nonce));
uint8_t data1[] = "packet1";
uint8_t data2[] = "packet2";
uint8_t data3[] = "packet3";
// First packet: will fail net_send (mocked to 0) and go to add_priority
// Queue: [packet1]
int ret1 = write_packet_tcp_secure_connection(logger, &con, data1, sizeof(data1), true);
ASSERT_EQ(ret1, 1);
ASSERT_NE(con.priority_queue_start, nullptr);
ASSERT_EQ(con.priority_queue_start, con.priority_queue_end);
// Second packet: will go to add_priority
// Queue: [packet1] -> [packet2]
int ret2 = write_packet_tcp_secure_connection(logger, &con, data2, sizeof(data2), true);
ASSERT_EQ(ret2, 1);
ASSERT_NE(con.priority_queue_start->next, nullptr);
ASSERT_EQ(con.priority_queue_start->next, con.priority_queue_end);
// Third packet: will go to add_priority
// WITH BUG: Queue becomes [packet1] -> [packet3], packet2 is LOST
// WITHOUT BUG: Queue: [packet1] -> [packet2] -> [packet3]
int ret3 = write_packet_tcp_secure_connection(logger, &con, data3, sizeof(data3), true);
ASSERT_EQ(ret3, 1);
// Verify integrity
TCP_Priority_List *p = con.priority_queue_start;
int count = 0;
while (p) {
count++;
p = p->next;
}
// This is where it will fail if the change in
// https://github.com/TokTok/c-toxcore/pull/2387 is applied.
// The count will be 2 instead of 3.
EXPECT_EQ(count, 3)
<< "Priority queue lost packets! (likely due to incorrect tail pointer usage)";
// Clean up
wipe_priority_list(con.mem, con.priority_queue_start);
logger_kill(logger);
}
}

View File

@@ -21,8 +21,10 @@
#include "logger.h"
#include "mem.h"
#include "mono_time.h"
#include "net.h"
#include "net_profile.h"
#include "network.h"
#include "rng.h"
#define TCP_CONN_NONE 0
#define TCP_CONN_VALID 1

View File

@@ -5,6 +5,6 @@
namespace {
// TODO(Jfreegman) make this useful or remove it after NGC is merged
TEST(TCP_connection, NullTest) { (void)tcp_send_oob_packet_using_relay; }
TEST(TCP_connection, NullTest) { (void)&tcp_send_oob_packet_using_relay; }
} // namespace

View File

@@ -974,7 +974,7 @@ TCP_Server *new_tcp_server(const Logger *logger, const Memory *mem, const Random
temp->socks_listening = socks_listening;
#ifdef TCP_SERVER_USE_EPOLL
temp->efd = epoll_create(8);
temp->efd = epoll_create1(EPOLL_CLOEXEC);
if (temp->efd == -1) {
LOGGER_ERROR(logger, "epoll initialisation failed");

View File

@@ -9,15 +9,20 @@
#ifndef C_TOXCORE_TOXCORE_TCP_SERVER_H
#define C_TOXCORE_TOXCORE_TCP_SERVER_H
#include <stdbool.h>
#include <stdint.h>
#include "attributes.h"
#include "crypto_core.h"
#include "forwarding.h"
#include "logger.h"
#include "mem.h"
#include "mono_time.h"
#include "net.h"
#include "net_profile.h"
#include "network.h"
#include "onion.h"
#include "rng.h"
#ifdef __cplusplus
extern "C" {

View File

@@ -25,7 +25,7 @@
#include "timed_auth.h"
#include "util.h"
// Settings for the shared key cache
/* Settings for the shared key cache */
#define MAX_KEYS_PER_SLOT 4
#define KEYS_TIMEOUT 600

View File

@@ -5,6 +5,7 @@
#ifndef C_TOXCORE_TOXCORE_ANNOUNCE_H
#define C_TOXCORE_TOXCORE_ANNOUNCE_H
#include <stdbool.h>
#include <stdint.h>
#include "DHT.h"
@@ -15,6 +16,7 @@
#include "mem.h"
#include "mono_time.h"
#include "network.h"
#include "rng.h"
#define MAX_ANNOUNCEMENT_SIZE 512

View File

@@ -19,7 +19,7 @@ struct Bin_Pack {
cmp_ctx_t ctx;
};
static bool null_reader(cmp_ctx_t *_Nonnull ctx, void *_Nonnull data, size_t limit)
static bool null_reader(cmp_ctx_t *_Nonnull ctx, void *_Nullable data, size_t limit)
{
assert(limit == 0);
return false;
@@ -31,10 +31,18 @@ static bool null_skipper(cmp_ctx_t *_Nonnull ctx, size_t count)
return false;
}
static size_t buf_writer(cmp_ctx_t *_Nonnull ctx, const void *_Nonnull data, size_t count)
static size_t buf_writer(cmp_ctx_t *_Nonnull ctx, const void *_Nullable data, size_t count)
{
const uint8_t *bytes = (const uint8_t *)data;
Bin_Pack *bp = (Bin_Pack *)ctx->buf;
const uint8_t *const bytes = (const uint8_t *)data;
if (count == 0) {
return 0;
}
if (bytes == nullptr) {
return 0;
}
Bin_Pack *const bp = (Bin_Pack *)ctx->buf;
assert(bp != nullptr);
const uint32_t new_pos = bp->bytes_pos + count;
if (new_pos < bp->bytes_pos) {
@@ -159,9 +167,30 @@ bool bin_pack_u64(Bin_Pack *bp, uint64_t val)
bool bin_pack_bin(Bin_Pack *bp, const uint8_t *data, uint32_t length)
{
if (length == 0) {
return cmp_write_bin_marker(&bp->ctx, 0);
}
if (data == nullptr) {
return false;
}
return cmp_write_bin(&bp->ctx, data, length);
}
bool bin_pack_str(Bin_Pack *bp, const char *data, uint32_t length)
{
if (length == 0) {
return cmp_write_str_marker(&bp->ctx, 0);
}
if (data == nullptr) {
return false;
}
return cmp_write_str(&bp->ctx, data, length);
}
bool bin_pack_nil(Bin_Pack *bp)
{
return cmp_write_nil(&bp->ctx);
@@ -197,5 +226,9 @@ bool bin_pack_u64_b(Bin_Pack *bp, uint64_t val)
bool bin_pack_bin_b(Bin_Pack *bp, const uint8_t *data, uint32_t length)
{
if (length > 0 && data == nullptr) {
return false;
}
return bp->ctx.write(&bp->ctx, data, length) == length;
}

View File

@@ -162,7 +162,9 @@ bool bin_pack_u64(Bin_Pack *_Nonnull bp, uint64_t val);
/** @brief Pack an empty array member as a MessagePack nil value. */
bool bin_pack_nil(Bin_Pack *_Nonnull bp);
/** @brief Pack a byte array as MessagePack bin. */
bool bin_pack_bin(Bin_Pack *_Nonnull bp, const uint8_t *_Nonnull data, uint32_t length);
bool bin_pack_bin(Bin_Pack *_Nonnull bp, const uint8_t *_Nullable data, uint32_t length);
/** @brief Pack a string as MessagePack str. */
bool bin_pack_str(Bin_Pack *_Nonnull bp, const char *_Nullable data, uint32_t length);
/** @brief Start packing a custom binary representation.
*
* A call to this function must be followed by exactly `size` bytes packed by functions below.
@@ -183,7 +185,7 @@ bool bin_pack_u64_b(Bin_Pack *_Nonnull bp, uint64_t val);
* Note that unless you prepend the array length manually, there is no record of it in the resulting
* serialised representation.
*/
bool bin_pack_bin_b(Bin_Pack *_Nonnull bp, const uint8_t *_Nonnull data, uint32_t length);
bool bin_pack_bin_b(Bin_Pack *_Nonnull bp, const uint8_t *_Nullable data, uint32_t length);
#ifdef __cplusplus
} /* extern "C" */

View File

@@ -4,40 +4,42 @@
#include <array>
#include "attributes.h"
#include "bin_unpack.h"
#include "logger.h"
#include "mem.h"
#include "os_memory.h"
#include "test_util.hh"
namespace {
TEST(BinPack, TooSmallBufferIsNotExceeded)
{
const uint64_t orig = 1234567812345678LL;
std::array<uint8_t, sizeof(orig) - 1> buf;
const std::uint64_t orig = 1234567812345678LL;
std::array<std::uint8_t, sizeof(orig) - 1> buf;
EXPECT_FALSE(bin_pack_obj(
[](const void *obj, const Logger *logger, Bin_Pack *bp) {
return bin_pack_u64_b(bp, *static_cast<const uint64_t *>(obj));
[](const void *_Nullable obj, const Logger *_Nullable logger, Bin_Pack *_Nonnull bp) {
return bin_pack_u64_b(bp, *static_cast<const std::uint64_t *>(REQUIRE_NOT_NULL(obj)));
},
&orig, nullptr, buf.data(), buf.size()));
}
TEST(BinPack, PackedUint64CanBeUnpacked)
{
const Memory *mem = os_memory();
const uint64_t orig = 1234567812345678LL;
std::array<uint8_t, 8> buf;
const Memory *_Nonnull mem = os_memory();
const std::uint64_t orig = 1234567812345678LL;
std::array<std::uint8_t, 8> buf;
EXPECT_TRUE(bin_pack_obj(
[](const void *obj, const Logger *logger, Bin_Pack *bp) {
return bin_pack_u64_b(bp, *static_cast<const uint64_t *>(obj));
[](const void *_Nullable obj, const Logger *_Nullable logger, Bin_Pack *_Nonnull bp) {
return bin_pack_u64_b(bp, *static_cast<const std::uint64_t *>(REQUIRE_NOT_NULL(obj)));
},
&orig, nullptr, buf.data(), buf.size()));
uint64_t unpacked = 0;
std::uint64_t unpacked = 0;
EXPECT_TRUE(bin_unpack_obj(
mem,
[](void *obj, Bin_Unpack *bu) {
return bin_unpack_u64_b(bu, static_cast<uint64_t *>(obj));
[](void *_Nonnull obj, Bin_Unpack *_Nonnull bu) {
return bin_unpack_u64_b(bu, static_cast<std::uint64_t *>(obj));
},
&unpacked, buf.data(), buf.size()));
EXPECT_EQ(unpacked, 1234567812345678LL);
@@ -45,38 +47,42 @@ TEST(BinPack, PackedUint64CanBeUnpacked)
TEST(BinPack, MsgPackedUint8CanBeUnpackedAsUint32)
{
const Memory *mem = os_memory();
const uint8_t orig = 123;
std::array<uint8_t, 2> buf;
const Memory *_Nonnull mem = os_memory();
const std::uint8_t orig = 123;
std::array<std::uint8_t, 2> buf;
EXPECT_TRUE(bin_pack_obj(
[](const void *obj, const Logger *logger, Bin_Pack *bp) {
return bin_pack_u08(bp, *static_cast<const uint8_t *>(obj));
[](const void *_Nullable obj, const Logger *_Nullable logger, Bin_Pack *_Nonnull bp) {
return bin_pack_u08(bp, *static_cast<const std::uint8_t *>(REQUIRE_NOT_NULL(obj)));
},
&orig, nullptr, buf.data(), buf.size()));
uint32_t unpacked = 0;
std::uint32_t unpacked = 0;
EXPECT_TRUE(bin_unpack_obj(
mem,
[](void *obj, Bin_Unpack *bu) { return bin_unpack_u32(bu, static_cast<uint32_t *>(obj)); },
[](void *_Nonnull obj, Bin_Unpack *_Nonnull bu) {
return bin_unpack_u32(bu, static_cast<std::uint32_t *>(obj));
},
&unpacked, buf.data(), buf.size()));
EXPECT_EQ(unpacked, 123);
}
TEST(BinPack, MsgPackedUint32CanBeUnpackedAsUint8IfSmallEnough)
{
const Memory *mem = os_memory();
const uint32_t orig = 123;
std::array<uint8_t, 2> buf;
const Memory *_Nonnull mem = os_memory();
const std::uint32_t orig = 123;
std::array<std::uint8_t, 2> buf;
EXPECT_TRUE(bin_pack_obj(
[](const void *obj, const Logger *logger, Bin_Pack *bp) {
return bin_pack_u32(bp, *static_cast<const uint32_t *>(obj));
[](const void *_Nullable obj, const Logger *_Nullable logger, Bin_Pack *_Nonnull bp) {
return bin_pack_u32(bp, *static_cast<const std::uint32_t *>(REQUIRE_NOT_NULL(obj)));
},
&orig, nullptr, buf.data(), buf.size()));
uint8_t unpacked = 0;
std::uint8_t unpacked = 0;
EXPECT_TRUE(bin_unpack_obj(
mem,
[](void *obj, Bin_Unpack *bu) { return bin_unpack_u08(bu, static_cast<uint8_t *>(obj)); },
[](void *_Nonnull obj, Bin_Unpack *_Nonnull bu) {
return bin_unpack_u08(bu, static_cast<std::uint8_t *>(obj));
},
&unpacked, buf.data(), buf.size()));
EXPECT_EQ(unpacked, 123);
@@ -85,18 +91,20 @@ TEST(BinPack, MsgPackedUint32CanBeUnpackedAsUint8IfSmallEnough)
TEST(BinPack, LargeMsgPackedUint32CannotBeUnpackedAsUint8)
{
const Memory *mem = os_memory();
const uint32_t orig = 1234567;
std::array<uint8_t, 5> buf;
const std::uint32_t orig = 1234567;
std::array<std::uint8_t, 5> buf;
EXPECT_TRUE(bin_pack_obj(
[](const void *obj, const Logger *logger, Bin_Pack *bp) {
return bin_pack_u32(bp, *static_cast<const uint32_t *>(obj));
return bin_pack_u32(bp, *static_cast<const std::uint32_t *>(obj));
},
&orig, nullptr, buf.data(), buf.size()));
uint8_t unpacked = 0;
std::uint8_t unpacked = 0;
EXPECT_FALSE(bin_unpack_obj(
mem,
[](void *obj, Bin_Unpack *bu) { return bin_unpack_u08(bu, static_cast<uint8_t *>(obj)); },
[](void *obj, Bin_Unpack *bu) {
return bin_unpack_u08(bu, static_cast<std::uint8_t *>(obj));
},
&unpacked, buf.data(), buf.size()));
}
@@ -104,13 +112,13 @@ TEST(BinPack, BinCanHoldPackedInts)
{
const Memory *mem = os_memory();
struct Stuff {
uint64_t u64;
uint16_t u16;
std::uint64_t u64;
std::uint16_t u16;
};
const Stuff orig = {1234567812345678LL, 54321};
static const uint32_t packed_size = sizeof(uint64_t) + sizeof(uint16_t);
static const std::uint32_t packed_size = sizeof(std::uint64_t) + sizeof(std::uint16_t);
std::array<uint8_t, 12> buf;
std::array<std::uint8_t, 12> buf;
EXPECT_TRUE(bin_pack_obj(
[](const void *obj, const Logger *logger, Bin_Pack *bp) {
const Stuff *self = static_cast<const Stuff *>(obj);
@@ -125,7 +133,7 @@ TEST(BinPack, BinCanHoldPackedInts)
mem,
[](void *obj, Bin_Unpack *bu) {
Stuff *stuff = static_cast<Stuff *>(obj);
uint32_t size;
std::uint32_t size;
return bin_unpack_bin_size(bu, &size) //
&& size == 10 //
&& bin_unpack_u64_b(bu, &stuff->u64) //
@@ -139,38 +147,293 @@ TEST(BinPack, BinCanHoldPackedInts)
TEST(BinPack, BinCanHoldArbitraryData)
{
const Memory *mem = os_memory();
std::array<uint8_t, 7> buf;
std::array<std::uint8_t, 7> buf;
EXPECT_TRUE(bin_pack_obj(
[](const void *obj, const Logger *logger, Bin_Pack *bp) {
return bin_pack_bin_marker(bp, 5) //
&& bin_pack_bin_b(bp, reinterpret_cast<const uint8_t *>("hello"), 5);
&& bin_pack_bin_b(bp, reinterpret_cast<const std::uint8_t *>("hello"), 5);
},
nullptr, nullptr, buf.data(), buf.size()));
std::array<uint8_t, 5> str;
std::array<std::uint8_t, 5> str;
EXPECT_TRUE(bin_unpack_obj(
mem,
[](void *obj, Bin_Unpack *bu) {
uint8_t *data = static_cast<uint8_t *>(obj);
std::uint8_t *data = static_cast<std::uint8_t *>(obj);
return bin_unpack_bin_fixed(bu, data, 5);
},
str.data(), buf.data(), buf.size()));
EXPECT_EQ(str, (std::array<uint8_t, 5>{'h', 'e', 'l', 'l', 'o'}));
EXPECT_EQ(str, (std::array<std::uint8_t, 5>{'h', 'e', 'l', 'l', 'o'}));
}
TEST(BinPack, OversizedArrayFailsUnpack)
{
const Memory *mem = os_memory();
std::array<uint8_t, 1> buf = {0x91};
std::array<std::uint8_t, 1> buf = {0x91};
uint32_t size;
std::uint32_t size;
EXPECT_FALSE(bin_unpack_obj(
mem,
[](void *obj, Bin_Unpack *bu) {
uint32_t *size_ptr = static_cast<uint32_t *>(obj);
std::uint32_t *size_ptr = static_cast<std::uint32_t *>(obj);
return bin_unpack_array(bu, size_ptr);
},
&size, buf.data(), buf.size()));
}
TEST(BinPack, StringCanBePackedAndUnpacked)
{
const Memory *mem = os_memory();
const char *orig = "hello world";
const uint32_t orig_len = strlen(orig);
std::array<std::uint8_t, 13> buf;
EXPECT_TRUE(bin_pack_obj(
[](const void *obj, const Logger *logger, Bin_Pack *bp) {
const char *str = static_cast<const char *>(obj);
return bin_pack_str(bp, str, strlen(str));
},
orig, nullptr, buf.data(), buf.size()));
struct {
char *str;
uint32_t len;
} unpacked = {nullptr, 0};
EXPECT_TRUE(bin_unpack_obj(
mem,
[](void *obj, Bin_Unpack *bu) {
auto *res = static_cast<decltype(unpacked) *>(obj);
return bin_unpack_str(bu, &res->str, &res->len);
},
&unpacked, buf.data(), buf.size()));
EXPECT_EQ(unpacked.len, orig_len);
EXPECT_STREQ(unpacked.str, orig);
mem_delete(mem, unpacked.str);
}
TEST(BinPack, EmptyStringCanBePackedAndUnpacked)
{
const Memory *mem = os_memory();
const char *orig = "";
const uint32_t orig_len = 0;
std::array<std::uint8_t, 1> buf;
EXPECT_TRUE(bin_pack_obj(
[](const void *obj, const Logger *logger, Bin_Pack *bp) {
const char *str = static_cast<const char *>(obj);
return bin_pack_str(bp, str, 0);
},
orig, nullptr, buf.data(), buf.size()));
struct {
char *str;
uint32_t len;
} unpacked = {nullptr, 0};
EXPECT_TRUE(bin_unpack_obj(
mem,
[](void *obj, Bin_Unpack *bu) {
auto *res = static_cast<decltype(unpacked) *>(obj);
return bin_unpack_str(bu, &res->str, &res->len);
},
&unpacked, buf.data(), buf.size()));
EXPECT_EQ(unpacked.len, orig_len);
EXPECT_STREQ(unpacked.str, orig);
mem_delete(mem, unpacked.str);
}
TEST(BinPack, EmptyBinCanBePackedAndUnpacked)
{
const Memory *mem = os_memory();
std::array<std::uint8_t, 2> buf;
EXPECT_TRUE(bin_pack_obj(
[](const void *obj, const Logger *logger, Bin_Pack *bp) {
uint8_t dummy = 0;
return bin_pack_bin(bp, &dummy, 0);
},
nullptr, nullptr, buf.data(), buf.size()));
struct {
uint8_t *data;
uint32_t len;
} unpacked = {reinterpret_cast<uint8_t *>(1),
1}; // Initialize with non-null to check it gets set to null
EXPECT_TRUE(bin_unpack_obj(
mem,
[](void *obj, Bin_Unpack *bu) {
auto *res = static_cast<decltype(unpacked) *>(obj);
return bin_unpack_bin(bu, &res->data, &res->len);
},
&unpacked, buf.data(), buf.size()));
EXPECT_EQ(unpacked.len, 0);
EXPECT_EQ(unpacked.data, nullptr);
}
TEST(BinPack, NullStringWithZeroLengthCanBePackedAndUnpacked)
{
const Memory *mem = os_memory();
std::array<std::uint8_t, 1> buf;
EXPECT_TRUE(bin_pack_obj([](const void *obj, const Logger *logger,
Bin_Pack *bp) { return bin_pack_str(bp, nullptr, 0); },
nullptr, nullptr, buf.data(), buf.size()));
struct {
char *str;
uint32_t len;
} unpacked = {nullptr, 0};
EXPECT_TRUE(bin_unpack_obj(
mem,
[](void *obj, Bin_Unpack *bu) {
auto *res = static_cast<decltype(unpacked) *>(obj);
return bin_unpack_str(bu, &res->str, &res->len);
},
&unpacked, buf.data(), buf.size()));
EXPECT_EQ(unpacked.len, 0);
ASSERT_NE(unpacked.str, nullptr);
EXPECT_EQ(unpacked.str[0], '\0');
mem_delete(mem, unpacked.str);
}
TEST(BinPack, NullBinWithZeroLengthCanBePackedAndUnpacked)
{
const Memory *mem = os_memory();
std::array<std::uint8_t, 2> buf;
EXPECT_TRUE(bin_pack_obj([](const void *obj, const Logger *logger,
Bin_Pack *bp) { return bin_pack_bin(bp, nullptr, 0); },
nullptr, nullptr, buf.data(), buf.size()));
struct {
uint8_t *data;
uint32_t len;
} unpacked = {reinterpret_cast<uint8_t *>(1), 1};
EXPECT_TRUE(bin_unpack_obj(
mem,
[](void *obj, Bin_Unpack *bu) {
auto *res = static_cast<decltype(unpacked) *>(obj);
return bin_unpack_bin(bu, &res->data, &res->len);
},
&unpacked, buf.data(), buf.size()));
EXPECT_EQ(unpacked.len, 0);
EXPECT_EQ(unpacked.data, nullptr);
}
TEST(BinPack, PackFailsWithNullAndNonZeroLength)
{
std::array<std::uint8_t, 10> buf;
// bin_pack_str
EXPECT_FALSE(bin_pack_obj([](const void *obj, const Logger *logger,
Bin_Pack *bp) { return bin_pack_str(bp, nullptr, 1); },
nullptr, nullptr, buf.data(), buf.size()));
// bin_pack_bin
EXPECT_FALSE(bin_pack_obj([](const void *obj, const Logger *logger,
Bin_Pack *bp) { return bin_pack_bin(bp, nullptr, 1); },
nullptr, nullptr, buf.data(), buf.size()));
// bin_pack_bin_b
EXPECT_FALSE(bin_pack_obj([](const void *obj, const Logger *logger,
Bin_Pack *bp) { return bin_pack_bin_b(bp, nullptr, 1); },
nullptr, nullptr, buf.data(), buf.size()));
}
TEST(BinPack, PlainBinaryZeroLengthCanBePackedAndUnpacked)
{
const Memory *mem = os_memory();
std::array<std::uint8_t, 1> buf = {0xAA}; // Canary
EXPECT_TRUE(bin_pack_obj([](const void *obj, const Logger *logger,
Bin_Pack *bp) { return bin_pack_bin_b(bp, nullptr, 0); },
nullptr, nullptr, buf.data(), buf.size()));
// pos should not have advanced
EXPECT_EQ(buf[0], 0xAA);
std::uint8_t dummy = 0xBB;
EXPECT_TRUE(bin_unpack_obj(
mem,
[](void *obj, Bin_Unpack *bu) {
return bin_unpack_bin_b(bu, static_cast<std::uint8_t *>(obj), 0);
},
&dummy, buf.data(), 0));
EXPECT_EQ(dummy, 0xBB);
}
TEST(BinPack, StringUnpackGuaranteesNonNull)
{
const Memory *mem = os_memory();
std::array<std::uint8_t, 1> buf;
// Pack empty string
bin_pack_obj(
[](const void *obj, const Logger *logger, Bin_Pack *bp) { return bin_pack_str(bp, "", 0); },
nullptr, nullptr, buf.data(), buf.size());
char *res = nullptr;
EXPECT_TRUE(bin_unpack_obj(
mem,
[](void *obj, Bin_Unpack *bu) {
auto **ptr = static_cast<char **>(obj);
uint32_t dummy_len;
return bin_unpack_str(bu, ptr, &dummy_len);
},
&res, buf.data(), buf.size()));
ASSERT_NE(res, nullptr);
EXPECT_EQ(res[0], '\0');
mem_delete(mem, res);
}
TEST(BinPack, UnpackFailsOnBufferOverrun)
{
const Memory *mem = os_memory();
// 1. String claiming to be 100 bytes in a 5 byte buffer
std::array<std::uint8_t, 5> buf;
buf[0] = 0xD9; // str 8
buf[1] = 100;
struct StrRes {
char *s;
uint32_t l;
} res_str = {nullptr, 0};
EXPECT_FALSE(bin_unpack_obj(
mem,
[](void *obj, Bin_Unpack *bu) {
auto *res = static_cast<StrRes *>(obj);
return bin_unpack_str(bu, &res->s, &res->l);
},
&res_str, buf.data(), buf.size()));
// 2. Bin claiming to be 100 bytes
buf[0] = 0xC4; // bin 8
buf[1] = 100;
struct BinRes {
uint8_t *b;
uint32_t l;
} res_bin = {nullptr, 0};
EXPECT_FALSE(bin_unpack_obj(
mem,
[](void *obj, Bin_Unpack *bu) {
auto *res = static_cast<BinRes *>(obj);
return bin_unpack_bin(bu, &res->b, &res->l);
},
&res_bin, buf.data(), buf.size()));
}
} // namespace

View File

@@ -20,10 +20,18 @@ struct Bin_Unpack {
cmp_ctx_t ctx;
};
static bool buf_reader(cmp_ctx_t *_Nonnull ctx, void *_Nonnull data, size_t limit)
static bool buf_reader(cmp_ctx_t *_Nonnull ctx, void *_Nullable data, size_t limit)
{
uint8_t *bytes = (uint8_t *)data;
Bin_Unpack *reader = (Bin_Unpack *)ctx->buf;
uint8_t *const bytes = (uint8_t *)data;
if (limit == 0) {
return true;
}
if (bytes == nullptr) {
return false;
}
Bin_Unpack *const reader = (Bin_Unpack *)ctx->buf;
assert(reader != nullptr && reader->bytes != nullptr);
if (limit > reader->bytes_size) {
return false;
@@ -36,7 +44,10 @@ static bool buf_reader(cmp_ctx_t *_Nonnull ctx, void *_Nonnull data, size_t limi
static bool buf_skipper(cmp_ctx_t *_Nonnull ctx, size_t count)
{
Bin_Unpack *reader = (Bin_Unpack *)ctx->buf;
if (count == 0) {
return true;
}
Bin_Unpack *const reader = (Bin_Unpack *)ctx->buf;
assert(reader != nullptr && reader->bytes != nullptr);
if (count > reader->bytes_size) {
return false;
@@ -46,7 +57,7 @@ static bool buf_skipper(cmp_ctx_t *_Nonnull ctx, size_t count)
return true;
}
static size_t null_writer(cmp_ctx_t *_Nonnull ctx, const void *_Nonnull data, size_t count)
static size_t null_writer(cmp_ctx_t *_Nonnull ctx, const void *_Nullable data, size_t count)
{
assert(count == 0);
return 0;
@@ -119,6 +130,13 @@ 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;
}
if (bin_size == 0) {
*data_ptr = nullptr;
*data_length_ptr = 0;
return true;
}
uint8_t *const data = (uint8_t *)mem_balloc(bu->mem, bin_size);
if (data == nullptr) {
@@ -135,6 +153,36 @@ bool bin_unpack_bin(Bin_Unpack *bu, uint8_t **data_ptr, uint32_t *data_length_pt
return true;
}
bool bin_unpack_str(Bin_Unpack *bu, char **str_ptr, uint32_t *str_length_ptr)
{
uint32_t str_size;
if (!cmp_read_str_size(&bu->ctx, &str_size) || str_size > bu->bytes_size) {
return false;
}
if (str_size == UINT32_MAX) {
return false;
}
char *const str = (char *)mem_balloc(bu->mem, str_size + 1);
if (str == nullptr) {
return false;
}
if (str_size > 0) {
if (!bin_unpack_bin_b(bu, (uint8_t *)str, str_size)) {
mem_delete(bu->mem, str);
return false;
}
}
str[str_size] = 0;
*str_ptr = str;
*str_length_ptr = str_size;
return true;
}
bool bin_unpack_bin_max(Bin_Unpack *bu, uint8_t *data, uint16_t *data_length_ptr, uint16_t max_data_length)
{
uint32_t bin_size;

View File

@@ -84,7 +84,9 @@ bool bin_unpack_nil(Bin_Unpack *_Nonnull bu);
* remaining to be unpacked as the bin claims to need, so it's not possible to cause an arbitrarily
* large allocation unless the input array was already that large.
*/
bool bin_unpack_bin(Bin_Unpack *_Nonnull bu, uint8_t *_Nonnull *_Nonnull data_ptr, uint32_t *_Nonnull data_length_ptr);
bool bin_unpack_bin(Bin_Unpack *_Nonnull bu, uint8_t *_Nullable *_Nonnull data_ptr, uint32_t *_Nonnull data_length_ptr);
/** @brief Unpack a MessagePack str into a newly allocated string. */
bool bin_unpack_str(Bin_Unpack *_Nonnull bu, char *_Nonnull *_Nonnull str_ptr, uint32_t *_Nonnull str_length_ptr);
/** @brief Unpack a variable size MessagePack bin into a fixed size byte array.
*
* Stores unpacked data into `data` with its length stored in `data_length_ptr`. This function does
@@ -114,7 +116,7 @@ bool bin_unpack_u32_b(Bin_Unpack *_Nonnull bu, uint32_t *_Nonnull val);
bool bin_unpack_u64_b(Bin_Unpack *_Nonnull bu, uint64_t *_Nonnull val);
/** @brief Read a byte array directly from the packer, consuming `length` bytes. */
bool bin_unpack_bin_b(Bin_Unpack *_Nonnull bu, uint8_t *_Nonnull data, uint32_t length);
bool bin_unpack_bin_b(Bin_Unpack *_Nonnull bu, uint8_t *_Nullable data, uint32_t length);
#ifdef __cplusplus
} /* extern "C" */

View File

@@ -13,7 +13,7 @@
#include "attributes.h"
#include "ccompat.h"
#include "mem.h"
#include "tox_random.h"
#include "rng.h"
#include "util.h"
static_assert(CRYPTO_PUBLIC_KEY_SIZE == crypto_box_PUBLICKEYBYTES,
@@ -195,7 +195,7 @@ uint64_t random_u64(const Random *rng)
uint32_t random_range_u32(const Random *rng, uint32_t upper_bound)
{
return tox_random_uniform(rng, upper_bound);
return rng_uniform(rng, upper_bound);
}
bool crypto_signature_create(uint8_t signature[CRYPTO_SIGNATURE_SIZE],
@@ -486,5 +486,5 @@ void crypto_sha512(uint8_t hash[CRYPTO_SHA512_SIZE], const uint8_t *data, size_t
void random_bytes(const Random *rng, uint8_t *bytes, size_t length)
{
tox_random_bytes(rng, bytes, length);
rng_bytes(rng, bytes, length);
}

View File

@@ -17,7 +17,7 @@
#include "attributes.h"
#include "mem.h"
#include "tox_random.h"
#include "rng.h"
#ifdef __cplusplus
extern "C" {
@@ -190,11 +190,6 @@ bool crypto_sha512_eq(const uint8_t cksum1[_Nonnull CRYPTO_SHA512_SIZE], const u
*/
bool crypto_sha256_eq(const uint8_t cksum1[_Nonnull CRYPTO_SHA256_SIZE], const uint8_t cksum2[_Nonnull CRYPTO_SHA256_SIZE]);
/**
* @brief Shorter internal name for the RNG type.
*/
typedef Tox_Random Random;
/**
* @brief Return a random 8 bit integer.
*/

View File

@@ -7,17 +7,18 @@
#include <algorithm>
#include <array>
#include <cstdint>
#include <vector>
#include "crypto_core_test_util.hh"
namespace {
using HmacKey = std::array<uint8_t, CRYPTO_HMAC_KEY_SIZE>;
using Hmac = std::array<uint8_t, CRYPTO_HMAC_SIZE>;
using SecretKey = std::array<uint8_t, CRYPTO_SECRET_KEY_SIZE>;
using Signature = std::array<uint8_t, CRYPTO_SIGNATURE_SIZE>;
using Nonce = std::array<uint8_t, CRYPTO_NONCE_SIZE>;
using HmacKey = std::array<std::uint8_t, CRYPTO_HMAC_KEY_SIZE>;
using Hmac = std::array<std::uint8_t, CRYPTO_HMAC_SIZE>;
using SecretKey = std::array<std::uint8_t, CRYPTO_SECRET_KEY_SIZE>;
using Signature = std::array<std::uint8_t, CRYPTO_SIGNATURE_SIZE>;
using Nonce = std::array<std::uint8_t, CRYPTO_NONCE_SIZE>;
using tox::test::SimulatedEnvironment;
@@ -26,8 +27,8 @@ TEST(PkEqual, TwoRandomIdsAreNotEqual)
SimulatedEnvironment env;
auto &rng = env.fake_random();
uint8_t pk1[CRYPTO_PUBLIC_KEY_SIZE];
uint8_t pk2[CRYPTO_PUBLIC_KEY_SIZE];
std::uint8_t pk1[CRYPTO_PUBLIC_KEY_SIZE];
std::uint8_t pk2[CRYPTO_PUBLIC_KEY_SIZE];
rng.bytes(pk1, sizeof(pk1));
rng.bytes(pk2, sizeof(pk2));
@@ -40,8 +41,8 @@ TEST(PkEqual, IdCopyMakesKeysEqual)
SimulatedEnvironment env;
auto &rng = env.fake_random();
uint8_t pk1[CRYPTO_PUBLIC_KEY_SIZE];
uint8_t pk2[CRYPTO_PUBLIC_KEY_SIZE] = {0};
std::uint8_t pk1[CRYPTO_PUBLIC_KEY_SIZE];
std::uint8_t pk2[CRYPTO_PUBLIC_KEY_SIZE] = {0};
rng.bytes(pk1, sizeof(pk1));
@@ -53,8 +54,8 @@ TEST(PkEqual, IdCopyMakesKeysEqual)
TEST(CryptoCore, EncryptLargeData)
{
SimulatedEnvironment env;
auto c_mem = env.fake_memory().get_c_memory();
auto c_rng = env.fake_random().get_c_random();
auto c_mem = env.fake_memory().c_memory();
auto c_rng = env.fake_random().c_random();
Nonce nonce{};
PublicKey pk;
@@ -62,8 +63,8 @@ TEST(CryptoCore, EncryptLargeData)
crypto_new_keypair(&c_rng, pk.data(), sk.data());
// 100 MiB of data (all zeroes, doesn't matter what's inside).
std::vector<uint8_t> plain(100 * 1024 * 1024);
std::vector<uint8_t> encrypted(plain.size() + CRYPTO_MAC_SIZE);
std::vector<std::uint8_t> plain(100 * 1024 * 1024);
std::vector<std::uint8_t> encrypted(plain.size() + CRYPTO_MAC_SIZE);
encrypt_data(
&c_mem, pk.data(), sk.data(), nonce.data(), plain.data(), plain.size(), encrypted.data());
@@ -105,18 +106,18 @@ TEST(CryptoCore, IncrementNonceNumber)
TEST(CryptoCore, Signatures)
{
SimulatedEnvironment env;
auto c_rng = env.fake_random().get_c_random();
auto c_rng = env.fake_random().c_random();
Extended_Public_Key pk;
Extended_Secret_Key sk;
EXPECT_TRUE(create_extended_keypair(&pk, &sk, &c_rng));
std::vector<uint8_t> message{0};
std::vector<std::uint8_t> message{0};
message.clear();
// Try a few different sizes, including empty 0 length message.
for (uint8_t i = 0; i < 100; ++i) {
for (std::uint8_t i = 0; i < 100; ++i) {
Signature signature;
EXPECT_TRUE(crypto_signature_create(
signature.data(), message.data(), message.size(), get_sig_sk(&sk)));
@@ -130,16 +131,16 @@ TEST(CryptoCore, Signatures)
TEST(CryptoCore, Hmac)
{
SimulatedEnvironment env;
auto c_rng = env.fake_random().get_c_random();
auto c_rng = env.fake_random().c_random();
HmacKey sk;
new_hmac_key(&c_rng, sk.data());
std::vector<uint8_t> message{0};
std::vector<std::uint8_t> message{0};
message.clear();
// Try a few different sizes, including empty 0 length message.
for (uint8_t i = 0; i < 100; ++i) {
for (std::uint8_t i = 0; i < 100; ++i) {
Hmac auth;
crypto_hmac(auth.data(), sk.data(), message.data(), message.size());
EXPECT_TRUE(crypto_hmac_verify(auth.data(), sk.data(), message.data(), message.size()));

View File

@@ -2,22 +2,30 @@
#include <cstring>
#include <iomanip>
#include <ostream>
#include "crypto_core.h"
#include "test_util.hh"
PublicKey random_pk(const Random *rng)
PublicKey random_pk(const Random *_Nonnull rng)
{
PublicKey pk;
random_bytes(rng, pk.data(), pk.size());
return pk;
}
std::array<std::uint8_t, CRYPTO_SECRET_KEY_SIZE> random_sk(const Random *rng)
{
std::array<std::uint8_t, CRYPTO_SECRET_KEY_SIZE> sk;
random_bytes(rng, sk.data(), sk.size());
return sk;
}
std::ostream &operator<<(std::ostream &out, PublicKey const &pk)
{
out << '"';
for (uint8_t byte : pk) {
out << std::setw(2) << std::setfill('0') << std::hex << uint32_t(byte);
for (std::uint8_t byte : pk) {
out << std::setw(2) << std::setfill('0') << std::hex << std::uint32_t(byte);
}
out << '"';
return out;

View File

@@ -3,13 +3,15 @@
#include <algorithm>
#include <array>
#include <cstdint>
#include <iosfwd>
#include "attributes.h"
#include "crypto_core.h"
#include "test_util.hh"
struct PublicKey : private std::array<uint8_t, CRYPTO_PUBLIC_KEY_SIZE> {
using Base = std::array<uint8_t, CRYPTO_PUBLIC_KEY_SIZE>;
struct PublicKey : private std::array<std::uint8_t, CRYPTO_PUBLIC_KEY_SIZE> {
using Base = std::array<std::uint8_t, CRYPTO_PUBLIC_KEY_SIZE>;
using Base::begin;
using Base::data;
@@ -18,16 +20,16 @@ struct PublicKey : private std::array<uint8_t, CRYPTO_PUBLIC_KEY_SIZE> {
using Base::operator[];
PublicKey() = default;
explicit PublicKey(uint8_t const (&arr)[CRYPTO_PUBLIC_KEY_SIZE])
explicit PublicKey(std::uint8_t const (&arr)[CRYPTO_PUBLIC_KEY_SIZE])
: PublicKey(to_array(arr))
{
}
explicit PublicKey(std::array<uint8_t, CRYPTO_PUBLIC_KEY_SIZE> const &arr)
explicit PublicKey(std::array<std::uint8_t, CRYPTO_PUBLIC_KEY_SIZE> const &arr)
{
std::copy(arr.begin(), arr.end(), begin());
}
PublicKey(std::initializer_list<uint8_t> const &arr)
PublicKey(std::initializer_list<std::uint8_t> const &arr)
{
std::copy(arr.begin(), arr.end(), begin());
}
@@ -52,6 +54,8 @@ inline bool operator==(PublicKey::Base const &pk1, PublicKey const &pk2)
std::ostream &operator<<(std::ostream &out, PublicKey const &pk);
PublicKey random_pk(const Tox_Random *rng);
PublicKey random_pk(const Random *_Nonnull rng);
std::array<std::uint8_t, CRYPTO_SECRET_KEY_SIZE> random_sk(const Random *_Nonnull rng);
#endif // C_TOXCORE_TOXCORE_CRYPTO_CORE_TEST_UTIL_H

47
toxcore/ev.c Normal file
View File

@@ -0,0 +1,47 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright © 2026 The TokTok team.
*/
#include "ev.h"
#include <assert.h>
#include "ccompat.h"
bool ev_add(Ev *ev, Socket sock, Ev_Events events, void *data)
{
assert(ev != nullptr);
return ev->funcs->add_callback(ev->user_data, sock, events, data);
}
bool ev_mod(Ev *ev, Socket sock, Ev_Events events, void *data)
{
assert(ev != nullptr);
return ev->funcs->mod_callback(ev->user_data, sock, events, data);
}
bool ev_del(Ev *ev, Socket sock)
{
assert(ev != nullptr);
return ev->funcs->del_callback(ev->user_data, sock);
}
int32_t ev_run(Ev *ev, Ev_Result *results, uint32_t max_results, int32_t timeout_ms)
{
assert(ev != nullptr);
if (max_results == 0) {
return 0;
}
return ev->funcs->run_callback(ev->user_data, results, max_results, timeout_ms);
}
void ev_kill(Ev *ev)
{
if (ev == nullptr) {
return;
}
ev->funcs->kill_callback(ev);
}

130
toxcore/ev.h Normal file
View File

@@ -0,0 +1,130 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright © 2026 The TokTok team.
*/
#ifndef C_TOXCORE_TOXCORE_EV_H
#define C_TOXCORE_TOXCORE_EV_H
#include <stdbool.h>
#include <stdint.h>
#include "attributes.h"
#include "net.h" // For Socket
#ifdef __cplusplus
extern "C" {
#endif
typedef struct Ev Ev;
/**
* @brief Event types to monitor.
*/
typedef uint8_t Ev_Events;
#define EV_READ (1 << 0)
#define EV_WRITE (1 << 1)
#define EV_ERROR (1 << 2)
/**
* @brief Result of a triggered event.
*/
typedef struct Ev_Result {
Socket sock;
Ev_Events events;
void *_Nullable data;
} Ev_Result;
/**
* @brief Add a socket to the monitored set.
*
* This is called by `ev_add` to register a socket for event monitoring.
*
* @param self Backend-specific state.
* @param sock The socket to monitor.
* @param events Bitmask of events to monitor (EV_READ, EV_WRITE).
* @param data User context pointer to be returned in Ev_Result.
*
* @return true on success, false if the socket is already registered or on error.
*/
typedef bool ev_add_cb(void *_Nullable self, Socket sock, Ev_Events events, void *_Nullable data);
/**
* @brief Modify a registered socket's monitoring parameters.
*
* This is called by `ev_mod` to change the events or user data for a socket
* that is already being monitored.
*
* @param self Backend-specific state.
* @param sock The socket to modify.
* @param events New bitmask of events to monitor.
* @param data New user context pointer.
*
* @return true on success, false if the socket is not found or on error.
*/
typedef bool ev_mod_cb(void *_Nullable self, Socket sock, Ev_Events events, void *_Nullable data);
/**
* @brief Remove a socket from the monitored set.
*
* This is called by `ev_del` to stop monitoring a socket.
*
* @param self Backend-specific state.
* @param sock The socket to remove.
*
* @return true on success, false if the socket is not found.
*/
typedef bool ev_del_cb(void *_Nullable self, Socket sock);
/**
* @brief Wait for events on registered sockets.
*
* This is called by `ev_run`. It blocks until at least one event occurs,
* the timeout expires, or `ev_break` is called.
*
* @param self Backend-specific state.
* @param results Array to be populated with triggered events.
* @param max_results Maximum number of results to store in the array.
* @param timeout_ms Maximum time to wait in milliseconds. 0 for non-blocking,
* -1 for infinite wait.
*
* @return Number of events stored in `results`, 0 on timeout, or -1 on error.
*/
typedef int32_t ev_run_cb(void *_Nullable self, Ev_Result results[_Nonnull], uint32_t max_results, int32_t timeout_ms);
/** @brief Cleanup the event loop and free the Ev object. */
typedef void ev_kill_cb(Ev *_Nonnull ev);
/**
* @brief Virtual function table for Ev.
*/
typedef struct Ev_Funcs {
ev_add_cb *_Nonnull add_callback;
ev_mod_cb *_Nonnull mod_callback;
ev_del_cb *_Nonnull del_callback;
ev_run_cb *_Nonnull run_callback;
ev_kill_cb *_Nonnull kill_callback;
} Ev_Funcs;
/**
* @brief The Event Loop object.
*/
struct Ev {
const Ev_Funcs *_Nonnull funcs;
void *_Nullable user_data;
};
/**
* @brief Wrapper functions.
*/
bool ev_add(Ev *_Nonnull ev, Socket sock, Ev_Events events, void *_Nullable data);
bool ev_mod(Ev *_Nonnull ev, Socket sock, Ev_Events events, void *_Nullable data);
bool ev_del(Ev *_Nonnull ev, Socket sock);
int32_t ev_run(Ev *_Nonnull ev, Ev_Result results[_Nonnull], uint32_t max_results, int32_t timeout_ms);
void ev_kill(Ev *_Nullable ev);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* C_TOXCORE_TOXCORE_EV_H */

152
toxcore/ev_bench.cc Normal file
View File

@@ -0,0 +1,152 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright © 2026 The TokTok team.
*/
#include <benchmark/benchmark.h>
#include <cstdlib>
#include <vector>
#include "ev_test_util.hh"
#include "logger.h"
#include "net.h"
#include "os_event.h"
#include "os_memory.h"
#include "os_network.h"
namespace {
class EvBenchFixture : public benchmark::Fixture {
public:
void SetUp(const ::benchmark::State &state) override
{
if (os_network() == nullptr) {
setup_error = "os_network failed";
return;
}
mem = os_memory();
log = logger_new(mem);
// We don't want log output during benchmark
ev = os_event_new(mem, log);
}
void TearDown(const ::benchmark::State &state) override
{
for (size_t i = 0; i < sockets_r.size(); ++i) {
close_pair(sockets_r[i], sockets_w[i]);
}
sockets_r.clear();
sockets_w.clear();
ev_kill(ev);
logger_kill(log);
}
const Memory *mem = nullptr;
Logger *log = nullptr;
Ev *ev = nullptr;
std::vector<Socket> sockets_r;
std::vector<Socket> sockets_w;
int tag = 1;
std::string setup_error;
};
// Specialized SetUp to handle socket creation based on range
class EvBenchSocketsFixture : public EvBenchFixture {
public:
void SetUp(const ::benchmark::State &state) override
{
EvBenchFixture::SetUp(state);
if (!setup_error.empty()) {
return;
}
const int num_sockets = state.range(0);
for (int i = 0; i < num_sockets; ++i) {
Socket r{}, w{};
if (create_pair(&r, &w) != 0) {
setup_error = "Failed to create socket pair";
return;
}
sockets_r.push_back(r);
sockets_w.push_back(w);
if (!ev_add(ev, r, EV_READ, &tag)) {
setup_error = "Failed to add socket to event loop";
return;
}
}
}
};
BENCHMARK_DEFINE_F(EvBenchSocketsFixture, EventLoopRun)(benchmark::State &state)
{
if (!setup_error.empty()) {
state.SkipWithError(setup_error.c_str());
return;
}
// Sockets are already created in SetUp.
Ev_Result results[1];
char buf = 'x';
// We trigger the last socket
if (write_socket(sockets_w.back(), &buf, 1) != 1) {
state.SkipWithError("Failed to write to socket");
return;
}
for (auto _ : state) {
int32_t n = ev_run(ev, results, 1, 100);
if (n != 1) {
state.SkipWithError("ev_run did not return event");
break;
}
}
}
BENCHMARK_REGISTER_F(EvBenchSocketsFixture, EventLoopRun)->Range(8, 1024);
BENCHMARK_DEFINE_F(EvBenchSocketsFixture, EventLoopMultipleActive)(benchmark::State &state)
{
if (!setup_error.empty()) {
state.SkipWithError(setup_error.c_str());
return;
}
const int num_sockets = state.range(0);
const int num_active = state.range(1);
if (num_active > num_sockets) {
state.SkipWithError("Active sockets cannot exceed total sockets");
return;
}
char buf = 'x';
// Trigger 'num_active' sockets
for (int i = 0; i < num_active; ++i) {
if (write_socket(sockets_w[i], &buf, 1) != 1) {
state.SkipWithError("Failed to write socket");
return;
}
}
std::vector<Ev_Result> results(num_active);
for (auto _ : state) {
int32_t n = ev_run(ev, results.data(), num_active, 100);
if (n != num_active) {
state.SkipWithError("ev_run did not return expected number of events");
break;
}
}
}
// Fix N=1024, vary M
BENCHMARK_REGISTER_F(EvBenchSocketsFixture, EventLoopMultipleActive)
->Args({1024, 1})
->Args({1024, 10})
->Args({1024, 100})
->Args({1024, 1024});
} // namespace
BENCHMARK_MAIN();

329
toxcore/ev_test.cc Normal file
View File

@@ -0,0 +1,329 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright © 2026 The TokTok team.
*/
#include "ev.h"
#include <gtest/gtest.h>
#include <vector>
#include "ev_test_util.hh"
#include "logger.h"
#include "net.h"
#include "os_event.h"
#include "os_memory.h"
#include "os_network.h"
#ifndef _WIN32
#include <unistd.h>
#endif
namespace {
class EvTest : public ::testing::Test {
static void logger_cb_stderr(void *context, Logger_Level level, const char *file, uint32_t line,
const char *func, const char *message, void *userdata)
{
fprintf(stderr, "[%d] %s:%u: %s: %s\n", level, file, line, func, message);
}
protected:
void SetUp() override
{
ASSERT_NE(os_network(), nullptr); // WSAStartup
mem = os_memory();
log = logger_new(mem);
logger_callback_log(log, logger_cb_stderr, nullptr, nullptr);
ev = os_event_new(mem, log);
ASSERT_NE(ev, nullptr);
}
void TearDown() override
{
ev_kill(ev);
logger_kill(log);
}
const Memory *mem;
Logger *log;
Ev *ev;
int tag1;
int tag2;
int tag3;
int tag4;
};
TEST_F(EvTest, Lifecycle)
{
// Already covered by SetUp/TearDown
}
TEST_F(EvTest, AddDel)
{
Socket s1{}, s2{};
ASSERT_EQ(create_pair(&s1, &s2), 0);
EXPECT_TRUE(ev_add(ev, s1, EV_READ, &tag1));
EXPECT_TRUE(ev_add(ev, s2, EV_WRITE, &tag2));
// Adding same socket again should fail
EXPECT_FALSE(ev_add(ev, s1, EV_READ, &tag3));
EXPECT_TRUE(ev_del(ev, s1));
EXPECT_TRUE(ev_del(ev, s2));
// Deleting non-existent socket should fail
EXPECT_FALSE(ev_del(ev, s1));
close_pair(s1, s2);
}
TEST_F(EvTest, RunPipe)
{
Socket rs{}, ws{};
ASSERT_EQ(create_pair(&rs, &ws), 0);
EXPECT_TRUE(ev_add(ev, rs, EV_READ, &tag4));
Ev_Result results[1];
// Should timeout immediately
EXPECT_EQ(ev_run(ev, results, 1, 0), 0);
// Write something to the pipe/socket
char buf = 'x';
ASSERT_EQ(write_socket(ws, &buf, 1), 1);
// Should now be readable
int32_t n = ev_run(ev, results, 1, 100);
EXPECT_EQ(n, 1);
EXPECT_EQ(net_socket_to_native(results[0].sock), net_socket_to_native(rs));
EXPECT_EQ(results[0].events, EV_READ);
EXPECT_EQ(results[0].data, &tag4);
close_pair(rs, ws);
}
TEST_F(EvTest, WriteEvent)
{
Socket rs{}, ws{};
ASSERT_EQ(create_pair(&rs, &ws), 0);
// Register write end for EV_WRITE
EXPECT_TRUE(ev_add(ev, ws, EV_WRITE, &tag1));
Ev_Result results[1];
// Should be immediately writable
int32_t n = ev_run(ev, results, 1, 100);
EXPECT_EQ(n, 1);
EXPECT_EQ(net_socket_to_native(results[0].sock), net_socket_to_native(ws));
EXPECT_EQ(results[0].events, EV_WRITE);
EXPECT_EQ(results[0].data, &tag1);
close_pair(rs, ws);
}
TEST_F(EvTest, Mod)
{
Socket rs{}, ws{};
ASSERT_EQ(create_pair(&rs, &ws), 0);
EXPECT_TRUE(ev_add(ev, rs, EV_READ, &tag1));
EXPECT_TRUE(ev_mod(ev, rs, EV_READ, &tag2));
// Write something to the pipe/socket to make it readable
char buf = 'x';
ASSERT_EQ(write_socket(ws, &buf, 1), 1);
Ev_Result results[1];
int32_t n = ev_run(ev, results, 1, 100);
EXPECT_EQ(n, 1);
EXPECT_EQ(net_socket_to_native(results[0].sock), net_socket_to_native(rs));
EXPECT_EQ(results[0].events, EV_READ);
EXPECT_EQ(results[0].data, &tag2);
close_pair(rs, ws);
}
TEST_F(EvTest, MultipleEvents)
{
Socket rs1{}, ws1{};
Socket rs2{}, ws2{};
ASSERT_EQ(create_pair(&rs1, &ws1), 0);
ASSERT_EQ(create_pair(&rs2, &ws2), 0);
EXPECT_TRUE(ev_add(ev, rs1, EV_READ, &tag1));
EXPECT_TRUE(ev_add(ev, rs2, EV_READ, &tag2));
char buf = 'x';
ASSERT_EQ(write_socket(ws1, &buf, 1), 1);
ASSERT_EQ(write_socket(ws2, &buf, 1), 1);
Ev_Result results[2];
int32_t n = ev_run(ev, results, 2, 100);
EXPECT_EQ(n, 2);
bool found1 = false;
bool found2 = false;
for (int i = 0; i < 2; ++i) {
if (results[i].data == &tag1)
found1 = true;
if (results[i].data == &tag2)
found2 = true;
}
EXPECT_TRUE(found1);
EXPECT_TRUE(found2);
close_pair(rs1, ws1);
close_pair(rs2, ws2);
}
TEST_F(EvTest, MaxResults)
{
Socket rs1{}, ws1{};
Socket rs2{}, ws2{};
ASSERT_EQ(create_pair(&rs1, &ws1), 0);
ASSERT_EQ(create_pair(&rs2, &ws2), 0);
EXPECT_TRUE(ev_add(ev, rs1, EV_READ, &tag1));
EXPECT_TRUE(ev_add(ev, rs2, EV_READ, &tag2));
char buf = 'x';
ASSERT_EQ(write_socket(ws1, &buf, 1), 1);
ASSERT_EQ(write_socket(ws2, &buf, 1), 1);
Ev_Result results[1];
int32_t n = ev_run(ev, results, 1, 100);
EXPECT_EQ(n, 1);
// The second event should still be there for the next run
n = ev_run(ev, results, 1, 100);
EXPECT_EQ(n, 1);
close_pair(rs1, ws1);
close_pair(rs2, ws2);
}
TEST_F(EvTest, EmptyLoop)
{
Ev_Result results[1];
// Should timeout immediately
EXPECT_EQ(ev_run(ev, results, 1, 10), 0);
}
TEST_F(EvTest, ZeroMaxResults)
{
Socket rs{}, ws{};
ASSERT_EQ(create_pair(&rs, &ws), 0);
EXPECT_TRUE(ev_add(ev, rs, EV_READ, nullptr));
char buf = 'x';
ASSERT_EQ(write_socket(ws, &buf, 1), 1);
Ev_Result results[1];
int32_t n = ev_run(ev, results, 0, 100);
EXPECT_LE(n, 0);
close_pair(rs, ws);
}
TEST_F(EvTest, ErrorEvent)
{
Socket rs{}, ws{};
ASSERT_EQ(create_pair(&rs, &ws), 0);
EXPECT_TRUE(ev_add(ev, rs, EV_READ, &tag1));
// Close the write end to potentially trigger something on the read end
close_socket(ws);
Ev_Result results[1];
int32_t n = ev_run(ev, results, 1, 100);
// On Linux, closing the write end of a pipe makes the read end readable (EOF).
EXPECT_EQ(n, 1);
EXPECT_EQ(net_socket_to_native(results[0].sock), net_socket_to_native(rs));
close_socket(rs);
}
TEST_F(EvTest, ReallocPointers)
{
Socket rs{}, ws{};
ASSERT_EQ(create_pair(&rs, &ws), 0);
// Add first socket. This will be at index 0.
EXPECT_TRUE(ev_add(ev, rs, EV_READ, &tag1));
// Add enough sockets to force realloc of regs array.
// Initial capacity is 0, then 8.
// We need > 8 sockets. Let's add 20 more.
std::vector<Socket> extra_sockets_r;
std::vector<Socket> extra_sockets_w;
for (int i = 0; i < 20; ++i) {
Socket r{}, w{};
ASSERT_EQ(create_pair(&r, &w), 0);
extra_sockets_r.push_back(r);
extra_sockets_w.push_back(w);
EXPECT_TRUE(ev_add(ev, r, EV_READ, nullptr));
}
// Now write to the first socket to trigger event.
char buf = 'x';
ASSERT_EQ(write_socket(ws, &buf, 1), 1);
Ev_Result results[1];
int32_t n = ev_run(ev, results, 1, 100);
EXPECT_EQ(n, 1);
// Check if we got the correct data back
EXPECT_EQ(net_socket_to_native(results[0].sock), net_socket_to_native(rs));
EXPECT_EQ(results[0].data, &tag1);
// Cleanup
close_pair(rs, ws);
for (size_t i = 0; i < extra_sockets_r.size(); ++i) {
close_pair(extra_sockets_r[i], extra_sockets_w[i]);
}
}
#ifdef EV_USE_EPOLL
TEST(EvManualTest, ExhaustFds)
{
ASSERT_NE(os_network(), nullptr);
const Memory *mem = os_memory();
Logger *log = logger_new(mem);
// Consume all file descriptors
std::vector<int> fds;
while (true) {
int fd = dup(0);
if (fd < 0) {
break;
}
fds.push_back(fd);
}
// New event loop creation should fail gracefully
Ev *ev = os_event_new(mem, log);
EXPECT_EQ(ev, nullptr);
// Release one FD and try again (epoll_create needs 1 FD)
if (!fds.empty()) {
close(fds.back());
fds.pop_back();
ev = os_event_new(mem, log);
EXPECT_NE(ev, nullptr);
ev_kill(ev);
}
// Cleanup
for (int fd : fds) {
close(fd);
}
logger_kill(log);
}
#endif // EV_USE_EPOLL
} // namespace

106
toxcore/ev_test_util.cc Normal file
View File

@@ -0,0 +1,106 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright © 2026 The TokTok team.
*/
#include "ev_test_util.hh"
#include "net.h"
#ifdef _WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
#else
#include <unistd.h>
#endif
#ifdef _WIN32
int create_pair(Socket *rs, Socket *ws)
{
SOCKET listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (listener == INVALID_SOCKET)
return -1;
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
addr.sin_port = 0;
if (bind(listener, (struct sockaddr *)&addr, sizeof(addr)) != 0) {
closesocket(listener);
return -1;
}
if (listen(listener, 1) != 0) {
closesocket(listener);
return -1;
}
socklen_t len = sizeof(addr);
if (getsockname(listener, (struct sockaddr *)&addr, &len) != 0) {
closesocket(listener);
return -1;
}
SOCKET client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (client == INVALID_SOCKET) {
closesocket(listener);
return -1;
}
if (connect(client, (struct sockaddr *)&addr, sizeof(addr)) != 0) {
closesocket(client);
closesocket(listener);
return -1;
}
SOCKET server = accept(listener, nullptr, nullptr);
if (server == INVALID_SOCKET) {
closesocket(client);
closesocket(listener);
return -1;
}
closesocket(listener);
*rs = net_socket_from_native((int)client);
*ws = net_socket_from_native((int)server);
return 0;
}
void close_socket(Socket s) { closesocket(net_socket_to_native(s)); }
void close_pair(Socket s1, Socket s2)
{
closesocket(net_socket_to_native(s1));
closesocket(net_socket_to_native(s2));
}
int write_socket(Socket s, const void *buf, size_t count)
{
return send(net_socket_to_native(s), (const char *)buf, (int)count, 0);
}
#else
int create_pair(Socket *rs, Socket *ws)
{
int pipefds[2];
if (pipe(pipefds) != 0)
return -1;
*rs = net_socket_from_native(pipefds[0]);
*ws = net_socket_from_native(pipefds[1]);
return 0;
}
void close_socket(Socket s) { close(net_socket_to_native(s)); }
void close_pair(Socket s1, Socket s2)
{
close(net_socket_to_native(s1));
close(net_socket_to_native(s2));
}
int write_socket(Socket s, const void *buf, size_t count)
{
return write(net_socket_to_native(s), buf, count);
}
#endif

35
toxcore/ev_test_util.hh Normal file
View File

@@ -0,0 +1,35 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright © 2026 The TokTok team.
*/
#ifndef C_TOXCORE_TOXCORE_EV_TEST_UTIL_HH
#define C_TOXCORE_TOXCORE_EV_TEST_UTIL_HH
#include <stddef.h>
#include "net.h"
/**
* @brief Creates a connected pair of sockets (like socketpair or a TCP loopback connection).
* @param rs [out] The read-side socket.
* @param ws [out] The write-side socket.
* @return 0 on success, -1 on failure.
*/
int create_pair(Socket *rs, Socket *ws);
/**
* @brief Closes the socket pair.
*/
void close_pair(Socket s1, Socket s2);
/**
* @brief Closes a single socket.
*/
void close_socket(Socket s);
/**
* @brief Writes data to a socket.
*/
int write_socket(Socket s, const void *buf, size_t count);
#endif /* C_TOXCORE_TOXCORE_EV_TEST_UTIL_HH */

View File

@@ -14,6 +14,7 @@
#include "../tox.h"
#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_struct.h"
/*****************************************************
*
@@ -86,7 +87,7 @@ Tox_Event_Conference_Connected *tox_event_conference_connected_new(const Memory
void tox_event_conference_connected_free(Tox_Event_Conference_Connected *conference_connected, const Memory *mem)
{
if (conference_connected != nullptr) {
tox_event_conference_connected_destruct((Tox_Event_Conference_Connected * _Nonnull)conference_connected, mem);
tox_event_conference_connected_destruct(conference_connected, mem);
}
mem_delete(mem, conference_connected);
}
@@ -147,7 +148,8 @@ static Tox_Event_Conference_Connected *tox_event_conference_connected_alloc(Tox_
*****************************************************/
void tox_events_handle_conference_connected(
Tox *tox, uint32_t conference_number,
Tox *tox,
uint32_t conference_number,
void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
@@ -159,3 +161,14 @@ void tox_events_handle_conference_connected(
tox_event_conference_connected_set_conference_number(conference_connected, conference_number);
}
void tox_events_handle_conference_connected_dispatch(Tox *tox, const Tox_Event_Conference_Connected *event, void *user_data)
{
if (tox->conference_connected_callback == nullptr) {
return;
}
tox_unlock(tox);
tox->conference_connected_callback(tox, event->conference_number, user_data);
tox_lock(tox);
}

View File

@@ -16,6 +16,7 @@
#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_pack.h"
#include "../tox_struct.h"
#include "../tox_unpack.h"
/*****************************************************
@@ -27,7 +28,7 @@
struct Tox_Event_Conference_Invite {
uint32_t friend_number;
Tox_Conference_Type type;
uint8_t *cookie;
uint8_t *_Nullable cookie;
uint32_t cookie_length;
};
@@ -68,6 +69,12 @@ static bool tox_event_conference_invite_set_cookie(Tox_Event_Conference_Invite *
return true;
}
if (cookie_length == 0) {
conference_invite->cookie = nullptr;
conference_invite->cookie_length = 0;
return true;
}
uint8_t *cookie_copy = (uint8_t *)mem_balloc(mem, cookie_length);
if (cookie_copy == nullptr) {
@@ -149,7 +156,7 @@ Tox_Event_Conference_Invite *tox_event_conference_invite_new(const Memory *mem)
void tox_event_conference_invite_free(Tox_Event_Conference_Invite *conference_invite, const Memory *mem)
{
if (conference_invite != nullptr) {
tox_event_conference_invite_destruct((Tox_Event_Conference_Invite * _Nonnull)conference_invite, mem);
tox_event_conference_invite_destruct(conference_invite, mem);
}
mem_delete(mem, conference_invite);
}
@@ -210,7 +217,10 @@ static Tox_Event_Conference_Invite *tox_event_conference_invite_alloc(Tox_Events
*****************************************************/
void tox_events_handle_conference_invite(
Tox *tox, uint32_t friend_number, Tox_Conference_Type type, const uint8_t *cookie, size_t length,
Tox *tox,
uint32_t friend_number,
Tox_Conference_Type type,
const uint8_t *cookie, size_t length,
void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
@@ -222,5 +232,18 @@ void tox_events_handle_conference_invite(
tox_event_conference_invite_set_friend_number(conference_invite, friend_number);
tox_event_conference_invite_set_type(conference_invite, type);
tox_event_conference_invite_set_cookie(conference_invite, state->mem, cookie, length);
if (!tox_event_conference_invite_set_cookie(conference_invite, state->mem, cookie, length)) {
state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
}
}
void tox_events_handle_conference_invite_dispatch(Tox *tox, const Tox_Event_Conference_Invite *event, void *user_data)
{
if (tox->conference_invite_callback == nullptr) {
return;
}
tox_unlock(tox);
tox->conference_invite_callback(tox, event->friend_number, event->type, event->cookie, event->cookie_length, user_data);
tox_lock(tox);
}

View File

@@ -16,6 +16,7 @@
#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_pack.h"
#include "../tox_struct.h"
#include "../tox_unpack.h"
/*****************************************************
@@ -28,7 +29,7 @@ struct Tox_Event_Conference_Message {
uint32_t conference_number;
uint32_t peer_number;
Tox_Message_Type type;
uint8_t *message;
uint8_t *_Nullable message;
uint32_t message_length;
};
@@ -80,6 +81,12 @@ static bool tox_event_conference_message_set_message(Tox_Event_Conference_Messag
return true;
}
if (message_length == 0) {
conference_message->message = nullptr;
conference_message->message_length = 0;
return true;
}
uint8_t *message_copy = (uint8_t *)mem_balloc(mem, message_length);
if (message_copy == nullptr) {
@@ -163,7 +170,7 @@ Tox_Event_Conference_Message *tox_event_conference_message_new(const Memory *mem
void tox_event_conference_message_free(Tox_Event_Conference_Message *conference_message, const Memory *mem)
{
if (conference_message != nullptr) {
tox_event_conference_message_destruct((Tox_Event_Conference_Message * _Nonnull)conference_message, mem);
tox_event_conference_message_destruct(conference_message, mem);
}
mem_delete(mem, conference_message);
}
@@ -224,7 +231,11 @@ static Tox_Event_Conference_Message *tox_event_conference_message_alloc(Tox_Even
*****************************************************/
void tox_events_handle_conference_message(
Tox *tox, uint32_t conference_number, uint32_t peer_number, Tox_Message_Type type, const uint8_t *message, size_t length,
Tox *tox,
uint32_t conference_number,
uint32_t peer_number,
Tox_Message_Type type,
const uint8_t *message, size_t length,
void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
@@ -237,5 +248,18 @@ void tox_events_handle_conference_message(
tox_event_conference_message_set_conference_number(conference_message, conference_number);
tox_event_conference_message_set_peer_number(conference_message, peer_number);
tox_event_conference_message_set_type(conference_message, type);
tox_event_conference_message_set_message(conference_message, state->mem, message, length);
if (!tox_event_conference_message_set_message(conference_message, state->mem, message, length)) {
state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
}
}
void tox_events_handle_conference_message_dispatch(Tox *tox, const Tox_Event_Conference_Message *event, void *user_data)
{
if (tox->conference_message_callback == nullptr) {
return;
}
tox_unlock(tox);
tox->conference_message_callback(tox, event->conference_number, event->peer_number, event->type, event->message, event->message_length, user_data);
tox_lock(tox);
}

View File

@@ -14,6 +14,7 @@
#include "../tox.h"
#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_struct.h"
/*****************************************************
*
@@ -86,7 +87,7 @@ Tox_Event_Conference_Peer_List_Changed *tox_event_conference_peer_list_changed_n
void tox_event_conference_peer_list_changed_free(Tox_Event_Conference_Peer_List_Changed *conference_peer_list_changed, const Memory *mem)
{
if (conference_peer_list_changed != nullptr) {
tox_event_conference_peer_list_changed_destruct((Tox_Event_Conference_Peer_List_Changed * _Nonnull)conference_peer_list_changed, mem);
tox_event_conference_peer_list_changed_destruct(conference_peer_list_changed, mem);
}
mem_delete(mem, conference_peer_list_changed);
}
@@ -147,7 +148,8 @@ static Tox_Event_Conference_Peer_List_Changed *tox_event_conference_peer_list_ch
*****************************************************/
void tox_events_handle_conference_peer_list_changed(
Tox *tox, uint32_t conference_number,
Tox *tox,
uint32_t conference_number,
void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
@@ -159,3 +161,14 @@ void tox_events_handle_conference_peer_list_changed(
tox_event_conference_peer_list_changed_set_conference_number(conference_peer_list_changed, conference_number);
}
void tox_events_handle_conference_peer_list_changed_dispatch(Tox *tox, const Tox_Event_Conference_Peer_List_Changed *event, void *user_data)
{
if (tox->conference_peer_list_changed_callback == nullptr) {
return;
}
tox_unlock(tox);
tox->conference_peer_list_changed_callback(tox, event->conference_number, user_data);
tox_lock(tox);
}

View File

@@ -15,6 +15,7 @@
#include "../tox.h"
#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_struct.h"
/*****************************************************
*
@@ -25,7 +26,7 @@
struct Tox_Event_Conference_Peer_Name {
uint32_t conference_number;
uint32_t peer_number;
uint8_t *name;
uint8_t *_Nullable name;
uint32_t name_length;
};
@@ -66,6 +67,12 @@ static bool tox_event_conference_peer_name_set_name(Tox_Event_Conference_Peer_Na
return true;
}
if (name_length == 0) {
conference_peer_name->name = nullptr;
conference_peer_name->name_length = 0;
return true;
}
uint8_t *name_copy = (uint8_t *)mem_balloc(mem, name_length);
if (name_copy == nullptr) {
@@ -147,7 +154,7 @@ Tox_Event_Conference_Peer_Name *tox_event_conference_peer_name_new(const Memory
void tox_event_conference_peer_name_free(Tox_Event_Conference_Peer_Name *conference_peer_name, const Memory *mem)
{
if (conference_peer_name != nullptr) {
tox_event_conference_peer_name_destruct((Tox_Event_Conference_Peer_Name * _Nonnull)conference_peer_name, mem);
tox_event_conference_peer_name_destruct(conference_peer_name, mem);
}
mem_delete(mem, conference_peer_name);
}
@@ -208,7 +215,10 @@ static Tox_Event_Conference_Peer_Name *tox_event_conference_peer_name_alloc(Tox_
*****************************************************/
void tox_events_handle_conference_peer_name(
Tox *tox, uint32_t conference_number, uint32_t peer_number, const uint8_t *name, size_t length,
Tox *tox,
uint32_t conference_number,
uint32_t peer_number,
const uint8_t *name, size_t length,
void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
@@ -220,5 +230,18 @@ void tox_events_handle_conference_peer_name(
tox_event_conference_peer_name_set_conference_number(conference_peer_name, conference_number);
tox_event_conference_peer_name_set_peer_number(conference_peer_name, peer_number);
tox_event_conference_peer_name_set_name(conference_peer_name, state->mem, name, length);
if (!tox_event_conference_peer_name_set_name(conference_peer_name, state->mem, name, length)) {
state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
}
}
void tox_events_handle_conference_peer_name_dispatch(Tox *tox, const Tox_Event_Conference_Peer_Name *event, void *user_data)
{
if (tox->conference_peer_name_callback == nullptr) {
return;
}
tox_unlock(tox);
tox->conference_peer_name_callback(tox, event->conference_number, event->peer_number, event->name, event->name_length, user_data);
tox_lock(tox);
}

View File

@@ -15,6 +15,7 @@
#include "../tox.h"
#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_struct.h"
/*****************************************************
*
@@ -25,7 +26,7 @@
struct Tox_Event_Conference_Title {
uint32_t conference_number;
uint32_t peer_number;
uint8_t *title;
uint8_t *_Nullable title;
uint32_t title_length;
};
@@ -66,6 +67,12 @@ static bool tox_event_conference_title_set_title(Tox_Event_Conference_Title *_No
return true;
}
if (title_length == 0) {
conference_title->title = nullptr;
conference_title->title_length = 0;
return true;
}
uint8_t *title_copy = (uint8_t *)mem_balloc(mem, title_length);
if (title_copy == nullptr) {
@@ -147,7 +154,7 @@ Tox_Event_Conference_Title *tox_event_conference_title_new(const Memory *mem)
void tox_event_conference_title_free(Tox_Event_Conference_Title *conference_title, const Memory *mem)
{
if (conference_title != nullptr) {
tox_event_conference_title_destruct((Tox_Event_Conference_Title * _Nonnull)conference_title, mem);
tox_event_conference_title_destruct(conference_title, mem);
}
mem_delete(mem, conference_title);
}
@@ -208,7 +215,10 @@ static Tox_Event_Conference_Title *tox_event_conference_title_alloc(Tox_Events_S
*****************************************************/
void tox_events_handle_conference_title(
Tox *tox, uint32_t conference_number, uint32_t peer_number, const uint8_t *title, size_t length,
Tox *tox,
uint32_t conference_number,
uint32_t peer_number,
const uint8_t *title, size_t length,
void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
@@ -220,5 +230,18 @@ void tox_events_handle_conference_title(
tox_event_conference_title_set_conference_number(conference_title, conference_number);
tox_event_conference_title_set_peer_number(conference_title, peer_number);
tox_event_conference_title_set_title(conference_title, state->mem, title, length);
if (!tox_event_conference_title_set_title(conference_title, state->mem, title, length)) {
state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
}
}
void tox_events_handle_conference_title_dispatch(Tox *tox, const Tox_Event_Conference_Title *event, void *user_data)
{
if (tox->conference_title_callback == nullptr) {
return;
}
tox_unlock(tox);
tox->conference_title_callback(tox, event->conference_number, event->peer_number, event->title, event->title_length, user_data);
tox_lock(tox);
}

View File

@@ -15,6 +15,7 @@
#include "../tox.h"
#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_struct.h"
/*****************************************************
*
@@ -24,7 +25,7 @@
struct Tox_Event_Dht_Nodes_Response {
uint8_t public_key[TOX_PUBLIC_KEY_SIZE];
uint8_t *ip;
char *_Nullable ip;
uint32_t ip_length;
uint16_t port;
};
@@ -42,7 +43,7 @@ const uint8_t *tox_event_dht_nodes_response_get_public_key(const Tox_Event_Dht_N
}
static bool tox_event_dht_nodes_response_set_ip(Tox_Event_Dht_Nodes_Response *_Nonnull dht_nodes_response,
const Memory *_Nonnull mem, const uint8_t *_Nullable ip, uint32_t ip_length)
const Memory *_Nonnull mem, const char *_Nullable ip, uint32_t ip_length)
{
assert(dht_nodes_response != nullptr);
if (dht_nodes_response->ip != nullptr) {
@@ -56,7 +57,11 @@ static bool tox_event_dht_nodes_response_set_ip(Tox_Event_Dht_Nodes_Response *_N
return true;
}
uint8_t *ip_copy = (uint8_t *)mem_balloc(mem, ip_length + 1);
if (ip_length == UINT32_MAX) {
return false;
}
char *ip_copy = (char *)mem_balloc(mem, ip_length + 1);
if (ip_copy == nullptr) {
return false;
@@ -73,7 +78,7 @@ uint32_t tox_event_dht_nodes_response_get_ip_length(const Tox_Event_Dht_Nodes_Re
assert(dht_nodes_response != nullptr);
return dht_nodes_response->ip_length;
}
const uint8_t *tox_event_dht_nodes_response_get_ip(const Tox_Event_Dht_Nodes_Response *dht_nodes_response)
const char *tox_event_dht_nodes_response_get_ip(const Tox_Event_Dht_Nodes_Response *dht_nodes_response)
{
assert(dht_nodes_response != nullptr);
return dht_nodes_response->ip;
@@ -108,7 +113,7 @@ bool tox_event_dht_nodes_response_pack(
{
return bin_pack_array(bp, 3)
&& bin_pack_bin(bp, event->public_key, TOX_PUBLIC_KEY_SIZE)
&& bin_pack_bin(bp, event->ip, event->ip_length)
&& bin_pack_str(bp, event->ip, event->ip_length)
&& bin_pack_u16(bp, event->port);
}
@@ -120,7 +125,7 @@ static bool tox_event_dht_nodes_response_unpack_into(Tox_Event_Dht_Nodes_Respons
}
return bin_unpack_bin_fixed(bu, event->public_key, TOX_PUBLIC_KEY_SIZE)
&& bin_unpack_bin(bu, &event->ip, &event->ip_length)
&& bin_unpack_str(bu, &event->ip, &event->ip_length)
&& bin_unpack_u16(bu, &event->port);
}
@@ -151,7 +156,7 @@ Tox_Event_Dht_Nodes_Response *tox_event_dht_nodes_response_new(const Memory *mem
void tox_event_dht_nodes_response_free(Tox_Event_Dht_Nodes_Response *dht_nodes_response, const Memory *mem)
{
if (dht_nodes_response != nullptr) {
tox_event_dht_nodes_response_destruct((Tox_Event_Dht_Nodes_Response * _Nonnull)dht_nodes_response, mem);
tox_event_dht_nodes_response_destruct(dht_nodes_response, mem);
}
mem_delete(mem, dht_nodes_response);
}
@@ -212,7 +217,10 @@ static Tox_Event_Dht_Nodes_Response *tox_event_dht_nodes_response_alloc(Tox_Even
*****************************************************/
void tox_events_handle_dht_nodes_response(
Tox *tox, const uint8_t *public_key, const char *ip, uint32_t ip_length, uint16_t port,
Tox *tox,
const uint8_t *public_key,
const char *ip, uint32_t ip_length,
uint16_t port,
void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
@@ -223,6 +231,19 @@ void tox_events_handle_dht_nodes_response(
}
tox_event_dht_nodes_response_set_public_key(dht_nodes_response, public_key);
tox_event_dht_nodes_response_set_ip(dht_nodes_response, state->mem, (const uint8_t *)ip, ip_length);
if (!tox_event_dht_nodes_response_set_ip(dht_nodes_response, state->mem, ip, ip_length)) {
state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
}
tox_event_dht_nodes_response_set_port(dht_nodes_response, port);
}
void tox_events_handle_dht_nodes_response_dispatch(Tox *tox, const Tox_Event_Dht_Nodes_Response *event, void *user_data)
{
if (tox->dht_nodes_response_callback == nullptr) {
return;
}
tox_unlock(tox);
tox->dht_nodes_response_callback(tox, event->public_key, (const char *)event->ip, event->ip_length, event->port, user_data);
tox_lock(tox);
}

View File

@@ -61,7 +61,13 @@ bool tox_events_add(Tox_Events *events, const Tox_Event *event)
}
if (events->events_size == events->events_capacity) {
const uint32_t new_events_capacity = events->events_capacity * 2 + 1;
const uint64_t new_events_capacity_64 = (uint64_t)events->events_capacity * 2 + 1;
if (new_events_capacity_64 > UINT32_MAX) {
return false;
}
const uint32_t new_events_capacity = (uint32_t)new_events_capacity_64;
Tox_Event *new_events = (Tox_Event *)mem_vrealloc(
events->mem, events->events, new_events_capacity, sizeof(Tox_Event));

View File

@@ -5,6 +5,9 @@
#ifndef C_TOXCORE_TOXCORE_EVENTS_EVENTS_ALLOC_H
#define C_TOXCORE_TOXCORE_EVENTS_EVENTS_ALLOC_H
#include <stdbool.h>
#include <stdint.h>
#include "../attributes.h"
#include "../tox.h"
#include "../tox_events.h"
@@ -14,20 +17,20 @@
extern "C" {
#endif
struct Tox_Memory;
struct Memory;
struct Tox_Events {
Tox_Event *_Nonnull events;
Tox_Event *_Nullable events;
uint32_t events_size;
uint32_t events_capacity;
const struct Tox_Memory *_Nonnull mem;
const struct Memory *_Nonnull mem;
};
typedef struct Tox_Events_State {
Tox_Err_Events_Iterate error;
const struct Tox_Memory *_Nonnull mem;
Tox_Events *_Nonnull events;
const struct Memory *_Nonnull mem;
Tox_Events *_Nullable events;
} Tox_Events_State;
tox_conference_connected_cb tox_events_handle_conference_connected;

View File

@@ -14,6 +14,7 @@
#include "../tox.h"
#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_struct.h"
/*****************************************************
*
@@ -133,7 +134,7 @@ Tox_Event_File_Chunk_Request *tox_event_file_chunk_request_new(const Memory *mem
void tox_event_file_chunk_request_free(Tox_Event_File_Chunk_Request *file_chunk_request, const Memory *mem)
{
if (file_chunk_request != nullptr) {
tox_event_file_chunk_request_destruct((Tox_Event_File_Chunk_Request * _Nonnull)file_chunk_request, mem);
tox_event_file_chunk_request_destruct(file_chunk_request, mem);
}
mem_delete(mem, file_chunk_request);
}
@@ -194,7 +195,11 @@ static Tox_Event_File_Chunk_Request *tox_event_file_chunk_request_alloc(Tox_Even
*****************************************************/
void tox_events_handle_file_chunk_request(
Tox *tox, uint32_t friend_number, uint32_t file_number, uint64_t position, size_t length,
Tox *tox,
uint32_t friend_number,
uint32_t file_number,
uint64_t position,
size_t length,
void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
@@ -209,3 +214,14 @@ void tox_events_handle_file_chunk_request(
tox_event_file_chunk_request_set_position(file_chunk_request, position);
tox_event_file_chunk_request_set_length(file_chunk_request, length);
}
void tox_events_handle_file_chunk_request_dispatch(Tox *tox, const Tox_Event_File_Chunk_Request *event, void *user_data)
{
if (tox->file_chunk_request_callback == nullptr) {
return;
}
tox_unlock(tox);
tox->file_chunk_request_callback(tox, event->friend_number, event->file_number, event->position, event->length, user_data);
tox_lock(tox);
}

View File

@@ -15,6 +15,7 @@
#include "../tox.h"
#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_struct.h"
/*****************************************************
*
@@ -27,7 +28,7 @@ struct Tox_Event_File_Recv {
uint32_t file_number;
uint32_t kind;
uint64_t file_size;
uint8_t *filename;
uint8_t *_Nullable filename;
uint32_t filename_length;
};
@@ -90,6 +91,12 @@ static bool tox_event_file_recv_set_filename(Tox_Event_File_Recv *_Nonnull file_
return true;
}
if (filename_length == 0) {
file_recv->filename = nullptr;
file_recv->filename_length = 0;
return true;
}
uint8_t *filename_copy = (uint8_t *)mem_balloc(mem, filename_length);
if (filename_copy == nullptr) {
@@ -175,7 +182,7 @@ Tox_Event_File_Recv *tox_event_file_recv_new(const Memory *mem)
void tox_event_file_recv_free(Tox_Event_File_Recv *file_recv, const Memory *mem)
{
if (file_recv != nullptr) {
tox_event_file_recv_destruct((Tox_Event_File_Recv * _Nonnull)file_recv, mem);
tox_event_file_recv_destruct(file_recv, mem);
}
mem_delete(mem, file_recv);
}
@@ -236,7 +243,12 @@ static Tox_Event_File_Recv *tox_event_file_recv_alloc(Tox_Events_State *_Nonnull
*****************************************************/
void tox_events_handle_file_recv(
Tox *tox, uint32_t friend_number, uint32_t file_number, uint32_t kind, uint64_t file_size, const uint8_t *filename, size_t filename_length,
Tox *tox,
uint32_t friend_number,
uint32_t file_number,
uint32_t kind,
uint64_t file_size,
const uint8_t *filename, size_t filename_length,
void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
@@ -250,5 +262,18 @@ void tox_events_handle_file_recv(
tox_event_file_recv_set_file_number(file_recv, file_number);
tox_event_file_recv_set_kind(file_recv, kind);
tox_event_file_recv_set_file_size(file_recv, file_size);
tox_event_file_recv_set_filename(file_recv, state->mem, filename, filename_length);
if (!tox_event_file_recv_set_filename(file_recv, state->mem, filename, filename_length)) {
state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
}
}
void tox_events_handle_file_recv_dispatch(Tox *tox, const Tox_Event_File_Recv *event, void *user_data)
{
if (tox->file_recv_callback == nullptr) {
return;
}
tox_unlock(tox);
tox->file_recv_callback(tox, event->friend_number, event->file_number, event->kind, event->file_size, event->filename, event->filename_length, user_data);
tox_lock(tox);
}

View File

@@ -15,6 +15,7 @@
#include "../tox.h"
#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_struct.h"
/*****************************************************
*
@@ -26,7 +27,7 @@ struct Tox_Event_File_Recv_Chunk {
uint32_t friend_number;
uint32_t file_number;
uint64_t position;
uint8_t *data;
uint8_t *_Nullable data;
uint32_t data_length;
};
@@ -78,6 +79,12 @@ static bool tox_event_file_recv_chunk_set_data(Tox_Event_File_Recv_Chunk *_Nonnu
return true;
}
if (data_length == 0) {
file_recv_chunk->data = nullptr;
file_recv_chunk->data_length = 0;
return true;
}
uint8_t *data_copy = (uint8_t *)mem_balloc(mem, data_length);
if (data_copy == nullptr) {
@@ -161,7 +168,7 @@ Tox_Event_File_Recv_Chunk *tox_event_file_recv_chunk_new(const Memory *mem)
void tox_event_file_recv_chunk_free(Tox_Event_File_Recv_Chunk *file_recv_chunk, const Memory *mem)
{
if (file_recv_chunk != nullptr) {
tox_event_file_recv_chunk_destruct((Tox_Event_File_Recv_Chunk * _Nonnull)file_recv_chunk, mem);
tox_event_file_recv_chunk_destruct(file_recv_chunk, mem);
}
mem_delete(mem, file_recv_chunk);
}
@@ -222,7 +229,11 @@ static Tox_Event_File_Recv_Chunk *tox_event_file_recv_chunk_alloc(Tox_Events_Sta
*****************************************************/
void tox_events_handle_file_recv_chunk(
Tox *tox, uint32_t friend_number, uint32_t file_number, uint64_t position, const uint8_t *data, size_t length,
Tox *tox,
uint32_t friend_number,
uint32_t file_number,
uint64_t position,
const uint8_t *data, size_t length,
void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
@@ -235,5 +246,18 @@ void tox_events_handle_file_recv_chunk(
tox_event_file_recv_chunk_set_friend_number(file_recv_chunk, friend_number);
tox_event_file_recv_chunk_set_file_number(file_recv_chunk, file_number);
tox_event_file_recv_chunk_set_position(file_recv_chunk, position);
tox_event_file_recv_chunk_set_data(file_recv_chunk, state->mem, data, length);
if (!tox_event_file_recv_chunk_set_data(file_recv_chunk, state->mem, data, length)) {
state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
}
}
void tox_events_handle_file_recv_chunk_dispatch(Tox *tox, const Tox_Event_File_Recv_Chunk *event, void *user_data)
{
if (tox->file_recv_chunk_callback == nullptr) {
return;
}
tox_unlock(tox);
tox->file_recv_chunk_callback(tox, event->friend_number, event->file_number, event->position, event->data, event->data_length, user_data);
tox_lock(tox);
}

View File

@@ -15,6 +15,7 @@
#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_pack.h"
#include "../tox_struct.h"
#include "../tox_unpack.h"
/*****************************************************
@@ -121,7 +122,7 @@ Tox_Event_File_Recv_Control *tox_event_file_recv_control_new(const Memory *mem)
void tox_event_file_recv_control_free(Tox_Event_File_Recv_Control *file_recv_control, const Memory *mem)
{
if (file_recv_control != nullptr) {
tox_event_file_recv_control_destruct((Tox_Event_File_Recv_Control * _Nonnull)file_recv_control, mem);
tox_event_file_recv_control_destruct(file_recv_control, mem);
}
mem_delete(mem, file_recv_control);
}
@@ -182,7 +183,10 @@ static Tox_Event_File_Recv_Control *tox_event_file_recv_control_alloc(Tox_Events
*****************************************************/
void tox_events_handle_file_recv_control(
Tox *tox, uint32_t friend_number, uint32_t file_number, Tox_File_Control control,
Tox *tox,
uint32_t friend_number,
uint32_t file_number,
Tox_File_Control control,
void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
@@ -196,3 +200,14 @@ void tox_events_handle_file_recv_control(
tox_event_file_recv_control_set_file_number(file_recv_control, file_number);
tox_event_file_recv_control_set_control(file_recv_control, control);
}
void tox_events_handle_file_recv_control_dispatch(Tox *tox, const Tox_Event_File_Recv_Control *event, void *user_data)
{
if (tox->file_recv_control_callback == nullptr) {
return;
}
tox_unlock(tox);
tox->file_recv_control_callback(tox, event->friend_number, event->file_number, event->control, user_data);
tox_lock(tox);
}

View File

@@ -15,6 +15,7 @@
#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_pack.h"
#include "../tox_struct.h"
#include "../tox_unpack.h"
/*****************************************************
@@ -107,7 +108,7 @@ Tox_Event_Friend_Connection_Status *tox_event_friend_connection_status_new(const
void tox_event_friend_connection_status_free(Tox_Event_Friend_Connection_Status *friend_connection_status, const Memory *mem)
{
if (friend_connection_status != nullptr) {
tox_event_friend_connection_status_destruct((Tox_Event_Friend_Connection_Status * _Nonnull)friend_connection_status, mem);
tox_event_friend_connection_status_destruct(friend_connection_status, mem);
}
mem_delete(mem, friend_connection_status);
}
@@ -168,7 +169,9 @@ static Tox_Event_Friend_Connection_Status *tox_event_friend_connection_status_al
*****************************************************/
void tox_events_handle_friend_connection_status(
Tox *tox, uint32_t friend_number, Tox_Connection connection_status,
Tox *tox,
uint32_t friend_number,
Tox_Connection connection_status,
void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
@@ -181,3 +184,14 @@ void tox_events_handle_friend_connection_status(
tox_event_friend_connection_status_set_friend_number(friend_connection_status, friend_number);
tox_event_friend_connection_status_set_connection_status(friend_connection_status, connection_status);
}
void tox_events_handle_friend_connection_status_dispatch(Tox *tox, const Tox_Event_Friend_Connection_Status *event, void *user_data)
{
if (tox->friend_connection_status_callback == nullptr) {
return;
}
tox_unlock(tox);
tox->friend_connection_status_callback(tox, event->friend_number, event->connection_status, user_data);
tox_lock(tox);
}

View File

@@ -15,6 +15,7 @@
#include "../tox.h"
#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_struct.h"
/*****************************************************
*
@@ -24,7 +25,7 @@
struct Tox_Event_Friend_Lossless_Packet {
uint32_t friend_number;
uint8_t *data;
uint8_t *_Nullable data;
uint32_t data_length;
};
@@ -54,6 +55,12 @@ static bool tox_event_friend_lossless_packet_set_data(Tox_Event_Friend_Lossless_
return true;
}
if (data_length == 0) {
friend_lossless_packet->data = nullptr;
friend_lossless_packet->data_length = 0;
return true;
}
uint8_t *data_copy = (uint8_t *)mem_balloc(mem, data_length);
if (data_copy == nullptr) {
@@ -133,7 +140,7 @@ Tox_Event_Friend_Lossless_Packet *tox_event_friend_lossless_packet_new(const Mem
void tox_event_friend_lossless_packet_free(Tox_Event_Friend_Lossless_Packet *friend_lossless_packet, const Memory *mem)
{
if (friend_lossless_packet != nullptr) {
tox_event_friend_lossless_packet_destruct((Tox_Event_Friend_Lossless_Packet * _Nonnull)friend_lossless_packet, mem);
tox_event_friend_lossless_packet_destruct(friend_lossless_packet, mem);
}
mem_delete(mem, friend_lossless_packet);
}
@@ -194,7 +201,9 @@ static Tox_Event_Friend_Lossless_Packet *tox_event_friend_lossless_packet_alloc(
*****************************************************/
void tox_events_handle_friend_lossless_packet(
Tox *tox, uint32_t friend_number, const uint8_t *data, size_t length,
Tox *tox,
uint32_t friend_number,
const uint8_t *data, size_t length,
void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
@@ -205,5 +214,18 @@ void tox_events_handle_friend_lossless_packet(
}
tox_event_friend_lossless_packet_set_friend_number(friend_lossless_packet, friend_number);
tox_event_friend_lossless_packet_set_data(friend_lossless_packet, state->mem, data, length);
if (!tox_event_friend_lossless_packet_set_data(friend_lossless_packet, state->mem, data, length)) {
state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
}
}
void tox_events_handle_friend_lossless_packet_dispatch(Tox *tox, const Tox_Event_Friend_Lossless_Packet *event, void *user_data)
{
if (event->data_length == 0 || tox->friend_lossless_packet_callback_per_pktid[event->data[0]] == nullptr) {
return;
}
tox_unlock(tox);
tox->friend_lossless_packet_callback_per_pktid[event->data[0]](tox, event->friend_number, event->data, event->data_length, user_data);
tox_lock(tox);
}

View File

@@ -15,6 +15,7 @@
#include "../tox.h"
#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_struct.h"
/*****************************************************
*
@@ -24,7 +25,7 @@
struct Tox_Event_Friend_Lossy_Packet {
uint32_t friend_number;
uint8_t *data;
uint8_t *_Nullable data;
uint32_t data_length;
};
@@ -54,6 +55,12 @@ static bool tox_event_friend_lossy_packet_set_data(Tox_Event_Friend_Lossy_Packet
return true;
}
if (data_length == 0) {
friend_lossy_packet->data = nullptr;
friend_lossy_packet->data_length = 0;
return true;
}
uint8_t *data_copy = (uint8_t *)mem_balloc(mem, data_length);
if (data_copy == nullptr) {
@@ -133,7 +140,7 @@ Tox_Event_Friend_Lossy_Packet *tox_event_friend_lossy_packet_new(const Memory *m
void tox_event_friend_lossy_packet_free(Tox_Event_Friend_Lossy_Packet *friend_lossy_packet, const Memory *mem)
{
if (friend_lossy_packet != nullptr) {
tox_event_friend_lossy_packet_destruct((Tox_Event_Friend_Lossy_Packet * _Nonnull)friend_lossy_packet, mem);
tox_event_friend_lossy_packet_destruct(friend_lossy_packet, mem);
}
mem_delete(mem, friend_lossy_packet);
}
@@ -194,7 +201,9 @@ static Tox_Event_Friend_Lossy_Packet *tox_event_friend_lossy_packet_alloc(Tox_Ev
*****************************************************/
void tox_events_handle_friend_lossy_packet(
Tox *tox, uint32_t friend_number, const uint8_t *data, size_t length,
Tox *tox,
uint32_t friend_number,
const uint8_t *data, size_t length,
void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
@@ -205,5 +214,18 @@ void tox_events_handle_friend_lossy_packet(
}
tox_event_friend_lossy_packet_set_friend_number(friend_lossy_packet, friend_number);
tox_event_friend_lossy_packet_set_data(friend_lossy_packet, state->mem, data, length);
if (!tox_event_friend_lossy_packet_set_data(friend_lossy_packet, state->mem, data, length)) {
state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
}
}
void tox_events_handle_friend_lossy_packet_dispatch(Tox *tox, const Tox_Event_Friend_Lossy_Packet *event, void *user_data)
{
if (event->data_length == 0 || tox->friend_lossy_packet_callback_per_pktid[event->data[0]] == nullptr) {
return;
}
tox_unlock(tox);
tox->friend_lossy_packet_callback_per_pktid[event->data[0]](tox, event->friend_number, event->data, event->data_length, user_data);
tox_lock(tox);
}

View File

@@ -16,6 +16,7 @@
#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_pack.h"
#include "../tox_struct.h"
#include "../tox_unpack.h"
/*****************************************************
@@ -27,7 +28,7 @@
struct Tox_Event_Friend_Message {
uint32_t friend_number;
Tox_Message_Type type;
uint8_t *message;
uint8_t *_Nullable message;
uint32_t message_length;
};
@@ -68,6 +69,12 @@ static bool tox_event_friend_message_set_message(Tox_Event_Friend_Message *_Nonn
return true;
}
if (message_length == 0) {
friend_message->message = nullptr;
friend_message->message_length = 0;
return true;
}
uint8_t *message_copy = (uint8_t *)mem_balloc(mem, message_length);
if (message_copy == nullptr) {
@@ -149,7 +156,7 @@ Tox_Event_Friend_Message *tox_event_friend_message_new(const Memory *mem)
void tox_event_friend_message_free(Tox_Event_Friend_Message *friend_message, const Memory *mem)
{
if (friend_message != nullptr) {
tox_event_friend_message_destruct((Tox_Event_Friend_Message * _Nonnull)friend_message, mem);
tox_event_friend_message_destruct(friend_message, mem);
}
mem_delete(mem, friend_message);
}
@@ -210,7 +217,10 @@ static Tox_Event_Friend_Message *tox_event_friend_message_alloc(Tox_Events_State
*****************************************************/
void tox_events_handle_friend_message(
Tox *tox, uint32_t friend_number, Tox_Message_Type type, const uint8_t *message, size_t length,
Tox *tox,
uint32_t friend_number,
Tox_Message_Type type,
const uint8_t *message, size_t length,
void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
@@ -222,5 +232,18 @@ void tox_events_handle_friend_message(
tox_event_friend_message_set_friend_number(friend_message, friend_number);
tox_event_friend_message_set_type(friend_message, type);
tox_event_friend_message_set_message(friend_message, state->mem, message, length);
if (!tox_event_friend_message_set_message(friend_message, state->mem, message, length)) {
state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
}
}
void tox_events_handle_friend_message_dispatch(Tox *tox, const Tox_Event_Friend_Message *event, void *user_data)
{
if (tox->friend_message_callback == nullptr) {
return;
}
tox_unlock(tox);
tox->friend_message_callback(tox, event->friend_number, event->type, event->message, event->message_length, user_data);
tox_lock(tox);
}

View File

@@ -15,6 +15,7 @@
#include "../tox.h"
#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_struct.h"
/*****************************************************
*
@@ -24,7 +25,7 @@
struct Tox_Event_Friend_Name {
uint32_t friend_number;
uint8_t *name;
uint8_t *_Nullable name;
uint32_t name_length;
};
@@ -54,6 +55,12 @@ static bool tox_event_friend_name_set_name(Tox_Event_Friend_Name *_Nonnull frien
return true;
}
if (name_length == 0) {
friend_name->name = nullptr;
friend_name->name_length = 0;
return true;
}
uint8_t *name_copy = (uint8_t *)mem_balloc(mem, name_length);
if (name_copy == nullptr) {
@@ -133,7 +140,7 @@ Tox_Event_Friend_Name *tox_event_friend_name_new(const Memory *mem)
void tox_event_friend_name_free(Tox_Event_Friend_Name *friend_name, const Memory *mem)
{
if (friend_name != nullptr) {
tox_event_friend_name_destruct((Tox_Event_Friend_Name * _Nonnull)friend_name, mem);
tox_event_friend_name_destruct(friend_name, mem);
}
mem_delete(mem, friend_name);
}
@@ -194,7 +201,9 @@ static Tox_Event_Friend_Name *tox_event_friend_name_alloc(Tox_Events_State *_Non
*****************************************************/
void tox_events_handle_friend_name(
Tox *tox, uint32_t friend_number, const uint8_t *name, size_t length,
Tox *tox,
uint32_t friend_number,
const uint8_t *name, size_t length,
void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
@@ -205,5 +214,18 @@ void tox_events_handle_friend_name(
}
tox_event_friend_name_set_friend_number(friend_name, friend_number);
tox_event_friend_name_set_name(friend_name, state->mem, name, length);
if (!tox_event_friend_name_set_name(friend_name, state->mem, name, length)) {
state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
}
}
void tox_events_handle_friend_name_dispatch(Tox *tox, const Tox_Event_Friend_Name *event, void *user_data)
{
if (tox->friend_name_callback == nullptr) {
return;
}
tox_unlock(tox);
tox->friend_name_callback(tox, event->friend_number, event->name, event->name_length, user_data);
tox_lock(tox);
}

View File

@@ -14,6 +14,7 @@
#include "../tox.h"
#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_struct.h"
/*****************************************************
*
@@ -105,7 +106,7 @@ Tox_Event_Friend_Read_Receipt *tox_event_friend_read_receipt_new(const Memory *m
void tox_event_friend_read_receipt_free(Tox_Event_Friend_Read_Receipt *friend_read_receipt, const Memory *mem)
{
if (friend_read_receipt != nullptr) {
tox_event_friend_read_receipt_destruct((Tox_Event_Friend_Read_Receipt * _Nonnull)friend_read_receipt, mem);
tox_event_friend_read_receipt_destruct(friend_read_receipt, mem);
}
mem_delete(mem, friend_read_receipt);
}
@@ -166,7 +167,9 @@ static Tox_Event_Friend_Read_Receipt *tox_event_friend_read_receipt_alloc(Tox_Ev
*****************************************************/
void tox_events_handle_friend_read_receipt(
Tox *tox, uint32_t friend_number, uint32_t message_id,
Tox *tox,
uint32_t friend_number,
uint32_t message_id,
void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
@@ -179,3 +182,14 @@ void tox_events_handle_friend_read_receipt(
tox_event_friend_read_receipt_set_friend_number(friend_read_receipt, friend_number);
tox_event_friend_read_receipt_set_message_id(friend_read_receipt, message_id);
}
void tox_events_handle_friend_read_receipt_dispatch(Tox *tox, const Tox_Event_Friend_Read_Receipt *event, void *user_data)
{
if (tox->friend_read_receipt_callback == nullptr) {
return;
}
tox_unlock(tox);
tox->friend_read_receipt_callback(tox, event->friend_number, event->message_id, user_data);
tox_lock(tox);
}

View File

@@ -15,6 +15,7 @@
#include "../tox.h"
#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_struct.h"
/*****************************************************
*
@@ -24,7 +25,7 @@
struct Tox_Event_Friend_Request {
uint8_t public_key[TOX_PUBLIC_KEY_SIZE];
uint8_t *message;
uint8_t *_Nullable message;
uint32_t message_length;
};
@@ -55,6 +56,12 @@ static bool tox_event_friend_request_set_message(Tox_Event_Friend_Request *_Nonn
return true;
}
if (message_length == 0) {
friend_request->message = nullptr;
friend_request->message_length = 0;
return true;
}
uint8_t *message_copy = (uint8_t *)mem_balloc(mem, message_length);
if (message_copy == nullptr) {
@@ -136,7 +143,7 @@ Tox_Event_Friend_Request *tox_event_friend_request_new(const Memory *mem)
void tox_event_friend_request_free(Tox_Event_Friend_Request *friend_request, const Memory *mem)
{
if (friend_request != nullptr) {
tox_event_friend_request_destruct((Tox_Event_Friend_Request * _Nonnull)friend_request, mem);
tox_event_friend_request_destruct(friend_request, mem);
}
mem_delete(mem, friend_request);
}
@@ -197,7 +204,9 @@ static Tox_Event_Friend_Request *tox_event_friend_request_alloc(Tox_Events_State
*****************************************************/
void tox_events_handle_friend_request(
Tox *tox, const uint8_t *public_key, const uint8_t *message, size_t length,
Tox *tox,
const uint8_t *public_key,
const uint8_t *message, size_t length,
void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
@@ -208,5 +217,18 @@ void tox_events_handle_friend_request(
}
tox_event_friend_request_set_public_key(friend_request, public_key);
tox_event_friend_request_set_message(friend_request, state->mem, message, length);
if (!tox_event_friend_request_set_message(friend_request, state->mem, message, length)) {
state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
}
}
void tox_events_handle_friend_request_dispatch(Tox *tox, const Tox_Event_Friend_Request *event, void *user_data)
{
if (tox->friend_request_callback == nullptr) {
return;
}
tox_unlock(tox);
tox->friend_request_callback(tox, event->public_key, event->message, event->message_length, user_data);
tox_lock(tox);
}

View File

@@ -15,6 +15,7 @@
#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_pack.h"
#include "../tox_struct.h"
#include "../tox_unpack.h"
/*****************************************************
@@ -107,7 +108,7 @@ Tox_Event_Friend_Status *tox_event_friend_status_new(const Memory *mem)
void tox_event_friend_status_free(Tox_Event_Friend_Status *friend_status, const Memory *mem)
{
if (friend_status != nullptr) {
tox_event_friend_status_destruct((Tox_Event_Friend_Status * _Nonnull)friend_status, mem);
tox_event_friend_status_destruct(friend_status, mem);
}
mem_delete(mem, friend_status);
}
@@ -168,7 +169,9 @@ static Tox_Event_Friend_Status *tox_event_friend_status_alloc(Tox_Events_State *
*****************************************************/
void tox_events_handle_friend_status(
Tox *tox, uint32_t friend_number, Tox_User_Status status,
Tox *tox,
uint32_t friend_number,
Tox_User_Status status,
void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
@@ -181,3 +184,14 @@ void tox_events_handle_friend_status(
tox_event_friend_status_set_friend_number(friend_status, friend_number);
tox_event_friend_status_set_status(friend_status, status);
}
void tox_events_handle_friend_status_dispatch(Tox *tox, const Tox_Event_Friend_Status *event, void *user_data)
{
if (tox->friend_status_callback == nullptr) {
return;
}
tox_unlock(tox);
tox->friend_status_callback(tox, event->friend_number, event->status, user_data);
tox_lock(tox);
}

View File

@@ -15,6 +15,7 @@
#include "../tox.h"
#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_struct.h"
/*****************************************************
*
@@ -24,7 +25,7 @@
struct Tox_Event_Friend_Status_Message {
uint32_t friend_number;
uint8_t *message;
uint8_t *_Nullable message;
uint32_t message_length;
};
@@ -54,6 +55,12 @@ static bool tox_event_friend_status_message_set_message(Tox_Event_Friend_Status_
return true;
}
if (message_length == 0) {
friend_status_message->message = nullptr;
friend_status_message->message_length = 0;
return true;
}
uint8_t *message_copy = (uint8_t *)mem_balloc(mem, message_length);
if (message_copy == nullptr) {
@@ -133,7 +140,7 @@ Tox_Event_Friend_Status_Message *tox_event_friend_status_message_new(const Memor
void tox_event_friend_status_message_free(Tox_Event_Friend_Status_Message *friend_status_message, const Memory *mem)
{
if (friend_status_message != nullptr) {
tox_event_friend_status_message_destruct((Tox_Event_Friend_Status_Message * _Nonnull)friend_status_message, mem);
tox_event_friend_status_message_destruct(friend_status_message, mem);
}
mem_delete(mem, friend_status_message);
}
@@ -194,7 +201,9 @@ static Tox_Event_Friend_Status_Message *tox_event_friend_status_message_alloc(To
*****************************************************/
void tox_events_handle_friend_status_message(
Tox *tox, uint32_t friend_number, const uint8_t *message, size_t length,
Tox *tox,
uint32_t friend_number,
const uint8_t *message, size_t length,
void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
@@ -205,5 +214,18 @@ void tox_events_handle_friend_status_message(
}
tox_event_friend_status_message_set_friend_number(friend_status_message, friend_number);
tox_event_friend_status_message_set_message(friend_status_message, state->mem, message, length);
if (!tox_event_friend_status_message_set_message(friend_status_message, state->mem, message, length)) {
state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
}
}
void tox_events_handle_friend_status_message_dispatch(Tox *tox, const Tox_Event_Friend_Status_Message *event, void *user_data)
{
if (tox->friend_status_message_callback == nullptr) {
return;
}
tox_unlock(tox);
tox->friend_status_message_callback(tox, event->friend_number, event->message, event->message_length, user_data);
tox_lock(tox);
}

View File

@@ -14,6 +14,7 @@
#include "../tox.h"
#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_struct.h"
/*****************************************************
*
@@ -105,7 +106,7 @@ Tox_Event_Friend_Typing *tox_event_friend_typing_new(const Memory *mem)
void tox_event_friend_typing_free(Tox_Event_Friend_Typing *friend_typing, const Memory *mem)
{
if (friend_typing != nullptr) {
tox_event_friend_typing_destruct((Tox_Event_Friend_Typing * _Nonnull)friend_typing, mem);
tox_event_friend_typing_destruct(friend_typing, mem);
}
mem_delete(mem, friend_typing);
}
@@ -166,7 +167,9 @@ static Tox_Event_Friend_Typing *tox_event_friend_typing_alloc(Tox_Events_State *
*****************************************************/
void tox_events_handle_friend_typing(
Tox *tox, uint32_t friend_number, bool typing,
Tox *tox,
uint32_t friend_number,
bool typing,
void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
@@ -179,3 +182,14 @@ void tox_events_handle_friend_typing(
tox_event_friend_typing_set_friend_number(friend_typing, friend_number);
tox_event_friend_typing_set_typing(friend_typing, typing);
}
void tox_events_handle_friend_typing_dispatch(Tox *tox, const Tox_Event_Friend_Typing *event, void *user_data)
{
if (tox->friend_typing_callback == nullptr) {
return;
}
tox_unlock(tox);
tox->friend_typing_callback(tox, event->friend_number, event->typing, user_data);
tox_lock(tox);
}

View File

@@ -15,6 +15,7 @@
#include "../tox.h"
#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_struct.h"
/*****************************************************
*
@@ -25,7 +26,7 @@
struct Tox_Event_Group_Custom_Packet {
uint32_t group_number;
uint32_t peer_id;
uint8_t *data;
uint8_t *_Nullable data;
uint32_t data_length;
};
@@ -66,6 +67,12 @@ static bool tox_event_group_custom_packet_set_data(Tox_Event_Group_Custom_Packet
return true;
}
if (data_length == 0) {
group_custom_packet->data = nullptr;
group_custom_packet->data_length = 0;
return true;
}
uint8_t *data_copy = (uint8_t *)mem_balloc(mem, data_length);
if (data_copy == nullptr) {
@@ -147,7 +154,7 @@ Tox_Event_Group_Custom_Packet *tox_event_group_custom_packet_new(const Memory *m
void tox_event_group_custom_packet_free(Tox_Event_Group_Custom_Packet *group_custom_packet, const Memory *mem)
{
if (group_custom_packet != nullptr) {
tox_event_group_custom_packet_destruct((Tox_Event_Group_Custom_Packet * _Nonnull)group_custom_packet, mem);
tox_event_group_custom_packet_destruct(group_custom_packet, mem);
}
mem_delete(mem, group_custom_packet);
}
@@ -208,7 +215,10 @@ static Tox_Event_Group_Custom_Packet *tox_event_group_custom_packet_alloc(Tox_Ev
*****************************************************/
void tox_events_handle_group_custom_packet(
Tox *tox, uint32_t group_number, uint32_t peer_id, const uint8_t *data, size_t data_length,
Tox *tox,
uint32_t group_number,
uint32_t peer_id,
const uint8_t *data, size_t data_length,
void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
@@ -220,5 +230,18 @@ void tox_events_handle_group_custom_packet(
tox_event_group_custom_packet_set_group_number(group_custom_packet, group_number);
tox_event_group_custom_packet_set_peer_id(group_custom_packet, peer_id);
tox_event_group_custom_packet_set_data(group_custom_packet, state->mem, data, data_length);
if (!tox_event_group_custom_packet_set_data(group_custom_packet, state->mem, data, data_length)) {
state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
}
}
void tox_events_handle_group_custom_packet_dispatch(Tox *tox, const Tox_Event_Group_Custom_Packet *event, void *user_data)
{
if (tox->group_custom_packet_callback == nullptr) {
return;
}
tox_unlock(tox);
tox->group_custom_packet_callback(tox, event->group_number, event->peer_id, event->data, event->data_length, user_data);
tox_lock(tox);
}

View File

@@ -15,6 +15,7 @@
#include "../tox.h"
#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_struct.h"
/*****************************************************
*
@@ -25,7 +26,7 @@
struct Tox_Event_Group_Custom_Private_Packet {
uint32_t group_number;
uint32_t peer_id;
uint8_t *data;
uint8_t *_Nullable data;
uint32_t data_length;
};
@@ -66,6 +67,12 @@ static bool tox_event_group_custom_private_packet_set_data(Tox_Event_Group_Custo
return true;
}
if (data_length == 0) {
group_custom_private_packet->data = nullptr;
group_custom_private_packet->data_length = 0;
return true;
}
uint8_t *data_copy = (uint8_t *)mem_balloc(mem, data_length);
if (data_copy == nullptr) {
@@ -147,7 +154,7 @@ Tox_Event_Group_Custom_Private_Packet *tox_event_group_custom_private_packet_new
void tox_event_group_custom_private_packet_free(Tox_Event_Group_Custom_Private_Packet *group_custom_private_packet, const Memory *mem)
{
if (group_custom_private_packet != nullptr) {
tox_event_group_custom_private_packet_destruct((Tox_Event_Group_Custom_Private_Packet * _Nonnull)group_custom_private_packet, mem);
tox_event_group_custom_private_packet_destruct(group_custom_private_packet, mem);
}
mem_delete(mem, group_custom_private_packet);
}
@@ -208,7 +215,10 @@ static Tox_Event_Group_Custom_Private_Packet *tox_event_group_custom_private_pac
*****************************************************/
void tox_events_handle_group_custom_private_packet(
Tox *tox, uint32_t group_number, uint32_t peer_id, const uint8_t *data, size_t data_length,
Tox *tox,
uint32_t group_number,
uint32_t peer_id,
const uint8_t *data, size_t data_length,
void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
@@ -220,5 +230,18 @@ void tox_events_handle_group_custom_private_packet(
tox_event_group_custom_private_packet_set_group_number(group_custom_private_packet, group_number);
tox_event_group_custom_private_packet_set_peer_id(group_custom_private_packet, peer_id);
tox_event_group_custom_private_packet_set_data(group_custom_private_packet, state->mem, data, data_length);
if (!tox_event_group_custom_private_packet_set_data(group_custom_private_packet, state->mem, data, data_length)) {
state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
}
}
void tox_events_handle_group_custom_private_packet_dispatch(Tox *tox, const Tox_Event_Group_Custom_Private_Packet *event, void *user_data)
{
if (tox->group_custom_private_packet_callback == nullptr) {
return;
}
tox_unlock(tox);
tox->group_custom_private_packet_callback(tox, event->group_number, event->peer_id, event->data, event->data_length, user_data);
tox_lock(tox);
}

View File

@@ -15,6 +15,7 @@
#include "../tox.h"
#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_struct.h"
/*****************************************************
*
@@ -24,9 +25,9 @@
struct Tox_Event_Group_Invite {
uint32_t friend_number;
uint8_t *invite_data;
uint8_t *_Nullable invite_data;
uint32_t invite_data_length;
uint8_t *group_name;
uint8_t *_Nullable group_name;
uint32_t group_name_length;
};
@@ -56,6 +57,12 @@ static bool tox_event_group_invite_set_invite_data(Tox_Event_Group_Invite *_Nonn
return true;
}
if (invite_data_length == 0) {
group_invite->invite_data = nullptr;
group_invite->invite_data_length = 0;
return true;
}
uint8_t *invite_data_copy = (uint8_t *)mem_balloc(mem, invite_data_length);
if (invite_data_copy == nullptr) {
@@ -93,6 +100,12 @@ static bool tox_event_group_invite_set_group_name(Tox_Event_Group_Invite *_Nonnu
return true;
}
if (group_name_length == 0) {
group_invite->group_name = nullptr;
group_invite->group_name_length = 0;
return true;
}
uint8_t *group_name_copy = (uint8_t *)mem_balloc(mem, group_name_length);
if (group_name_copy == nullptr) {
@@ -175,7 +188,7 @@ Tox_Event_Group_Invite *tox_event_group_invite_new(const Memory *mem)
void tox_event_group_invite_free(Tox_Event_Group_Invite *group_invite, const Memory *mem)
{
if (group_invite != nullptr) {
tox_event_group_invite_destruct((Tox_Event_Group_Invite * _Nonnull)group_invite, mem);
tox_event_group_invite_destruct(group_invite, mem);
}
mem_delete(mem, group_invite);
}
@@ -236,7 +249,10 @@ static Tox_Event_Group_Invite *tox_event_group_invite_alloc(Tox_Events_State *_N
*****************************************************/
void tox_events_handle_group_invite(
Tox *tox, uint32_t friend_number, const uint8_t *invite_data, size_t invite_data_length, const uint8_t *group_name, size_t group_name_length,
Tox *tox,
uint32_t friend_number,
const uint8_t *invite_data, size_t invite_data_length,
const uint8_t *group_name, size_t group_name_length,
void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
@@ -247,6 +263,21 @@ void tox_events_handle_group_invite(
}
tox_event_group_invite_set_friend_number(group_invite, friend_number);
tox_event_group_invite_set_invite_data(group_invite, state->mem, invite_data, invite_data_length);
tox_event_group_invite_set_group_name(group_invite, state->mem, group_name, group_name_length);
if (!tox_event_group_invite_set_invite_data(group_invite, state->mem, invite_data, invite_data_length)) {
state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
}
if (!tox_event_group_invite_set_group_name(group_invite, state->mem, group_name, group_name_length)) {
state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
}
}
void tox_events_handle_group_invite_dispatch(Tox *tox, const Tox_Event_Group_Invite *event, void *user_data)
{
if (tox->group_invite_callback == nullptr) {
return;
}
tox_unlock(tox);
tox->group_invite_callback(tox, event->friend_number, event->invite_data, event->invite_data_length, event->group_name, event->group_name_length, user_data);
tox_lock(tox);
}

View File

@@ -15,6 +15,7 @@
#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_pack.h"
#include "../tox_struct.h"
#include "../tox_unpack.h"
/*****************************************************
@@ -107,7 +108,7 @@ Tox_Event_Group_Join_Fail *tox_event_group_join_fail_new(const Memory *mem)
void tox_event_group_join_fail_free(Tox_Event_Group_Join_Fail *group_join_fail, const Memory *mem)
{
if (group_join_fail != nullptr) {
tox_event_group_join_fail_destruct((Tox_Event_Group_Join_Fail * _Nonnull)group_join_fail, mem);
tox_event_group_join_fail_destruct(group_join_fail, mem);
}
mem_delete(mem, group_join_fail);
}
@@ -168,7 +169,9 @@ static Tox_Event_Group_Join_Fail *tox_event_group_join_fail_alloc(Tox_Events_Sta
*****************************************************/
void tox_events_handle_group_join_fail(
Tox *tox, uint32_t group_number, Tox_Group_Join_Fail fail_type,
Tox *tox,
uint32_t group_number,
Tox_Group_Join_Fail fail_type,
void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
@@ -181,3 +184,14 @@ void tox_events_handle_group_join_fail(
tox_event_group_join_fail_set_group_number(group_join_fail, group_number);
tox_event_group_join_fail_set_fail_type(group_join_fail, fail_type);
}
void tox_events_handle_group_join_fail_dispatch(Tox *tox, const Tox_Event_Group_Join_Fail *event, void *user_data)
{
if (tox->group_join_fail_callback == nullptr) {
return;
}
tox_unlock(tox);
tox->group_join_fail_callback(tox, event->group_number, event->fail_type, user_data);
tox_lock(tox);
}

View File

@@ -16,6 +16,7 @@
#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_pack.h"
#include "../tox_struct.h"
#include "../tox_unpack.h"
/*****************************************************
@@ -28,7 +29,7 @@ struct Tox_Event_Group_Message {
uint32_t group_number;
uint32_t peer_id;
Tox_Message_Type message_type;
uint8_t *message;
uint8_t *_Nullable message;
uint32_t message_length;
uint32_t message_id;
};
@@ -81,6 +82,12 @@ static bool tox_event_group_message_set_message(Tox_Event_Group_Message *_Nonnul
return true;
}
if (message_length == 0) {
group_message->message = nullptr;
group_message->message_length = 0;
return true;
}
uint8_t *message_copy = (uint8_t *)mem_balloc(mem, message_length);
if (message_copy == nullptr) {
@@ -177,7 +184,7 @@ Tox_Event_Group_Message *tox_event_group_message_new(const Memory *mem)
void tox_event_group_message_free(Tox_Event_Group_Message *group_message, const Memory *mem)
{
if (group_message != nullptr) {
tox_event_group_message_destruct((Tox_Event_Group_Message * _Nonnull)group_message, mem);
tox_event_group_message_destruct(group_message, mem);
}
mem_delete(mem, group_message);
}
@@ -238,7 +245,12 @@ static Tox_Event_Group_Message *tox_event_group_message_alloc(Tox_Events_State *
*****************************************************/
void tox_events_handle_group_message(
Tox *tox, uint32_t group_number, uint32_t peer_id, Tox_Message_Type message_type, const uint8_t *message, size_t message_length, uint32_t message_id,
Tox *tox,
uint32_t group_number,
uint32_t peer_id,
Tox_Message_Type message_type,
const uint8_t *message, size_t message_length,
uint32_t message_id,
void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
@@ -251,6 +263,19 @@ void tox_events_handle_group_message(
tox_event_group_message_set_group_number(group_message, group_number);
tox_event_group_message_set_peer_id(group_message, peer_id);
tox_event_group_message_set_message_type(group_message, message_type);
tox_event_group_message_set_message(group_message, state->mem, message, message_length);
if (!tox_event_group_message_set_message(group_message, state->mem, message, message_length)) {
state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
}
tox_event_group_message_set_message_id(group_message, message_id);
}
void tox_events_handle_group_message_dispatch(Tox *tox, const Tox_Event_Group_Message *event, void *user_data)
{
if (tox->group_message_callback == nullptr) {
return;
}
tox_unlock(tox);
tox->group_message_callback(tox, event->group_number, event->peer_id, event->message_type, event->message, event->message_length, event->message_id, user_data);
tox_lock(tox);
}

View File

@@ -15,6 +15,7 @@
#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_pack.h"
#include "../tox_struct.h"
#include "../tox_unpack.h"
/*****************************************************
@@ -135,7 +136,7 @@ Tox_Event_Group_Moderation *tox_event_group_moderation_new(const Memory *mem)
void tox_event_group_moderation_free(Tox_Event_Group_Moderation *group_moderation, const Memory *mem)
{
if (group_moderation != nullptr) {
tox_event_group_moderation_destruct((Tox_Event_Group_Moderation * _Nonnull)group_moderation, mem);
tox_event_group_moderation_destruct(group_moderation, mem);
}
mem_delete(mem, group_moderation);
}
@@ -196,7 +197,11 @@ static Tox_Event_Group_Moderation *tox_event_group_moderation_alloc(Tox_Events_S
*****************************************************/
void tox_events_handle_group_moderation(
Tox *tox, uint32_t group_number, uint32_t source_peer_id, uint32_t target_peer_id, Tox_Group_Mod_Event mod_type,
Tox *tox,
uint32_t group_number,
uint32_t source_peer_id,
uint32_t target_peer_id,
Tox_Group_Mod_Event mod_type,
void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
@@ -211,3 +216,14 @@ void tox_events_handle_group_moderation(
tox_event_group_moderation_set_target_peer_id(group_moderation, target_peer_id);
tox_event_group_moderation_set_mod_type(group_moderation, mod_type);
}
void tox_events_handle_group_moderation_dispatch(Tox *tox, const Tox_Event_Group_Moderation *event, void *user_data)
{
if (tox->group_moderation_callback == nullptr) {
return;
}
tox_unlock(tox);
tox->group_moderation_callback(tox, event->group_number, event->source_peer_id, event->target_peer_id, event->mod_type, user_data);
tox_lock(tox);
}

View File

@@ -15,6 +15,7 @@
#include "../tox.h"
#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_struct.h"
/*****************************************************
*
@@ -24,7 +25,7 @@
struct Tox_Event_Group_Password {
uint32_t group_number;
uint8_t *password;
uint8_t *_Nullable password;
uint32_t password_length;
};
@@ -54,6 +55,12 @@ static bool tox_event_group_password_set_password(Tox_Event_Group_Password *_Non
return true;
}
if (password_length == 0) {
group_password->password = nullptr;
group_password->password_length = 0;
return true;
}
uint8_t *password_copy = (uint8_t *)mem_balloc(mem, password_length);
if (password_copy == nullptr) {
@@ -133,7 +140,7 @@ Tox_Event_Group_Password *tox_event_group_password_new(const Memory *mem)
void tox_event_group_password_free(Tox_Event_Group_Password *group_password, const Memory *mem)
{
if (group_password != nullptr) {
tox_event_group_password_destruct((Tox_Event_Group_Password * _Nonnull)group_password, mem);
tox_event_group_password_destruct(group_password, mem);
}
mem_delete(mem, group_password);
}
@@ -194,7 +201,9 @@ static Tox_Event_Group_Password *tox_event_group_password_alloc(Tox_Events_State
*****************************************************/
void tox_events_handle_group_password(
Tox *tox, uint32_t group_number, const uint8_t *password, size_t password_length,
Tox *tox,
uint32_t group_number,
const uint8_t *password, size_t password_length,
void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
@@ -205,5 +214,18 @@ void tox_events_handle_group_password(
}
tox_event_group_password_set_group_number(group_password, group_number);
tox_event_group_password_set_password(group_password, state->mem, password, password_length);
if (!tox_event_group_password_set_password(group_password, state->mem, password, password_length)) {
state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
}
}
void tox_events_handle_group_password_dispatch(Tox *tox, const Tox_Event_Group_Password *event, void *user_data)
{
if (tox->group_password_callback == nullptr) {
return;
}
tox_unlock(tox);
tox->group_password_callback(tox, event->group_number, event->password, event->password_length, user_data);
tox_lock(tox);
}

View File

@@ -16,6 +16,7 @@
#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_pack.h"
#include "../tox_struct.h"
#include "../tox_unpack.h"
/*****************************************************
@@ -28,9 +29,9 @@ struct Tox_Event_Group_Peer_Exit {
uint32_t group_number;
uint32_t peer_id;
Tox_Group_Exit_Type exit_type;
uint8_t *name;
uint8_t *_Nullable name;
uint32_t name_length;
uint8_t *part_message;
uint8_t *_Nullable part_message;
uint32_t part_message_length;
};
@@ -82,6 +83,12 @@ static bool tox_event_group_peer_exit_set_name(Tox_Event_Group_Peer_Exit *_Nonnu
return true;
}
if (name_length == 0) {
group_peer_exit->name = nullptr;
group_peer_exit->name_length = 0;
return true;
}
uint8_t *name_copy = (uint8_t *)mem_balloc(mem, name_length);
if (name_copy == nullptr) {
@@ -119,6 +126,12 @@ static bool tox_event_group_peer_exit_set_part_message(Tox_Event_Group_Peer_Exit
return true;
}
if (part_message_length == 0) {
group_peer_exit->part_message = nullptr;
group_peer_exit->part_message_length = 0;
return true;
}
uint8_t *part_message_copy = (uint8_t *)mem_balloc(mem, part_message_length);
if (part_message_copy == nullptr) {
@@ -205,7 +218,7 @@ Tox_Event_Group_Peer_Exit *tox_event_group_peer_exit_new(const Memory *mem)
void tox_event_group_peer_exit_free(Tox_Event_Group_Peer_Exit *group_peer_exit, const Memory *mem)
{
if (group_peer_exit != nullptr) {
tox_event_group_peer_exit_destruct((Tox_Event_Group_Peer_Exit * _Nonnull)group_peer_exit, mem);
tox_event_group_peer_exit_destruct(group_peer_exit, mem);
}
mem_delete(mem, group_peer_exit);
}
@@ -266,7 +279,12 @@ static Tox_Event_Group_Peer_Exit *tox_event_group_peer_exit_alloc(Tox_Events_Sta
*****************************************************/
void tox_events_handle_group_peer_exit(
Tox *tox, uint32_t group_number, uint32_t peer_id, Tox_Group_Exit_Type exit_type, const uint8_t *name, size_t name_length, const uint8_t *part_message, size_t part_message_length,
Tox *tox,
uint32_t group_number,
uint32_t peer_id,
Tox_Group_Exit_Type exit_type,
const uint8_t *name, size_t name_length,
const uint8_t *part_message, size_t part_message_length,
void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
@@ -279,6 +297,21 @@ void tox_events_handle_group_peer_exit(
tox_event_group_peer_exit_set_group_number(group_peer_exit, group_number);
tox_event_group_peer_exit_set_peer_id(group_peer_exit, peer_id);
tox_event_group_peer_exit_set_exit_type(group_peer_exit, exit_type);
tox_event_group_peer_exit_set_name(group_peer_exit, state->mem, name, name_length);
tox_event_group_peer_exit_set_part_message(group_peer_exit, state->mem, part_message, part_message_length);
if (!tox_event_group_peer_exit_set_name(group_peer_exit, state->mem, name, name_length)) {
state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
}
if (!tox_event_group_peer_exit_set_part_message(group_peer_exit, state->mem, part_message, part_message_length)) {
state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
}
}
void tox_events_handle_group_peer_exit_dispatch(Tox *tox, const Tox_Event_Group_Peer_Exit *event, void *user_data)
{
if (tox->group_peer_exit_callback == nullptr) {
return;
}
tox_unlock(tox);
tox->group_peer_exit_callback(tox, event->group_number, event->peer_id, event->exit_type, event->name, event->name_length, event->part_message, event->part_message_length, user_data);
tox_lock(tox);
}

View File

@@ -14,6 +14,7 @@
#include "../tox.h"
#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_struct.h"
/*****************************************************
*
@@ -105,7 +106,7 @@ Tox_Event_Group_Peer_Join *tox_event_group_peer_join_new(const Memory *mem)
void tox_event_group_peer_join_free(Tox_Event_Group_Peer_Join *group_peer_join, const Memory *mem)
{
if (group_peer_join != nullptr) {
tox_event_group_peer_join_destruct((Tox_Event_Group_Peer_Join * _Nonnull)group_peer_join, mem);
tox_event_group_peer_join_destruct(group_peer_join, mem);
}
mem_delete(mem, group_peer_join);
}
@@ -166,7 +167,9 @@ static Tox_Event_Group_Peer_Join *tox_event_group_peer_join_alloc(Tox_Events_Sta
*****************************************************/
void tox_events_handle_group_peer_join(
Tox *tox, uint32_t group_number, uint32_t peer_id,
Tox *tox,
uint32_t group_number,
uint32_t peer_id,
void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
@@ -179,3 +182,14 @@ void tox_events_handle_group_peer_join(
tox_event_group_peer_join_set_group_number(group_peer_join, group_number);
tox_event_group_peer_join_set_peer_id(group_peer_join, peer_id);
}
void tox_events_handle_group_peer_join_dispatch(Tox *tox, const Tox_Event_Group_Peer_Join *event, void *user_data)
{
if (tox->group_peer_join_callback == nullptr) {
return;
}
tox_unlock(tox);
tox->group_peer_join_callback(tox, event->group_number, event->peer_id, user_data);
tox_lock(tox);
}

View File

@@ -14,6 +14,7 @@
#include "../tox.h"
#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_struct.h"
/*****************************************************
*
@@ -105,7 +106,7 @@ Tox_Event_Group_Peer_Limit *tox_event_group_peer_limit_new(const Memory *mem)
void tox_event_group_peer_limit_free(Tox_Event_Group_Peer_Limit *group_peer_limit, const Memory *mem)
{
if (group_peer_limit != nullptr) {
tox_event_group_peer_limit_destruct((Tox_Event_Group_Peer_Limit * _Nonnull)group_peer_limit, mem);
tox_event_group_peer_limit_destruct(group_peer_limit, mem);
}
mem_delete(mem, group_peer_limit);
}
@@ -166,7 +167,9 @@ static Tox_Event_Group_Peer_Limit *tox_event_group_peer_limit_alloc(Tox_Events_S
*****************************************************/
void tox_events_handle_group_peer_limit(
Tox *tox, uint32_t group_number, uint32_t peer_limit,
Tox *tox,
uint32_t group_number,
uint32_t peer_limit,
void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
@@ -179,3 +182,14 @@ void tox_events_handle_group_peer_limit(
tox_event_group_peer_limit_set_group_number(group_peer_limit, group_number);
tox_event_group_peer_limit_set_peer_limit(group_peer_limit, peer_limit);
}
void tox_events_handle_group_peer_limit_dispatch(Tox *tox, const Tox_Event_Group_Peer_Limit *event, void *user_data)
{
if (tox->group_peer_limit_callback == nullptr) {
return;
}
tox_unlock(tox);
tox->group_peer_limit_callback(tox, event->group_number, event->peer_limit, user_data);
tox_lock(tox);
}

View File

@@ -15,6 +15,7 @@
#include "../tox.h"
#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_struct.h"
/*****************************************************
*
@@ -25,7 +26,7 @@
struct Tox_Event_Group_Peer_Name {
uint32_t group_number;
uint32_t peer_id;
uint8_t *name;
uint8_t *_Nullable name;
uint32_t name_length;
};
@@ -66,6 +67,12 @@ static bool tox_event_group_peer_name_set_name(Tox_Event_Group_Peer_Name *_Nonnu
return true;
}
if (name_length == 0) {
group_peer_name->name = nullptr;
group_peer_name->name_length = 0;
return true;
}
uint8_t *name_copy = (uint8_t *)mem_balloc(mem, name_length);
if (name_copy == nullptr) {
@@ -147,7 +154,7 @@ Tox_Event_Group_Peer_Name *tox_event_group_peer_name_new(const Memory *mem)
void tox_event_group_peer_name_free(Tox_Event_Group_Peer_Name *group_peer_name, const Memory *mem)
{
if (group_peer_name != nullptr) {
tox_event_group_peer_name_destruct((Tox_Event_Group_Peer_Name * _Nonnull)group_peer_name, mem);
tox_event_group_peer_name_destruct(group_peer_name, mem);
}
mem_delete(mem, group_peer_name);
}
@@ -208,7 +215,10 @@ static Tox_Event_Group_Peer_Name *tox_event_group_peer_name_alloc(Tox_Events_Sta
*****************************************************/
void tox_events_handle_group_peer_name(
Tox *tox, uint32_t group_number, uint32_t peer_id, const uint8_t *name, size_t name_length,
Tox *tox,
uint32_t group_number,
uint32_t peer_id,
const uint8_t *name, size_t name_length,
void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
@@ -220,5 +230,18 @@ void tox_events_handle_group_peer_name(
tox_event_group_peer_name_set_group_number(group_peer_name, group_number);
tox_event_group_peer_name_set_peer_id(group_peer_name, peer_id);
tox_event_group_peer_name_set_name(group_peer_name, state->mem, name, name_length);
if (!tox_event_group_peer_name_set_name(group_peer_name, state->mem, name, name_length)) {
state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
}
}
void tox_events_handle_group_peer_name_dispatch(Tox *tox, const Tox_Event_Group_Peer_Name *event, void *user_data)
{
if (tox->group_peer_name_callback == nullptr) {
return;
}
tox_unlock(tox);
tox->group_peer_name_callback(tox, event->group_number, event->peer_id, event->name, event->name_length, user_data);
tox_lock(tox);
}

View File

@@ -15,6 +15,7 @@
#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_pack.h"
#include "../tox_struct.h"
#include "../tox_unpack.h"
/*****************************************************
@@ -121,7 +122,7 @@ Tox_Event_Group_Peer_Status *tox_event_group_peer_status_new(const Memory *mem)
void tox_event_group_peer_status_free(Tox_Event_Group_Peer_Status *group_peer_status, const Memory *mem)
{
if (group_peer_status != nullptr) {
tox_event_group_peer_status_destruct((Tox_Event_Group_Peer_Status * _Nonnull)group_peer_status, mem);
tox_event_group_peer_status_destruct(group_peer_status, mem);
}
mem_delete(mem, group_peer_status);
}
@@ -182,7 +183,10 @@ static Tox_Event_Group_Peer_Status *tox_event_group_peer_status_alloc(Tox_Events
*****************************************************/
void tox_events_handle_group_peer_status(
Tox *tox, uint32_t group_number, uint32_t peer_id, Tox_User_Status status,
Tox *tox,
uint32_t group_number,
uint32_t peer_id,
Tox_User_Status status,
void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
@@ -196,3 +200,14 @@ void tox_events_handle_group_peer_status(
tox_event_group_peer_status_set_peer_id(group_peer_status, peer_id);
tox_event_group_peer_status_set_status(group_peer_status, status);
}
void tox_events_handle_group_peer_status_dispatch(Tox *tox, const Tox_Event_Group_Peer_Status *event, void *user_data)
{
if (tox->group_peer_status_callback == nullptr) {
return;
}
tox_unlock(tox);
tox->group_peer_status_callback(tox, event->group_number, event->peer_id, event->status, user_data);
tox_lock(tox);
}

View File

@@ -15,6 +15,7 @@
#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_pack.h"
#include "../tox_struct.h"
#include "../tox_unpack.h"
/*****************************************************
@@ -107,7 +108,7 @@ Tox_Event_Group_Privacy_State *tox_event_group_privacy_state_new(const Memory *m
void tox_event_group_privacy_state_free(Tox_Event_Group_Privacy_State *group_privacy_state, const Memory *mem)
{
if (group_privacy_state != nullptr) {
tox_event_group_privacy_state_destruct((Tox_Event_Group_Privacy_State * _Nonnull)group_privacy_state, mem);
tox_event_group_privacy_state_destruct(group_privacy_state, mem);
}
mem_delete(mem, group_privacy_state);
}
@@ -168,7 +169,9 @@ static Tox_Event_Group_Privacy_State *tox_event_group_privacy_state_alloc(Tox_Ev
*****************************************************/
void tox_events_handle_group_privacy_state(
Tox *tox, uint32_t group_number, Tox_Group_Privacy_State privacy_state,
Tox *tox,
uint32_t group_number,
Tox_Group_Privacy_State privacy_state,
void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
@@ -181,3 +184,14 @@ void tox_events_handle_group_privacy_state(
tox_event_group_privacy_state_set_group_number(group_privacy_state, group_number);
tox_event_group_privacy_state_set_privacy_state(group_privacy_state, privacy_state);
}
void tox_events_handle_group_privacy_state_dispatch(Tox *tox, const Tox_Event_Group_Privacy_State *event, void *user_data)
{
if (tox->group_privacy_state_callback == nullptr) {
return;
}
tox_unlock(tox);
tox->group_privacy_state_callback(tox, event->group_number, event->privacy_state, user_data);
tox_lock(tox);
}

View File

@@ -16,6 +16,7 @@
#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_pack.h"
#include "../tox_struct.h"
#include "../tox_unpack.h"
/*****************************************************
@@ -28,7 +29,7 @@ struct Tox_Event_Group_Private_Message {
uint32_t group_number;
uint32_t peer_id;
Tox_Message_Type message_type;
uint8_t *message;
uint8_t *_Nullable message;
uint32_t message_length;
uint32_t message_id;
};
@@ -81,6 +82,12 @@ static bool tox_event_group_private_message_set_message(Tox_Event_Group_Private_
return true;
}
if (message_length == 0) {
group_private_message->message = nullptr;
group_private_message->message_length = 0;
return true;
}
uint8_t *message_copy = (uint8_t *)mem_balloc(mem, message_length);
if (message_copy == nullptr) {
@@ -177,7 +184,7 @@ Tox_Event_Group_Private_Message *tox_event_group_private_message_new(const Memor
void tox_event_group_private_message_free(Tox_Event_Group_Private_Message *group_private_message, const Memory *mem)
{
if (group_private_message != nullptr) {
tox_event_group_private_message_destruct((Tox_Event_Group_Private_Message * _Nonnull)group_private_message, mem);
tox_event_group_private_message_destruct(group_private_message, mem);
}
mem_delete(mem, group_private_message);
}
@@ -238,7 +245,12 @@ static Tox_Event_Group_Private_Message *tox_event_group_private_message_alloc(To
*****************************************************/
void tox_events_handle_group_private_message(
Tox *tox, uint32_t group_number, uint32_t peer_id, Tox_Message_Type message_type, const uint8_t *message, size_t message_length, uint32_t message_id,
Tox *tox,
uint32_t group_number,
uint32_t peer_id,
Tox_Message_Type message_type,
const uint8_t *message, size_t message_length,
uint32_t message_id,
void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
@@ -251,6 +263,19 @@ void tox_events_handle_group_private_message(
tox_event_group_private_message_set_group_number(group_private_message, group_number);
tox_event_group_private_message_set_peer_id(group_private_message, peer_id);
tox_event_group_private_message_set_message_type(group_private_message, message_type);
tox_event_group_private_message_set_message(group_private_message, state->mem, message, message_length);
if (!tox_event_group_private_message_set_message(group_private_message, state->mem, message, message_length)) {
state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
}
tox_event_group_private_message_set_message_id(group_private_message, message_id);
}
void tox_events_handle_group_private_message_dispatch(Tox *tox, const Tox_Event_Group_Private_Message *event, void *user_data)
{
if (tox->group_private_message_callback == nullptr) {
return;
}
tox_unlock(tox);
tox->group_private_message_callback(tox, event->group_number, event->peer_id, event->message_type, event->message, event->message_length, event->message_id, user_data);
tox_lock(tox);
}

View File

@@ -14,6 +14,7 @@
#include "../tox.h"
#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_struct.h"
/*****************************************************
*
@@ -86,7 +87,7 @@ Tox_Event_Group_Self_Join *tox_event_group_self_join_new(const Memory *mem)
void tox_event_group_self_join_free(Tox_Event_Group_Self_Join *group_self_join, const Memory *mem)
{
if (group_self_join != nullptr) {
tox_event_group_self_join_destruct((Tox_Event_Group_Self_Join * _Nonnull)group_self_join, mem);
tox_event_group_self_join_destruct(group_self_join, mem);
}
mem_delete(mem, group_self_join);
}
@@ -147,7 +148,8 @@ static Tox_Event_Group_Self_Join *tox_event_group_self_join_alloc(Tox_Events_Sta
*****************************************************/
void tox_events_handle_group_self_join(
Tox *tox, uint32_t group_number,
Tox *tox,
uint32_t group_number,
void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
@@ -159,3 +161,14 @@ void tox_events_handle_group_self_join(
tox_event_group_self_join_set_group_number(group_self_join, group_number);
}
void tox_events_handle_group_self_join_dispatch(Tox *tox, const Tox_Event_Group_Self_Join *event, void *user_data)
{
if (tox->group_self_join_callback == nullptr) {
return;
}
tox_unlock(tox);
tox->group_self_join_callback(tox, event->group_number, user_data);
tox_lock(tox);
}

View File

@@ -15,6 +15,7 @@
#include "../tox.h"
#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_struct.h"
/*****************************************************
*
@@ -25,7 +26,7 @@
struct Tox_Event_Group_Topic {
uint32_t group_number;
uint32_t peer_id;
uint8_t *topic;
uint8_t *_Nullable topic;
uint32_t topic_length;
};
@@ -66,6 +67,12 @@ static bool tox_event_group_topic_set_topic(Tox_Event_Group_Topic *_Nonnull grou
return true;
}
if (topic_length == 0) {
group_topic->topic = nullptr;
group_topic->topic_length = 0;
return true;
}
uint8_t *topic_copy = (uint8_t *)mem_balloc(mem, topic_length);
if (topic_copy == nullptr) {
@@ -147,7 +154,7 @@ Tox_Event_Group_Topic *tox_event_group_topic_new(const Memory *mem)
void tox_event_group_topic_free(Tox_Event_Group_Topic *group_topic, const Memory *mem)
{
if (group_topic != nullptr) {
tox_event_group_topic_destruct((Tox_Event_Group_Topic * _Nonnull)group_topic, mem);
tox_event_group_topic_destruct(group_topic, mem);
}
mem_delete(mem, group_topic);
}
@@ -208,7 +215,10 @@ static Tox_Event_Group_Topic *tox_event_group_topic_alloc(Tox_Events_State *_Non
*****************************************************/
void tox_events_handle_group_topic(
Tox *tox, uint32_t group_number, uint32_t peer_id, const uint8_t *topic, size_t topic_length,
Tox *tox,
uint32_t group_number,
uint32_t peer_id,
const uint8_t *topic, size_t topic_length,
void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
@@ -220,5 +230,18 @@ void tox_events_handle_group_topic(
tox_event_group_topic_set_group_number(group_topic, group_number);
tox_event_group_topic_set_peer_id(group_topic, peer_id);
tox_event_group_topic_set_topic(group_topic, state->mem, topic, topic_length);
if (!tox_event_group_topic_set_topic(group_topic, state->mem, topic, topic_length)) {
state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
}
}
void tox_events_handle_group_topic_dispatch(Tox *tox, const Tox_Event_Group_Topic *event, void *user_data)
{
if (tox->group_topic_callback == nullptr) {
return;
}
tox_unlock(tox);
tox->group_topic_callback(tox, event->group_number, event->peer_id, event->topic, event->topic_length, user_data);
tox_lock(tox);
}

View File

@@ -15,6 +15,7 @@
#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_pack.h"
#include "../tox_struct.h"
#include "../tox_unpack.h"
/*****************************************************
@@ -107,7 +108,7 @@ Tox_Event_Group_Topic_Lock *tox_event_group_topic_lock_new(const Memory *mem)
void tox_event_group_topic_lock_free(Tox_Event_Group_Topic_Lock *group_topic_lock, const Memory *mem)
{
if (group_topic_lock != nullptr) {
tox_event_group_topic_lock_destruct((Tox_Event_Group_Topic_Lock * _Nonnull)group_topic_lock, mem);
tox_event_group_topic_lock_destruct(group_topic_lock, mem);
}
mem_delete(mem, group_topic_lock);
}
@@ -168,7 +169,9 @@ static Tox_Event_Group_Topic_Lock *tox_event_group_topic_lock_alloc(Tox_Events_S
*****************************************************/
void tox_events_handle_group_topic_lock(
Tox *tox, uint32_t group_number, Tox_Group_Topic_Lock topic_lock,
Tox *tox,
uint32_t group_number,
Tox_Group_Topic_Lock topic_lock,
void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
@@ -181,3 +184,14 @@ void tox_events_handle_group_topic_lock(
tox_event_group_topic_lock_set_group_number(group_topic_lock, group_number);
tox_event_group_topic_lock_set_topic_lock(group_topic_lock, topic_lock);
}
void tox_events_handle_group_topic_lock_dispatch(Tox *tox, const Tox_Event_Group_Topic_Lock *event, void *user_data)
{
if (tox->group_topic_lock_callback == nullptr) {
return;
}
tox_unlock(tox);
tox->group_topic_lock_callback(tox, event->group_number, event->topic_lock, user_data);
tox_lock(tox);
}

View File

@@ -15,6 +15,7 @@
#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_pack.h"
#include "../tox_struct.h"
#include "../tox_unpack.h"
/*****************************************************
@@ -107,7 +108,7 @@ Tox_Event_Group_Voice_State *tox_event_group_voice_state_new(const Memory *mem)
void tox_event_group_voice_state_free(Tox_Event_Group_Voice_State *group_voice_state, const Memory *mem)
{
if (group_voice_state != nullptr) {
tox_event_group_voice_state_destruct((Tox_Event_Group_Voice_State * _Nonnull)group_voice_state, mem);
tox_event_group_voice_state_destruct(group_voice_state, mem);
}
mem_delete(mem, group_voice_state);
}
@@ -168,7 +169,9 @@ static Tox_Event_Group_Voice_State *tox_event_group_voice_state_alloc(Tox_Events
*****************************************************/
void tox_events_handle_group_voice_state(
Tox *tox, uint32_t group_number, Tox_Group_Voice_State voice_state,
Tox *tox,
uint32_t group_number,
Tox_Group_Voice_State voice_state,
void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
@@ -181,3 +184,14 @@ void tox_events_handle_group_voice_state(
tox_event_group_voice_state_set_group_number(group_voice_state, group_number);
tox_event_group_voice_state_set_voice_state(group_voice_state, voice_state);
}
void tox_events_handle_group_voice_state_dispatch(Tox *tox, const Tox_Event_Group_Voice_State *event, void *user_data)
{
if (tox->group_voice_state_callback == nullptr) {
return;
}
tox_unlock(tox);
tox->group_voice_state_callback(tox, event->group_number, event->voice_state, user_data);
tox_lock(tox);
}

View File

@@ -15,6 +15,7 @@
#include "../tox_event.h"
#include "../tox_events.h"
#include "../tox_pack.h"
#include "../tox_struct.h"
#include "../tox_unpack.h"
/*****************************************************
@@ -88,7 +89,7 @@ Tox_Event_Self_Connection_Status *tox_event_self_connection_status_new(const Mem
void tox_event_self_connection_status_free(Tox_Event_Self_Connection_Status *self_connection_status, const Memory *mem)
{
if (self_connection_status != nullptr) {
tox_event_self_connection_status_destruct((Tox_Event_Self_Connection_Status * _Nonnull)self_connection_status, mem);
tox_event_self_connection_status_destruct(self_connection_status, mem);
}
mem_delete(mem, self_connection_status);
}
@@ -149,7 +150,8 @@ static Tox_Event_Self_Connection_Status *tox_event_self_connection_status_alloc(
*****************************************************/
void tox_events_handle_self_connection_status(
Tox *tox, Tox_Connection connection_status,
Tox *tox,
Tox_Connection connection_status,
void *user_data)
{
Tox_Events_State *state = tox_events_alloc(user_data);
@@ -161,3 +163,14 @@ void tox_events_handle_self_connection_status(
tox_event_self_connection_status_set_connection_status(self_connection_status, connection_status);
}
void tox_events_handle_self_connection_status_dispatch(Tox *tox, const Tox_Event_Self_Connection_Status *event, void *user_data)
{
if (tox->self_connection_status_callback == nullptr) {
return;
}
tox_unlock(tox);
tox->self_connection_status_callback(tox, event->connection_status, user_data);
tox_lock(tox);
}

View File

@@ -5,13 +5,18 @@
#ifndef C_TOXCORE_TOXCORE_FORWARDING_H
#define C_TOXCORE_TOXCORE_FORWARDING_H
#include <stdbool.h>
#include <stdint.h>
#include "DHT.h"
#include "attributes.h"
#include "crypto_core.h"
#include "logger.h"
#include "mem.h"
#include "mono_time.h"
#include "net.h"
#include "network.h"
#include "rng.h"
#ifdef __cplusplus
extern "C" {

View File

@@ -15,37 +15,39 @@ using tox::test::configure_fuzz_memory_source;
using tox::test::Fuzz_Data;
using tox::test::SimulatedEnvironment;
constexpr uint16_t SIZE_IP_PORT = SIZE_IP6 + sizeof(uint16_t);
constexpr std::uint16_t SIZE_IP_PORT = SIZE_IP6 + sizeof(std::uint16_t);
template <typename T>
using Ptr = std::unique_ptr<T, void (*)(T *)>;
std::optional<std::tuple<IP_Port, IP_Port, const uint8_t *, size_t>> prepare(Fuzz_Data &input)
std::optional<std::tuple<IP_Port, IP_Port, const std::uint8_t *, std::size_t>> prepare(
Fuzz_Data &input)
{
CONSUME_OR_RETURN_VAL(const uint8_t *ipp_packed, input, SIZE_IP_PORT, std::nullopt);
CONSUME_OR_RETURN_VAL(const std::uint8_t *ipp_packed, input, SIZE_IP_PORT, std::nullopt);
IP_Port ipp{};
unpack_ip_port(&ipp, ipp_packed, SIZE_IP6, true);
CONSUME_OR_RETURN_VAL(const uint8_t *forwarder_packed, input, SIZE_IP_PORT, std::nullopt);
CONSUME_OR_RETURN_VAL(const std::uint8_t *forwarder_packed, input, SIZE_IP_PORT, std::nullopt);
IP_Port forwarder{};
unpack_ip_port(&forwarder, forwarder_packed, SIZE_IP6, true);
// 2 bytes: size of the request
CONSUME_OR_RETURN_VAL(const uint8_t *data_size_bytes, input, sizeof(uint16_t), std::nullopt);
uint16_t data_size;
std::memcpy(&data_size, data_size_bytes, sizeof(uint16_t));
CONSUME_OR_RETURN_VAL(
const std::uint8_t *data_size_bytes, input, sizeof(std::uint16_t), std::nullopt);
std::uint16_t data_size;
std::memcpy(&data_size, data_size_bytes, sizeof(std::uint16_t));
// data bytes (max 64K)
CONSUME_OR_RETURN_VAL(const uint8_t *data, input, data_size, std::nullopt);
CONSUME_OR_RETURN_VAL(const std::uint8_t *data, input, data_size, std::nullopt);
return {{ipp, forwarder, data, data_size}};
}
void TestSendForwardRequest(Fuzz_Data &input)
{
CONSUME1_OR_RETURN(const uint16_t, chain_length, input);
const uint16_t chain_keys_size = chain_length * CRYPTO_PUBLIC_KEY_SIZE;
CONSUME_OR_RETURN(const uint8_t *chain_keys, input, chain_keys_size);
CONSUME1_OR_RETURN(const std::uint16_t, chain_length, input);
const std::uint16_t chain_keys_size = chain_length * CRYPTO_PUBLIC_KEY_SIZE;
CONSUME_OR_RETURN(const std::uint8_t *chain_keys, input, chain_keys_size);
const auto prep = prepare(input);
if (!prep.has_value()) {
@@ -75,8 +77,8 @@ void TestSendForwardRequest(Fuzz_Data &input)
void TestForwardReply(Fuzz_Data &input)
{
CONSUME1_OR_RETURN(const uint16_t, sendback_length, input);
CONSUME_OR_RETURN(const uint8_t *sendback, input, sendback_length);
CONSUME1_OR_RETURN(const std::uint16_t, sendback_length, input);
CONSUME_OR_RETURN(const std::uint8_t *sendback, input, sendback_length);
const auto prep = prepare(input);
if (!prep.has_value()) {
@@ -106,8 +108,8 @@ void TestForwardReply(Fuzz_Data &input)
} // namespace
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t *data, std::size_t size);
extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t *data, std::size_t size)
{
tox::test::fuzz_select_target<TestSendForwardRequest, TestForwardReply>(data, size);
return 0;

View File

@@ -9,6 +9,7 @@
#ifndef C_TOXCORE_TOXCORE_FRIEND_CONNECTION_H
#define C_TOXCORE_TOXCORE_FRIEND_CONNECTION_H
#include <stdbool.h>
#include <stdint.h>
#include "DHT.h"
@@ -16,6 +17,7 @@
#include "logger.h"
#include "mem.h"
#include "mono_time.h"
#include "net.h"
#include "net_crypto.h"
#include "network.h"
#include "onion_client.h"

View File

@@ -13,6 +13,7 @@
#include "../testing/support/public/simulated_environment.hh"
#include "DHT_test_util.hh"
#include "attributes.h"
#include "crypto_core.h"
#include "logger.h"
#include "mono_time.h"
@@ -20,6 +21,7 @@
#include "net_profile.h"
#include "network.h"
#include "onion_client.h"
#include "test_util.hh"
namespace {
@@ -30,7 +32,7 @@ using namespace tox::test;
template <typename DHTWrapper>
class FriendConnTestNode {
public:
FriendConnTestNode(SimulatedEnvironment &env, uint16_t port)
FriendConnTestNode(SimulatedEnvironment &env, std::uint16_t port)
: dht_wrapper_(env, port)
, net_profile_(netprof_new(dht_wrapper_.logger(), &dht_wrapper_.node().c_memory),
[mem = &dht_wrapper_.node().c_memory](Net_Profile *p) { netprof_kill(mem, p); })
@@ -40,8 +42,9 @@ public:
{
logger_callback_log(
dht_wrapper_.logger(),
[](void *context, Logger_Level level, const char *file, uint32_t line, const char *func,
const char *message, void *userdata) {
[](void *_Nullable context, Logger_Level level, const char *_Nonnull file,
std::uint32_t line, const char *_Nonnull func, const char *_Nonnull message,
void *_Nullable userdata) {
fprintf(stderr, "[%d] %s:%u: %s: %s\n", level, file, line, func, message);
},
nullptr, nullptr);
@@ -67,12 +70,18 @@ public:
dht_wrapper_.get_dht(), net_crypto_.get(), dht_wrapper_.networking(), true));
}
Friend_Connections *get_friend_connections() { return friend_connections_.get(); }
Onion_Client *get_onion_client() { return onion_client_.get(); }
Net_Crypto *get_net_crypto() { return net_crypto_.get(); }
DHT *get_dht() { return dht_wrapper_.get_dht(); }
const uint8_t *dht_public_key() const { return dht_wrapper_.dht_public_key(); }
const uint8_t *real_public_key() const { return nc_get_self_public_key(net_crypto_.get()); }
Friend_Connections *_Nonnull get_friend_connections()
{
return REQUIRE_NOT_NULL(friend_connections_.get());
}
Onion_Client *_Nonnull get_onion_client() { return REQUIRE_NOT_NULL(onion_client_.get()); }
Net_Crypto *_Nonnull get_net_crypto() { return REQUIRE_NOT_NULL(net_crypto_.get()); }
DHT *_Nonnull get_dht() { return dht_wrapper_.get_dht(); }
const std::uint8_t *dht_public_key() const { return dht_wrapper_.dht_public_key(); }
const std::uint8_t *real_public_key() const
{
return nc_get_self_public_key(net_crypto_.get());
}
const Random *get_random() { return &dht_wrapper_.node().c_random; }
IP_Port get_ip_port() const { return dht_wrapper_.get_ip_port(); }
@@ -114,8 +123,8 @@ TEST_F(FriendConnectionTest, CreationAndDestruction)
TEST_F(FriendConnectionTest, AddKillConnection)
{
FriendConnNode alice(env, 33445);
uint8_t friend_pk[CRYPTO_PUBLIC_KEY_SIZE];
uint8_t friend_sk[CRYPTO_SECRET_KEY_SIZE];
std::uint8_t friend_pk[CRYPTO_PUBLIC_KEY_SIZE];
std::uint8_t friend_sk[CRYPTO_SECRET_KEY_SIZE];
crypto_new_keypair(alice.get_random(), friend_pk, friend_sk);
// Add Connection

View File

@@ -10,6 +10,7 @@
#define C_TOXCORE_TOXCORE_FRIEND_REQUESTS_H
#include <stddef.h>
#include <stdint.h>
#include "attributes.h"
#include "friend_connection.h"

View File

@@ -9,6 +9,7 @@
#ifndef C_TOXCORE_TOXCORE_GROUP_H
#define C_TOXCORE_TOXCORE_GROUP_H
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>

View File

@@ -18,6 +18,7 @@
#include "logger.h"
#include "mem.h"
#include "mono_time.h"
#include "net.h"
#include "network.h"
#ifdef __cplusplus

View File

@@ -7,6 +7,7 @@
#include "../testing/support/public/fuzz_data.hh"
#include "../testing/support/public/simulated_environment.hh"
#include "attributes.h"
namespace {
@@ -16,21 +17,21 @@ using tox::test::SimulatedEnvironment;
void TestUnpackAnnouncesList(Fuzz_Data &input)
{
CONSUME1_OR_RETURN(const uint8_t, max_count, input);
CONSUME1_OR_RETURN(const std::uint8_t, max_count, input);
// Always allocate at least something to avoid passing nullptr to functions below.
std::vector<GC_Announce> announces(max_count + 1);
// TODO(iphydf): How do we know the packed size?
CONSUME1_OR_RETURN(const uint16_t, packed_size, input);
CONSUME1_OR_RETURN(const std::uint16_t, packed_size, input);
SimulatedEnvironment env;
auto c_mem = env.fake_memory().get_c_memory();
auto c_mem = env.fake_memory().c_memory();
Logger *logger = logger_new(&c_mem);
if (gca_unpack_announces_list(logger, input.data(), input.size(), announces.data(), max_count)
!= -1) {
// Always allocate at least something to avoid passing nullptr to functions below.
std::vector<uint8_t> packed(packed_size + 1);
size_t processed;
std::vector<std::uint8_t> packed(packed_size + 1);
std::size_t processed;
gca_pack_announces_list(
logger, packed.data(), packed_size, announces.data(), max_count, &processed);
}
@@ -42,14 +43,14 @@ void TestUnpackPublicAnnounce(Fuzz_Data &input)
GC_Public_Announce public_announce;
// TODO(iphydf): How do we know the packed size?
CONSUME1_OR_RETURN(const uint16_t, packed_size, input);
CONSUME1_OR_RETURN(const std::uint16_t, packed_size, input);
SimulatedEnvironment env;
auto c_mem = env.fake_memory().get_c_memory();
auto c_mem = env.fake_memory().c_memory();
Logger *logger = logger_new(&c_mem);
if (gca_unpack_public_announce(logger, input.data(), input.size(), &public_announce) != -1) {
// Always allocate at least something to avoid passing nullptr to functions below.
std::vector<uint8_t> packed(packed_size + 1);
std::vector<std::uint8_t> packed(packed_size + 1);
gca_pack_public_announce(logger, packed.data(), packed_size, &public_announce);
}
logger_kill(logger);
@@ -58,13 +59,13 @@ void TestUnpackPublicAnnounce(Fuzz_Data &input)
void TestDoGca(Fuzz_Data &input)
{
SimulatedEnvironment env;
auto c_mem = env.fake_memory().get_c_memory();
auto c_mem = env.fake_memory().c_memory();
std::unique_ptr<Logger, void (*)(Logger *)> logger(logger_new(&c_mem), logger_kill);
std::unique_ptr<Mono_Time, std::function<void(Mono_Time *)>> mono_time(
mono_time_new(
&c_mem,
[](void *user_data) -> uint64_t {
[](void *_Nullable user_data) -> std::uint64_t {
return static_cast<FakeClock *>(user_data)->current_time_ms();
},
&env.fake_clock()),
@@ -76,12 +77,12 @@ void TestDoGca(Fuzz_Data &input)
assert(gca != nullptr);
while (!input.empty()) {
CONSUME1_OR_RETURN(const uint8_t, choice, input);
CONSUME1_OR_RETURN(const std::uint8_t, choice, input);
switch (choice) {
case 0: {
// Add an announce.
CONSUME1_OR_RETURN(const uint16_t, length, input);
CONSUME_OR_RETURN(const uint8_t *data, input, length);
CONSUME1_OR_RETURN(const std::uint16_t, length, input);
CONSUME_OR_RETURN(const std::uint8_t *data, input, length);
GC_Public_Announce public_announce;
if (gca_unpack_public_announce(logger.get(), data, length, &public_announce) != -1) {
gca_add_announce(&c_mem, mono_time.get(), gca.get(), &public_announce);
@@ -90,7 +91,7 @@ void TestDoGca(Fuzz_Data &input)
}
case 1: {
// Advance the time by a number of tox_iteration_intervals.
CONSUME1_OR_RETURN(const uint8_t, iterations, input);
CONSUME1_OR_RETURN(const std::uint8_t, iterations, input);
env.fake_clock().advance(iterations * 20);
// Do an iteration.
do_gca(mono_time.get(), gca.get());
@@ -98,18 +99,18 @@ void TestDoGca(Fuzz_Data &input)
}
case 2: {
// Get announces.
CONSUME1_OR_RETURN(const uint8_t, max_nodes, input);
CONSUME1_OR_RETURN(const std::uint8_t, max_nodes, input);
// Always allocate at least something to avoid passing nullptr to functions below.
std::vector<GC_Announce> gc_announces(max_nodes + 1);
CONSUME_OR_RETURN(const uint8_t *chat_id, input, CHAT_ID_SIZE);
CONSUME_OR_RETURN(const uint8_t *except_public_key, input, ENC_PUBLIC_KEY_SIZE);
CONSUME_OR_RETURN(const std::uint8_t *chat_id, input, CHAT_ID_SIZE);
CONSUME_OR_RETURN(const std::uint8_t *except_public_key, input, ENC_PUBLIC_KEY_SIZE);
gca_get_announces(
gca.get(), gc_announces.data(), max_nodes, chat_id, except_public_key);
break;
}
case 3: {
// Remove a chat.
CONSUME_OR_RETURN(const uint8_t *chat_id, input, CHAT_ID_SIZE);
CONSUME_OR_RETURN(const std::uint8_t *chat_id, input, CHAT_ID_SIZE);
cleanup_gca(gca.get(), chat_id);
break;
}
@@ -119,8 +120,8 @@ void TestDoGca(Fuzz_Data &input)
} // namespace
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t *data, std::size_t size);
extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t *data, std::size_t size)
{
tox::test::fuzz_select_target<TestUnpackAnnouncesList, TestUnpackPublicAnnounce, TestDoGca>(
data, size);

View File

@@ -6,6 +6,7 @@
#include <gtest/gtest.h>
#include "DHT.h"
#include "attributes.h"
#include "crypto_core.h"
#include "logger.h"
#include "mono_time.h"
@@ -20,15 +21,15 @@ using tox::test::SimulatedEnvironment;
struct Announces : ::testing::Test {
protected:
SimulatedEnvironment env;
Tox_Memory c_mem_;
Mono_Time *mono_time_ = nullptr;
GC_Announces_List *gca_ = nullptr;
Memory c_mem_;
Mono_Time *_Nullable mono_time_ = nullptr;
GC_Announces_List *_Nullable gca_ = nullptr;
GC_Announce _ann1;
GC_Announce _ann2;
void SetUp() override
{
c_mem_ = env.fake_memory().get_c_memory();
c_mem_ = env.fake_memory().c_memory();
mono_time_ = mono_time_new(&c_mem_, nullptr, nullptr);
ASSERT_NE(mono_time_, nullptr);
setup_fake_clock(mono_time_, env.fake_clock());
@@ -43,7 +44,7 @@ protected:
mono_time_free(&c_mem_, mono_time_);
}
void advance_clock(uint64_t increment)
void advance_clock(std::uint64_t increment)
{
env.fake_clock().advance(increment);
mono_time_update(mono_time_);
@@ -105,7 +106,7 @@ TEST_F(Announces, AnnouncesGetAndCleanup)
ASSERT_NE(gca_add_announce(&c_mem_, mono_time_, gca_, &ann2), nullptr);
ASSERT_NE(gca_add_announce(&c_mem_, mono_time_, gca_, &ann2), nullptr);
uint8_t empty_pk[ENC_PUBLIC_KEY_SIZE] = {0};
std::uint8_t empty_pk[ENC_PUBLIC_KEY_SIZE] = {0};
GC_Announce announces;
ASSERT_EQ(gca_get_announces(gca_, &announces, 1, ann1.chat_public_key, empty_pk), 1);
@@ -124,13 +125,13 @@ TEST_F(Announces, AnnouncesGetAndCleanup)
struct AnnouncesPack : ::testing::Test {
protected:
SimulatedEnvironment env;
Tox_Memory c_mem_;
Memory c_mem_;
std::vector<GC_Announce> announces_;
Logger *logger_ = nullptr;
void SetUp() override
{
c_mem_ = env.fake_memory().get_c_memory();
c_mem_ = env.fake_memory().c_memory();
logger_ = logger_new(&c_mem_);
ASSERT_NE(logger_, nullptr);
@@ -168,7 +169,7 @@ TEST_F(AnnouncesPack, PublicAnnounceCanBePackedAndUnpacked)
ann.chat_public_key[0] = 0x88;
ann.base_announce = announces_[0];
std::vector<uint8_t> packed(GCA_PUBLIC_ANNOUNCE_MAX_SIZE);
std::vector<std::uint8_t> packed(GCA_PUBLIC_ANNOUNCE_MAX_SIZE);
const int packed_size = gca_pack_public_announce(logger_, packed.data(), packed.size(), &ann);
EXPECT_GT(packed_size, 0);
@@ -182,7 +183,7 @@ TEST_F(AnnouncesPack, UnpackEmptyPublicAnnounce)
{
#ifndef __clang__
GC_Public_Announce ann{};
std::vector<uint8_t> packed(GCA_PUBLIC_ANNOUNCE_MAX_SIZE);
std::vector<std::uint8_t> packed(GCA_PUBLIC_ANNOUNCE_MAX_SIZE);
EXPECT_EQ(gca_unpack_public_announce(logger_, nullptr, 0, &ann), -1);
EXPECT_EQ(gca_unpack_public_announce(logger_, packed.data(), packed.size(), nullptr), -1);
@@ -193,7 +194,7 @@ TEST_F(AnnouncesPack, PackEmptyPublicAnnounce)
{
#ifndef __clang__
GC_Public_Announce ann{};
std::vector<uint8_t> packed(GCA_PUBLIC_ANNOUNCE_MAX_SIZE);
std::vector<std::uint8_t> packed(GCA_PUBLIC_ANNOUNCE_MAX_SIZE);
EXPECT_EQ(gca_pack_public_announce(logger_, packed.data(), packed.size(), nullptr), -1);
EXPECT_EQ(gca_pack_public_announce(logger_, nullptr, 0, &ann), -1);
#endif
@@ -202,13 +203,13 @@ TEST_F(AnnouncesPack, PackEmptyPublicAnnounce)
TEST_F(AnnouncesPack, PublicAnnouncePackNull)
{
GC_Public_Announce ann{};
std::vector<uint8_t> packed(GCA_PUBLIC_ANNOUNCE_MAX_SIZE);
std::vector<std::uint8_t> packed(GCA_PUBLIC_ANNOUNCE_MAX_SIZE);
EXPECT_EQ(gca_pack_public_announce(logger_, packed.data(), packed.size(), &ann), -1);
ann.chat_public_key[0] = 0x88;
ann.base_announce = announces_[0];
std::vector<uint8_t> packedTooSmall(GCA_PUBLIC_ANNOUNCE_MAX_SIZE - 1);
std::vector<std::uint8_t> packedTooSmall(GCA_PUBLIC_ANNOUNCE_MAX_SIZE - 1);
EXPECT_EQ(
gca_pack_public_announce(logger_, packedTooSmall.data(), packedTooSmall.size(), &ann), -1);
@@ -235,9 +236,9 @@ TEST_F(AnnouncesPack, AnnouncesValidationCheck)
TEST_F(AnnouncesPack, UnpackIncompleteAnnouncesList)
{
const uint8_t data[] = {0x00, 0x24, 0x3d, 0x00, 0x3d, 0xff, 0xff, 0x5b, 0x04, 0x20, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00};
const std::uint8_t data[] = {0x00, 0x24, 0x3d, 0x00, 0x3d, 0xff, 0xff, 0x5b, 0x04, 0x20, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00};
GC_Announce announce;
EXPECT_EQ(gca_unpack_announces_list(logger_, data, sizeof(data), &announce, 1), -1);
@@ -249,10 +250,10 @@ TEST_F(AnnouncesPack, UnpackIncompleteAnnouncesList)
TEST_F(AnnouncesPack, PackedAnnouncesListCanBeUnpacked)
{
const uint16_t size = gca_pack_announces_list_size(announces_.size());
std::vector<uint8_t> packed(size);
const std::uint16_t size = gca_pack_announces_list_size(announces_.size());
std::vector<std::uint8_t> packed(size);
size_t processed = 0;
std::size_t processed = 0;
EXPECT_GT(gca_pack_announces_list(logger_, packed.data(), packed.size(), announces_.data(),
announces_.size(), &processed),
@@ -269,7 +270,7 @@ TEST_F(AnnouncesPack, PackedAnnouncesListCanBeUnpacked)
TEST_F(AnnouncesPack, PackingEmptyAnnounceFails)
{
GC_Announce announce{}; // all zeroes
std::vector<uint8_t> packed(gca_pack_announces_list_size(1));
std::vector<std::uint8_t> packed(gca_pack_announces_list_size(1));
EXPECT_EQ(
gca_pack_announces_list(logger_, packed.data(), packed.size(), &announce, 1, nullptr), -1);
#ifndef __clang__
@@ -282,7 +283,7 @@ TEST_F(AnnouncesPack, PackingEmptyAnnounceFails)
TEST_F(AnnouncesPack, PackAnnounceNull)
{
#ifndef __clang__
std::vector<uint8_t> data(GCA_ANNOUNCE_MAX_SIZE);
std::vector<std::uint8_t> data(GCA_ANNOUNCE_MAX_SIZE);
GC_Announce announce;
ASSERT_EQ(gca_pack_announce(logger_, nullptr, 0, &announce), -1);
ASSERT_EQ(gca_pack_announce(logger_, data.data(), data.size(), nullptr), -1);

View File

@@ -1967,7 +1967,7 @@ static bool sync_response_send_state(GC_Chat *_Nonnull chat, GC_Connection *_Non
* Return -3 if we fail to send a response packet.
* Return -4 if `peer_number` does not designate a valid peer.
*/
static int handle_gc_sync_request(GC_Chat *_Nonnull chat, uint32_t peer_number, const uint8_t *_Nonnull data, uint16_t length)
static int handle_gc_sync_request(GC_Chat *_Nonnull chat, uint32_t peer_number, const uint8_t *_Nullable data, uint16_t length)
{
GC_Connection *gconn = get_gc_connection(chat, peer_number);
@@ -2067,7 +2067,7 @@ static bool send_gc_tcp_relays(const GC_Chat *_Nonnull chat, GC_Connection *_Non
* Return -1 if packet has invalid size.
* Return -2 if packet contains invalid data.
*/
static int handle_gc_tcp_relays(GC_Chat *_Nonnull chat, GC_Connection *_Nonnull gconn, const uint8_t *_Nonnull data, uint16_t length)
static int handle_gc_tcp_relays(GC_Chat *_Nonnull chat, GC_Connection *_Nonnull gconn, const uint8_t *_Nullable data, uint16_t length)
{
if (length == 0) {
return -1;
@@ -2203,7 +2203,7 @@ static bool send_gc_invite_response_reject(const GC_Chat *_Nonnull chat, GC_Conn
* Return -3 if we fail to send an invite response.
* Return -4 if peer_number does not designate a valid peer.
*/
static int handle_gc_invite_request(GC_Chat *_Nonnull chat, uint32_t peer_number, const uint8_t *_Nonnull data, uint16_t length)
static int handle_gc_invite_request(GC_Chat *_Nonnull chat, uint32_t peer_number, const uint8_t *_Nullable data, uint16_t length)
{
if (chat->shared_state.version == 0) { // we aren't synced yet; ignore request
return 0;
@@ -2682,7 +2682,7 @@ static bool send_gc_peer_exchange(const GC_Chat *chat, GC_Connection *gconn)
* Return -8 if memory allocation fails.
*/
static int handle_gc_peer_info_response(const GC_Session *_Nonnull c, GC_Chat *_Nonnull chat, uint32_t peer_number,
const uint8_t *_Nonnull data, uint16_t length, void *_Nullable userdata)
const uint8_t *_Nullable data, uint16_t length, void *_Nullable userdata)
{
if (length < PACKED_GC_PEER_SIZE) {
return -1;
@@ -2918,7 +2918,7 @@ static int handle_gc_shared_state_error(GC_Chat *_Nonnull chat, GC_Connection *_
* Return 0 if packet is successfully handled.
* Return -1 if packet is invalid and this is not successfully handled.
*/
static int handle_gc_shared_state(const GC_Session *_Nonnull c, GC_Chat *_Nonnull chat, GC_Connection *_Nonnull gconn, const uint8_t *_Nonnull data,
static int handle_gc_shared_state(const GC_Session *_Nonnull c, GC_Chat *_Nonnull chat, GC_Connection *_Nonnull gconn, const uint8_t *_Nullable data,
uint16_t length, void *_Nullable userdata)
{
if (length < GC_SHARED_STATE_ENC_PACKET_SIZE) {
@@ -3015,7 +3015,7 @@ static int validate_unpack_mod_list(GC_Chat *_Nonnull chat, const uint8_t *_Nonn
* Return -1 if packet has invalid size.
* Return -2 if packet contained invalid data or validation failed.
*/
static int handle_gc_mod_list(const GC_Session *_Nonnull c, GC_Chat *_Nonnull chat, const uint8_t *_Nonnull data, uint16_t length, void *_Nullable userdata)
static int handle_gc_mod_list(const GC_Session *_Nonnull c, GC_Chat *_Nonnull chat, const uint8_t *_Nullable data, uint16_t length, void *_Nullable userdata)
{
if (length < sizeof(uint16_t)) {
return -1;
@@ -3094,7 +3094,7 @@ static int handle_gc_sanctions_list_error(GC_Chat *_Nonnull chat)
* Return -1 if we failed to gracefully handle a sanctions list error.
* Return -2 if packet has invalid size.
*/
static int handle_gc_sanctions_list(const GC_Session *_Nonnull c, GC_Chat *_Nonnull chat, const uint8_t *_Nonnull data, uint16_t length,
static int handle_gc_sanctions_list(const GC_Session *_Nonnull c, GC_Chat *_Nonnull chat, const uint8_t *_Nullable data, uint16_t length,
void *_Nullable userdata)
{
if (length < sizeof(uint16_t)) {
@@ -3869,7 +3869,7 @@ static bool handle_gc_topic_validate(const GC_Chat *_Nonnull chat, const GC_Peer
* Return 0 if packet is correctly handled.
* Return -1 if packet has invalid size.
*/
static int handle_gc_topic(const GC_Session *_Nonnull c, GC_Chat *_Nonnull chat, const GC_Peer *_Nonnull peer, const uint8_t *_Nonnull data,
static int handle_gc_topic(const GC_Session *_Nonnull c, GC_Chat *_Nonnull chat, const GC_Peer *_Nonnull peer, const uint8_t *_Nullable data,
uint16_t length, void *_Nullable userdata)
{
if (length < SIGNATURE_SIZE + GC_MIN_PACKED_TOPIC_INFO_SIZE) {
@@ -3931,7 +3931,7 @@ static int handle_gc_topic(const GC_Session *_Nonnull c, GC_Chat *_Nonnull chat,
* Return -2 if we fail to create a new session keypair.
* Return -3 if response packet fails to send.
*/
static int handle_gc_key_exchange(const GC_Chat *_Nonnull chat, GC_Connection *_Nonnull gconn, const uint8_t *_Nonnull data, uint16_t length)
static int handle_gc_key_exchange(const GC_Chat *_Nonnull chat, GC_Connection *_Nonnull gconn, const uint8_t *_Nullable data, uint16_t length)
{
if (length < 1 + ENC_PUBLIC_KEY_SIZE) {
return -1;
@@ -4995,7 +4995,7 @@ int gc_send_custom_private_packet(const GC_Chat *chat, bool lossless, GC_Peer_Id
* @retval -1 if packet has invalid size.
*/
static int handle_gc_custom_private_packet(const GC_Session *_Nonnull c, const GC_Chat *_Nonnull chat, const GC_Peer *_Nonnull peer,
const uint8_t *_Nonnull data, uint16_t length, bool lossless, void *_Nullable userdata)
const uint8_t *_Nullable data, uint16_t length, bool lossless, void *_Nullable userdata)
{
if (!custom_gc_packet_length_is_valid(length, lossless)) {
return -1;
@@ -5038,7 +5038,7 @@ int gc_send_custom_packet(const GC_Chat *chat, bool lossless, const uint8_t *dat
* Return 0 if packet is handled correctly.
* Return -1 if packet has invalid size.
*/
static int handle_gc_custom_packet(const GC_Session *_Nonnull c, const GC_Chat *_Nonnull chat, const GC_Peer *_Nonnull peer, const uint8_t *_Nonnull data,
static int handle_gc_custom_packet(const GC_Session *_Nonnull c, const GC_Chat *_Nonnull chat, const GC_Peer *_Nonnull peer, const uint8_t *_Nullable data,
uint16_t length, bool lossless, void *_Nullable userdata)
{
if (!custom_gc_packet_length_is_valid(length, lossless)) {
@@ -5301,7 +5301,7 @@ int gc_set_ignore(const GC_Chat *chat, GC_Peer_Id peer_id, bool ignore)
* Returns 0 if packet is handled correctly.
* Returns -1 on failure.
*/
static int handle_gc_broadcast(const GC_Session *_Nonnull c, GC_Chat *_Nonnull chat, uint32_t peer_number, const uint8_t *_Nonnull data,
static int handle_gc_broadcast(const GC_Session *_Nonnull c, GC_Chat *_Nonnull chat, uint32_t peer_number, const uint8_t *_Nullable data,
uint16_t length, void *_Nullable userdata)
{
if (length < GC_BROADCAST_ENC_HEADER_SIZE) {
@@ -5483,7 +5483,7 @@ static int make_gc_handshake_packet(const GC_Chat *_Nonnull chat, const GC_Conne
uint8_t data[GC_MIN_HS_PACKET_PAYLOAD_SIZE + sizeof(Node_format)];
uint16_t length = sizeof(uint8_t);
uint32_t length = sizeof(uint8_t);
data[0] = handshake_type;
memcpy(data + length, gconn->session_public_key, ENC_PUBLIC_KEY_SIZE);
@@ -5505,7 +5505,7 @@ static int make_gc_handshake_packet(const GC_Chat *_Nonnull chat, const GC_Conne
const int enc_len = wrap_group_handshake_packet(
chat->log, chat->mem, chat->rng, chat->self_public_key.enc, chat->self_secret_key.enc,
gconn->addr.public_key.enc, packet, (uint16_t)packet_size, data, length);
gconn->addr.public_key.enc, packet, (uint16_t)packet_size, data, (uint16_t)length);
if (enc_len != GC_MIN_ENCRYPTED_HS_PAYLOAD_SIZE + nodes_size) {
LOGGER_WARNING(chat->log, "Failed to wrap handshake packet: %d", enc_len);
@@ -7766,6 +7766,11 @@ int gc_invite_friend(const GC_Session *c, GC_Chat *chat, int32_t friend_number,
mem_delete(chat->mem, packet);
if (chat->saved_invites[chat->saved_invites_index] != -1) {
LOGGER_WARNING(chat->log, "Overwriting pending group invite for friend %d due to buffer overflow",
chat->saved_invites[chat->saved_invites_index]);
}
chat->saved_invites[chat->saved_invites_index] = friend_number;
chat->saved_invites_index = (chat->saved_invites_index + 1) % MAX_GC_SAVED_INVITES;
@@ -7992,6 +7997,8 @@ bool handle_gc_invite_accepted_packet(const GC_Session *c, int friend_number, co
const int peer_number = peer_add(chat, nullptr, invite_chat_pk);
if (!friend_was_invited(m, chat, friend_number)) {
LOGGER_WARNING(chat->log, "Group invite acceptance from friend %d rejected (not invited or invite buffer overflowed)",
friend_number);
return false;
}

View File

@@ -680,7 +680,7 @@ bool gc_send_message_ack(const GC_Chat *_Nonnull chat, GC_Connection *_Nonnull g
*
* @retval true if packet is successfully handled.
*/
bool handle_gc_lossless_helper(const GC_Session *_Nonnull c, GC_Chat *_Nonnull chat, uint32_t peer_number, const uint8_t *_Nonnull data,
bool handle_gc_lossless_helper(const GC_Session *_Nonnull c, GC_Chat *_Nonnull chat, uint32_t peer_number, const uint8_t *_Nullable data,
uint16_t length, uint8_t packet_type, void *_Nullable userdata);
/** @brief Handles an invite accept packet.
*

View File

@@ -20,6 +20,7 @@
#include "logger.h"
#include "mem.h"
#include "mono_time.h"
#include "net.h"
#include "net_profile.h"
#include "network.h"

View File

@@ -512,14 +512,7 @@ static bool process_recv_array_entry(const GC_Session *_Nonnull c, GC_Chat *_Non
uint8_t sender_pk[ENC_PUBLIC_KEY_SIZE];
memcpy(sender_pk, get_enc_key(&gconn->addr.public_key), ENC_PUBLIC_KEY_SIZE);
const uint8_t *data = array_entry->data;
// TODO(iphydf): This is ugly. We should probably change all the handlers to accept nullable.
const uint8_t empty_data[1] = { 0 };
if (data == nullptr) {
data = empty_data;
}
const bool ret = handle_gc_lossless_helper(c, chat, peer_number, data, array_entry->data_length,
const bool ret = handle_gc_lossless_helper(c, chat, peer_number, array_entry->data, array_entry->data_length,
array_entry->packet_type, userdata);
/* peer number can change from peer add operations in packet handlers */

View File

@@ -10,6 +10,9 @@
#ifndef C_TOXCORE_TOXCORE_GROUP_CONNECTION_H
#define C_TOXCORE_TOXCORE_GROUP_CONNECTION_H
#include <stdbool.h>
#include <stdint.h>
#include "DHT.h"
#include "TCP_connection.h"
#include "attributes.h"
@@ -18,6 +21,7 @@
#include "logger.h"
#include "mem.h"
#include "mono_time.h"
#include "net.h"
#include "network.h"
/* Max number of TCP relays we share with a peer on handshake */

View File

@@ -10,9 +10,9 @@ using tox::test::SimulatedEnvironment;
void TestModListUnpack(Fuzz_Data &input)
{
CONSUME1_OR_RETURN(const uint16_t, num_mods, input);
CONSUME1_OR_RETURN(const std::uint16_t, num_mods, input);
SimulatedEnvironment env;
auto c_mem = env.fake_memory().get_c_memory();
auto c_mem = env.fake_memory().c_memory();
Moderation mods{&c_mem};
mod_list_unpack(&mods, input.data(), input.size(), num_mods);
mod_list_cleanup(&mods);
@@ -22,21 +22,21 @@ void TestSanctionsListUnpack(Fuzz_Data &input)
{
Mod_Sanction sanctions[10];
Mod_Sanction_Creds creds;
uint16_t processed_data_len;
std::uint16_t processed_data_len;
sanctions_list_unpack(sanctions, &creds, 10, input.data(), input.size(), &processed_data_len);
}
void TestSanctionCredsUnpack(Fuzz_Data &input)
{
CONSUME_OR_RETURN(const uint8_t *data, input, MOD_SANCTIONS_CREDS_SIZE);
CONSUME_OR_RETURN(const std::uint8_t *data, input, MOD_SANCTIONS_CREDS_SIZE);
Mod_Sanction_Creds creds;
sanctions_creds_unpack(&creds, data);
}
} // namespace
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t *data, std::size_t size);
extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t *data, std::size_t size)
{
tox::test::fuzz_select_target<TestModListUnpack, TestSanctionsListUnpack,
TestSanctionCredsUnpack>(data, size);

View File

@@ -7,6 +7,8 @@
#include <algorithm>
#include <array>
#include <cstdint>
#include <cstring>
#include <vector>
#include "DHT.h"
@@ -18,16 +20,16 @@
namespace {
using tox::test::SimulatedEnvironment;
using ModerationHash = std::array<uint8_t, MOD_MODERATION_HASH_SIZE>;
using ModerationHash = std::array<std::uint8_t, MOD_MODERATION_HASH_SIZE>;
TEST(ModList, PackedSizeOfEmptyModListIsZero)
{
SimulatedEnvironment env;
auto c_mem = env.fake_memory().get_c_memory();
auto c_mem = env.fake_memory().c_memory();
Moderation mods{&c_mem};
EXPECT_EQ(mod_list_packed_size(&mods), 0);
uint8_t byte = 1;
std::uint8_t byte = 1;
mod_list_pack(&mods, &byte);
EXPECT_EQ(byte, 1);
}
@@ -35,19 +37,19 @@ TEST(ModList, PackedSizeOfEmptyModListIsZero)
TEST(ModList, UnpackingZeroSizeArrayIsNoop)
{
SimulatedEnvironment env;
auto c_mem = env.fake_memory().get_c_memory();
auto c_mem = env.fake_memory().c_memory();
Moderation mods{&c_mem};
const uint8_t byte = 1;
const std::uint8_t byte = 1;
EXPECT_EQ(mod_list_unpack(&mods, &byte, 0, 0), 0);
}
TEST(ModList, AddRemoveMultipleMods)
{
SimulatedEnvironment env;
auto c_mem = env.fake_memory().get_c_memory();
auto c_mem = env.fake_memory().c_memory();
Moderation mods{&c_mem};
uint8_t sig_pk1[32] = {1};
uint8_t sig_pk2[32] = {2};
std::uint8_t sig_pk1[32] = {1};
std::uint8_t sig_pk2[32] = {2};
EXPECT_TRUE(mod_list_add_entry(&mods, sig_pk1));
EXPECT_TRUE(mod_list_add_entry(&mods, sig_pk2));
EXPECT_TRUE(mod_list_remove_entry(&mods, sig_pk1));
@@ -56,13 +58,13 @@ TEST(ModList, AddRemoveMultipleMods)
TEST(ModList, PackingAndUnpackingList)
{
using ModListEntry = std::array<uint8_t, MOD_LIST_ENTRY_SIZE>;
using ModListEntry = std::array<std::uint8_t, MOD_LIST_ENTRY_SIZE>;
SimulatedEnvironment env;
auto c_mem = env.fake_memory().get_c_memory();
auto c_mem = env.fake_memory().c_memory();
Moderation mods{&c_mem};
EXPECT_TRUE(mod_list_add_entry(&mods, ModListEntry{}.data()));
std::vector<uint8_t> packed(mod_list_packed_size(&mods));
std::vector<std::uint8_t> packed(mod_list_packed_size(&mods));
mod_list_pack(&mods, packed.data());
EXPECT_TRUE(mod_list_remove_entry(&mods, ModListEntry{}.data()));
@@ -74,13 +76,13 @@ TEST(ModList, PackingAndUnpackingList)
TEST(ModList, UnpackingTooManyModsFails)
{
using ModListEntry = std::array<uint8_t, MOD_LIST_ENTRY_SIZE>;
using ModListEntry = std::array<std::uint8_t, MOD_LIST_ENTRY_SIZE>;
SimulatedEnvironment env;
auto c_mem = env.fake_memory().get_c_memory();
auto c_mem = env.fake_memory().c_memory();
Moderation mods{&c_mem};
EXPECT_TRUE(mod_list_add_entry(&mods, ModListEntry{}.data()));
std::vector<uint8_t> packed(mod_list_packed_size(&mods));
std::vector<std::uint8_t> packed(mod_list_packed_size(&mods));
mod_list_pack(&mods, packed.data());
Moderation mods2{&c_mem};
@@ -90,10 +92,10 @@ TEST(ModList, UnpackingTooManyModsFails)
TEST(ModList, UnpackingFromEmptyBufferFails)
{
std::vector<uint8_t> packed(1);
std::vector<std::uint8_t> packed(1);
SimulatedEnvironment env;
auto c_mem = env.fake_memory().get_c_memory();
auto c_mem = env.fake_memory().c_memory();
Moderation mods{&c_mem};
EXPECT_EQ(mod_list_unpack(&mods, packed.data(), 0, 1), -1);
}
@@ -101,8 +103,8 @@ TEST(ModList, UnpackingFromEmptyBufferFails)
TEST(ModList, HashOfEmptyModListZeroesOutBuffer)
{
SimulatedEnvironment env;
auto c_mem = env.fake_memory().get_c_memory();
auto c_rng = env.fake_random().get_c_random();
auto c_mem = env.fake_memory().c_memory();
auto c_rng = env.fake_random().c_random();
Moderation mods{&c_mem};
@@ -116,7 +118,7 @@ TEST(ModList, HashOfEmptyModListZeroesOutBuffer)
TEST(ModList, RemoveIndexFromEmptyModListFails)
{
SimulatedEnvironment env;
auto c_mem = env.fake_memory().get_c_memory();
auto c_mem = env.fake_memory().c_memory();
Moderation mods{&c_mem};
EXPECT_FALSE(mod_list_remove_index(&mods, 0));
EXPECT_FALSE(mod_list_remove_index(&mods, UINT16_MAX));
@@ -125,18 +127,18 @@ TEST(ModList, RemoveIndexFromEmptyModListFails)
TEST(ModList, RemoveEntryFromEmptyModListFails)
{
SimulatedEnvironment env;
auto c_mem = env.fake_memory().get_c_memory();
auto c_mem = env.fake_memory().c_memory();
Moderation mods{&c_mem};
uint8_t sig_pk[32] = {0};
std::uint8_t sig_pk[32] = {0};
EXPECT_FALSE(mod_list_remove_entry(&mods, sig_pk));
}
TEST(ModList, ModListRemoveIndex)
{
SimulatedEnvironment env;
auto c_mem = env.fake_memory().get_c_memory();
auto c_mem = env.fake_memory().c_memory();
Moderation mods{&c_mem};
uint8_t sig_pk[32] = {1};
std::uint8_t sig_pk[32] = {1};
EXPECT_TRUE(mod_list_add_entry(&mods, sig_pk));
EXPECT_TRUE(mod_list_remove_index(&mods, 0));
}
@@ -144,7 +146,7 @@ TEST(ModList, ModListRemoveIndex)
TEST(ModList, CleanupOnEmptyModsIsNoop)
{
SimulatedEnvironment env;
auto c_mem = env.fake_memory().get_c_memory();
auto c_mem = env.fake_memory().c_memory();
Moderation mods{&c_mem};
mod_list_cleanup(&mods);
}
@@ -152,18 +154,18 @@ TEST(ModList, CleanupOnEmptyModsIsNoop)
TEST(ModList, EmptyModListCannotVerifyAnySigPk)
{
SimulatedEnvironment env;
auto c_mem = env.fake_memory().get_c_memory();
auto c_mem = env.fake_memory().c_memory();
Moderation mods{&c_mem};
uint8_t sig_pk[32] = {1};
std::uint8_t sig_pk[32] = {1};
EXPECT_FALSE(mod_list_verify_sig_pk(&mods, sig_pk));
}
TEST(ModList, ModListAddVerifyRemoveSigPK)
{
SimulatedEnvironment env;
auto c_mem = env.fake_memory().get_c_memory();
auto c_mem = env.fake_memory().c_memory();
Moderation mods{&c_mem};
uint8_t sig_pk[32] = {1};
std::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));
EXPECT_TRUE(mod_list_remove_entry(&mods, sig_pk));
@@ -173,10 +175,10 @@ TEST(ModList, ModListAddVerifyRemoveSigPK)
TEST(ModList, ModListHashCheck)
{
SimulatedEnvironment env;
auto c_mem = env.fake_memory().get_c_memory();
auto c_mem = env.fake_memory().c_memory();
Moderation mods1{&c_mem};
uint8_t sig_pk1[32] = {1};
std::array<uint8_t, MOD_MODERATION_HASH_SIZE> hash1;
std::uint8_t sig_pk1[32] = {1};
std::array<std::uint8_t, MOD_MODERATION_HASH_SIZE> hash1;
EXPECT_TRUE(mod_list_add_entry(&mods1, sig_pk1));
EXPECT_TRUE(mod_list_make_hash(&mods1, hash1.data()));
@@ -186,20 +188,20 @@ TEST(ModList, ModListHashCheck)
TEST(SanctionsList, PackingIntoUndersizedBufferFails)
{
Mod_Sanction sanctions[1] = {};
std::array<uint8_t, 1> packed;
std::array<std::uint8_t, 1> packed;
EXPECT_EQ(sanctions_list_pack(packed.data(), packed.size(), sanctions, 1, nullptr), -1);
uint16_t length = sanctions_list_packed_size(1) - 1;
std::vector<uint8_t> packed2(length);
std::uint16_t length = sanctions_list_packed_size(1) - 1;
std::vector<std::uint8_t> packed2(length);
EXPECT_EQ(sanctions_list_pack(packed2.data(), packed2.size(), sanctions, 1, nullptr), -1);
}
TEST(SanctionsList, PackUnpackSanctionsCreds)
{
SimulatedEnvironment env;
auto c_mem = env.fake_memory().get_c_memory();
auto c_mem = env.fake_memory().c_memory();
Moderation mod{&c_mem};
std::array<uint8_t, MOD_SANCTIONS_CREDS_SIZE> packed;
std::array<std::uint8_t, MOD_SANCTIONS_CREDS_SIZE> packed;
EXPECT_EQ(sanctions_creds_pack(&mod.sanctions_creds, packed.data()), MOD_SANCTIONS_CREDS_SIZE);
EXPECT_EQ(
sanctions_creds_unpack(&mod.sanctions_creds, packed.data()), MOD_SANCTIONS_CREDS_SIZE);
@@ -208,8 +210,8 @@ TEST(SanctionsList, PackUnpackSanctionsCreds)
struct SanctionsListMod : ::testing::Test {
protected:
SimulatedEnvironment env;
Tox_Memory c_mem_;
Tox_Random c_rng_;
Memory c_mem_;
Random c_rng_;
Extended_Public_Key pk;
Extended_Secret_Key sk;
@@ -217,12 +219,12 @@ protected:
Moderation mod;
Mod_Sanction sanctions[2] = {};
const uint8_t sanctioned_pk1[32] = {1};
const uint8_t sanctioned_pk2[32] = {2};
const std::uint8_t sanctioned_pk1[32] = {1};
const std::uint8_t sanctioned_pk2[32] = {2};
SanctionsListMod()
: c_mem_(env.fake_memory().get_c_memory())
, c_rng_(env.fake_random().get_c_random())
: c_mem_(env.fake_memory().c_memory())
, c_rng_(env.fake_random().c_random())
, mod{&c_mem_}
{
}
@@ -234,8 +236,8 @@ protected:
mod.log = log;
memcpy(mod.self_public_sig_key, get_sig_pk(&pk), SIG_PUBLIC_KEY_SIZE);
memcpy(mod.self_secret_sig_key, get_sig_sk(&sk), SIG_SECRET_KEY_SIZE);
std::memcpy(mod.self_public_sig_key, get_sig_pk(&pk), SIG_PUBLIC_KEY_SIZE);
std::memcpy(mod.self_secret_sig_key, get_sig_sk(&sk), SIG_SECRET_KEY_SIZE);
ASSERT_TRUE(mod_list_add_entry(&mod, get_sig_pk(&pk)));
@@ -267,13 +269,13 @@ protected:
// TODO(JFreegman): Split this up into smaller subtests
TEST_F(SanctionsListMod, PackUnpackSanction)
{
std::vector<uint8_t> packed(sanctions_list_packed_size(2));
std::vector<std::uint8_t> packed(sanctions_list_packed_size(2));
EXPECT_EQ(
sanctions_list_pack(packed.data(), packed.size(), sanctions, 2, nullptr), packed.size());
Mod_Sanction unpacked_sanctions[2] = {};
uint16_t processed_data_len = 0;
std::uint16_t processed_data_len = 0;
EXPECT_EQ(sanctions_list_unpack(unpacked_sanctions, &mod.sanctions_creds, 2, packed.data(),
packed.size(), &processed_data_len),

View File

@@ -6,6 +6,8 @@
#ifndef C_TOXCORE_TOXCORE_GROUP_ONION_ANNOUNCE_H
#define C_TOXCORE_TOXCORE_GROUP_ONION_ANNOUNCE_H
#include <stdint.h>
#include "attributes.h"
#include "crypto_core.h"
#include "group_announce.h"

View File

@@ -11,6 +11,7 @@
#define C_TOXCORE_TOXCORE_GROUP_PACK_H
#include <stdbool.h>
#include <stdint.h>
#include "attributes.h"
#include "bin_pack.h"

View File

@@ -2,6 +2,9 @@
#include <gtest/gtest.h>
#include <cstdint>
#include <cstring>
#include "mem.h"
#include "os_memory.h"
@@ -11,7 +14,7 @@ TEST(List, CreateAndDestroyWithNonZeroSize)
{
const Memory *mem = os_memory();
BS_List list;
bs_list_init(&list, mem, sizeof(int), 10, memcmp);
bs_list_init(&list, mem, sizeof(int), 10, std::memcmp);
bs_list_free(&list);
}
@@ -19,7 +22,7 @@ TEST(List, CreateAndDestroyWithZeroSize)
{
const Memory *mem = os_memory();
BS_List list;
bs_list_init(&list, mem, sizeof(int), 0, memcmp);
bs_list_init(&list, mem, sizeof(int), 0, std::memcmp);
bs_list_free(&list);
}
@@ -27,8 +30,8 @@ TEST(List, DeleteFromEmptyList)
{
const Memory *mem = os_memory();
BS_List list;
bs_list_init(&list, mem, sizeof(int), 0, memcmp);
const uint8_t data[sizeof(int)] = {0};
bs_list_init(&list, mem, sizeof(int), 0, std::memcmp);
const std::uint8_t data[sizeof(int)] = {0};
bs_list_remove(&list, data, 0);
bs_list_free(&list);
}

View File

@@ -74,7 +74,9 @@ void logger_write(const Logger *log, Logger_Level level, const char *file, uint3
// The full path may contain PII of the person compiling toxcore (their
// username and directory layout).
const char *filename = strrchr(file, '/');
file = filename != nullptr ? filename + 1 : file;
if (filename != nullptr) {
file = &filename[1];
}
#if defined(_WIN32) || defined(__CYGWIN__)
// On Windows, the path separator *may* be a backslash, so we look for that
// one too.

Some files were not shown because too many files have changed in this diff Show More