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:
@@ -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",
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
/**
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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" {
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
98
toxcore/TCP_common_test.cc
Normal file
98
toxcore/TCP_common_test.cc
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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" {
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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" */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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" */
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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()));
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
47
toxcore/ev.c
Normal 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
130
toxcore/ev.h
Normal 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
152
toxcore/ev_bench.cc
Normal 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
329
toxcore/ev_test.cc
Normal 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
106
toxcore/ev_test_util.cc
Normal 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
35
toxcore/ev_test_util.hh
Normal 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 */
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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" {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#define C_TOXCORE_TOXCORE_FRIEND_REQUESTS_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "attributes.h"
|
||||
#include "friend_connection.h"
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "logger.h"
|
||||
#include "mem.h"
|
||||
#include "mono_time.h"
|
||||
#include "net.h"
|
||||
#include "network.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "logger.h"
|
||||
#include "mem.h"
|
||||
#include "mono_time.h"
|
||||
#include "net.h"
|
||||
#include "net_profile.h"
|
||||
#include "network.h"
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#define C_TOXCORE_TOXCORE_GROUP_PACK_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "attributes.h"
|
||||
#include "bin_pack.h"
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user