Compare commits

..

12 Commits

Author SHA1 Message Date
586b49f4a8 fix rare race condition in debug vid src
Some checks failed
ContinuousDelivery / linux-ubuntu (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Has been cancelled
ContinuousDelivery / windows (push) Has been cancelled
ContinuousDelivery / windows-asan (push) Has been cancelled
ContinuousIntegration / linux (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Has been cancelled
ContinuousIntegration / macos (push) Has been cancelled
ContinuousIntegration / windows (push) Has been cancelled
ContinuousDelivery / release (push) Has been cancelled
2024-12-22 15:31:54 +01:00
ac951b2afa update toxcore, includes ngc mem savings
Some checks failed
ContinuousDelivery / linux-ubuntu (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Has been cancelled
ContinuousDelivery / windows (push) Has been cancelled
ContinuousDelivery / windows-asan (push) Has been cancelled
ContinuousIntegration / linux (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Has been cancelled
ContinuousIntegration / macos (push) Has been cancelled
ContinuousIntegration / windows (push) Has been cancelled
ContinuousDelivery / release (push) Has been cancelled
Merge commit '261d2e53b7a513de7eb35e022fe3b2ae4efa835f'
2024-12-19 16:27:50 +01:00
261d2e53b7 Squashed 'external/toxcore/c-toxcore/' changes from 55752a2e2ef..11ab1d2a723
11ab1d2a723 fix: reduce memory usage in group chats by 75% Significantly reduced the memory usage of groups since all message slots are preallocated for every peer for send and receive buffers of buffer size (hundreds of MiB peak when save contained alot of peers to try to connect to)
4f09f4e147c chore: Fix tsan build by moving it to GitHub CI.
6460c25c9e0 refactor: Use `merge_sort` instead of `qsort` for sorting.
c660bbe8c95 test: Fix crypto_test to initialise its plain text buffer.
0204db6184b cleanup: Fix layering check warnings.
df2211e1548 refactor: Use tox memory allocator for temporary buffers in crypto.
ac812871a2e feat: implement the last 2 missing network struct functions and make use of them
29d1043be0b test: friend request test now tests min/max message sizes
93aafd78c1f fix: friend requests with very long messages are no longer dropped
819aa2b2618 feat: Add option to disable DNS lookups in toxcore.
0ac23cee035 fix: windows use of REUSEADDR
7d2811d302d chore(ci): make bazel server shutdown faster
1dc399ba20d chore: Use vcpkg instead of conan in the MSVC build.
14d823165d9 chore: Migrate to conan 2.
bdd17c16787 cleanup: Allocate logger using tox memory allocator.
b396c061515 chore(deps): bump third_party/cmp from `2ac6bca` to `52bfcfa`
2e94da60d09 feat(net): add missing connect to network struct
41fb1839c7b chore: Add check to ensure version numbers agree.
934a8301113 chore: Release 0.2.20
3acef4bf044 fix: Add missing free in dht_get_nodes_response event.

git-subtree-dir: external/toxcore/c-toxcore
git-subtree-split: 11ab1d2a7232eee19b51ce126ccce267d6578903
2024-12-19 16:27:40 +01:00
d71ebb79aa asan cmake and frame pointer 2024-12-19 16:26:40 +01:00
bb510b685a fix some crashes (how) and bitset wierdness
Some checks are pending
ContinuousDelivery / linux-ubuntu (push) Waiting to run
ContinuousDelivery / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Waiting to run
ContinuousDelivery / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Waiting to run
ContinuousDelivery / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Waiting to run
ContinuousDelivery / windows (push) Waiting to run
ContinuousDelivery / windows-asan (push) Waiting to run
ContinuousDelivery / release (push) Blocked by required conditions
ContinuousIntegration / linux (push) Waiting to run
ContinuousIntegration / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Waiting to run
ContinuousIntegration / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Waiting to run
ContinuousIntegration / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Waiting to run
ContinuousIntegration / macos (push) Waiting to run
ContinuousIntegration / windows (push) Waiting to run
2024-12-18 21:39:50 +01:00
876f482391 fix sdl image loder io leak and send image popup fixes
Some checks are pending
ContinuousDelivery / linux-ubuntu (push) Waiting to run
ContinuousDelivery / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Waiting to run
ContinuousDelivery / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Waiting to run
ContinuousDelivery / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Waiting to run
ContinuousDelivery / windows (push) Waiting to run
ContinuousDelivery / windows-asan (push) Waiting to run
ContinuousDelivery / release (push) Blocked by required conditions
ContinuousIntegration / linux (push) Waiting to run
ContinuousIntegration / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Waiting to run
ContinuousIntegration / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Waiting to run
ContinuousIntegration / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Waiting to run
ContinuousIntegration / macos (push) Waiting to run
ContinuousIntegration / windows (push) Waiting to run
2024-12-18 21:12:20 +01:00
42dd6d16d7 fix reading char from empty line
Some checks are pending
ContinuousDelivery / linux-ubuntu (push) Waiting to run
ContinuousDelivery / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Waiting to run
ContinuousDelivery / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Waiting to run
ContinuousDelivery / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Waiting to run
ContinuousDelivery / windows (push) Waiting to run
ContinuousDelivery / windows-asan (push) Waiting to run
ContinuousDelivery / release (push) Blocked by required conditions
ContinuousIntegration / linux (push) Waiting to run
ContinuousIntegration / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Waiting to run
ContinuousIntegration / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Waiting to run
ContinuousIntegration / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Waiting to run
ContinuousIntegration / macos (push) Waiting to run
ContinuousIntegration / windows (push) Waiting to run
2024-12-18 16:21:11 +01:00
11ae259f67 texture cache refactor to later allow async loading
Some checks failed
ContinuousDelivery / linux-ubuntu (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Has been cancelled
ContinuousDelivery / windows (push) Has been cancelled
ContinuousDelivery / windows-asan (push) Has been cancelled
ContinuousIntegration / linux (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Has been cancelled
ContinuousIntegration / macos (push) Has been cancelled
ContinuousIntegration / windows (push) Has been cancelled
ContinuousDelivery / release (push) Has been cancelled
2024-12-16 00:32:07 +01:00
f2027befc8 fix bitset getting rendered all the time
Some checks are pending
ContinuousDelivery / linux-ubuntu (push) Waiting to run
ContinuousDelivery / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Waiting to run
ContinuousDelivery / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Waiting to run
ContinuousDelivery / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Waiting to run
ContinuousDelivery / windows (push) Waiting to run
ContinuousDelivery / windows-asan (push) Waiting to run
ContinuousDelivery / release (push) Blocked by required conditions
ContinuousIntegration / linux (push) Waiting to run
ContinuousIntegration / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Waiting to run
ContinuousIntegration / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Waiting to run
ContinuousIntegration / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Waiting to run
ContinuousIntegration / macos (push) Waiting to run
ContinuousIntegration / windows (push) Waiting to run
2024-12-15 22:01:53 +01:00
9777cb81cb remote (combined) bitset have
Some checks are pending
ContinuousDelivery / linux-ubuntu (push) Waiting to run
ContinuousDelivery / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Waiting to run
ContinuousDelivery / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Waiting to run
ContinuousDelivery / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Waiting to run
ContinuousDelivery / windows (push) Waiting to run
ContinuousDelivery / windows-asan (push) Waiting to run
ContinuousDelivery / release (push) Blocked by required conditions
ContinuousIntegration / linux (push) Waiting to run
ContinuousIntegration / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Waiting to run
ContinuousIntegration / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Waiting to run
ContinuousIntegration / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Waiting to run
ContinuousIntegration / macos (push) Waiting to run
ContinuousIntegration / windows (push) Waiting to run
2024-12-14 23:47:04 +01:00
84ade4d683 local have bitset rendering
Some checks failed
ContinuousDelivery / linux-ubuntu (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Has been cancelled
ContinuousDelivery / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Has been cancelled
ContinuousDelivery / windows (push) Has been cancelled
ContinuousDelivery / windows-asan (push) Has been cancelled
ContinuousIntegration / linux (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Has been cancelled
ContinuousIntegration / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Has been cancelled
ContinuousIntegration / macos (push) Has been cancelled
ContinuousIntegration / windows (push) Has been cancelled
ContinuousDelivery / release (push) Has been cancelled
2024-12-13 00:53:48 +01:00
f89aeae62b indicate have all on ft
Some checks are pending
ContinuousDelivery / linux-ubuntu (push) Waiting to run
ContinuousDelivery / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Waiting to run
ContinuousDelivery / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Waiting to run
ContinuousDelivery / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Waiting to run
ContinuousDelivery / windows (push) Waiting to run
ContinuousDelivery / windows-asan (push) Waiting to run
ContinuousDelivery / release (push) Blocked by required conditions
ContinuousIntegration / linux (push) Waiting to run
ContinuousIntegration / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Waiting to run
ContinuousIntegration / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Waiting to run
ContinuousIntegration / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Waiting to run
ContinuousIntegration / macos (push) Waiting to run
ContinuousIntegration / windows (push) Waiting to run
2024-12-12 15:36:16 +01:00
96 changed files with 1798 additions and 2063 deletions

View File

@ -27,9 +27,18 @@ option(TOMATO_TOX_AV "Build tomato with ToxAV" OFF)
if (TOMATO_ASAN)
if (${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU" OR ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang")
if (NOT WIN32) # exclude mingw
#link_libraries(-fsanitize=address)
link_libraries(-fsanitize=address,undefined)
#link_libraries(-fsanitize=undefined)
add_compile_options(-fno-omit-frame-pointer)
add_compile_options(-fsanitize=address,undefined)
#add_compile_options(-fsanitize=address,undefined,pointer-compare,pointer-subtract)
#add_compile_options(-fhardened)
#add_compile_options(-D_FORTIFY_SOURCE=3 -D_GLIBCXX_ASSERTIONS -ftrivial-auto-var-init=zero -fPIE -pie -Wl,-z,relro,-z,now -fstack-protector-strong -fstack-clash-protection -fcf-protection=full)
add_link_options(-fno-omit-frame-pointer)
add_link_options(-fsanitize=address,undefined)
#add_link_options(-fsanitize=address,undefined,pointer-compare,pointer-subtract)
#add_link_options(-fhardened)
#add_link_options(-D_FORTIFY_SOURCE=3 -D_GLIBCXX_ASSERTIONS -ftrivial-auto-var-init=zero -fPIE -pie -Wl,-z,relro,-z,now -fstack-protector-strong -fstack-clash-protection -fcf-protection=full)
link_libraries(-static-libasan) # make it "work" on nix
message("II enabled ASAN")
else()

View File

@ -3,21 +3,15 @@ version: 2
workflows:
version: 2
program-analysis:
# TODO(iphydf): Re-enable tsan when it's fixed.
circleci:
jobs:
# Dynamic analysis in the Bazel build
- bazel-asan
- bazel-msan
# - bazel-tsan
# Dynamic analysis with CMake
- asan
# - tsan
- ubsan
# Static analysis
- clang-analyze
- cpplint
- static-analysis
- cimplefmt
- generate-events
jobs:
bazel-asan:
@ -30,20 +24,6 @@ jobs:
- run: .circleci/bazel-test
//c-toxcore/...
bazel-tsan:
working_directory: /tmp/cirrus-ci-build
docker:
- image: toxchat/toktok-stack:latest-tsan
steps:
- checkout
- run: .circleci/bazel-test
//c-toxcore/...
-//c-toxcore/auto_tests:conference_av_test
-//c-toxcore/auto_tests:conference_test
-//c-toxcore/auto_tests:onion_test
-//c-toxcore/auto_tests:tox_many_test
bazel-msan:
working_directory: /tmp/cirrus-ci-build
docker:
@ -54,7 +34,7 @@ jobs:
- run: .circleci/bazel-test
//c-toxcore/auto_tests:lossless_packet_test
asan:
static-analysis:
working_directory: ~/work
docker:
- image: ubuntu
@ -68,6 +48,7 @@ jobs:
clang
cmake
git
libbenchmark-dev
libconfig-dev
libgmock-dev
libgtest-dev
@ -77,39 +58,6 @@ jobs:
llvm-dev
ninja-build
pkg-config
- checkout
- run: git submodule update --init --recursive
- run: CC=clang .circleci/cmake-asan
tsan:
working_directory: ~/work
docker:
- image: ubuntu
steps:
- run: *apt_install
- checkout
- run: git submodule update --init --recursive
- run: CC=clang .circleci/cmake-tsan
ubsan:
working_directory: ~/work
docker:
- image: ubuntu
steps:
- run: *apt_install
- checkout
- run: git submodule update --init --recursive
- run: CC=clang .circleci/cmake-ubsan
static-analysis:
working_directory: ~/work
docker:
- image: ubuntu
steps:
- run: *apt_install
- run:
apt-get install -y --no-install-recommends
ca-certificates
@ -146,3 +94,22 @@ jobs:
- checkout
- run: git submodule update --init --recursive
- run: other/analysis/run-cpplint
cimplefmt:
working_directory: ~/work
machine: { image: ubuntu-2204:current }
steps:
- checkout
- run: git submodule update --init --recursive
- run: other/docker/cimplefmt/run -u $(find tox* -name "*.[ch]")
generate-events:
working_directory: ~/work
machine: { image: ubuntu-2204:current }
steps:
- checkout
- run: git submodule update --init --recursive
- run: other/event_tooling/run
- run: git diff --exit-code

View File

@ -18,7 +18,7 @@ jobs:
fail-fast: false
matrix:
tool: [autotools, clang-tidy, compcert, cppcheck, doxygen, goblint, infer, freebsd, misra, modules, pkgsrc, rpm, slimcc, sparse, tcc, tokstyle]
runs-on: ubuntu-latest
runs-on: ubuntu-22.04
steps:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
@ -34,8 +34,25 @@ jobs:
with:
file: other/docker/${{ matrix.tool }}/${{ matrix.tool }}.Dockerfile
sanitizer:
strategy:
fail-fast: false
matrix:
sanitizer: [asan, tsan, ubsan]
runs-on: ubuntu-22.04
steps:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
driver: docker
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Run sanitizer
run: other/docker/circleci/run "${{ matrix.sanitizer }}"
coverage-linux:
runs-on: ubuntu-latest
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
with:
@ -43,28 +60,8 @@ jobs:
- name: Build, test, and upload coverage
run: other/docker/coverage/run
generate-events:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Run generate_event_c
run: |
other/event_tooling/run
git diff --exit-code
cimplefmt:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Run cimplefmt
run: other/docker/cimplefmt/run -u $(find tox* -name "*.[ch]")
build-android:
runs-on: ubuntu-latest
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
with:
@ -111,7 +108,7 @@ jobs:
ctest -j50 --output-on-failure --rerun-failed --repeat until-pass:6 --build-config Debug
build-netbsd:
runs-on: ubuntu-latest
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
with:
@ -146,7 +143,7 @@ jobs:
ctest -j50 --output-on-failure --rerun-failed --repeat until-pass:6
build-freebsd:
runs-on: ubuntu-latest
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
with:
@ -183,7 +180,7 @@ jobs:
ctest -j50 --output-on-failure --rerun-failed --repeat until-pass:6
mypy:
runs-on: ubuntu-latest
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
with:

View File

@ -36,7 +36,6 @@ testing/data
# Vim
*.swp
*.nvimlog
# Object files
*.o

View File

@ -309,8 +309,6 @@ set(toxcore_SOURCES
toxcore/mono_time.h
toxcore/net_crypto.c
toxcore/net_crypto.h
toxcore/net_profile.c
toxcore/net_profile.h
toxcore/network.c
toxcore/network.h
toxcore/onion_announce.c
@ -325,6 +323,8 @@ set(toxcore_SOURCES
toxcore/ping.h
toxcore/shared_key_cache.c
toxcore/shared_key_cache.h
toxcore/sort.c
toxcore/sort.h
toxcore/state.c
toxcore/state.h
toxcore/TCP_client.c

View File

@ -78,6 +78,7 @@ extra_data = {
"//c-toxcore/toxcore:tox",
"//c-toxcore/toxcore:tox_dispatch",
"//c-toxcore/toxcore:tox_events",
"//c-toxcore/toxcore:tox_unpack",
"//c-toxcore/toxcore:util",
"//c-toxcore/toxencryptsave",
"@libsodium",

View File

@ -71,7 +71,6 @@ auto_test(invalid_udp_proxy)
auto_test(lan_discovery)
auto_test(lossless_packet)
auto_test(lossy_packet)
auto_test(netprof)
auto_test(network)
auto_test(onion)
auto_test(overflow_recvq)

View File

@ -102,7 +102,7 @@ static void test_basic(void)
random_nonce(rng, handshake + CRYPTO_PUBLIC_KEY_SIZE);
// Encrypting handshake
int ret = encrypt_data(self_public_key, f_secret_key, handshake + CRYPTO_PUBLIC_KEY_SIZE, handshake_plain,
int ret = encrypt_data(mem, self_public_key, f_secret_key, handshake + CRYPTO_PUBLIC_KEY_SIZE, handshake_plain,
TCP_HANDSHAKE_PLAIN_SIZE, handshake + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE);
ck_assert_msg(ret == TCP_CLIENT_HANDSHAKE_SIZE - (CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE),
"encrypt_data() call failed.");
@ -111,12 +111,12 @@ static void test_basic(void)
// Sending the handshake
ck_assert_msg(net_send(ns, logger, sock, handshake, TCP_CLIENT_HANDSHAKE_SIZE - 1,
&localhost, nullptr) == TCP_CLIENT_HANDSHAKE_SIZE - 1,
&localhost) == TCP_CLIENT_HANDSHAKE_SIZE - 1,
"An attempt to send the initial handshake minus last byte failed.");
do_tcp_server_delay(tcp_s, mono_time, 50);
ck_assert_msg(net_send(ns, logger, sock, handshake + (TCP_CLIENT_HANDSHAKE_SIZE - 1), 1, &localhost, nullptr) == 1,
ck_assert_msg(net_send(ns, logger, sock, handshake + (TCP_CLIENT_HANDSHAKE_SIZE - 1), 1, &localhost) == 1,
"The attempt to send the last byte of handshake failed.");
free(handshake);
@ -128,7 +128,7 @@ static void test_basic(void)
uint8_t response_plain[TCP_HANDSHAKE_PLAIN_SIZE];
ck_assert_msg(net_recv(ns, logger, sock, response, TCP_SERVER_HANDSHAKE_SIZE, &localhost) == TCP_SERVER_HANDSHAKE_SIZE,
"Could/did not receive a server response to the initial handshake.");
ret = decrypt_data(self_public_key, f_secret_key, response, response + CRYPTO_NONCE_SIZE,
ret = decrypt_data(mem, self_public_key, f_secret_key, response, response + CRYPTO_NONCE_SIZE,
TCP_SERVER_HANDSHAKE_SIZE - CRYPTO_NONCE_SIZE, response_plain);
ck_assert_msg(ret == TCP_HANDSHAKE_PLAIN_SIZE, "Failed to decrypt handshake response.");
uint8_t f_nonce_r[CRYPTO_NONCE_SIZE];
@ -143,7 +143,7 @@ static void test_basic(void)
uint8_t r_req[2 + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE];
uint16_t size = 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE;
size = net_htons(size);
encrypt_data_symmetric(f_shared_key, f_nonce, r_req_p, 1 + CRYPTO_PUBLIC_KEY_SIZE, r_req + 2);
encrypt_data_symmetric(mem, f_shared_key, f_nonce, r_req_p, 1 + CRYPTO_PUBLIC_KEY_SIZE, r_req + 2);
increment_nonce(f_nonce);
memcpy(r_req, &size, 2);
@ -155,7 +155,7 @@ static void test_basic(void)
msg_length = sizeof(r_req) - i;
}
ck_assert_msg(net_send(ns, logger, sock, r_req + i, msg_length, &localhost, nullptr) == msg_length,
ck_assert_msg(net_send(ns, logger, sock, r_req + i, msg_length, &localhost) == msg_length,
"Failed to send request after completing the handshake.");
i += msg_length;
@ -174,7 +174,7 @@ static void test_basic(void)
"Wrong packet size for request response.");
uint8_t packet_resp_plain[4096];
ret = decrypt_data_symmetric(f_shared_key, f_nonce_r, packet_resp + 2, recv_data_len - 2, packet_resp_plain);
ret = decrypt_data_symmetric(mem, f_shared_key, f_nonce_r, packet_resp + 2, recv_data_len - 2, packet_resp_plain);
ck_assert_msg(ret != -1, "Failed to decrypt the TCP server's response.");
increment_nonce(f_nonce_r);
@ -228,18 +228,18 @@ static struct sec_TCP_con *new_tcp_con(const Logger *logger, const Memory *mem,
memcpy(handshake, sec_c->public_key, CRYPTO_PUBLIC_KEY_SIZE);
random_nonce(rng, handshake + CRYPTO_PUBLIC_KEY_SIZE);
int ret = encrypt_data(tcp_server_public_key(tcp_s), f_secret_key, handshake + CRYPTO_PUBLIC_KEY_SIZE, handshake_plain,
int ret = encrypt_data(mem, tcp_server_public_key(tcp_s), f_secret_key, handshake + CRYPTO_PUBLIC_KEY_SIZE, handshake_plain,
TCP_HANDSHAKE_PLAIN_SIZE, handshake + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE);
ck_assert_msg(ret == TCP_CLIENT_HANDSHAKE_SIZE - (CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE),
"Failed to encrypt the outgoing handshake.");
ck_assert_msg(net_send(ns, logger, sock, handshake, TCP_CLIENT_HANDSHAKE_SIZE - 1,
&localhost, nullptr) == TCP_CLIENT_HANDSHAKE_SIZE - 1,
&localhost) == TCP_CLIENT_HANDSHAKE_SIZE - 1,
"Failed to send the first portion of the handshake to the TCP relay server.");
do_tcp_server_delay(tcp_s, mono_time, 50);
ck_assert_msg(net_send(ns, logger, sock, handshake + (TCP_CLIENT_HANDSHAKE_SIZE - 1), 1, &localhost, nullptr) == 1,
ck_assert_msg(net_send(ns, logger, sock, handshake + (TCP_CLIENT_HANDSHAKE_SIZE - 1), 1, &localhost) == 1,
"Failed to send last byte of handshake.");
do_tcp_server_delay(tcp_s, mono_time, 50);
@ -248,7 +248,7 @@ static struct sec_TCP_con *new_tcp_con(const Logger *logger, const Memory *mem,
uint8_t response_plain[TCP_HANDSHAKE_PLAIN_SIZE];
ck_assert_msg(net_recv(sec_c->ns, logger, sock, response, TCP_SERVER_HANDSHAKE_SIZE, &localhost) == TCP_SERVER_HANDSHAKE_SIZE,
"Failed to receive server handshake response.");
ret = decrypt_data(tcp_server_public_key(tcp_s), f_secret_key, response, response + CRYPTO_NONCE_SIZE,
ret = decrypt_data(mem, tcp_server_public_key(tcp_s), f_secret_key, response, response + CRYPTO_NONCE_SIZE,
TCP_SERVER_HANDSHAKE_SIZE - CRYPTO_NONCE_SIZE, response_plain);
ck_assert_msg(ret == TCP_HANDSHAKE_PLAIN_SIZE, "Failed to decrypt server handshake response.");
encrypt_precompute(response_plain, t_secret_key, sec_c->shared_key);
@ -271,7 +271,7 @@ static int write_packet_tcp_test_connection(const Logger *logger, struct sec_TCP
uint16_t c_length = net_htons(length + CRYPTO_MAC_SIZE);
memcpy(packet, &c_length, sizeof(uint16_t));
int len = encrypt_data_symmetric(con->shared_key, con->sent_nonce, data, length, packet + sizeof(uint16_t));
int len = encrypt_data_symmetric(con->mem, con->shared_key, con->sent_nonce, data, length, packet + sizeof(uint16_t));
if ((unsigned int)len != (packet_size - sizeof(uint16_t))) {
return -1;
@ -283,7 +283,7 @@ static int write_packet_tcp_test_connection(const Logger *logger, struct sec_TCP
localhost.ip = get_loopback();
localhost.port = 0;
ck_assert_msg(net_send(con->ns, logger, con->sock, packet, packet_size, &localhost, nullptr) == packet_size,
ck_assert_msg(net_send(con->ns, logger, con->sock, packet, packet_size, &localhost) == packet_size,
"Failed to send a packet.");
return 0;
}
@ -296,7 +296,7 @@ static int read_packet_sec_tcp(const Logger *logger, struct sec_TCP_con *con, ui
int rlen = net_recv(con->ns, logger, con->sock, data, length, &localhost);
ck_assert_msg(rlen == length, "Did not receive packet of correct length. Wanted %i, instead got %i", length, rlen);
rlen = decrypt_data_symmetric(con->shared_key, con->recv_nonce, data + 2, length - 2, data);
rlen = decrypt_data_symmetric(con->mem, con->shared_key, con->recv_nonce, data + 2, length - 2, data);
ck_assert_msg(rlen != -1, "Failed to decrypt a received packet from the Relay server.");
increment_nonce(con->recv_nonce);
return rlen;
@ -524,7 +524,7 @@ static void test_client(void)
ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]);
ip_port_tcp_s.ip = get_loopback();
TCP_Client_Connection *conn = new_tcp_connection(logger, mem, mono_time, rng, ns, &ip_port_tcp_s, self_public_key, f_public_key, f_secret_key, nullptr, nullptr);
TCP_Client_Connection *conn = new_tcp_connection(logger, mem, mono_time, rng, ns, &ip_port_tcp_s, self_public_key, f_public_key, f_secret_key, nullptr);
// TCP sockets might need a moment before they can be written to.
c_sleep(50);
do_tcp_connection(logger, mono_time, conn, nullptr);
@ -560,7 +560,7 @@ static void test_client(void)
crypto_new_keypair(rng, f2_public_key, f2_secret_key);
ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]);
TCP_Client_Connection *conn2 = new_tcp_connection(logger, mem, mono_time, rng, ns, &ip_port_tcp_s, self_public_key, f2_public_key,
f2_secret_key, nullptr, nullptr);
f2_secret_key, nullptr);
c_sleep(50);
// The client should call this function (defined earlier) during the routing process.
@ -657,7 +657,7 @@ static void test_client_invalid(void)
ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]);
ip_port_tcp_s.ip = get_loopback();
TCP_Client_Connection *conn = new_tcp_connection(logger, mem, mono_time, rng, ns, &ip_port_tcp_s,
self_public_key, f_public_key, f_secret_key, nullptr, nullptr);
self_public_key, f_public_key, f_secret_key, nullptr);
// Run the client's main loop but not the server.
mono_time_update(mono_time);

View File

@ -80,6 +80,9 @@ static const uint8_t test_c[147] = {
static void test_known(void)
{
const Memory *mem = os_memory();
ck_assert(mem != nullptr);
uint8_t c[147];
uint8_t m[131];
@ -88,12 +91,12 @@ static void test_known(void)
ck_assert_msg(sizeof(test_c) == sizeof(c), "sanity check failed");
ck_assert_msg(sizeof(test_m) == sizeof(m), "sanity check failed");
const uint16_t clen = encrypt_data(bobpk, alicesk, test_nonce, test_m, sizeof(test_m) / sizeof(uint8_t), c);
const uint16_t clen = encrypt_data(mem, bobpk, alicesk, test_nonce, test_m, sizeof(test_m) / sizeof(uint8_t), c);
ck_assert_msg(memcmp(test_c, c, sizeof(c)) == 0, "cyphertext doesn't match test vector");
ck_assert_msg(clen == sizeof(c) / sizeof(uint8_t), "wrong ciphertext length");
const uint16_t mlen = decrypt_data(bobpk, alicesk, test_nonce, test_c, sizeof(test_c) / sizeof(uint8_t), m);
const uint16_t mlen = decrypt_data(mem, bobpk, alicesk, test_nonce, test_c, sizeof(test_c) / sizeof(uint8_t), m);
ck_assert_msg(memcmp(test_m, m, sizeof(m)) == 0, "decrypted text doesn't match test vector");
ck_assert_msg(mlen == sizeof(m) / sizeof(uint8_t), "wrong plaintext length");
@ -101,6 +104,9 @@ static void test_known(void)
static void test_fast_known(void)
{
const Memory *mem = os_memory();
ck_assert(mem != nullptr);
uint8_t k[CRYPTO_SHARED_KEY_SIZE];
uint8_t c[147];
uint8_t m[131];
@ -112,12 +118,12 @@ static void test_fast_known(void)
ck_assert_msg(sizeof(test_c) == sizeof(c), "sanity check failed");
ck_assert_msg(sizeof(test_m) == sizeof(m), "sanity check failed");
const uint16_t clen = encrypt_data_symmetric(k, test_nonce, test_m, sizeof(test_m) / sizeof(uint8_t), c);
const uint16_t clen = encrypt_data_symmetric(mem, k, test_nonce, test_m, sizeof(test_m) / sizeof(uint8_t), c);
ck_assert_msg(memcmp(test_c, c, sizeof(c)) == 0, "cyphertext doesn't match test vector");
ck_assert_msg(clen == sizeof(c) / sizeof(uint8_t), "wrong ciphertext length");
const uint16_t mlen = decrypt_data_symmetric(k, test_nonce, test_c, sizeof(test_c) / sizeof(uint8_t), m);
const uint16_t mlen = decrypt_data_symmetric(mem, k, test_nonce, test_c, sizeof(test_c) / sizeof(uint8_t), m);
ck_assert_msg(memcmp(test_m, m, sizeof(m)) == 0, "decrypted text doesn't match test vector");
ck_assert_msg(mlen == sizeof(m) / sizeof(uint8_t), "wrong plaintext length");
@ -125,6 +131,8 @@ static void test_fast_known(void)
static void test_endtoend(void)
{
const Memory *mem = os_memory();
ck_assert(mem != nullptr);
const Random *rng = os_random();
ck_assert(rng != nullptr);
@ -166,10 +174,10 @@ static void test_endtoend(void)
ck_assert_msg(memcmp(k1, k2, CRYPTO_SHARED_KEY_SIZE) == 0, "encrypt_precompute: bad");
//Encrypt all four ways
const uint16_t c1len = encrypt_data(pk2, sk1, n, m, mlen, c1);
const uint16_t c2len = encrypt_data(pk1, sk2, n, m, mlen, c2);
const uint16_t c3len = encrypt_data_symmetric(k1, n, m, mlen, c3);
const uint16_t c4len = encrypt_data_symmetric(k2, n, m, mlen, c4);
const uint16_t c1len = encrypt_data(mem, pk2, sk1, n, m, mlen, c1);
const uint16_t c2len = encrypt_data(mem, pk1, sk2, n, m, mlen, c2);
const uint16_t c3len = encrypt_data_symmetric(mem, k1, n, m, mlen, c3);
const uint16_t c4len = encrypt_data_symmetric(mem, k2, n, m, mlen, c4);
ck_assert_msg(c1len == c2len && c1len == c3len && c1len == c4len, "cyphertext lengths differ");
ck_assert_msg(c1len == mlen + (uint16_t)CRYPTO_MAC_SIZE, "wrong cyphertext length");
@ -177,10 +185,10 @@ static void test_endtoend(void)
&& memcmp(c1, c4, c1len) == 0, "crypertexts differ");
//Decrypt all four ways
const uint16_t m1len = decrypt_data(pk2, sk1, n, c1, c1len, m1);
const uint16_t m2len = decrypt_data(pk1, sk2, n, c1, c1len, m2);
const uint16_t m3len = decrypt_data_symmetric(k1, n, c1, c1len, m3);
const uint16_t m4len = decrypt_data_symmetric(k2, n, c1, c1len, m4);
const uint16_t m1len = decrypt_data(mem, pk2, sk1, n, c1, c1len, m1);
const uint16_t m2len = decrypt_data(mem, pk1, sk2, n, c1, c1len, m2);
const uint16_t m3len = decrypt_data_symmetric(mem, k1, n, c1, c1len, m3);
const uint16_t m4len = decrypt_data_symmetric(mem, k2, n, c1, c1len, m4);
ck_assert_msg(m1len == m2len && m1len == m3len && m1len == m4len, "decrypted text lengths differ");
ck_assert_msg(m1len == mlen, "wrong decrypted text length");
@ -192,6 +200,8 @@ static void test_endtoend(void)
static void test_large_data(void)
{
const Memory *mem = os_memory();
ck_assert(mem != nullptr);
const Random *rng = os_random();
ck_assert(rng != nullptr);
uint8_t k[CRYPTO_SHARED_KEY_SIZE];
@ -216,13 +226,13 @@ static void test_large_data(void)
//Generate key
rand_bytes(rng, k, CRYPTO_SHARED_KEY_SIZE);
const uint16_t c1len = encrypt_data_symmetric(k, n, m1, m1_size, c1);
const uint16_t c2len = encrypt_data_symmetric(k, n, m2, m2_size, c2);
const uint16_t c1len = encrypt_data_symmetric(mem, k, n, m1, m1_size, c1);
const uint16_t c2len = encrypt_data_symmetric(mem, k, n, m2, m2_size, c2);
ck_assert_msg(c1len == m1_size + CRYPTO_MAC_SIZE, "could not encrypt");
ck_assert_msg(c2len == m2_size + CRYPTO_MAC_SIZE, "could not encrypt");
const uint16_t m1plen = decrypt_data_symmetric(k, n, c1, c1len, m1prime);
const uint16_t m1plen = decrypt_data_symmetric(mem, k, n, c1, c1len, m1prime);
ck_assert_msg(m1plen == m1_size, "decrypted text lengths differ");
ck_assert_msg(memcmp(m1prime, m1, m1_size) == 0, "decrypted texts differ");
@ -236,6 +246,8 @@ static void test_large_data(void)
static void test_large_data_symmetric(void)
{
const Memory *mem = os_memory();
ck_assert(mem != nullptr);
const Random *rng = os_random();
ck_assert(rng != nullptr);
uint8_t k[CRYPTO_SYMMETRIC_KEY_SIZE];
@ -256,10 +268,10 @@ static void test_large_data_symmetric(void)
//Generate key
new_symmetric_key(rng, k);
const uint16_t c1len = encrypt_data_symmetric(k, n, m1, m1_size, c1);
const uint16_t c1len = encrypt_data_symmetric(mem, k, n, m1, m1_size, c1);
ck_assert_msg(c1len == m1_size + CRYPTO_MAC_SIZE, "could not encrypt data");
const uint16_t m1plen = decrypt_data_symmetric(k, n, c1, c1len, m1prime);
const uint16_t m1plen = decrypt_data_symmetric(mem, k, n, c1, c1len, m1prime);
ck_assert_msg(m1plen == m1_size, "decrypted text lengths differ");
ck_assert_msg(memcmp(m1prime, m1, m1_size) == 0, "decrypted texts differ");
@ -271,6 +283,8 @@ static void test_large_data_symmetric(void)
static void test_very_large_data(void)
{
const Memory *mem = os_memory();
ck_assert(mem != nullptr);
const Random *rng = os_random();
ck_assert(rng != nullptr);
@ -287,7 +301,9 @@ static void test_very_large_data(void)
ck_assert(plain != nullptr);
ck_assert(encrypted != nullptr);
encrypt_data(pk, sk, nonce, plain, plain_size, encrypted);
memset(plain, 0, plain_size);
encrypt_data(mem, pk, sk, nonce, plain, plain_size, encrypted);
free(encrypted);
free(plain);

View File

@ -1,121 +0,0 @@
/** Auto Tests: basic network profile functionality test (UDP only)
* TODO(JFreegman): test TCP packets as well
*/
#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
#include "../toxcore/tox_private.h"
#include "../toxcore/util.h"
#include "auto_test_support.h"
#include "check_compat.h"
#define NUM_TOXES 2
static void test_netprof(AutoTox *autotoxes)
{
// Send some messages to create fake traffic
for (size_t i = 0; i < 256; ++i) {
for (uint32_t j = 0; j < NUM_TOXES; ++j) {
tox_friend_send_message(autotoxes[j].tox, 0, TOX_MESSAGE_TYPE_NORMAL, (const uint8_t *)"test", 4, nullptr);
}
iterate_all_wait(autotoxes, NUM_TOXES, ITERATION_INTERVAL);
}
// idle traffic for a while
for (size_t i = 0; i < 100; ++i) {
iterate_all_wait(autotoxes, NUM_TOXES, ITERATION_INTERVAL);
}
const Tox *tox1 = autotoxes[0].tox;
const uint64_t UDP_count_sent1 = tox_netprof_get_packet_total_count(tox1, TOX_NETPROF_PACKET_TYPE_UDP,
TOX_NETPROF_DIRECTION_SENT);
const uint64_t UDP_count_recv1 = tox_netprof_get_packet_total_count(tox1, TOX_NETPROF_PACKET_TYPE_UDP,
TOX_NETPROF_DIRECTION_RECV);
const uint64_t TCP_count_sent1 = tox_netprof_get_packet_total_count(tox1, TOX_NETPROF_PACKET_TYPE_TCP,
TOX_NETPROF_DIRECTION_SENT);
const uint64_t TCP_count_recv1 = tox_netprof_get_packet_total_count(tox1, TOX_NETPROF_PACKET_TYPE_TCP,
TOX_NETPROF_DIRECTION_RECV);
const uint64_t UDP_bytes_sent1 = tox_netprof_get_packet_total_bytes(tox1, TOX_NETPROF_PACKET_TYPE_UDP,
TOX_NETPROF_DIRECTION_SENT);
const uint64_t UDP_bytes_recv1 = tox_netprof_get_packet_total_bytes(tox1, TOX_NETPROF_PACKET_TYPE_UDP,
TOX_NETPROF_DIRECTION_RECV);
const uint64_t TCP_bytes_sent1 = tox_netprof_get_packet_total_bytes(tox1, TOX_NETPROF_PACKET_TYPE_TCP,
TOX_NETPROF_DIRECTION_SENT);
const uint64_t TCP_bytes_recv1 = tox_netprof_get_packet_total_bytes(tox1, TOX_NETPROF_PACKET_TYPE_TCP,
TOX_NETPROF_DIRECTION_RECV);
ck_assert(UDP_count_recv1 > 0 && UDP_count_sent1 > 0);
ck_assert(UDP_bytes_recv1 > 0 && UDP_bytes_sent1 > 0);
(void)TCP_count_sent1;
(void)TCP_bytes_sent1;
(void)TCP_bytes_recv1;
(void)TCP_count_recv1;
uint64_t total_sent_count = 0;
uint64_t total_recv_count = 0;
uint64_t total_sent_bytes = 0;
uint64_t total_recv_bytes = 0;
// tox1 makes sure the sum value of all packet ID's is equal to the totals
for (size_t i = 0; i < 256; ++i) {
// this id isn't valid for UDP packets but we still want to call the
// functions and make sure they return some non-zero value
if (i == TOX_NETPROF_PACKET_ID_TCP_DATA) {
ck_assert(tox_netprof_get_packet_id_count(tox1, TOX_NETPROF_PACKET_TYPE_UDP, i,
TOX_NETPROF_DIRECTION_SENT) > 0);
ck_assert(tox_netprof_get_packet_id_bytes(tox1, TOX_NETPROF_PACKET_TYPE_UDP, i,
TOX_NETPROF_DIRECTION_SENT) > 0);
ck_assert(tox_netprof_get_packet_id_bytes(tox1, TOX_NETPROF_PACKET_TYPE_UDP, i,
TOX_NETPROF_DIRECTION_SENT) > 0);
ck_assert(tox_netprof_get_packet_id_bytes(tox1, TOX_NETPROF_PACKET_TYPE_UDP, i,
TOX_NETPROF_DIRECTION_RECV) > 0);
continue;
}
total_sent_count += tox_netprof_get_packet_id_count(tox1, TOX_NETPROF_PACKET_TYPE_UDP, i,
TOX_NETPROF_DIRECTION_SENT);
total_recv_count += tox_netprof_get_packet_id_count(tox1, TOX_NETPROF_PACKET_TYPE_UDP, i,
TOX_NETPROF_DIRECTION_RECV);
total_sent_bytes += tox_netprof_get_packet_id_bytes(tox1, TOX_NETPROF_PACKET_TYPE_UDP, i,
TOX_NETPROF_DIRECTION_SENT);
total_recv_bytes += tox_netprof_get_packet_id_bytes(tox1, TOX_NETPROF_PACKET_TYPE_UDP, i,
TOX_NETPROF_DIRECTION_RECV);
}
const uint64_t total_packets = total_sent_count + total_recv_count;
ck_assert_msg(total_packets == UDP_count_sent1 + UDP_count_recv1,
"%" PRIu64 "does not match %" PRIu64 "\n", total_packets, UDP_count_sent1 + UDP_count_recv1);
ck_assert_msg(total_sent_count == UDP_count_sent1, "%" PRIu64 " does not match %" PRIu64 "\n", total_sent_count, UDP_count_sent1);
ck_assert_msg(total_recv_count == UDP_count_recv1, "%" PRIu64 " does not match %" PRIu64"\n", total_recv_count, UDP_count_recv1);
const uint64_t total_bytes = total_sent_bytes + total_recv_bytes;
ck_assert_msg(total_bytes == UDP_bytes_sent1 + UDP_bytes_recv1,
"%" PRIu64 "does not match %" PRIu64 "\n", total_bytes, UDP_bytes_sent1 + UDP_bytes_recv1);
ck_assert_msg(total_sent_bytes == UDP_bytes_sent1, "%" PRIu64 " does not match %" PRIu64 "\n", total_sent_bytes, UDP_bytes_sent1);
ck_assert_msg(total_recv_bytes == UDP_bytes_recv1, "%" PRIu64 " does not match %" PRIu64 "\n", total_recv_bytes, UDP_bytes_recv1);
}
int main(void)
{
setvbuf(stdout, nullptr, _IONBF, 0);
Run_Auto_Options autotox_opts = default_run_auto_options();
autotox_opts.graph = GRAPH_COMPLETE;
run_auto_test(nullptr, NUM_TOXES, test_netprof, 0, &autotox_opts);
return 0;
}
#undef NUM_TOXES

View File

@ -109,7 +109,7 @@ static int handle_test_3(void *object, const IP_Port *source, const uint8_t *pac
#if 0
print_client_id(packet, length);
#endif
int len = decrypt_data(test_3_pub_key, dht_get_self_secret_key(onion->dht),
int len = decrypt_data(onion->mem, test_3_pub_key, dht_get_self_secret_key(onion->dht),
packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH,
packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE,
2 + CRYPTO_SHA256_SIZE + CRYPTO_MAC_SIZE, plain);
@ -144,7 +144,7 @@ static int handle_test_3_old(void *object, const IP_Port *source, const uint8_t
#if 0
print_client_id(packet, length);
#endif
int len = decrypt_data(test_3_pub_key, dht_get_self_secret_key(onion->dht),
int len = decrypt_data(onion->mem, test_3_pub_key, dht_get_self_secret_key(onion->dht),
packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH,
packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE,
1 + CRYPTO_SHA256_SIZE + CRYPTO_MAC_SIZE, plain);
@ -182,7 +182,7 @@ static int handle_test_4(void *object, const IP_Port *source, const uint8_t *pac
return 1;
}
int len = decrypt_data(packet + 1 + CRYPTO_NONCE_SIZE, dht_get_self_secret_key(onion->dht), packet + 1,
int len = decrypt_data(onion->mem, packet + 1 + CRYPTO_NONCE_SIZE, dht_get_self_secret_key(onion->dht), packet + 1,
packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE, sizeof("Install gentoo") + CRYPTO_MAC_SIZE, plain);
if (len == -1) {
@ -202,10 +202,10 @@ static int handle_test_4(void *object, const IP_Port *source, const uint8_t *pac
* Use Onion_Path path to send data of length to dest.
* Maximum length of data is ONION_MAX_DATA_SIZE.
*/
static void send_onion_packet(const Networking_Core *net, const Random *rng, const Onion_Path *path, const IP_Port *dest, const uint8_t *data, uint16_t length)
static void send_onion_packet(const Networking_Core *net, const Memory *mem, const Random *rng, const Onion_Path *path, const IP_Port *dest, const uint8_t *data, uint16_t length)
{
uint8_t packet[ONION_MAX_PACKET_SIZE];
const int len = create_onion_packet(rng, packet, sizeof(packet), path, dest, data, length);
const int len = create_onion_packet(mem, rng, packet, sizeof(packet), path, dest, data, length);
ck_assert_msg(len != -1, "failed to create onion packet");
ck_assert_msg(sendpacket(net, &path->ip_port1, packet, len) == len, "failed to send onion packet");
}
@ -264,7 +264,7 @@ static void test_basic(void)
nodes[3] = n2;
Onion_Path path;
create_onion_path(rng, onion1->dht, &path, nodes);
send_onion_packet(onion1->net, rng, &path, &nodes[3].ip_port, req_packet, sizeof(req_packet));
send_onion_packet(onion1->net, onion1->mem, rng, &path, &nodes[3].ip_port, req_packet, sizeof(req_packet));
handled_test_1 = 0;
@ -291,7 +291,7 @@ static void test_basic(void)
uint64_t s;
memcpy(&s, sb_data, sizeof(uint64_t));
memcpy(test_3_pub_key, nodes[3].public_key, CRYPTO_PUBLIC_KEY_SIZE);
int ret = send_announce_request(log1, onion1->net, rng, &path, &nodes[3],
int ret = send_announce_request(log1, onion1->mem, onion1->net, rng, &path, &nodes[3],
dht_get_self_public_key(onion1->dht),
dht_get_self_secret_key(onion1->dht),
zeroes,
@ -313,7 +313,7 @@ static void test_basic(void)
memcpy(onion_announce_entry_public_key(onion2_a, 1), dht_get_self_public_key(onion2->dht), CRYPTO_PUBLIC_KEY_SIZE);
onion_announce_entry_set_time(onion2_a, 1, mono_time_get(mono_time2));
networking_registerhandler(onion1->net, NET_PACKET_ONION_DATA_RESPONSE, &handle_test_4, onion1);
send_announce_request(log1, onion1->net, rng, &path, &nodes[3],
send_announce_request(log1, onion1->mem, onion1->net, rng, &path, &nodes[3],
dht_get_self_public_key(onion1->dht),
dht_get_self_secret_key(onion1->dht),
test_3_ping_id,
@ -338,7 +338,7 @@ static void test_basic(void)
ck_assert_msg((onion3 != nullptr), "Onion failed initializing.");
random_nonce(rng, nonce);
ret = send_data_request(log3, onion3->net, rng, &path, &nodes[3].ip_port,
ret = send_data_request(log3, onion3->mem, onion3->net, rng, &path, &nodes[3].ip_port,
dht_get_self_public_key(onion1->dht),
dht_get_self_public_key(onion1->dht),
nonce, (const uint8_t *)"Install gentoo", sizeof("Install gentoo"));

View File

@ -21,10 +21,15 @@ cc_binary(
"//c-toxcore/toxcore:Messenger",
"//c-toxcore/toxcore:TCP_server",
"//c-toxcore/toxcore:ccompat",
"//c-toxcore/toxcore:crypto_core",
"//c-toxcore/toxcore:forwarding",
"//c-toxcore/toxcore:group_announce",
"//c-toxcore/toxcore:group_onion_announce",
"//c-toxcore/toxcore:logger",
"//c-toxcore/toxcore:mem",
"//c-toxcore/toxcore:mono_time",
"//c-toxcore/toxcore:network",
"//c-toxcore/toxcore:onion",
"//c-toxcore/toxcore:onion_announce",
"//c-toxcore/toxcore:tox",
],

View File

@ -15,7 +15,7 @@ CPPFLAGS+=("-Itoxav")
CPPFLAGS+=("-Itoxencryptsave")
CPPFLAGS+=("-Ithird_party/cmp")
LDFLAGS=("-lopus" "-lsodium" "-lvpx" "-lpthread" "-lconfig" "-lgmock" "-lgtest")
LDFLAGS=("-lopus" "-lsodium" "-lvpx" "-lpthread" "-lconfig" "-lgmock" "-lgtest" "-lbenchmark")
LDFLAGS+=("-fuse-ld=gold")
LDFLAGS+=("-Wl,--detect-odr-violations")
LDFLAGS+=("-Wl,--warn-common")
@ -27,7 +27,7 @@ put() {
if [ "$SKIP_LINES" = "" ]; then
echo "#line 1 \"$1\"" >>amalgamation.cc
fi
cat "$1" >>amalgamation.cc
grep -v '^BENCHMARK_MAIN' "$1" >>amalgamation.cc
}
putmain() {

View File

@ -6,16 +6,24 @@ cc_binary(
"src/*.c",
"src/*.h",
]),
tags = ["no-windows"],
deps = [
"//c-toxcore/other:bootstrap_node_packets",
"//c-toxcore/toxcore:DHT",
"//c-toxcore/toxcore:LAN_discovery",
"//c-toxcore/toxcore:TCP_server",
"//c-toxcore/toxcore:announce",
"//c-toxcore/toxcore:attributes",
"//c-toxcore/toxcore:ccompat",
"//c-toxcore/toxcore:crypto_core",
"//c-toxcore/toxcore:forwarding",
"//c-toxcore/toxcore:group_announce",
"//c-toxcore/toxcore:group_onion_announce",
"//c-toxcore/toxcore:logger",
"//c-toxcore/toxcore:mem",
"//c-toxcore/toxcore:mono_time",
"//c-toxcore/toxcore:network",
"//c-toxcore/toxcore:onion",
"//c-toxcore/toxcore:onion_announce",
"//c-toxcore/toxcore:tox",
"@libconfig",

View File

@ -1,18 +1,18 @@
################################################
# cmake-asan
FROM ubuntu:20.04
FROM ubuntu:24.04
RUN apt-get update && \
DEBIAN_FRONTEND="noninteractive" apt-get install -y --no-install-recommends \
clang \
cmake \
libclang-rt-dev \
libconfig-dev \
libgmock-dev \
libgtest-dev \
libopus-dev \
libsodium-dev \
libvpx-dev \
llvm-dev \
ninja-build \
pkg-config \
&& apt-get clean \
@ -22,8 +22,8 @@ COPY entrypoint.sh /
RUN ["chmod", "755", "/entrypoint.sh"]
WORKDIR /home/builder
RUN groupadd -r -g 1000 builder \
&& useradd --no-log-init -r -g builder -u 1000 builder \
RUN groupadd -r -g 987 builder \
&& useradd --no-log-init -r -g builder -u 987 builder \
&& chown builder:builder /home/builder
USER builder

View File

@ -1,9 +1,9 @@
#!/bin/sh
set -eu
set -eux
SANITIZER="${1:-asan}"
cp -a /c-toxcore .
cd c-toxcore
.circleci/cmake-"$SANITIZER"
.circleci/cmake-"$SANITIZER" || (cat /home/builder/c-toxcore/_build/CMakeFiles/CMakeError.log && false)

View File

@ -1,6 +1,14 @@
#!/bin/sh
set -eux
SANITIZER="${1:-asan}"
if [ -t 0 ]; then
TTY=true
else
TTY=false
fi
docker build -t toxchat/c-toxcore:circleci other/docker/circleci
docker run --name toxcore-circleci --rm -it -v "$PWD:/c-toxcore" toxchat/c-toxcore:circleci "$SANITIZER"
docker run --name toxcore-circleci --rm --interactive="$TTY" --tty="$TTY" --volume "$PWD:/c-toxcore" toxchat/c-toxcore:circleci "$SANITIZER"

View File

@ -9,6 +9,7 @@ cc_binary(
"main/tox_main.h",
],
deps = [
"//c-toxcore/toxcore:ccompat",
"//c-toxcore/toxcore:tox",
"//c-toxcore/toxcore:tox_events",
],

View File

@ -50,6 +50,10 @@ module "//c-toxcore/third_party:cmp" {
module "//c-toxcore/toxencryptsave:defines" {
header "toxencryptsave/defines.h"
}
module "@benchmark" {
textual header "/usr/include/benchmark/benchmark.h"
use std
}
module "@com_google_googletest//:gtest" {
textual header "/usr/include/gmock/gmock.h"
textual header "/usr/include/gtest/gtest.h"
@ -83,9 +87,9 @@ class Context:
pass
def bzl_exports_files(
self,
srcs: list[str],
visibility: Optional[list[str]] = None,
self,
srcs: list[str],
visibility: Optional[list[str]] = None,
) -> None:
pass
@ -110,7 +114,7 @@ class Context:
hdrs,
}
def bzl_cc_test(
def bzl_cc_binary(
self,
name: str,
srcs: Iterable[str] = tuple(),
@ -161,7 +165,8 @@ def main() -> None:
"load": ctx.bzl_load,
"exports_files": ctx.bzl_exports_files,
"cc_library": ctx.bzl_cc_library,
"cc_test": ctx.bzl_cc_test,
"cc_binary": ctx.bzl_cc_binary,
"cc_test": ctx.bzl_cc_binary,
"cc_fuzz_test": ctx.bzl_cc_fuzz_test,
"select": ctx.bzl_select,
"glob": ctx.bzl_glob,

View File

@ -3,6 +3,7 @@ FROM alpine:3.19.0
RUN ["apk", "add", "--no-cache", \
"bash", \
"benchmark-dev", \
"clang", \
"gtest-dev", \
"libconfig-dev", \

View File

@ -4,4 +4,5 @@ cc_binary(
name = "grencez_tok5",
srcs = ["grencez_tok5.c"],
copts = ["-Wno-unused-result"],
tags = ["no-windows"],
)

View File

@ -48,6 +48,7 @@ cc_fuzz_test(
deps = [
":fuzz_support",
":fuzz_tox",
"//c-toxcore/toxcore:crypto_core",
"//c-toxcore/toxcore:tox",
"//c-toxcore/toxcore:tox_dispatch",
"//c-toxcore/toxcore:tox_events",
@ -102,6 +103,7 @@ cc_test(
deps = [
":fuzz_support",
":fuzz_tox",
"//c-toxcore/toxcore:crypto_core",
"//c-toxcore/toxcore:tox",
"//c-toxcore/toxcore:tox_dispatch",
"//c-toxcore/toxcore:tox_events",
@ -117,6 +119,7 @@ cc_fuzz_test(
deps = [
":fuzz_support",
":fuzz_tox",
"//c-toxcore/toxcore:crypto_core",
"//c-toxcore/toxcore:tox",
"//c-toxcore/toxcore:tox_dispatch",
"//c-toxcore/toxcore:tox_events",

View File

@ -4,8 +4,15 @@
#include "fuzz_support.hh"
#ifdef _WIN32
#include <winsock2.h>
// Comment line here to avoid reordering by source code formatters.
#include <windows.h>
#include <ws2tcpip.h>
#else
#include <arpa/inet.h>
#include <sys/socket.h>
#endif
#include <algorithm>
#include <cassert>

View File

@ -1,4 +1,4 @@
load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test")
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library", "cc_test")
load("@rules_fuzzing//fuzzing:cc_defs.bzl", "cc_fuzz_test")
exports_files(
@ -100,14 +100,58 @@ cc_test(
size = "small",
srcs = ["util_test.cc"],
deps = [
":crypto_core",
":crypto_core_test_util",
":util",
"@com_google_googletest//:gtest",
"@com_google_googletest//:gtest_main",
],
)
cc_library(
name = "sort",
srcs = ["sort.c"],
hdrs = ["sort.h"],
deps = [
":attributes",
":ccompat",
":util",
],
)
cc_library(
name = "sort_test_util",
testonly = True,
srcs = ["sort_test_util.cc"],
hdrs = ["sort_test_util.hh"],
deps = [
":sort",
":util",
],
)
cc_test(
name = "sort_test",
size = "small",
srcs = ["sort_test.cc"],
deps = [
":sort",
":sort_test_util",
"@com_google_googletest//:gtest",
"@com_google_googletest//:gtest_main",
],
)
cc_binary(
name = "sort_bench",
testonly = True,
srcs = ["sort_bench.cc"],
deps = [
":mem",
":sort",
":sort_test_util",
"@benchmark",
],
)
cc_library(
name = "logger",
srcs = ["logger.c"],
@ -171,6 +215,7 @@ cc_library(
deps = [
":attributes",
":ccompat",
":mem",
":util",
"@libsodium",
],
@ -209,6 +254,7 @@ cc_test(
deps = [
":crypto_core",
":crypto_core_test_util",
":mem_test_util",
":util",
"@com_google_googletest//:gtest",
"@com_google_googletest//:gtest_main",
@ -300,18 +346,6 @@ cc_library(
],
)
cc_library(
name = "net_profile",
srcs = ["net_profile.c"],
hdrs = ["net_profile.h"],
deps = [
":attributes",
":ccompat",
":logger",
":mem",
],
)
cc_library(
name = "network",
srcs = ["network.c"],
@ -331,7 +365,6 @@ cc_library(
":logger",
":mem",
":mono_time",
":net_profile",
":util",
"@libsodium",
"@psocket",
@ -450,6 +483,7 @@ cc_library(
":network",
":ping_array",
":shared_key_cache",
":sort",
":state",
":util",
],
@ -493,10 +527,12 @@ cc_test(
cc_fuzz_test(
name = "DHT_fuzz_test",
size = "small",
testonly = True,
srcs = ["DHT_fuzz_test.cc"],
corpus = ["//tools/toktok-fuzzer/corpus:DHT_fuzz_test"],
deps = [
":DHT",
":mem_test_util",
"//c-toxcore/testing/fuzzing:fuzz_support",
],
)
@ -505,7 +541,11 @@ cc_library(
name = "onion",
srcs = ["onion.c"],
hdrs = ["onion.h"],
visibility = ["//c-toxcore/auto_tests:__pkg__"],
visibility = [
"//c-toxcore/auto_tests:__pkg__",
"//c-toxcore/other:__pkg__",
"//c-toxcore/other/bootstrap_daemon:__pkg__",
],
deps = [
":DHT",
":attributes",
@ -524,7 +564,11 @@ cc_library(
name = "forwarding",
srcs = ["forwarding.c"],
hdrs = ["forwarding.h"],
visibility = ["//c-toxcore/auto_tests:__pkg__"],
visibility = [
"//c-toxcore/auto_tests:__pkg__",
"//c-toxcore/other:__pkg__",
"//c-toxcore/other/bootstrap_daemon:__pkg__",
],
deps = [
":DHT",
":attributes",
@ -585,7 +629,6 @@ cc_library(
":crypto_core",
":logger",
":mem",
":net_profile",
":network",
],
)
@ -613,7 +656,6 @@ cc_library(
":logger",
":mem",
":mono_time",
":net_profile",
":network",
":onion",
":util",
@ -635,7 +677,6 @@ cc_library(
":logger",
":mem",
":mono_time",
":net_profile",
":network",
":util",
],
@ -658,7 +699,6 @@ cc_library(
":logger",
":mem",
":mono_time",
":net_profile",
":network",
":onion",
":util",
@ -696,7 +736,6 @@ cc_library(
":logger",
":mem",
":mono_time",
":net_profile",
":network",
":util",
"@pthread",
@ -724,6 +763,7 @@ cc_library(
":network",
":onion",
":shared_key_cache",
":sort",
":timed_auth",
":util",
],
@ -797,6 +837,7 @@ cc_library(
":crypto_core",
":group_announce",
":logger",
":mem",
":mono_time",
":network",
":onion_announce",
@ -826,6 +867,7 @@ cc_library(
":onion",
":onion_announce",
":ping_array",
":sort",
":timed_auth",
":util",
],
@ -991,9 +1033,11 @@ cc_library(
":crypto_core",
":friend_connection",
":logger",
":mem",
":mono_time",
":net_crypto",
":network",
":sort",
":state",
":util",
],
@ -1016,7 +1060,6 @@ cc_library(
":DHT",
":Messenger",
":TCP_client",
":TCP_server",
":attributes",
":ccompat",
":crypto_core",
@ -1027,7 +1070,6 @@ cc_library(
":mem",
":mono_time",
":net_crypto",
":net_profile",
":network",
":onion_client",
":state",

View File

@ -9,7 +9,6 @@
#include "DHT.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "LAN_discovery.h"
@ -24,7 +23,9 @@
#include "ping.h"
#include "ping_array.h"
#include "shared_key_cache.h"
#include "sort.h"
#include "state.h"
#include "util.h"
/** The timeout after which a node is discarded completely. */
#define KILL_NODE_TIMEOUT (BAD_NODE_TIMEOUT + PING_INTERVAL)
@ -279,7 +280,7 @@ const uint8_t *dht_get_shared_key_sent(DHT *dht, const uint8_t *public_key)
#define CRYPTO_SIZE (1 + CRYPTO_PUBLIC_KEY_SIZE * 2 + CRYPTO_NONCE_SIZE)
int create_request(const Random *rng, const uint8_t *send_public_key, const uint8_t *send_secret_key,
int create_request(const Memory *mem, const Random *rng, const uint8_t *send_public_key, const uint8_t *send_secret_key,
uint8_t *packet, const uint8_t *recv_public_key,
const uint8_t *data, uint32_t data_length, uint8_t request_id)
{
@ -296,7 +297,7 @@ int create_request(const Random *rng, const uint8_t *send_public_key, const uint
uint8_t temp[MAX_CRYPTO_REQUEST_SIZE] = {0};
temp[0] = request_id;
memcpy(temp + 1, data, data_length);
const int len = encrypt_data(recv_public_key, send_secret_key, nonce, temp, data_length + 1,
const int len = encrypt_data(mem, recv_public_key, send_secret_key, nonce, temp, data_length + 1,
packet + CRYPTO_SIZE);
if (len == -1) {
@ -312,7 +313,7 @@ int create_request(const Random *rng, const uint8_t *send_public_key, const uint
return len + CRYPTO_SIZE;
}
int handle_request(const uint8_t *self_public_key, const uint8_t *self_secret_key, uint8_t *public_key, uint8_t *data,
int handle_request(const Memory *mem, const uint8_t *self_public_key, const uint8_t *self_secret_key, uint8_t *public_key, uint8_t *data,
uint8_t *request_id, const uint8_t *packet, uint16_t packet_length)
{
if (self_public_key == nullptr || public_key == nullptr || data == nullptr || request_id == nullptr
@ -331,7 +332,7 @@ int handle_request(const uint8_t *self_public_key, const uint8_t *self_secret_ke
memcpy(public_key, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_PUBLIC_KEY_SIZE);
const uint8_t *const nonce = packet + 1 + CRYPTO_PUBLIC_KEY_SIZE * 2;
uint8_t temp[MAX_CRYPTO_REQUEST_SIZE];
int32_t len1 = decrypt_data(public_key, self_secret_key, nonce,
int32_t len1 = decrypt_data(mem, public_key, self_secret_key, nonce,
packet + CRYPTO_SIZE, packet_length - CRYPTO_SIZE, temp);
if (len1 == -1 || len1 == 0) {
@ -378,7 +379,7 @@ int dht_create_packet(const Memory *mem, const Random *rng,
random_nonce(rng, nonce);
const int encrypted_length = encrypt_data_symmetric(shared_key, nonce, plain, plain_length, encrypted);
const int encrypted_length = encrypt_data_symmetric(mem, shared_key, nonce, plain, plain_length, encrypted);
if (encrypted_length < 0) {
mem_delete(mem, encrypted);
@ -755,49 +756,6 @@ int get_close_nodes(
is_lan, want_announce);
}
typedef struct DHT_Cmp_Data {
uint64_t cur_time;
const uint8_t *base_public_key;
Client_data entry;
} DHT_Cmp_Data;
non_null()
static int dht_cmp_entry(const void *a, const void *b)
{
const DHT_Cmp_Data *cmp1 = (const DHT_Cmp_Data *)a;
const DHT_Cmp_Data *cmp2 = (const DHT_Cmp_Data *)b;
const Client_data entry1 = cmp1->entry;
const Client_data entry2 = cmp2->entry;
const uint8_t *cmp_public_key = cmp1->base_public_key;
const bool t1 = assoc_timeout(cmp1->cur_time, &entry1.assoc4) && assoc_timeout(cmp1->cur_time, &entry1.assoc6);
const bool t2 = assoc_timeout(cmp2->cur_time, &entry2.assoc4) && assoc_timeout(cmp2->cur_time, &entry2.assoc6);
if (t1 && t2) {
return 0;
}
if (t1) {
return -1;
}
if (t2) {
return 1;
}
const int closest = id_closest(cmp_public_key, entry1.public_key, entry2.public_key);
if (closest == 1) {
return 1;
}
if (closest == 2) {
return -1;
}
return 0;
}
#ifdef CHECK_ANNOUNCE_NODE
non_null()
static void set_announce_node_in_list(Client_data *list, uint32_t list_len, const uint8_t *public_key)
@ -870,7 +828,7 @@ static int handle_data_search_response(void *object, const IP_Port *source,
const uint8_t *public_key = packet + 1;
const uint8_t *shared_key = dht_get_shared_key_recv(dht, public_key);
if (decrypt_data_symmetric(shared_key,
if (decrypt_data_symmetric(dht->mem, shared_key,
packet + 1 + CRYPTO_PUBLIC_KEY_SIZE,
packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE,
plain_len + CRYPTO_MAC_SIZE,
@ -914,31 +872,117 @@ static bool store_node_ok(const Client_data *client, uint64_t cur_time, const ui
|| id_closest(comp_public_key, client->public_key, public_key) == 2;
}
typedef struct Client_data_Cmp {
const Memory *mem;
uint64_t cur_time;
const uint8_t *comp_public_key;
} Client_data_Cmp;
non_null()
static int client_data_cmp(const Client_data_Cmp *cmp, const Client_data *entry1, const Client_data *entry2)
{
const bool t1 = assoc_timeout(cmp->cur_time, &entry1->assoc4) && assoc_timeout(cmp->cur_time, &entry1->assoc6);
const bool t2 = assoc_timeout(cmp->cur_time, &entry2->assoc4) && assoc_timeout(cmp->cur_time, &entry2->assoc6);
if (t1 && t2) {
return 0;
}
if (t1) {
return -1;
}
if (t2) {
return 1;
}
const int closest = id_closest(cmp->comp_public_key, entry1->public_key, entry2->public_key);
if (closest == 1) {
return 1;
}
if (closest == 2) {
return -1;
}
return 0;
}
non_null()
static bool client_data_less_handler(const void *object, const void *a, const void *b)
{
const Client_data_Cmp *cmp = (const Client_data_Cmp *)object;
const Client_data *entry1 = (const Client_data *)a;
const Client_data *entry2 = (const Client_data *)b;
return client_data_cmp(cmp, entry1, entry2) < 0;
}
non_null()
static const void *client_data_get_handler(const void *arr, uint32_t index)
{
const Client_data *entries = (const Client_data *)arr;
return &entries[index];
}
non_null()
static void client_data_set_handler(void *arr, uint32_t index, const void *val)
{
Client_data *entries = (Client_data *)arr;
const Client_data *entry = (const Client_data *)val;
entries[index] = *entry;
}
non_null()
static void *client_data_subarr_handler(void *arr, uint32_t index, uint32_t size)
{
Client_data *entries = (Client_data *)arr;
return &entries[index];
}
non_null()
static void *client_data_alloc_handler(const void *object, uint32_t size)
{
const Client_data_Cmp *cmp = (const Client_data_Cmp *)object;
Client_data *tmp = (Client_data *)mem_valloc(cmp->mem, size, sizeof(Client_data));
if (tmp == nullptr) {
return nullptr;
}
return tmp;
}
non_null()
static void client_data_delete_handler(const void *object, void *arr, uint32_t size)
{
const Client_data_Cmp *cmp = (const Client_data_Cmp *)object;
mem_delete(cmp->mem, arr);
}
static const Sort_Funcs client_data_cmp_funcs = {
client_data_less_handler,
client_data_get_handler,
client_data_set_handler,
client_data_subarr_handler,
client_data_alloc_handler,
client_data_delete_handler,
};
non_null()
static void sort_client_list(const Memory *mem, Client_data *list, uint64_t cur_time, unsigned int length,
const uint8_t *comp_public_key)
{
// Pass comp_public_key to qsort with each Client_data entry, so the
// Pass comp_public_key to merge_sort with each Client_data entry, so the
// comparison function can use it as the base of comparison.
DHT_Cmp_Data *cmp_list = (DHT_Cmp_Data *)mem_valloc(mem, length, sizeof(DHT_Cmp_Data));
const Client_data_Cmp cmp = {
mem,
cur_time,
comp_public_key,
};
if (cmp_list == nullptr) {
return;
}
for (uint32_t i = 0; i < length; ++i) {
cmp_list[i].cur_time = cur_time;
cmp_list[i].base_public_key = comp_public_key;
cmp_list[i].entry = list[i];
}
qsort(cmp_list, length, sizeof(DHT_Cmp_Data), dht_cmp_entry);
for (uint32_t i = 0; i < length; ++i) {
list[i] = cmp_list[i].entry;
}
mem_delete(mem, cmp_list);
merge_sort(list, length, &cmp, &client_data_cmp_funcs);
}
non_null()
@ -1381,6 +1425,7 @@ static int handle_getnodes(void *object, const IP_Port *source, const uint8_t *p
uint8_t plain[CRYPTO_NODE_SIZE];
const uint8_t *shared_key = dht_get_shared_key_recv(dht, packet + 1);
const int len = decrypt_data_symmetric(
dht->mem,
shared_key,
packet + 1 + CRYPTO_PUBLIC_KEY_SIZE,
packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE,
@ -1442,6 +1487,7 @@ static bool handle_sendnodes_core(void *object, const IP_Port *source, const uin
VLA(uint8_t, plain, plain_size);
const uint8_t *shared_key = dht_get_shared_key_sent(dht, packet + 1);
const int len = decrypt_data_symmetric(
dht->mem,
shared_key,
packet + 1 + CRYPTO_PUBLIC_KEY_SIZE,
packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE,
@ -2123,7 +2169,7 @@ static int send_nat_ping(const DHT *dht, const uint8_t *public_key, uint64_t pin
memcpy(data + 1, &ping_id, sizeof(uint64_t));
/* 254 is NAT ping request packet id */
const int len = create_request(
dht->rng, dht->self_public_key, dht->self_secret_key, packet_data, public_key,
dht->mem, dht->rng, dht->self_public_key, dht->self_secret_key, packet_data, public_key,
data, sizeof(uint64_t) + 1, CRYPTO_PACKET_NAT_PING);
if (len == -1) {
@ -2458,7 +2504,7 @@ static int cryptopacket_handle(void *object, const IP_Port *source, const uint8_
uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE];
uint8_t data[MAX_CRYPTO_REQUEST_SIZE];
uint8_t number;
const int len = handle_request(dht->self_public_key, dht->self_secret_key, public_key,
const int len = handle_request(dht->mem, dht->self_public_key, dht->self_secret_key, public_key,
data, &number, packet, length);
if (len == -1 || len == 0) {

View File

@ -99,7 +99,7 @@ extern "C" {
* @return the length of the created packet on success.
*/
non_null()
int create_request(const Random *rng, const uint8_t *send_public_key, const uint8_t *send_secret_key,
int create_request(const Memory *mem, const Random *rng, const uint8_t *send_public_key, const uint8_t *send_secret_key,
uint8_t *packet, const uint8_t *recv_public_key,
const uint8_t *data, uint32_t data_length, uint8_t request_id);
@ -127,7 +127,7 @@ int create_request(const Random *rng, const uint8_t *send_public_key, const uint
*/
non_null()
int handle_request(
const uint8_t *self_public_key, const uint8_t *self_secret_key, uint8_t *public_key, uint8_t *data,
const Memory *mem, const uint8_t *self_public_key, const uint8_t *self_secret_key, uint8_t *public_key, uint8_t *data,
uint8_t *request_id, const uint8_t *packet, uint16_t packet_length);
typedef struct IPPTs {

View File

@ -6,19 +6,22 @@
#include <vector>
#include "../testing/fuzzing/fuzz_support.hh"
#include "mem_test_util.hh"
namespace {
void TestHandleRequest(Fuzz_Data &input)
{
const Test_Memory mem;
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);
uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE];
uint8_t request[MAX_CRYPTO_REQUEST_SIZE];
uint8_t request_id;
handle_request(self_public_key, self_secret_key, public_key, request, &request_id, input.data(),
input.size());
handle_request(mem, self_public_key, self_secret_key, public_key, request, &request_id,
input.data(), input.size());
}
void TestUnpackNodes(Fuzz_Data &input)

View File

@ -274,6 +274,7 @@ TEST(AddToList, KeepsKeysInOrder)
TEST(Request, CreateAndParse)
{
Test_Memory mem;
Test_Random rng;
// Peers.
@ -293,32 +294,32 @@ TEST(Request, CreateAndParse)
std::vector<uint8_t> outgoing(919);
random_bytes(rng, outgoing.data(), outgoing.size());
EXPECT_LT(create_request(rng, sender.pk.data(), sender.sk.data(), packet.data(),
EXPECT_LT(create_request(mem, rng, sender.pk.data(), sender.sk.data(), packet.data(),
receiver.pk.data(), outgoing.data(), outgoing.size(), sent_pkt_id),
0);
// Pop one element so the payload is 918 bytes. Packing should now succeed.
outgoing.pop_back();
const int max_sent_length = create_request(rng, sender.pk.data(), sender.sk.data(),
const int max_sent_length = create_request(mem, rng, sender.pk.data(), sender.sk.data(),
packet.data(), receiver.pk.data(), outgoing.data(), outgoing.size(), sent_pkt_id);
ASSERT_GT(max_sent_length, 0); // success.
// Check that handle_request rejects packets larger than the maximum created packet size.
EXPECT_LT(handle_request(receiver.pk.data(), receiver.sk.data(), pk.data(), incoming.data(),
&recvd_pkt_id, packet.data(), max_sent_length + 1),
EXPECT_LT(handle_request(mem, receiver.pk.data(), receiver.sk.data(), pk.data(),
incoming.data(), &recvd_pkt_id, packet.data(), max_sent_length + 1),
0);
// Now try all possible packet sizes from max (918) to 0.
while (!outgoing.empty()) {
// Pack:
const int sent_length = create_request(rng, sender.pk.data(), sender.sk.data(),
const int sent_length = create_request(mem, rng, sender.pk.data(), sender.sk.data(),
packet.data(), receiver.pk.data(), outgoing.data(), outgoing.size(), sent_pkt_id);
ASSERT_GT(sent_length, 0);
// Unpack:
const int recvd_length = handle_request(receiver.pk.data(), receiver.sk.data(), pk.data(),
incoming.data(), &recvd_pkt_id, packet.data(), sent_length);
const int recvd_length = handle_request(mem, receiver.pk.data(), receiver.sk.data(),
pk.data(), incoming.data(), &recvd_pkt_id, packet.data(), sent_length);
ASSERT_GE(recvd_length, 0);
EXPECT_EQ(

View File

@ -74,8 +74,6 @@ libtoxcore_la_SOURCES = ../third_party/cmp/cmp.c \
../toxcore/ping_array.c \
../toxcore/net_crypto.h \
../toxcore/net_crypto.c \
../toxcore/net_profile.c \
../toxcore/net_profile.h \
../toxcore/friend_requests.h \
../toxcore/friend_requests.c \
../toxcore/LAN_discovery.h \
@ -88,6 +86,8 @@ libtoxcore_la_SOURCES = ../third_party/cmp/cmp.c \
../toxcore/ping.c \
../toxcore/shared_key_cache.h \
../toxcore/shared_key_cache.c \
../toxcore/sort.h \
../toxcore/sort.c \
../toxcore/state.h \
../toxcore/state.c \
../toxcore/tox.h \

View File

@ -20,7 +20,6 @@
#include "logger.h"
#include "mem.h"
#include "mono_time.h"
#include "net_profile.h"
#include "network.h"
#include "util.h"
@ -313,7 +312,7 @@ static int generate_handshake(TCP_Client_Connection *tcp_conn)
memcpy(plain + CRYPTO_PUBLIC_KEY_SIZE, tcp_conn->con.sent_nonce, CRYPTO_NONCE_SIZE);
memcpy(tcp_conn->con.last_packet, tcp_conn->self_public_key, CRYPTO_PUBLIC_KEY_SIZE);
random_nonce(tcp_conn->con.rng, tcp_conn->con.last_packet + CRYPTO_PUBLIC_KEY_SIZE);
const int len = encrypt_data_symmetric(tcp_conn->con.shared_key, tcp_conn->con.last_packet + CRYPTO_PUBLIC_KEY_SIZE, plain,
const int len = encrypt_data_symmetric(tcp_conn->con.mem, tcp_conn->con.shared_key, tcp_conn->con.last_packet + CRYPTO_PUBLIC_KEY_SIZE, plain,
sizeof(plain), tcp_conn->con.last_packet + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE);
if (len != sizeof(plain) + CRYPTO_MAC_SIZE) {
@ -335,7 +334,7 @@ non_null()
static int handle_handshake(TCP_Client_Connection *tcp_conn, const uint8_t *data)
{
uint8_t plain[CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE];
const int len = decrypt_data_symmetric(tcp_conn->con.shared_key, data, data + CRYPTO_NONCE_SIZE,
const int len = decrypt_data_symmetric(tcp_conn->con.mem, tcp_conn->con.shared_key, data, data + CRYPTO_NONCE_SIZE,
TCP_SERVER_HANDSHAKE_SIZE - CRYPTO_NONCE_SIZE, plain);
if (len != sizeof(plain)) {
@ -583,7 +582,7 @@ void forwarding_handler(TCP_Client_Connection *con, forwarded_response_cb *forwa
TCP_Client_Connection *new_tcp_connection(
const Logger *logger, const Memory *mem, const Mono_Time *mono_time, const Random *rng, const Network *ns,
const IP_Port *ip_port, const uint8_t *public_key, const uint8_t *self_public_key, const uint8_t *self_secret_key,
const TCP_Proxy_Info *proxy_info, Net_Profile *net_profile)
const TCP_Proxy_Info *proxy_info)
{
assert(logger != nullptr);
assert(mem != nullptr);
@ -635,7 +634,6 @@ TCP_Client_Connection *new_tcp_connection(
temp->con.rng = rng;
temp->con.sock = sock;
temp->con.ip_port = *ip_port;
temp->con.net_profile = net_profile;
memcpy(temp->public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE);
memcpy(temp->self_public_key, self_public_key, CRYPTO_PUBLIC_KEY_SIZE);
encrypt_precompute(temp->public_key, self_secret_key, temp->con.shared_key);
@ -821,8 +819,6 @@ static int handle_tcp_client_packet(const Logger *logger, TCP_Client_Connection
return -1;
}
netprof_record_packet(conn->con.net_profile, data[0], length, PACKET_DIRECTION_RECV);
switch (data[0]) {
case TCP_PACKET_ROUTING_RESPONSE:
return handle_tcp_client_routing_response(conn, data, length);

View File

@ -15,7 +15,6 @@
#include "logger.h"
#include "mem.h"
#include "mono_time.h"
#include "net_profile.h"
#include "network.h"
#define TCP_CONNECTION_TIMEOUT 10
@ -61,11 +60,11 @@ non_null()
void tcp_con_set_custom_uint(TCP_Client_Connection *con, uint32_t value);
/** Create new TCP connection to ip_port/public_key */
non_null(1, 2, 3, 4, 5, 6, 7, 8, 9) nullable(10, 11)
non_null(1, 2, 3, 4, 5, 6, 7, 8, 9) nullable(10)
TCP_Client_Connection *new_tcp_connection(
const Logger *logger, const Memory *mem, const Mono_Time *mono_time, const Random *rng, const Network *ns,
const IP_Port *ip_port, const uint8_t *public_key, const uint8_t *self_public_key, const uint8_t *self_secret_key,
const TCP_Proxy_Info *proxy_info, Net_Profile *net_profile);
const TCP_Proxy_Info *proxy_info);
/** Run the TCP connection */
non_null(1, 2, 3) nullable(4)

View File

@ -35,8 +35,7 @@ int send_pending_data_nonpriority(const Logger *logger, TCP_Connection *con)
}
const uint16_t left = con->last_packet_length - con->last_packet_sent;
const int len = net_send(con->ns, logger, con->sock, con->last_packet + con->last_packet_sent, left, &con->ip_port,
con->net_profile);
const int len = net_send(con->ns, logger, con->sock, con->last_packet + con->last_packet_sent, left, &con->ip_port);
if (len <= 0) {
return -1;
@ -67,7 +66,7 @@ int send_pending_data(const Logger *logger, TCP_Connection *con)
while (p != nullptr) {
const uint16_t left = p->size - p->sent;
const int len = net_send(con->ns, logger, con->sock, p->data + p->sent, left, &con->ip_port, con->net_profile);
const int len = net_send(con->ns, logger, con->sock, p->data + p->sent, left, &con->ip_port);
if (len != left) {
if (len > 0) {
@ -158,15 +157,14 @@ int write_packet_tcp_secure_connection(const Logger *logger, TCP_Connection *con
uint16_t c_length = net_htons(length + CRYPTO_MAC_SIZE);
memcpy(packet, &c_length, sizeof(uint16_t));
int len = encrypt_data_symmetric(con->shared_key, con->sent_nonce, data, length, packet + sizeof(uint16_t));
int len = encrypt_data_symmetric(con->mem, con->shared_key, con->sent_nonce, data, length, packet + sizeof(uint16_t));
if ((unsigned int)len != (packet_size - sizeof(uint16_t))) {
return -1;
}
if (priority) {
len = sendpriority ? net_send(con->ns, logger, con->sock, packet, packet_size, &con->ip_port,
con->net_profile) : 0;
len = sendpriority ? net_send(con->ns, logger, con->sock, packet, packet_size, &con->ip_port) : 0;
if (len <= 0) {
len = 0;
@ -181,7 +179,7 @@ int write_packet_tcp_secure_connection(const Logger *logger, TCP_Connection *con
return add_priority(con, packet, packet_size, len) ? 1 : 0;
}
len = net_send(con->ns, logger, con->sock, packet, packet_size, &con->ip_port, con->net_profile);
len = net_send(con->ns, logger, con->sock, packet, packet_size, &con->ip_port);
if (len <= 0) {
return 0;
@ -307,7 +305,7 @@ int read_packet_tcp_secure_connection(
*next_packet_length = 0;
const int len = decrypt_data_symmetric(shared_key, recv_nonce, data_encrypted, len_packet, data);
const int len = decrypt_data_symmetric(mem, shared_key, recv_nonce, data_encrypted, len_packet, data);
if (len + CRYPTO_MAC_SIZE != len_packet) {
LOGGER_ERROR(logger, "decrypted length %d does not match expected length %d", len + CRYPTO_MAC_SIZE, len_packet);

View File

@ -10,7 +10,6 @@
#include "crypto_core.h"
#include "logger.h"
#include "mem.h"
#include "net_profile.h"
#include "network.h"
typedef struct TCP_Priority_List TCP_Priority_List;
@ -67,10 +66,6 @@ typedef struct TCP_Connection {
TCP_Priority_List *priority_queue_start;
TCP_Priority_List *priority_queue_end;
// This is a shared pointer to the parent's respective Net_Profile object
// (either TCP_Server for TCP server packets or TCP_Connections for TCP client packets).
Net_Profile *net_profile;
} TCP_Connection;
/**

View File

@ -20,7 +20,6 @@
#include "logger.h"
#include "mem.h"
#include "mono_time.h"
#include "net_profile.h"
#include "network.h"
#include "util.h"
@ -57,9 +56,6 @@ struct TCP_Connections {
bool onion_status;
uint16_t onion_num_conns;
/* Network profile for all TCP client packets. */
Net_Profile *net_profile;
};
static const TCP_Connection_to empty_tcp_connection_to = {0};
@ -932,8 +928,7 @@ static int reconnect_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connec
uint8_t relay_pk[CRYPTO_PUBLIC_KEY_SIZE];
memcpy(relay_pk, tcp_con_public_key(tcp_con->connection), CRYPTO_PUBLIC_KEY_SIZE);
kill_tcp_connection(tcp_con->connection);
tcp_con->connection = new_tcp_connection(tcp_c->logger, tcp_c->mem, tcp_c->mono_time, tcp_c->rng, tcp_c->ns, &ip_port, relay_pk, tcp_c->self_public_key, tcp_c->self_secret_key, &tcp_c->proxy_info,
tcp_c->net_profile);
tcp_con->connection = new_tcp_connection(tcp_c->logger, tcp_c->mem, tcp_c->mono_time, tcp_c->rng, tcp_c->ns, &ip_port, relay_pk, tcp_c->self_public_key, tcp_c->self_secret_key, &tcp_c->proxy_info);
if (tcp_con->connection == nullptr) {
kill_tcp_relay_connection(tcp_c, tcp_connections_number);
@ -1022,7 +1017,7 @@ static int unsleep_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connecti
tcp_con->connection = new_tcp_connection(
tcp_c->logger, tcp_c->mem, tcp_c->mono_time, tcp_c->rng, tcp_c->ns, &tcp_con->ip_port,
tcp_con->relay_pk, tcp_c->self_public_key, tcp_c->self_secret_key, &tcp_c->proxy_info, tcp_c->net_profile);
tcp_con->relay_pk, tcp_c->self_public_key, tcp_c->self_secret_key, &tcp_c->proxy_info);
if (tcp_con->connection == nullptr) {
kill_tcp_relay_connection(tcp_c, tcp_connections_number);
@ -1320,7 +1315,7 @@ static int add_tcp_relay_instance(TCP_Connections *tcp_c, const IP_Port *ip_port
tcp_con->connection = new_tcp_connection(
tcp_c->logger, tcp_c->mem, tcp_c->mono_time, tcp_c->rng, tcp_c->ns, &ipp_copy,
relay_pk, tcp_c->self_public_key, tcp_c->self_secret_key, &tcp_c->proxy_info, tcp_c->net_profile);
relay_pk, tcp_c->self_public_key, tcp_c->self_secret_key, &tcp_c->proxy_info);
if (tcp_con->connection == nullptr) {
return -1;
@ -1614,14 +1609,6 @@ TCP_Connections *new_tcp_connections(const Logger *logger, const Memory *mem, co
return nullptr;
}
Net_Profile *np = netprof_new(logger, mem);
if (np == nullptr) {
mem_delete(mem, temp);
return nullptr;
}
temp->net_profile = np;
temp->logger = logger;
temp->mem = mem;
temp->rng = rng;
@ -1736,17 +1723,7 @@ void kill_tcp_connections(TCP_Connections *tcp_c)
crypto_memzero(tcp_c->self_secret_key, sizeof(tcp_c->self_secret_key));
netprof_kill(tcp_c->mem, tcp_c->net_profile);
mem_delete(tcp_c->mem, tcp_c->tcp_connections);
mem_delete(tcp_c->mem, tcp_c->connections);
mem_delete(tcp_c->mem, tcp_c);
}
const Net_Profile *tcp_connection_get_client_net_profile(const TCP_Connections *tcp_c)
{
if (tcp_c == nullptr) {
return nullptr;
}
return tcp_c->net_profile;
}

View File

@ -21,7 +21,6 @@
#include "logger.h"
#include "mem.h"
#include "mono_time.h"
#include "net_profile.h"
#include "network.h"
#define TCP_CONN_NONE 0
@ -318,11 +317,4 @@ void do_tcp_connections(const Logger *logger, TCP_Connections *tcp_c, void *user
nullable(1)
void kill_tcp_connections(TCP_Connections *tcp_c);
/** @brief a pointer to the tcp client net profile associated with tcp_c.
*
* @retval null if tcp_c is null.
*/
non_null()
const Net_Profile *tcp_connection_get_client_net_profile(const TCP_Connections *tcp_c);
#endif /* C_TOXCORE_TOXCORE_TCP_CONNECTION_H */

View File

@ -27,7 +27,6 @@
#include "logger.h"
#include "mem.h"
#include "mono_time.h"
#include "net_profile.h"
#include "network.h"
#include "onion.h"
@ -92,9 +91,6 @@ struct TCP_Server {
uint64_t counter;
BS_List accepted_key_list;
/* Network profile for all TCP server packets. */
Net_Profile *net_profile;
};
static_assert(sizeof(TCP_Server) < 7 * 1024 * 1024,
@ -240,7 +236,6 @@ static int add_accepted(TCP_Server *tcp_server, const Mono_Time *mono_time, TCP_
tcp_server->accepted_connection_array[index].identifier = ++tcp_server->counter;
tcp_server->accepted_connection_array[index].last_pinged = mono_time_get(mono_time);
tcp_server->accepted_connection_array[index].ping_id = 0;
tcp_server->accepted_connection_array[index].con.net_profile = tcp_server->net_profile;
return index;
}
@ -332,7 +327,7 @@ static int handle_tcp_handshake(const Logger *logger, TCP_Secure_Connection *con
uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE];
encrypt_precompute(data, self_secret_key, shared_key);
uint8_t plain[TCP_HANDSHAKE_PLAIN_SIZE];
int len = decrypt_data_symmetric(shared_key, data + CRYPTO_PUBLIC_KEY_SIZE,
int len = decrypt_data_symmetric(con->con.mem, shared_key, data + CRYPTO_PUBLIC_KEY_SIZE,
data + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, TCP_HANDSHAKE_PLAIN_SIZE + CRYPTO_MAC_SIZE, plain);
if (len != TCP_HANDSHAKE_PLAIN_SIZE) {
@ -352,7 +347,7 @@ static int handle_tcp_handshake(const Logger *logger, TCP_Secure_Connection *con
uint8_t response[TCP_SERVER_HANDSHAKE_SIZE];
random_nonce(con->con.rng, response);
len = encrypt_data_symmetric(shared_key, response, resp_plain, TCP_HANDSHAKE_PLAIN_SIZE,
len = encrypt_data_symmetric(con->con.mem, shared_key, response, resp_plain, TCP_HANDSHAKE_PLAIN_SIZE,
response + CRYPTO_NONCE_SIZE);
if (len != TCP_HANDSHAKE_PLAIN_SIZE + CRYPTO_MAC_SIZE) {
@ -362,7 +357,7 @@ static int handle_tcp_handshake(const Logger *logger, TCP_Secure_Connection *con
const IP_Port ipp = {{{0}}};
if (TCP_SERVER_HANDSHAKE_SIZE != net_send(con->con.ns, logger, con->con.sock, response, TCP_SERVER_HANDSHAKE_SIZE, &ipp, con->con.net_profile)) {
if (TCP_SERVER_HANDSHAKE_SIZE != net_send(con->con.ns, logger, con->con.sock, response, TCP_SERVER_HANDSHAKE_SIZE, &ipp)) {
crypto_memzero(shared_key, sizeof(shared_key));
return -1;
}
@ -685,7 +680,6 @@ static int handle_tcp_packet(TCP_Server *tcp_server, uint32_t con_id, const uint
}
TCP_Secure_Connection *const con = &tcp_server->accepted_connection_array[con_id];
netprof_record_packet(con->con.net_profile, data[0], length, PACKET_DIRECTION_RECV);
switch (data[0]) {
case TCP_PACKET_ROUTING_REQUEST: {
@ -975,14 +969,6 @@ TCP_Server *new_tcp_server(const Logger *logger, const Memory *mem, const Random
return nullptr;
}
Net_Profile *np = netprof_new(logger, mem);
if (np == nullptr) {
mem_delete(mem, temp);
return nullptr;
}
temp->net_profile = np;
temp->logger = logger;
temp->mem = mem;
temp->ns = ns;
@ -992,7 +978,6 @@ TCP_Server *new_tcp_server(const Logger *logger, const Memory *mem, const Random
if (socks_listening == nullptr) {
LOGGER_ERROR(logger, "socket allocation failed");
netprof_kill(mem, temp->net_profile);
mem_delete(mem, temp);
return nullptr;
}
@ -1004,7 +989,6 @@ TCP_Server *new_tcp_server(const Logger *logger, const Memory *mem, const Random
if (temp->efd == -1) {
LOGGER_ERROR(logger, "epoll initialisation failed");
netprof_kill(mem, temp->net_profile);
mem_delete(mem, socks_listening);
mem_delete(mem, temp);
return nullptr;
@ -1038,7 +1022,6 @@ TCP_Server *new_tcp_server(const Logger *logger, const Memory *mem, const Random
}
if (temp->num_listening_socks == 0) {
netprof_kill(mem, temp->net_profile);
mem_delete(mem, temp->socks_listening);
mem_delete(mem, temp);
return nullptr;
@ -1439,16 +1422,6 @@ void kill_tcp_server(TCP_Server *tcp_server)
crypto_memzero(tcp_server->secret_key, sizeof(tcp_server->secret_key));
netprof_kill(tcp_server->mem, tcp_server->net_profile);
mem_delete(tcp_server->mem, tcp_server->socks_listening);
mem_delete(tcp_server->mem, tcp_server);
}
const Net_Profile *tcp_server_get_net_profile(const TCP_Server *tcp_server)
{
if (tcp_server == nullptr) {
return nullptr;
}
return tcp_server->net_profile;
}

View File

@ -15,7 +15,6 @@
#include "logger.h"
#include "mem.h"
#include "mono_time.h"
#include "net_profile.h"
#include "network.h"
#include "onion.h"
@ -53,11 +52,4 @@ void do_tcp_server(TCP_Server *tcp_server, const Mono_Time *mono_time);
nullable(1)
void kill_tcp_server(TCP_Server *tcp_server);
/** @brief Returns a pointer to the net profile associated with `tcp_server`.
*
* Returns null if `tcp_server` is null.
*/
nullable(1)
const Net_Profile *tcp_server_get_net_profile(const TCP_Server *tcp_server);
#endif /* C_TOXCORE_TOXCORE_TCP_SERVER_H */

View File

@ -451,7 +451,7 @@ static int create_reply_plain_store_announce_request(Announcements *announce,
return -1;
}
if (decrypt_data_symmetric(shared_key,
if (decrypt_data_symmetric(announce->mem, shared_key,
data + CRYPTO_PUBLIC_KEY_SIZE,
data + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE,
plain_len + CRYPTO_MAC_SIZE,
@ -568,7 +568,7 @@ static int create_reply(Announcements *announce, const IP_Port *source,
VLA(uint8_t, plain, plain_len);
const uint8_t *shared_key = dht_get_shared_key_recv(announce->dht, data + 1);
if (decrypt_data_symmetric(shared_key,
if (decrypt_data_symmetric(announce->mem, shared_key,
data + 1 + CRYPTO_PUBLIC_KEY_SIZE,
data + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE,
plain_len + CRYPTO_MAC_SIZE,

View File

@ -13,6 +13,7 @@
#include "attributes.h"
#include "ccompat.h"
#include "mem.h"
#include "util.h"
static_assert(CRYPTO_PUBLIC_KEY_SIZE == crypto_box_PUBLICKEYBYTES,
@ -88,9 +89,10 @@ const uint8_t *get_chat_id(const Extended_Public_Key *key)
}
#if !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
static uint8_t *crypto_malloc(size_t bytes)
non_null()
static uint8_t *crypto_malloc(const Memory *mem, size_t bytes)
{
uint8_t *ptr = (uint8_t *)malloc(bytes);
uint8_t *ptr = (uint8_t *)mem_balloc(mem, bytes);
if (ptr != nullptr) {
crypto_memlock(ptr, bytes);
@ -99,15 +101,15 @@ static uint8_t *crypto_malloc(size_t bytes)
return ptr;
}
nullable(1)
static void crypto_free(uint8_t *ptr, size_t bytes)
non_null(1) nullable(2)
static void crypto_free(const Memory *mem, uint8_t *ptr, size_t bytes)
{
if (ptr != nullptr) {
crypto_memzero(ptr, bytes);
crypto_memunlock(ptr, bytes);
}
free(ptr);
mem_delete(mem, ptr);
}
#endif /* !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) */
@ -240,7 +242,8 @@ int32_t encrypt_precompute(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */
}
int32_t encrypt_data_symmetric(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE],
int32_t encrypt_data_symmetric(const Memory *mem,
const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE],
const uint8_t nonce[CRYPTO_NONCE_SIZE],
const uint8_t *plain, size_t length, uint8_t *encrypted)
{
@ -258,12 +261,12 @@ int32_t encrypt_data_symmetric(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE],
const size_t size_temp_plain = length + crypto_box_ZEROBYTES;
const size_t size_temp_encrypted = length + crypto_box_MACBYTES + crypto_box_BOXZEROBYTES;
uint8_t *temp_plain = crypto_malloc(size_temp_plain);
uint8_t *temp_encrypted = crypto_malloc(size_temp_encrypted);
uint8_t *temp_plain = crypto_malloc(mem, size_temp_plain);
uint8_t *temp_encrypted = crypto_malloc(mem, size_temp_encrypted);
if (temp_plain == nullptr || temp_encrypted == nullptr) {
crypto_free(temp_plain, size_temp_plain);
crypto_free(temp_encrypted, size_temp_encrypted);
crypto_free(mem, temp_plain, size_temp_plain);
crypto_free(mem, temp_encrypted, size_temp_encrypted);
return -1;
}
@ -278,22 +281,23 @@ int32_t encrypt_data_symmetric(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE],
if (crypto_box_afternm(temp_encrypted, temp_plain, length + crypto_box_ZEROBYTES, nonce,
shared_key) != 0) {
crypto_free(temp_plain, size_temp_plain);
crypto_free(temp_encrypted, size_temp_encrypted);
crypto_free(mem, temp_plain, size_temp_plain);
crypto_free(mem, temp_encrypted, size_temp_encrypted);
return -1;
}
// Unpad the encrypted message.
memcpy(encrypted, temp_encrypted + crypto_box_BOXZEROBYTES, length + crypto_box_MACBYTES);
crypto_free(temp_plain, size_temp_plain);
crypto_free(temp_encrypted, size_temp_encrypted);
crypto_free(mem, temp_plain, size_temp_plain);
crypto_free(mem, temp_encrypted, size_temp_encrypted);
#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */
assert(length < INT32_MAX - crypto_box_MACBYTES);
return (int32_t)(length + crypto_box_MACBYTES);
}
int32_t decrypt_data_symmetric(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE],
int32_t decrypt_data_symmetric(const Memory *mem,
const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE],
const uint8_t nonce[CRYPTO_NONCE_SIZE],
const uint8_t *encrypted, size_t length, uint8_t *plain)
{
@ -310,12 +314,12 @@ int32_t decrypt_data_symmetric(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE],
const size_t size_temp_plain = length + crypto_box_ZEROBYTES;
const size_t size_temp_encrypted = length + crypto_box_BOXZEROBYTES;
uint8_t *temp_plain = crypto_malloc(size_temp_plain);
uint8_t *temp_encrypted = crypto_malloc(size_temp_encrypted);
uint8_t *temp_plain = crypto_malloc(mem, size_temp_plain);
uint8_t *temp_encrypted = crypto_malloc(mem, size_temp_encrypted);
if (temp_plain == nullptr || temp_encrypted == nullptr) {
crypto_free(temp_plain, size_temp_plain);
crypto_free(temp_encrypted, size_temp_encrypted);
crypto_free(mem, temp_plain, size_temp_plain);
crypto_free(mem, temp_encrypted, size_temp_encrypted);
return -1;
}
@ -330,22 +334,23 @@ int32_t decrypt_data_symmetric(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE],
if (crypto_box_open_afternm(temp_plain, temp_encrypted, length + crypto_box_BOXZEROBYTES, nonce,
shared_key) != 0) {
crypto_free(temp_plain, size_temp_plain);
crypto_free(temp_encrypted, size_temp_encrypted);
crypto_free(mem, temp_plain, size_temp_plain);
crypto_free(mem, temp_encrypted, size_temp_encrypted);
return -1;
}
memcpy(plain, temp_plain + crypto_box_ZEROBYTES, length - crypto_box_MACBYTES);
crypto_free(temp_plain, size_temp_plain);
crypto_free(temp_encrypted, size_temp_encrypted);
crypto_free(mem, temp_plain, size_temp_plain);
crypto_free(mem, temp_encrypted, size_temp_encrypted);
#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */
assert(length > crypto_box_MACBYTES);
assert(length < INT32_MAX);
return (int32_t)(length - crypto_box_MACBYTES);
}
int32_t encrypt_data(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
int32_t encrypt_data(const Memory *mem,
const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
const uint8_t secret_key[CRYPTO_SECRET_KEY_SIZE],
const uint8_t nonce[CRYPTO_NONCE_SIZE],
const uint8_t *plain, size_t length, uint8_t *encrypted)
@ -356,12 +361,13 @@ int32_t encrypt_data(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
uint8_t k[crypto_box_BEFORENMBYTES];
encrypt_precompute(public_key, secret_key, k);
const int ret = encrypt_data_symmetric(k, nonce, plain, length, encrypted);
const int ret = encrypt_data_symmetric(mem, k, nonce, plain, length, encrypted);
crypto_memzero(k, sizeof(k));
return ret;
}
int32_t decrypt_data(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
int32_t decrypt_data(const Memory *mem,
const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
const uint8_t secret_key[CRYPTO_SECRET_KEY_SIZE],
const uint8_t nonce[CRYPTO_NONCE_SIZE],
const uint8_t *encrypted, size_t length, uint8_t *plain)
@ -372,7 +378,7 @@ int32_t decrypt_data(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
uint8_t k[crypto_box_BEFORENMBYTES];
encrypt_precompute(public_key, secret_key, k);
const int ret = decrypt_data_symmetric(k, nonce, encrypted, length, plain);
const int ret = decrypt_data_symmetric(mem, k, nonce, encrypted, length, plain);
crypto_memzero(k, sizeof(k));
return ret;
}

View File

@ -16,6 +16,7 @@
#include <stdint.h>
#include "attributes.h"
#include "mem.h"
#ifdef __cplusplus
extern "C" {
@ -386,7 +387,8 @@ void crypto_derive_public_key(uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
* @return length of encrypted data if everything was fine.
*/
non_null()
int32_t encrypt_data(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
int32_t encrypt_data(const Memory *mem,
const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
const uint8_t secret_key[CRYPTO_SECRET_KEY_SIZE],
const uint8_t nonce[CRYPTO_NONCE_SIZE],
const uint8_t *plain, size_t length, uint8_t *encrypted);
@ -403,7 +405,8 @@ int32_t encrypt_data(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
* @return length of plain text data if everything was fine.
*/
non_null()
int32_t decrypt_data(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
int32_t decrypt_data(const Memory *mem,
const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
const uint8_t secret_key[CRYPTO_SECRET_KEY_SIZE],
const uint8_t nonce[CRYPTO_NONCE_SIZE],
const uint8_t *encrypted, size_t length, uint8_t *plain);
@ -431,7 +434,8 @@ int32_t encrypt_precompute(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
* @return length of encrypted data if everything was fine.
*/
non_null()
int32_t encrypt_data_symmetric(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE],
int32_t encrypt_data_symmetric(const Memory *mem,
const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE],
const uint8_t nonce[CRYPTO_NONCE_SIZE],
const uint8_t *plain, size_t length, uint8_t *encrypted);
@ -446,7 +450,8 @@ int32_t encrypt_data_symmetric(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE],
* @return length of plain data if everything was fine.
*/
non_null()
int32_t decrypt_data_symmetric(const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE],
int32_t decrypt_data_symmetric(const Memory *mem,
const uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE],
const uint8_t nonce[CRYPTO_NONCE_SIZE],
const uint8_t *encrypted, size_t length, uint8_t *plain);

View File

@ -7,6 +7,7 @@
#include <vector>
#include "crypto_core_test_util.hh"
#include "mem_test_util.hh"
#include "util.h"
namespace {
@ -17,8 +18,38 @@ 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>;
TEST(PkEqual, TwoRandomIdsAreNotEqual)
{
std::mt19937 rng;
std::uniform_int_distribution<unsigned short> dist{0, UINT8_MAX};
uint8_t pk1[CRYPTO_PUBLIC_KEY_SIZE];
uint8_t pk2[CRYPTO_PUBLIC_KEY_SIZE];
std::generate(std::begin(pk1), std::end(pk1), [&]() { return dist(rng); });
std::generate(std::begin(pk2), std::end(pk2), [&]() { return dist(rng); });
EXPECT_FALSE(pk_equal(pk1, pk2));
}
TEST(PkEqual, IdCopyMakesKeysEqual)
{
std::mt19937 rng;
std::uniform_int_distribution<unsigned short> dist{0, UINT8_MAX};
uint8_t pk1[CRYPTO_PUBLIC_KEY_SIZE];
uint8_t pk2[CRYPTO_PUBLIC_KEY_SIZE] = {0};
std::generate(std::begin(pk1), std::end(pk1), [&]() { return dist(rng); });
pk_copy(pk2, pk1);
EXPECT_TRUE(pk_equal(pk1, pk2));
}
TEST(CryptoCore, EncryptLargeData)
{
Test_Memory mem;
Test_Random rng;
Nonce nonce{};
@ -30,7 +61,8 @@ TEST(CryptoCore, EncryptLargeData)
std::vector<uint8_t> plain(100 * 1024 * 1024);
std::vector<uint8_t> encrypted(plain.size() + CRYPTO_MAC_SIZE);
encrypt_data(pk.data(), sk.data(), nonce.data(), plain.data(), plain.size(), encrypted.data());
encrypt_data(
mem, pk.data(), sk.data(), nonce.data(), plain.data(), plain.size(), encrypted.data());
}
TEST(CryptoCore, IncrementNonce)

View File

@ -9,7 +9,7 @@
#include "group.h"
#include <assert.h>
#include <stdlib.h>
#include <stdlib.h> // calloc, free
#include <string.h>
#include "DHT.h"
@ -20,9 +20,11 @@
#include "friend_connection.h"
#include "group_common.h"
#include "logger.h"
#include "mem.h"
#include "mono_time.h"
#include "net_crypto.h"
#include "network.h"
#include "sort.h"
#include "state.h"
#include "util.h"
@ -957,24 +959,75 @@ static bool delpeer(Group_Chats *g_c, uint32_t groupnumber, int peer_index, void
/** Order peers with friends first and with more recently active earlier */
non_null()
static int cmp_frozen(const void *a, const void *b)
static bool group_peer_less_handler(const void *object, const void *a, const void *b)
{
const Group_Peer *pa = (const Group_Peer *)a;
const Group_Peer *pb = (const Group_Peer *)b;
if (pa->is_friend ^ pb->is_friend) {
return pa->is_friend ? -1 : 1;
if (((pa->is_friend ? 1 : 0) ^ (pb->is_friend ? 1 : 0)) != 0) {
return pa->is_friend;
}
return cmp_uint(pb->last_active, pa->last_active);
return cmp_uint(pb->last_active, pa->last_active) < 0;
}
non_null()
static const void *group_peer_get_handler(const void *arr, uint32_t index)
{
const Group_Peer *entries = (const Group_Peer *)arr;
return &entries[index];
}
non_null()
static void group_peer_set_handler(void *arr, uint32_t index, const void *val)
{
Group_Peer *entries = (Group_Peer *)arr;
const Group_Peer *entry = (const Group_Peer *)val;
entries[index] = *entry;
}
non_null()
static void *group_peer_subarr_handler(void *arr, uint32_t index, uint32_t size)
{
Group_Peer *entries = (Group_Peer *)arr;
return &entries[index];
}
non_null()
static void *group_peer_alloc_handler(const void *object, uint32_t size)
{
const Memory *mem = (const Memory *)object;
Group_Peer *tmp = (Group_Peer *)mem_valloc(mem, size, sizeof(Group_Peer));
if (tmp == nullptr) {
return nullptr;
}
return tmp;
}
non_null()
static void group_peer_delete_handler(const void *object, void *arr, uint32_t size)
{
const Memory *mem = (const Memory *)object;
mem_delete(mem, arr);
}
static const Sort_Funcs group_peer_cmp_funcs = {
group_peer_less_handler,
group_peer_get_handler,
group_peer_set_handler,
group_peer_subarr_handler,
group_peer_alloc_handler,
group_peer_delete_handler,
};
/** @brief Delete frozen peers as necessary to ensure at most `g->maxfrozen` remain.
*
* @retval true if any frozen peers are removed.
*/
non_null()
static bool delete_old_frozen(Group_c *g)
static bool delete_old_frozen(Group_c *g, const Memory *mem)
{
if (g->numfrozen <= g->maxfrozen) {
return false;
@ -987,7 +1040,7 @@ static bool delete_old_frozen(Group_c *g)
return true;
}
qsort(g->frozen, g->numfrozen, sizeof(Group_Peer), cmp_frozen);
merge_sort(g->frozen, g->numfrozen, mem, &group_peer_cmp_funcs);
Group_Peer *temp = (Group_Peer *)realloc(g->frozen, g->maxfrozen * sizeof(Group_Peer));
@ -1032,7 +1085,7 @@ static bool freeze_peer(Group_Chats *g_c, uint32_t groupnumber, int peer_index,
++g->numfrozen;
delete_old_frozen(g);
delete_old_frozen(g, g_c->m->mem);
return true;
}
@ -1519,7 +1572,7 @@ int group_set_max_frozen(const Group_Chats *g_c, uint32_t groupnumber, uint32_t
}
g->maxfrozen = maxfrozen;
delete_old_frozen(g);
delete_old_frozen(g, g_c->m->mem);
return 0;
}

View File

@ -30,6 +30,7 @@
#include "group_moderation.h"
#include "group_pack.h"
#include "logger.h"
#include "mem.h"
#include "mono_time.h"
#include "net_crypto.h"
#include "network.h"
@ -1473,8 +1474,8 @@ static bool sign_gc_shared_state(GC_Chat *chat)
* Return -2 on decryption failure.
* Return -3 if plaintext payload length is invalid.
*/
non_null(1, 2, 3, 5, 6) nullable(4)
static int group_packet_unwrap(const Logger *log, const GC_Connection *gconn, uint8_t *data, uint64_t *message_id,
non_null(1, 2, 3, 4, 6, 7) nullable(5)
static int group_packet_unwrap(const Logger *log, const Memory *mem, const GC_Connection *gconn, uint8_t *data, uint64_t *message_id,
uint8_t *packet_type, const uint8_t *packet, uint16_t length)
{
assert(data != nullptr);
@ -1492,7 +1493,7 @@ static int group_packet_unwrap(const Logger *log, const GC_Connection *gconn, ui
return -1;
}
int plain_len = decrypt_data_symmetric(gconn->session_shared_key, packet, packet + CRYPTO_NONCE_SIZE,
int plain_len = decrypt_data_symmetric(mem, gconn->session_shared_key, packet, packet + CRYPTO_NONCE_SIZE,
length - CRYPTO_NONCE_SIZE, plain);
if (plain_len <= 0) {
@ -1533,7 +1534,7 @@ static int group_packet_unwrap(const Logger *log, const GC_Connection *gconn, ui
}
int group_packet_wrap(
const Logger *log, const Random *rng, const uint8_t *self_pk, const uint8_t *shared_key, uint8_t *packet,
const Logger *log, const Memory *mem, const Random *rng, const uint8_t *self_pk, const uint8_t *shared_key, uint8_t *packet,
uint16_t packet_size, const uint8_t *data, uint16_t length, uint64_t message_id,
uint8_t gp_packet_type, Net_Packet_Type net_packet_type)
{
@ -1588,7 +1589,7 @@ int group_packet_wrap(
return -2;
}
const int enc_len = encrypt_data_symmetric(shared_key, nonce, plain, plain_len, encrypt);
const int enc_len = encrypt_data_symmetric(mem, shared_key, nonce, plain, plain_len, encrypt);
free(plain);
@ -1634,7 +1635,7 @@ static bool send_lossy_group_packet(const GC_Chat *chat, const GC_Connection *gc
}
const int len = group_packet_wrap(
chat->log, chat->rng, chat->self_public_key.enc, gconn->session_shared_key, packet,
chat->log, chat->mem, chat->rng, chat->self_public_key.enc, gconn->session_shared_key, packet,
packet_size, data, length, 0, packet_type, NET_PACKET_GC_LOSSY);
if (len < 0) {
@ -5508,7 +5509,7 @@ static int handle_gc_broadcast(const GC_Session *c, GC_Chat *chat, uint32_t peer
* Return -2 if decryption fails.
*/
non_null()
static int unwrap_group_handshake_packet(const Logger *log, const uint8_t *self_sk, const uint8_t *sender_pk,
static int unwrap_group_handshake_packet(const Logger *log, const Memory *mem, const uint8_t *self_sk, const uint8_t *sender_pk,
uint8_t *plain, size_t plain_size, const uint8_t *packet, uint16_t length)
{
if (length <= CRYPTO_NONCE_SIZE) {
@ -5516,7 +5517,7 @@ static int unwrap_group_handshake_packet(const Logger *log, const uint8_t *self_
return -1;
}
const int plain_len = decrypt_data(sender_pk, self_sk, packet, packet + CRYPTO_NONCE_SIZE,
const int plain_len = decrypt_data(mem, sender_pk, self_sk, packet, packet + CRYPTO_NONCE_SIZE,
length - CRYPTO_NONCE_SIZE, plain);
if (plain_len < 0 || (uint32_t)plain_len != plain_size) {
@ -5539,7 +5540,7 @@ static int unwrap_group_handshake_packet(const Logger *log, const uint8_t *self_
*/
non_null()
static int wrap_group_handshake_packet(
const Logger *log, const Random *rng, const uint8_t *self_pk, const uint8_t *self_sk,
const Logger *log, const Memory *mem, const Random *rng, const uint8_t *self_pk, const uint8_t *self_sk,
const uint8_t *target_pk, uint8_t *packet, uint32_t packet_size,
const uint8_t *data, uint16_t length)
{
@ -5558,7 +5559,7 @@ static int wrap_group_handshake_packet(
return -2;
}
const int enc_len = encrypt_data(target_pk, self_sk, nonce, data, length, encrypt);
const int enc_len = encrypt_data(mem, target_pk, self_sk, nonce, data, length, encrypt);
if (enc_len < 0 || (size_t)enc_len != encrypt_buf_size) {
LOGGER_ERROR(log, "Failed to encrypt group handshake packet (len: %d)", enc_len);
@ -5622,7 +5623,7 @@ static int make_gc_handshake_packet(const GC_Chat *chat, const GC_Connection *gc
}
const int enc_len = wrap_group_handshake_packet(
chat->log, chat->rng, chat->self_public_key.enc, chat->self_secret_key.enc,
chat->log, chat->mem, chat->rng, chat->self_public_key.enc, chat->self_secret_key.enc,
gconn->addr.public_key.enc, packet, (uint16_t)packet_size, data, length);
if (enc_len != GC_MIN_ENCRYPTED_HS_PAYLOAD_SIZE + nodes_size) {
@ -5951,7 +5952,7 @@ static int handle_gc_handshake_packet(GC_Chat *chat, const uint8_t *sender_pk, c
return -1;
}
const int plain_len = unwrap_group_handshake_packet(chat->log, chat->self_secret_key.enc, sender_pk, data,
const int plain_len = unwrap_group_handshake_packet(chat->log, chat->mem, chat->self_secret_key.enc, sender_pk, data,
data_buf_size, packet, length);
if (plain_len < GC_MIN_HS_PACKET_PAYLOAD_SIZE) {
@ -6181,7 +6182,7 @@ static bool handle_gc_lossless_packet(const GC_Session *c, GC_Chat *chat, const
uint8_t packet_type;
uint64_t message_id;
const int len = group_packet_unwrap(chat->log, gconn, data, &message_id, &packet_type, packet, length);
const int len = group_packet_unwrap(chat->log, chat->mem, gconn, data, &message_id, &packet_type, packet, length);
if (len < 0) {
Ip_Ntoa ip_str;
@ -6334,7 +6335,7 @@ static bool handle_gc_lossy_packet(const GC_Session *c, GC_Chat *chat, const uin
uint8_t packet_type;
const int len = group_packet_unwrap(chat->log, gconn, data, nullptr, &packet_type, packet, length);
const int len = group_packet_unwrap(chat->log, chat->mem, gconn, data, nullptr, &packet_type, packet, length);
if (len <= 0) {
Ip_Ntoa ip_str;

View File

@ -22,6 +22,7 @@
#include "group_common.h"
#include "group_connection.h"
#include "logger.h"
#include "mem.h"
#include "network.h"
#define GC_PING_TIMEOUT 12
@ -141,9 +142,9 @@ int get_peer_number_of_enc_pk(const GC_Chat *chat, const uint8_t *public_enc_key
* Return -2 if malloc fails.
* Return -3 if encryption fails.
*/
non_null(1, 2, 3, 4, 5) nullable(7)
non_null(1, 2, 3, 4, 5, 6) nullable(8)
int group_packet_wrap(
const Logger *log, const Random *rng, const uint8_t *self_pk, const uint8_t *shared_key, uint8_t *packet,
const Logger *log, const Memory *mem, const Random *rng, const uint8_t *self_pk, const uint8_t *shared_key, uint8_t *packet,
uint16_t packet_size, const uint8_t *data, uint16_t length, uint64_t message_id,
uint8_t gp_packet_type, Net_Packet_Type net_packet_type);

View File

@ -52,7 +52,7 @@
#define MAX_GC_PACKET_SIZE (MAX_GC_PACKET_CHUNK_SIZE * 100)
/* Max number of messages to store in the send/recv arrays */
#define GCC_BUFFER_SIZE 8192
#define GCC_BUFFER_SIZE 2048
/** Self UDP status. Must correspond to return values from `ipport_self_copy()`. */
typedef enum Self_UDP_Status {

View File

@ -629,7 +629,7 @@ int gcc_encrypt_and_send_lossless_packet(const GC_Chat *chat, const GC_Connectio
}
const int enc_len = group_packet_wrap(
chat->log, chat->rng, chat->self_public_key.enc, gconn->session_shared_key, packet,
chat->log, chat->mem, chat->rng, chat->self_public_key.enc, gconn->session_shared_key, packet,
packet_size, data, length, message_id, packet_type, NET_PACKET_GC_LOSSLESS);
if (enc_len < 0) {

View File

@ -14,6 +14,7 @@
#include "crypto_core.h"
#include "group_announce.h"
#include "logger.h"
#include "mem.h"
#include "mono_time.h"
#include "network.h"
#include "onion_announce.h"
@ -76,7 +77,7 @@ void gca_onion_init(GC_Announces_List *group_announce, Onion_Announce *onion_a)
}
int create_gca_announce_request(
const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *dest_client_id,
const Memory *mem, const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *dest_client_id,
const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *ping_id,
const uint8_t *client_id, const uint8_t *data_public_key, uint64_t sendback_data,
const uint8_t *gc_data, uint16_t gc_data_length)
@ -108,7 +109,7 @@ int create_gca_announce_request(
random_nonce(rng, packet + 1);
memcpy(packet + 1 + CRYPTO_NONCE_SIZE, public_key, CRYPTO_PUBLIC_KEY_SIZE);
const int len = encrypt_data(dest_client_id, secret_key, packet + 1, plain,
const int len = encrypt_data(mem, dest_client_id, secret_key, packet + 1, plain,
encrypted_size, packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE);
const uint32_t full_length = (uint32_t)len + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE;

View File

@ -9,6 +9,7 @@
#include "attributes.h"
#include "crypto_core.h"
#include "group_announce.h"
#include "mem.h"
#include "onion_announce.h"
non_null()
@ -16,7 +17,7 @@ void gca_onion_init(GC_Announces_List *group_announce, Onion_Announce *onion_a);
non_null()
int create_gca_announce_request(
const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *dest_client_id,
const Memory *mem, const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *dest_client_id,
const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *ping_id,
const uint8_t *client_id, const uint8_t *data_public_key, uint64_t sendback_data,
const uint8_t *gc_data, uint16_t gc_data_length);

View File

@ -23,7 +23,6 @@
#include "logger.h"
#include "mem.h"
#include "mono_time.h"
#include "net_profile.h"
#include "network.h"
#include "util.h"
@ -231,7 +230,7 @@ static int create_cookie_request(const Net_Crypto *c, uint8_t *packet, const uin
packet[0] = NET_PACKET_COOKIE_REQUEST;
memcpy(packet + 1, dht_get_self_public_key(c->dht), CRYPTO_PUBLIC_KEY_SIZE);
memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, nonce, CRYPTO_NONCE_SIZE);
const int len = encrypt_data_symmetric(shared_key, nonce, plain, sizeof(plain),
const int len = encrypt_data_symmetric(c->mem, shared_key, nonce, plain, sizeof(plain),
packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE);
if (len != COOKIE_REQUEST_PLAIN_LENGTH + CRYPTO_MAC_SIZE) {
@ -247,7 +246,7 @@ static int create_cookie_request(const Net_Crypto *c, uint8_t *packet, const uin
* @retval 0 on success.
*/
non_null()
static int create_cookie(const Random *rng, const Mono_Time *mono_time, uint8_t *cookie, const uint8_t *bytes,
static int create_cookie(const Memory *mem, const Random *rng, const Mono_Time *mono_time, uint8_t *cookie, const uint8_t *bytes,
const uint8_t *encryption_key)
{
uint8_t contents[COOKIE_CONTENTS_LENGTH];
@ -255,7 +254,7 @@ static int create_cookie(const Random *rng, const Mono_Time *mono_time, uint8_t
memcpy(contents, &temp_time, sizeof(temp_time));
memcpy(contents + sizeof(temp_time), bytes, COOKIE_DATA_LENGTH);
random_nonce(rng, cookie);
const int len = encrypt_data_symmetric(encryption_key, cookie, contents, sizeof(contents), cookie + CRYPTO_NONCE_SIZE);
const int len = encrypt_data_symmetric(mem, encryption_key, cookie, contents, sizeof(contents), cookie + CRYPTO_NONCE_SIZE);
if (len != COOKIE_LENGTH - CRYPTO_NONCE_SIZE) {
return -1;
@ -270,11 +269,11 @@ static int create_cookie(const Random *rng, const Mono_Time *mono_time, uint8_t
* @retval 0 on success.
*/
non_null()
static int open_cookie(const Mono_Time *mono_time, uint8_t *bytes, const uint8_t *cookie,
static int open_cookie(const Memory *mem, const Mono_Time *mono_time, uint8_t *bytes, const uint8_t *cookie,
const uint8_t *encryption_key)
{
uint8_t contents[COOKIE_CONTENTS_LENGTH];
const int len = decrypt_data_symmetric(encryption_key, cookie, cookie + CRYPTO_NONCE_SIZE,
const int len = decrypt_data_symmetric(mem, encryption_key, cookie, cookie + CRYPTO_NONCE_SIZE,
COOKIE_LENGTH - CRYPTO_NONCE_SIZE, contents);
if (len != sizeof(contents)) {
@ -309,14 +308,14 @@ static int create_cookie_response(const Net_Crypto *c, uint8_t *packet, const ui
memcpy(cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, dht_public_key, CRYPTO_PUBLIC_KEY_SIZE);
uint8_t plain[COOKIE_LENGTH + sizeof(uint64_t)];
if (create_cookie(c->rng, c->mono_time, plain, cookie_plain, c->secret_symmetric_key) != 0) {
if (create_cookie(c->mem, c->rng, c->mono_time, plain, cookie_plain, c->secret_symmetric_key) != 0) {
return -1;
}
memcpy(plain + COOKIE_LENGTH, request_plain + COOKIE_DATA_LENGTH, sizeof(uint64_t));
packet[0] = NET_PACKET_COOKIE_RESPONSE;
random_nonce(c->rng, packet + 1);
const int len = encrypt_data_symmetric(shared_key, packet + 1, plain, sizeof(plain), packet + 1 + CRYPTO_NONCE_SIZE);
const int len = encrypt_data_symmetric(c->mem, shared_key, packet + 1, plain, sizeof(plain), packet + 1 + CRYPTO_NONCE_SIZE);
if (len != COOKIE_RESPONSE_LENGTH - (1 + CRYPTO_NONCE_SIZE)) {
return -1;
@ -343,7 +342,7 @@ static int handle_cookie_request(const Net_Crypto *c, uint8_t *request_plain, ui
memcpy(dht_public_key, packet + 1, CRYPTO_PUBLIC_KEY_SIZE);
const uint8_t *tmp_shared_key = dht_get_shared_key_sent(c->dht, dht_public_key);
memcpy(shared_key, tmp_shared_key, CRYPTO_SHARED_KEY_SIZE);
const int len = decrypt_data_symmetric(shared_key, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE,
const int len = decrypt_data_symmetric(c->mem, shared_key, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE,
packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, COOKIE_REQUEST_PLAIN_LENGTH + CRYPTO_MAC_SIZE,
request_plain);
@ -440,7 +439,7 @@ static int tcp_oob_handle_cookie_request(const Net_Crypto *c, unsigned int tcp_c
* @retval COOKIE_LENGTH on success.
*/
non_null()
static int handle_cookie_response(uint8_t *cookie, uint64_t *number,
static int handle_cookie_response(const Memory *mem, uint8_t *cookie, uint64_t *number,
const uint8_t *packet, uint16_t length,
const uint8_t *shared_key)
{
@ -449,7 +448,7 @@ static int handle_cookie_response(uint8_t *cookie, uint64_t *number,
}
uint8_t plain[COOKIE_LENGTH + sizeof(uint64_t)];
const int len = decrypt_data_symmetric(shared_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE,
const int len = decrypt_data_symmetric(mem, shared_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE,
length - (1 + CRYPTO_NONCE_SIZE), plain);
if (len != sizeof(plain)) {
@ -482,13 +481,13 @@ static int create_crypto_handshake(const Net_Crypto *c, uint8_t *packet, const u
memcpy(cookie_plain, peer_real_pk, CRYPTO_PUBLIC_KEY_SIZE);
memcpy(cookie_plain + CRYPTO_PUBLIC_KEY_SIZE, peer_dht_pubkey, CRYPTO_PUBLIC_KEY_SIZE);
if (create_cookie(c->rng, c->mono_time, plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE,
if (create_cookie(c->mem, c->rng, c->mono_time, plain + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE,
cookie_plain, c->secret_symmetric_key) != 0) {
return -1;
}
random_nonce(c->rng, packet + 1 + COOKIE_LENGTH);
const int len = encrypt_data(peer_real_pk, c->self_secret_key, packet + 1 + COOKIE_LENGTH, plain, sizeof(plain),
const int len = encrypt_data(c->mem, peer_real_pk, c->self_secret_key, packet + 1 + COOKIE_LENGTH, plain, sizeof(plain),
packet + 1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE);
if (len != HANDSHAKE_PACKET_LENGTH - (1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE)) {
@ -529,7 +528,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t
uint8_t cookie_plain[COOKIE_DATA_LENGTH];
if (open_cookie(c->mono_time, cookie_plain, packet + 1, c->secret_symmetric_key) != 0) {
if (open_cookie(c->mem, c->mono_time, cookie_plain, packet + 1, c->secret_symmetric_key) != 0) {
return false;
}
@ -541,7 +540,7 @@ static bool handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t
crypto_sha512(cookie_hash, packet + 1, COOKIE_LENGTH);
uint8_t plain[CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SHA512_SIZE + COOKIE_LENGTH];
const int len = decrypt_data(cookie_plain, c->self_secret_key, packet + 1 + COOKIE_LENGTH,
const int len = decrypt_data(c->mem, cookie_plain, c->self_secret_key, packet + 1 + COOKIE_LENGTH,
packet + 1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE,
HANDSHAKE_PACKET_LENGTH - (1 + COOKIE_LENGTH + CRYPTO_NONCE_SIZE), plain);
@ -1085,7 +1084,7 @@ static int send_data_packet(Net_Crypto *c, int crypt_connection_id, const uint8_
VLA(uint8_t, packet, packet_size);
packet[0] = NET_PACKET_CRYPTO_DATA;
memcpy(packet + 1, conn->sent_nonce + (CRYPTO_NONCE_SIZE - sizeof(uint16_t)), sizeof(uint16_t));
const int len = encrypt_data_symmetric(conn->shared_key, conn->sent_nonce, data, length, packet + 1 + sizeof(uint16_t));
const int len = encrypt_data_symmetric(c->mem, conn->shared_key, conn->sent_nonce, data, length, packet + 1 + sizeof(uint16_t));
if (len + 1 + sizeof(uint16_t) != packet_size) {
LOGGER_ERROR(c->log, "encryption failed: %d", len);
@ -1256,7 +1255,7 @@ static int handle_data_packet(const Net_Crypto *c, int crypt_connection_id, uint
net_unpack_u16(packet + 1, &num);
const uint16_t diff = num - num_cur_nonce;
increment_nonce_number(nonce, diff);
const int len = decrypt_data_symmetric(conn->shared_key, nonce, packet + 1 + sizeof(uint16_t),
const int len = decrypt_data_symmetric(c->mem, conn->shared_key, nonce, packet + 1 + sizeof(uint16_t),
length - (1 + sizeof(uint16_t)), data);
if ((unsigned int)len != length - crypto_packet_overhead) {
@ -1663,7 +1662,7 @@ static int handle_packet_cookie_response(Net_Crypto *c, int crypt_connection_id,
uint8_t cookie[COOKIE_LENGTH];
uint64_t number;
if (handle_cookie_response(cookie, &number, packet, length, conn->shared_key) != sizeof(cookie)) {
if (handle_cookie_response(c->mem, cookie, &number, packet, length, conn->shared_key) != sizeof(cookie)) {
return -1;
}
@ -3097,18 +3096,3 @@ void kill_net_crypto(Net_Crypto *c)
crypto_memzero(c, sizeof(Net_Crypto));
mem_delete(mem, c);
}
const Net_Profile *nc_get_tcp_client_net_profile(const Net_Crypto *c)
{
if (c == nullptr) {
return nullptr;
}
const TCP_Connections *tcp_c = nc_get_tcp_c(c);
if (tcp_c == nullptr) {
return nullptr;
}
return tcp_connection_get_client_net_profile(tcp_c);
}

View File

@ -20,7 +20,6 @@
#include "logger.h"
#include "mem.h"
#include "mono_time.h"
#include "net_profile.h"
#include "network.h"
/*** Crypto payloads. */
@ -418,11 +417,4 @@ void do_net_crypto(Net_Crypto *c, void *userdata);
nullable(1)
void kill_net_crypto(Net_Crypto *c);
/**
* Returns a pointer to the net profile object for the TCP client associated with `c`.
* Returns null if `c` is null or the TCP_Connections associated with `c` is null.
*/
non_null()
const Net_Profile *nc_get_tcp_client_net_profile(const Net_Crypto *c);
#endif /* C_TOXCORE_TOXCORE_NET_CRYPTO_H */

View File

@ -1,157 +0,0 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright © 2023-2024 The TokTok team.
*/
/**
* Functions for the network profile.
*/
#include "net_profile.h"
#include <stdint.h>
#include "attributes.h"
#include "logger.h"
#include "mem.h"
#include "ccompat.h"
#define NETPROF_TCP_DATA_PACKET_ID 0x10
typedef struct Net_Profile {
uint64_t packets_recv[NET_PROF_MAX_PACKET_IDS];
uint64_t packets_sent[NET_PROF_MAX_PACKET_IDS];
uint64_t total_packets_recv;
uint64_t total_packets_sent;
uint64_t bytes_recv[NET_PROF_MAX_PACKET_IDS];
uint64_t bytes_sent[NET_PROF_MAX_PACKET_IDS];
uint64_t total_bytes_recv;
uint64_t total_bytes_sent;
} Net_Profile;
/** Returns the number of sent or received packets for all ID's between `start_id` and `end_id`. */
nullable(1)
static uint64_t netprof_get_packet_count_id_range(const Net_Profile *profile, uint8_t start_id, uint8_t end_id,
Packet_Direction dir)
{
if (profile == nullptr) {
return 0;
}
const uint64_t *arr = dir == PACKET_DIRECTION_SEND ? profile->packets_sent : profile->packets_recv;
uint64_t count = 0;
for (size_t i = start_id; i <= end_id; ++i) {
count += arr[i];
}
return count;
}
/** Returns the number of sent or received bytes for all ID's between `start_id` and `end_id`. */
nullable(1)
static uint64_t netprof_get_bytes_id_range(const Net_Profile *profile, uint8_t start_id, uint8_t end_id,
Packet_Direction dir)
{
if (profile == nullptr) {
return 0;
}
const uint64_t *arr = dir == PACKET_DIRECTION_SEND ? profile->bytes_sent : profile->bytes_recv;
uint64_t bytes = 0;
for (size_t i = start_id; i <= end_id; ++i) {
bytes += arr[i];
}
return bytes;
}
void netprof_record_packet(Net_Profile *profile, uint8_t id, size_t length, Packet_Direction dir)
{
if (profile == nullptr) {
return;
}
if (dir == PACKET_DIRECTION_SEND) {
++profile->total_packets_sent;
++profile->packets_sent[id];
profile->total_bytes_sent += length;
profile->bytes_sent[id] += length;
} else {
++profile->total_packets_recv;
++profile->packets_recv[id];
profile->total_bytes_recv += length;
profile->bytes_recv[id] += length;
}
}
uint64_t netprof_get_packet_count_id(const Net_Profile *profile, uint8_t id, Packet_Direction dir)
{
if (profile == nullptr) {
return 0;
}
// Special case - TCP data packets can have any ID between 0x10 and 0xff
if (id == NETPROF_TCP_DATA_PACKET_ID) {
return netprof_get_packet_count_id_range(profile, id, UINT8_MAX, dir);
}
return dir == PACKET_DIRECTION_SEND ? profile->packets_sent[id] : profile->packets_recv[id];
}
uint64_t netprof_get_packet_count_total(const Net_Profile *profile, Packet_Direction dir)
{
if (profile == nullptr) {
return 0;
}
return dir == PACKET_DIRECTION_SEND ? profile->total_packets_sent : profile->total_packets_recv;
}
uint64_t netprof_get_bytes_id(const Net_Profile *profile, uint8_t id, Packet_Direction dir)
{
if (profile == nullptr) {
return 0;
}
// Special case - TCP data packets can have any ID between 0x10 and 0xff
if (id == NETPROF_TCP_DATA_PACKET_ID) {
return netprof_get_bytes_id_range(profile, id, 0xff, dir);
}
return dir == PACKET_DIRECTION_SEND ? profile->bytes_sent[id] : profile->bytes_recv[id];
}
uint64_t netprof_get_bytes_total(const Net_Profile *profile, Packet_Direction dir)
{
if (profile == nullptr) {
return 0;
}
return dir == PACKET_DIRECTION_SEND ? profile->total_bytes_sent : profile->total_bytes_recv;
}
Net_Profile *netprof_new(const Logger *log, const Memory *mem)
{
Net_Profile *np = (Net_Profile *)mem_alloc(mem, sizeof(Net_Profile));
if (np == nullptr) {
LOGGER_ERROR(log, "failed to allocate memory for net profiler");
return nullptr;
}
return np;
}
void netprof_kill(const Memory *mem, Net_Profile *net_profile)
{
if (net_profile != nullptr) {
mem_delete(mem, net_profile);
}
}

View File

@ -1,73 +0,0 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright © 2023-2024 The TokTok team.
*/
/**
* Functions for the network profile.
*/
#ifndef C_TOXCORE_TOXCORE_NET_PROFILE_H
#define C_TOXCORE_TOXCORE_NET_PROFILE_H
#include <stddef.h>
#include <stdint.h>
#include "attributes.h"
#include "logger.h"
#include "mem.h"
/* The max number of packet ID's (must fit inside one byte) */
#define NET_PROF_MAX_PACKET_IDS 256
/* If passed to a netprof function as a nullptr the function will have no effect. */
typedef struct Net_Profile Net_Profile;
/** Specifies whether the query is for sent or received packets. */
typedef enum Packet_Direction {
PACKET_DIRECTION_SEND,
PACKET_DIRECTION_RECV,
} Packet_Direction;
/**
* Records a sent or received packet of type `id` and size `length` to the given profile.
*/
nullable(1)
void netprof_record_packet(Net_Profile *profile, uint8_t id, size_t length, Packet_Direction dir);
/**
* Returns the number of sent or received packets of type `id` for the given profile.
*/
nullable(1)
uint64_t netprof_get_packet_count_id(const Net_Profile *profile, uint8_t id, Packet_Direction dir);
/**
* Returns the total number of sent or received packets for the given profile.
*/
nullable(1)
uint64_t netprof_get_packet_count_total(const Net_Profile *profile, Packet_Direction dir);
/**
* Returns the number of bytes sent or received of packet type `id` for the given profile.
*/
nullable(1)
uint64_t netprof_get_bytes_id(const Net_Profile *profile, uint8_t id, Packet_Direction dir);
/**
* Returns the total number of bytes sent or received for the given profile.
*/
nullable(1)
uint64_t netprof_get_bytes_total(const Net_Profile *profile, Packet_Direction dir);
/**
* Returns a new net_profile object. The caller is responsible for freeing the
* returned memory via `netprof_kill`.
*/
non_null()
Net_Profile *netprof_new(const Logger *log, const Memory *mem);
/**
* Kills a net_profile object and frees all associated memory.
*/
non_null(1) nullable(2)
void netprof_kill(const Memory *mem, Net_Profile *net_profile);
#endif /* C_TOXCORE_TOXCORE_NET_PROFILE_H */

View File

@ -86,7 +86,6 @@
#include "ccompat.h"
#include "logger.h"
#include "mem.h"
#include "net_profile.h"
#include "util.h"
// Disable MSG_NOSIGNAL on systems not supporting it, e.g. Windows, FreeBSD
@ -908,14 +907,9 @@ static void loglogdata(const Logger *log, const char *message, const uint8_t *bu
}
int net_send(const Network *ns, const Logger *log,
Socket sock, const uint8_t *buf, size_t len, const IP_Port *ip_port, Net_Profile *net_profile)
Socket sock, const uint8_t *buf, size_t len, const IP_Port *ip_port)
{
const int res = ns->funcs->send(ns->obj, sock, buf, len);
if (res > 0) {
netprof_record_packet(net_profile, buf[0], res, PACKET_DIRECTION_SEND);
}
loglogdata(log, "T=>", buf, len, ip_port, res);
return res;
}
@ -1019,8 +1013,6 @@ struct Networking_Core {
uint16_t port;
/* Our UDP socket. */
Socket sock;
Net_Profile *udp_net_profile;
};
Family net_family(const Networking_Core *net)
@ -1106,11 +1098,6 @@ int send_packet(const Networking_Core *net, const IP_Port *ip_port, Packet packe
loglogdata(net->log, "O=>", packet.data, packet.length, ip_port, res);
assert(res <= INT_MAX);
if (res == packet.length && packet.data != nullptr) {
netprof_record_packet(net->udp_net_profile, packet.data[0], packet.length, PACKET_DIRECTION_SEND);
}
return (int)res;
}
@ -1215,8 +1202,6 @@ void networking_poll(const Networking_Core *net, void *userdata)
continue;
}
netprof_record_packet(net->udp_net_profile, data[0], length, PACKET_DIRECTION_RECV);
const Packet_Handler *const handler = &net->packethandlers[data[0]];
if (handler->function == nullptr) {
@ -1277,14 +1262,6 @@ Networking_Core *new_networking_ex(
return nullptr;
}
Net_Profile *np = netprof_new(log, mem);
if (np == nullptr) {
free(temp);
return nullptr;
}
temp->udp_net_profile = np;
temp->ns = ns;
temp->log = log;
temp->mem = mem;
@ -1301,7 +1278,6 @@ Networking_Core *new_networking_ex(
char *strerror = net_new_strerror(neterror);
LOGGER_ERROR(log, "failed to get a socket?! %d, %s", neterror, strerror);
net_kill_strerror(strerror);
netprof_kill(mem, temp->udp_net_profile);
mem_delete(mem, temp);
if (error != nullptr) {
@ -1509,7 +1485,6 @@ void kill_networking(Networking_Core *net)
kill_sock(net->ns, net->sock);
}
netprof_kill(net->mem, net->udp_net_profile);
mem_delete(net->mem, net);
}
@ -2418,12 +2393,3 @@ void net_kill_strerror(char *strerror)
free(strerror);
#endif /* OS_WIN32 */
}
const Net_Profile *net_get_net_profile(const Networking_Core *net)
{
if (net == nullptr) {
return nullptr;
}
return net->udp_net_profile;
}

View File

@ -17,7 +17,6 @@
#include "bin_pack.h"
#include "logger.h"
#include "mem.h"
#include "net_profile.h"
#ifdef __cplusplus
extern "C" {
@ -237,9 +236,8 @@ Socket net_invalid_socket(void);
/**
* Calls send(sockfd, buf, len, MSG_NOSIGNAL).
*/
non_null(1, 2, 4, 6) nullable(7)
int net_send(const Network *ns, const Logger *log, Socket sock, const uint8_t *buf, size_t len, const IP_Port *ip_port,
Net_Profile *net_profile);
non_null()
int net_send(const Network *ns, const Logger *log, Socket sock, const uint8_t *buf, size_t len, const IP_Port *ip_port);
/**
* Calls recv(sockfd, buf, len, MSG_NOSIGNAL).
*/
@ -616,13 +614,6 @@ Networking_Core *new_networking_no_udp(const Logger *log, const Memory *mem, con
nullable(1)
void kill_networking(Networking_Core *net);
/** @brief Returns a pointer to the network net_profile object associated with `net`.
*
* Returns null if `net` is null.
*/
non_null()
const Net_Profile *net_get_net_profile(const Networking_Core *net);
#ifdef __cplusplus
} /* extern "C" */
#endif

View File

@ -180,7 +180,7 @@ int onion_path_to_nodes(Node_format *nodes, unsigned int num_nodes, const Onion_
* return -1 on failure.
* return length of created packet on success.
*/
int create_onion_packet(const Random *rng, uint8_t *packet, uint16_t max_packet_length,
int create_onion_packet(const Memory *mem, const Random *rng, uint8_t *packet, uint16_t max_packet_length,
const Onion_Path *path, const IP_Port *dest,
const uint8_t *data, uint16_t length)
{
@ -202,7 +202,7 @@ int create_onion_packet(const Random *rng, uint8_t *packet, uint16_t max_packet_
ipport_pack(step2, &path->ip_port3);
memcpy(step2 + SIZE_IPPORT, path->public_key3, CRYPTO_PUBLIC_KEY_SIZE);
int len = encrypt_data_symmetric(path->shared_key3, nonce, step1, step1_size,
int len = encrypt_data_symmetric(mem, path->shared_key3, nonce, step1, step1_size,
step2 + SIZE_IPPORT + CRYPTO_PUBLIC_KEY_SIZE);
if (len != SIZE_IPPORT + length + CRYPTO_MAC_SIZE) {
@ -213,7 +213,7 @@ int create_onion_packet(const Random *rng, uint8_t *packet, uint16_t max_packet_
VLA(uint8_t, step3, step3_size);
ipport_pack(step3, &path->ip_port2);
memcpy(step3 + SIZE_IPPORT, path->public_key2, CRYPTO_PUBLIC_KEY_SIZE);
len = encrypt_data_symmetric(path->shared_key2, nonce, step2, step2_size,
len = encrypt_data_symmetric(mem, path->shared_key2, nonce, step2, step2_size,
step3 + SIZE_IPPORT + CRYPTO_PUBLIC_KEY_SIZE);
if (len != SIZE_IPPORT + SEND_BASE + length + CRYPTO_MAC_SIZE) {
@ -224,7 +224,7 @@ int create_onion_packet(const Random *rng, uint8_t *packet, uint16_t max_packet_
memcpy(packet + 1, nonce, CRYPTO_NONCE_SIZE);
memcpy(packet + 1 + CRYPTO_NONCE_SIZE, path->public_key1, CRYPTO_PUBLIC_KEY_SIZE);
len = encrypt_data_symmetric(path->shared_key1, nonce, step3, step3_size,
len = encrypt_data_symmetric(mem, path->shared_key1, nonce, step3, step3_size,
packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE);
if (len != SIZE_IPPORT + SEND_BASE * 2 + length + CRYPTO_MAC_SIZE) {
@ -243,7 +243,7 @@ int create_onion_packet(const Random *rng, uint8_t *packet, uint16_t max_packet_
* return -1 on failure.
* return length of created packet on success.
*/
int create_onion_packet_tcp(const Random *rng, uint8_t *packet, uint16_t max_packet_length,
int create_onion_packet_tcp(const Memory *mem, const Random *rng, uint8_t *packet, uint16_t max_packet_length,
const Onion_Path *path, const IP_Port *dest,
const uint8_t *data, uint16_t length)
{
@ -265,7 +265,7 @@ int create_onion_packet_tcp(const Random *rng, uint8_t *packet, uint16_t max_pac
ipport_pack(step2, &path->ip_port3);
memcpy(step2 + SIZE_IPPORT, path->public_key3, CRYPTO_PUBLIC_KEY_SIZE);
int len = encrypt_data_symmetric(path->shared_key3, nonce, step1, step1_size,
int len = encrypt_data_symmetric(mem, path->shared_key3, nonce, step1, step1_size,
step2 + SIZE_IPPORT + CRYPTO_PUBLIC_KEY_SIZE);
if (len != SIZE_IPPORT + length + CRYPTO_MAC_SIZE) {
@ -274,7 +274,7 @@ int create_onion_packet_tcp(const Random *rng, uint8_t *packet, uint16_t max_pac
ipport_pack(packet + CRYPTO_NONCE_SIZE, &path->ip_port2);
memcpy(packet + CRYPTO_NONCE_SIZE + SIZE_IPPORT, path->public_key2, CRYPTO_PUBLIC_KEY_SIZE);
len = encrypt_data_symmetric(path->shared_key2, nonce, step2, step2_size,
len = encrypt_data_symmetric(mem, path->shared_key2, nonce, step2, step2_size,
packet + CRYPTO_NONCE_SIZE + SIZE_IPPORT + CRYPTO_PUBLIC_KEY_SIZE);
if (len != SIZE_IPPORT + SEND_BASE + length + CRYPTO_MAC_SIZE) {
@ -355,7 +355,7 @@ static int handle_send_initial(void *object, const IP_Port *source, const uint8_
}
const int len = decrypt_data_symmetric(
shared_key, &packet[nonce_start], &packet[ciphertext_start], ciphertext_length, plain);
onion->mem, shared_key, &packet[nonce_start], &packet[ciphertext_start], ciphertext_length, plain);
if (len != plaintext_length) {
LOGGER_TRACE(onion->log, "decrypt failed: %d != %d", len, plaintext_length);
@ -393,7 +393,7 @@ int onion_send_1(const Onion *onion, const uint8_t *plain, uint16_t len, const I
uint16_t data_len = 1 + CRYPTO_NONCE_SIZE + (len - SIZE_IPPORT);
uint8_t *ret_part = data + data_len;
random_nonce(onion->rng, ret_part);
len = encrypt_data_symmetric(onion->secret_symmetric_key, ret_part, ip_port, SIZE_IPPORT,
len = encrypt_data_symmetric(onion->mem, onion->secret_symmetric_key, ret_part, ip_port, SIZE_IPPORT,
ret_part + CRYPTO_NONCE_SIZE);
if (len != SIZE_IPPORT + CRYPTO_MAC_SIZE) {
@ -436,7 +436,7 @@ static int handle_send_1(void *object, const IP_Port *source, const uint8_t *pac
return 1;
}
int len = decrypt_data_symmetric(shared_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE,
int len = decrypt_data_symmetric(onion->mem, shared_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE,
length - (1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + RETURN_1), plain);
if (len != length - (1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + RETURN_1 + CRYPTO_MAC_SIZE)) {
@ -459,7 +459,7 @@ static int handle_send_1(void *object, const IP_Port *source, const uint8_t *pac
uint8_t ret_data[RETURN_1 + SIZE_IPPORT];
ipport_pack(ret_data, source);
memcpy(ret_data + SIZE_IPPORT, packet + (length - RETURN_1), RETURN_1);
len = encrypt_data_symmetric(onion->secret_symmetric_key, ret_part, ret_data, sizeof(ret_data),
len = encrypt_data_symmetric(onion->mem, onion->secret_symmetric_key, ret_part, ret_data, sizeof(ret_data),
ret_part + CRYPTO_NONCE_SIZE);
if (len != RETURN_2 - CRYPTO_NONCE_SIZE) {
@ -502,7 +502,7 @@ static int handle_send_2(void *object, const IP_Port *source, const uint8_t *pac
return 1;
}
int len = decrypt_data_symmetric(shared_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE,
int len = decrypt_data_symmetric(onion->mem, shared_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE,
length - (1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + RETURN_2), plain);
if (len != length - (1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + RETURN_2 + CRYPTO_MAC_SIZE)) {
@ -532,7 +532,7 @@ static int handle_send_2(void *object, const IP_Port *source, const uint8_t *pac
uint8_t ret_data[RETURN_2 + SIZE_IPPORT];
ipport_pack(ret_data, source);
memcpy(ret_data + SIZE_IPPORT, packet + (length - RETURN_2), RETURN_2);
len = encrypt_data_symmetric(onion->secret_symmetric_key, ret_part, ret_data, sizeof(ret_data),
len = encrypt_data_symmetric(onion->mem, onion->secret_symmetric_key, ret_part, ret_data, sizeof(ret_data),
ret_part + CRYPTO_NONCE_SIZE);
if (len != RETURN_3 - CRYPTO_NONCE_SIZE) {
@ -574,7 +574,7 @@ static int handle_recv_3(void *object, const IP_Port *source, const uint8_t *pac
change_symmetric_key(onion);
uint8_t plain[SIZE_IPPORT + RETURN_2];
const int len = decrypt_data_symmetric(onion->secret_symmetric_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE,
const int len = decrypt_data_symmetric(onion->mem, onion->secret_symmetric_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE,
SIZE_IPPORT + RETURN_2 + CRYPTO_MAC_SIZE, plain);
if ((uint32_t)len != sizeof(plain)) {
@ -627,7 +627,7 @@ static int handle_recv_2(void *object, const IP_Port *source, const uint8_t *pac
change_symmetric_key(onion);
uint8_t plain[SIZE_IPPORT + RETURN_1];
const int len = decrypt_data_symmetric(onion->secret_symmetric_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE,
const int len = decrypt_data_symmetric(onion->mem, onion->secret_symmetric_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE,
SIZE_IPPORT + RETURN_1 + CRYPTO_MAC_SIZE, plain);
if ((uint32_t)len != sizeof(plain)) {
@ -679,7 +679,7 @@ static int handle_recv_1(void *object, const IP_Port *source, const uint8_t *pac
change_symmetric_key(onion);
uint8_t plain[SIZE_IPPORT];
const int len = decrypt_data_symmetric(onion->secret_symmetric_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE,
const int len = decrypt_data_symmetric(onion->mem, onion->secret_symmetric_key, packet + 1, packet + 1 + CRYPTO_NONCE_SIZE,
SIZE_IPPORT + CRYPTO_MAC_SIZE, plain);
if ((uint32_t)len != SIZE_IPPORT) {

View File

@ -105,7 +105,7 @@ int onion_path_to_nodes(Node_format *nodes, unsigned int num_nodes, const Onion_
* return length of created packet on success.
*/
non_null()
int create_onion_packet(const Random *rng, uint8_t *packet, uint16_t max_packet_length,
int create_onion_packet(const Memory *mem, const Random *rng, uint8_t *packet, uint16_t max_packet_length,
const Onion_Path *path, const IP_Port *dest,
const uint8_t *data, uint16_t length);
@ -119,7 +119,7 @@ int create_onion_packet(const Random *rng, uint8_t *packet, uint16_t max_packet_
* return length of created packet on success.
*/
non_null()
int create_onion_packet_tcp(const Random *rng, uint8_t *packet, uint16_t max_packet_length,
int create_onion_packet_tcp(const Memory *mem, const Random *rng, uint8_t *packet, uint16_t max_packet_length,
const Onion_Path *path, const IP_Port *dest,
const uint8_t *data, uint16_t length);

View File

@ -9,7 +9,6 @@
#include "onion_announce.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "DHT.h"
@ -23,6 +22,7 @@
#include "network.h"
#include "onion.h"
#include "shared_key_cache.h"
#include "sort.h"
#include "timed_auth.h"
#define PING_ID_TIMEOUT ONION_ANNOUNCE_TIMEOUT
@ -103,7 +103,7 @@ void onion_announce_entry_set_time(Onion_Announce *onion_a, uint32_t entry, uint
* return -1 on failure.
* return packet length on success.
*/
int create_announce_request(const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *dest_client_id,
int create_announce_request(const Memory *mem, const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *dest_client_id,
const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *ping_id, const uint8_t *client_id,
const uint8_t *data_public_key, uint64_t sendback_data)
{
@ -122,7 +122,7 @@ int create_announce_request(const Random *rng, uint8_t *packet, uint16_t max_pac
packet[0] = NET_PACKET_ANNOUNCE_REQUEST_OLD;
random_nonce(rng, packet + 1);
const int len = encrypt_data(dest_client_id, secret_key, packet + 1, plain, sizeof(plain),
const int len = encrypt_data(mem, dest_client_id, secret_key, packet + 1, plain, sizeof(plain),
packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE);
if ((uint32_t)len + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE != ONION_ANNOUNCE_REQUEST_MIN_SIZE) {
@ -146,7 +146,7 @@ int create_announce_request(const Random *rng, uint8_t *packet, uint16_t max_pac
* return -1 on failure.
* return 0 on success.
*/
int create_data_request(const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *public_key,
int create_data_request(const Memory *mem, const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *public_key,
const uint8_t *encrypt_public_key, const uint8_t *nonce, const uint8_t *data, uint16_t length)
{
if (DATA_REQUEST_MIN_SIZE + length > max_packet_length) {
@ -167,7 +167,7 @@ int create_data_request(const Random *rng, uint8_t *packet, uint16_t max_packet_
memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, random_public_key, CRYPTO_PUBLIC_KEY_SIZE);
const int len = encrypt_data(encrypt_public_key, random_secret_key, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, data, length,
const int len = encrypt_data(mem, encrypt_public_key, random_secret_key, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, data, length,
packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE);
if (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + len != DATA_REQUEST_MIN_SIZE +
@ -193,14 +193,14 @@ int create_data_request(const Random *rng, uint8_t *packet, uint16_t max_packet_
* return 0 on success.
*/
int send_announce_request(
const Logger *log, const Networking_Core *net, const Random *rng,
const Logger *log, const Memory *mem, const Networking_Core *net, const Random *rng,
const Onion_Path *path, const Node_format *dest,
const uint8_t *public_key, const uint8_t *secret_key,
const uint8_t *ping_id, const uint8_t *client_id,
const uint8_t *data_public_key, uint64_t sendback_data)
{
uint8_t request[ONION_ANNOUNCE_REQUEST_MIN_SIZE];
int len = create_announce_request(rng, request, sizeof(request), dest->public_key, public_key, secret_key, ping_id,
int len = create_announce_request(mem, rng, request, sizeof(request), dest->public_key, public_key, secret_key, ping_id,
client_id, data_public_key, sendback_data);
if (len != sizeof(request)) {
@ -208,7 +208,7 @@ int send_announce_request(
}
uint8_t packet[ONION_MAX_PACKET_SIZE];
len = create_onion_packet(rng, packet, sizeof(packet), path, &dest->ip_port, request, sizeof(request));
len = create_onion_packet(mem, rng, packet, sizeof(packet), path, &dest->ip_port, request, sizeof(request));
if (len == -1) {
return -1;
@ -238,19 +238,19 @@ int send_announce_request(
* return 0 on success.
*/
int send_data_request(
const Logger *log, const Networking_Core *net, const Random *rng, const Onion_Path *path, const IP_Port *dest,
const Logger *log, const Memory *mem, const Networking_Core *net, const Random *rng, const Onion_Path *path, const IP_Port *dest,
const uint8_t *public_key, const uint8_t *encrypt_public_key, const uint8_t *nonce,
const uint8_t *data, uint16_t length)
{
uint8_t request[ONION_MAX_DATA_SIZE];
int len = create_data_request(rng, request, sizeof(request), public_key, encrypt_public_key, nonce, data, length);
int len = create_data_request(mem, rng, request, sizeof(request), public_key, encrypt_public_key, nonce, data, length);
if (len == -1) {
return -1;
}
uint8_t packet[ONION_MAX_PACKET_SIZE];
len = create_onion_packet(rng, packet, sizeof(packet), path, dest, request, len);
len = create_onion_packet(mem, rng, packet, sizeof(packet), path, dest, request, len);
if (len == -1) {
return -1;
@ -281,23 +281,17 @@ static int in_entries(const Onion_Announce *onion_a, const uint8_t *public_key)
return -1;
}
typedef struct Cmp_Data {
typedef struct Onion_Announce_Entry_Cmp {
const Memory *mem;
const Mono_Time *mono_time;
const uint8_t *base_public_key;
Onion_Announce_Entry entry;
} Cmp_Data;
const uint8_t *comp_public_key;
} Onion_Announce_Entry_Cmp;
non_null()
static int cmp_entry(const void *a, const void *b)
static int onion_announce_entry_cmp(const Onion_Announce_Entry_Cmp *cmp, const Onion_Announce_Entry *entry1, const Onion_Announce_Entry *entry2)
{
const Cmp_Data *cmp1 = (const Cmp_Data *)a;
const Cmp_Data *cmp2 = (const Cmp_Data *)b;
const Onion_Announce_Entry entry1 = cmp1->entry;
const Onion_Announce_Entry entry2 = cmp2->entry;
const uint8_t *cmp_public_key = cmp1->base_public_key;
const bool t1 = mono_time_is_timeout(cmp1->mono_time, entry1.announce_time, ONION_ANNOUNCE_TIMEOUT);
const bool t2 = mono_time_is_timeout(cmp1->mono_time, entry2.announce_time, ONION_ANNOUNCE_TIMEOUT);
const bool t1 = mono_time_is_timeout(cmp->mono_time, entry1->announce_time, ONION_ANNOUNCE_TIMEOUT);
const bool t2 = mono_time_is_timeout(cmp->mono_time, entry2->announce_time, ONION_ANNOUNCE_TIMEOUT);
if (t1 && t2) {
return 0;
@ -311,7 +305,7 @@ static int cmp_entry(const void *a, const void *b)
return 1;
}
const int closest = id_closest(cmp_public_key, entry1.public_key, entry2.public_key);
const int closest = id_closest(cmp->comp_public_key, entry1->public_key, entry2->public_key);
if (closest == 1) {
return 1;
@ -324,32 +318,81 @@ static int cmp_entry(const void *a, const void *b)
return 0;
}
non_null()
static bool onion_announce_entry_less_handler(const void *object, const void *a, const void *b)
{
const Onion_Announce_Entry_Cmp *cmp = (const Onion_Announce_Entry_Cmp *)object;
const Onion_Announce_Entry *entry1 = (const Onion_Announce_Entry *)a;
const Onion_Announce_Entry *entry2 = (const Onion_Announce_Entry *)b;
return onion_announce_entry_cmp(cmp, entry1, entry2) < 0;
}
non_null()
static const void *onion_announce_entry_get_handler(const void *arr, uint32_t index)
{
const Onion_Announce_Entry *entries = (const Onion_Announce_Entry *)arr;
return &entries[index];
}
non_null()
static void onion_announce_entry_set_handler(void *arr, uint32_t index, const void *val)
{
Onion_Announce_Entry *entries = (Onion_Announce_Entry *)arr;
const Onion_Announce_Entry *entry = (const Onion_Announce_Entry *)val;
entries[index] = *entry;
}
non_null()
static void *onion_announce_entry_subarr_handler(void *arr, uint32_t index, uint32_t size)
{
Onion_Announce_Entry *entries = (Onion_Announce_Entry *)arr;
return &entries[index];
}
non_null()
static void *onion_announce_entry_alloc_handler(const void *object, uint32_t size)
{
const Onion_Announce_Entry_Cmp *cmp = (const Onion_Announce_Entry_Cmp *)object;
Onion_Announce_Entry *tmp = (Onion_Announce_Entry *)mem_valloc(cmp->mem, size, sizeof(Onion_Announce_Entry));
if (tmp == nullptr) {
return nullptr;
}
return tmp;
}
non_null()
static void onion_announce_entry_delete_handler(const void *object, void *arr, uint32_t size)
{
const Onion_Announce_Entry_Cmp *cmp = (const Onion_Announce_Entry_Cmp *)object;
mem_delete(cmp->mem, arr);
}
static const Sort_Funcs onion_announce_entry_cmp_funcs = {
onion_announce_entry_less_handler,
onion_announce_entry_get_handler,
onion_announce_entry_set_handler,
onion_announce_entry_subarr_handler,
onion_announce_entry_alloc_handler,
onion_announce_entry_delete_handler,
};
non_null()
static void sort_onion_announce_list(const Memory *mem, const Mono_Time *mono_time,
Onion_Announce_Entry *list, unsigned int length,
const uint8_t *comp_public_key)
{
// Pass comp_public_key to qsort with each Client_data entry, so the
// Pass comp_public_key to sort with each Onion_Announce_Entry entry, so the
// comparison function can use it as the base of comparison.
Cmp_Data *cmp_list = (Cmp_Data *)mem_valloc(mem, length, sizeof(Cmp_Data));
const Onion_Announce_Entry_Cmp cmp = {
mem,
mono_time,
comp_public_key,
};
if (cmp_list == nullptr) {
return;
}
for (uint32_t i = 0; i < length; ++i) {
cmp_list[i].mono_time = mono_time;
cmp_list[i].base_public_key = comp_public_key;
cmp_list[i].entry = list[i];
}
qsort(cmp_list, length, sizeof(Cmp_Data), cmp_entry);
for (uint32_t i = 0; i < length; ++i) {
list[i] = cmp_list[i].entry;
}
mem_delete(mem, cmp_list);
merge_sort(list, length, &cmp, &onion_announce_entry_cmp_funcs);
}
/** @brief add entry to entries list
@ -455,7 +498,7 @@ static int handle_announce_request_common(
return 1;
}
const int decrypted_len = decrypt_data_symmetric(shared_key, packet + 1,
const int decrypted_len = decrypt_data_symmetric(onion_a->mem, shared_key, packet + 1,
packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE, plain_size + CRYPTO_MAC_SIZE, plain);
if ((uint32_t)decrypted_len != plain_size) {
@ -542,7 +585,7 @@ static int handle_announce_request_common(
offset += extra_size;
uint8_t data[ONION_ANNOUNCE_RESPONSE_MAX_SIZE];
const int len = encrypt_data_symmetric(shared_key, nonce, response, offset,
const int len = encrypt_data_symmetric(onion_a->mem, shared_key, nonce, response, offset,
data + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE);
if (len != offset + CRYPTO_MAC_SIZE) {

View File

@ -65,7 +65,7 @@ void onion_announce_entry_set_time(Onion_Announce *onion_a, uint32_t entry, uint
* return packet length on success.
*/
non_null()
int create_announce_request(const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *dest_client_id,
int create_announce_request(const Memory *mem, const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *dest_client_id,
const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *ping_id, const uint8_t *client_id,
const uint8_t *data_public_key, uint64_t sendback_data);
@ -82,7 +82,7 @@ int create_announce_request(const Random *rng, uint8_t *packet, uint16_t max_pac
* return 0 on success.
*/
non_null()
int create_data_request(const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *public_key,
int create_data_request(const Memory *mem, const Random *rng, uint8_t *packet, uint16_t max_packet_length, const uint8_t *public_key,
const uint8_t *encrypt_public_key, const uint8_t *nonce, const uint8_t *data, uint16_t length);
/** @brief Create and send an onion announce request packet.
@ -101,7 +101,7 @@ int create_data_request(const Random *rng, uint8_t *packet, uint16_t max_packet_
*/
non_null()
int send_announce_request(
const Logger *log, const Networking_Core *net, const Random *rng,
const Logger *log, const Memory *mem, const Networking_Core *net, const Random *rng,
const Onion_Path *path, const Node_format *dest,
const uint8_t *public_key, const uint8_t *secret_key,
const uint8_t *ping_id, const uint8_t *client_id,
@ -125,7 +125,7 @@ int send_announce_request(
*/
non_null()
int send_data_request(
const Logger *log, const Networking_Core *net, const Random *rng, const Onion_Path *path, const IP_Port *dest,
const Logger *log, const Memory *mem, const Networking_Core *net, const Random *rng, const Onion_Path *path, const IP_Port *dest,
const uint8_t *public_key, const uint8_t *encrypt_public_key, const uint8_t *nonce,
const uint8_t *data, uint16_t length);

View File

@ -10,7 +10,6 @@
#include "onion_client.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "DHT.h"
@ -29,6 +28,7 @@
#include "onion.h"
#include "onion_announce.h"
#include "ping_array.h"
#include "sort.h"
#include "timed_auth.h"
#include "util.h"
@ -528,7 +528,7 @@ static int send_onion_packet_tcp_udp(const Onion_Client *onion_c, const Onion_Pa
{
if (net_family_is_ipv4(path->ip_port1.ip.family) || net_family_is_ipv6(path->ip_port1.ip.family)) {
uint8_t packet[ONION_MAX_PACKET_SIZE];
const int len = create_onion_packet(onion_c->rng, packet, sizeof(packet), path, dest, data, length);
const int len = create_onion_packet(onion_c->mem, onion_c->rng, packet, sizeof(packet), path, dest, data, length);
if (len == -1) {
return -1;
@ -545,7 +545,7 @@ static int send_onion_packet_tcp_udp(const Onion_Client *onion_c, const Onion_Pa
if (ip_port_to_tcp_connections_number(&path->ip_port1, &tcp_connections_number)) {
uint8_t packet[ONION_MAX_PACKET_SIZE];
const int len = create_onion_packet_tcp(onion_c->rng, packet, sizeof(packet), path, dest, data, length);
const int len = create_onion_packet_tcp(onion_c->mem, onion_c->rng, packet, sizeof(packet), path, dest, data, length);
if (len == -1) {
return -1;
@ -661,7 +661,7 @@ static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, con
if (num == 0) {
len = create_announce_request(
onion_c->rng, request, sizeof(request), dest_pubkey, nc_get_self_public_key(onion_c->c),
onion_c->mem, onion_c->rng, request, sizeof(request), dest_pubkey, nc_get_self_public_key(onion_c->c),
nc_get_self_secret_key(onion_c->c), ping_id, nc_get_self_public_key(onion_c->c),
onion_c->temp_public_key, sendback);
} else {
@ -669,14 +669,14 @@ static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, con
if (onion_friend->gc_data_length == 0) { // contact is a friend
len = create_announce_request(
onion_c->rng, request, sizeof(request), dest_pubkey, onion_friend->temp_public_key,
onion_c->mem, onion_c->rng, request, sizeof(request), dest_pubkey, onion_friend->temp_public_key,
onion_friend->temp_secret_key, ping_id, onion_friend->real_public_key,
zero_ping_id, sendback);
} else { // contact is a gc
onion_friend->is_groupchat = true;
len = create_gca_announce_request(
onion_c->rng, request, sizeof(request), dest_pubkey, onion_friend->temp_public_key,
onion_c->mem, onion_c->rng, request, sizeof(request), dest_pubkey, onion_friend->temp_public_key,
onion_friend->temp_secret_key, ping_id, onion_friend->real_public_key,
zero_ping_id, sendback, onion_friend->gc_data,
onion_friend->gc_data_length);
@ -694,23 +694,17 @@ static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, con
return send_onion_packet_tcp_udp(onion_c, &path, dest, request, len);
}
typedef struct Onion_Client_Cmp_Data {
typedef struct Onion_Node_Cmp {
const Memory *mem;
const Mono_Time *mono_time;
const uint8_t *base_public_key;
Onion_Node entry;
} Onion_Client_Cmp_Data;
const uint8_t *comp_public_key;
} Onion_Node_Cmp;
non_null()
static int onion_client_cmp_entry(const void *a, const void *b)
static int onion_node_cmp(const Onion_Node_Cmp *cmp, const Onion_Node *entry1, const Onion_Node *entry2)
{
const Onion_Client_Cmp_Data *cmp1 = (const Onion_Client_Cmp_Data *)a;
const Onion_Client_Cmp_Data *cmp2 = (const Onion_Client_Cmp_Data *)b;
const Onion_Node entry1 = cmp1->entry;
const Onion_Node entry2 = cmp2->entry;
const uint8_t *cmp_public_key = cmp1->base_public_key;
const bool t1 = onion_node_timed_out(&entry1, cmp1->mono_time);
const bool t2 = onion_node_timed_out(&entry2, cmp2->mono_time);
const bool t1 = onion_node_timed_out(entry1, cmp->mono_time);
const bool t2 = onion_node_timed_out(entry2, cmp->mono_time);
if (t1 && t2) {
return 0;
@ -724,7 +718,7 @@ static int onion_client_cmp_entry(const void *a, const void *b)
return 1;
}
const int closest = id_closest(cmp_public_key, entry1.public_key, entry2.public_key);
const int closest = id_closest(cmp->comp_public_key, entry1->public_key, entry2->public_key);
if (closest == 1) {
return 1;
@ -737,31 +731,80 @@ static int onion_client_cmp_entry(const void *a, const void *b)
return 0;
}
non_null()
static bool onion_node_less_handler(const void *object, const void *a, const void *b)
{
const Onion_Node_Cmp *cmp = (const Onion_Node_Cmp *)object;
const Onion_Node *entry1 = (const Onion_Node *)a;
const Onion_Node *entry2 = (const Onion_Node *)b;
return onion_node_cmp(cmp, entry1, entry2) < 0;
}
non_null()
static const void *onion_node_get_handler(const void *arr, uint32_t index)
{
const Onion_Node *entries = (const Onion_Node *)arr;
return &entries[index];
}
non_null()
static void onion_node_set_handler(void *arr, uint32_t index, const void *val)
{
Onion_Node *entries = (Onion_Node *)arr;
const Onion_Node *entry = (const Onion_Node *)val;
entries[index] = *entry;
}
non_null()
static void *onion_node_subarr_handler(void *arr, uint32_t index, uint32_t size)
{
Onion_Node *entries = (Onion_Node *)arr;
return &entries[index];
}
non_null()
static void *onion_node_alloc_handler(const void *object, uint32_t size)
{
const Onion_Node_Cmp *cmp = (const Onion_Node_Cmp *)object;
Onion_Node *tmp = (Onion_Node *)mem_valloc(cmp->mem, size, sizeof(Onion_Node));
if (tmp == nullptr) {
return nullptr;
}
return tmp;
}
non_null()
static void onion_node_delete_handler(const void *object, void *arr, uint32_t size)
{
const Onion_Node_Cmp *cmp = (const Onion_Node_Cmp *)object;
mem_delete(cmp->mem, arr);
}
static const Sort_Funcs onion_node_cmp_funcs = {
onion_node_less_handler,
onion_node_get_handler,
onion_node_set_handler,
onion_node_subarr_handler,
onion_node_alloc_handler,
onion_node_delete_handler,
};
non_null()
static void sort_onion_node_list(const Memory *mem, const Mono_Time *mono_time,
Onion_Node *list, unsigned int length, const uint8_t *comp_public_key)
{
// Pass comp_public_key to qsort with each Client_data entry, so the
// Pass comp_public_key to sort with each Onion_Node entry, so the
// comparison function can use it as the base of comparison.
Onion_Client_Cmp_Data *cmp_list = (Onion_Client_Cmp_Data *)mem_valloc(mem, length, sizeof(Onion_Client_Cmp_Data));
const Onion_Node_Cmp cmp = {
mem,
mono_time,
comp_public_key,
};
if (cmp_list == nullptr) {
return;
}
for (uint32_t i = 0; i < length; ++i) {
cmp_list[i].mono_time = mono_time;
cmp_list[i].base_public_key = comp_public_key;
cmp_list[i].entry = list[i];
}
qsort(cmp_list, length, sizeof(Onion_Client_Cmp_Data), onion_client_cmp_entry);
for (uint32_t i = 0; i < length; ++i) {
list[i] = cmp_list[i].entry;
}
mem_delete(mem, cmp_list);
merge_sort(list, length, &cmp, &onion_node_cmp_funcs);
}
non_null()
@ -962,7 +1005,7 @@ static int handle_announce_response(void *object, const IP_Port *source, const u
const uint16_t ciphertext_size = length - ciphertext_start;
if (num == 0) {
len = decrypt_data(public_key, nc_get_self_secret_key(onion_c->c),
len = decrypt_data(onion_c->mem, public_key, nc_get_self_secret_key(onion_c->c),
&packet[nonce_start], &packet[ciphertext_start], ciphertext_size, plain);
} else {
if (!onion_c->friends_list[num - 1].is_valid) {
@ -970,7 +1013,7 @@ static int handle_announce_response(void *object, const IP_Port *source, const u
return 1;
}
len = decrypt_data(public_key, onion_c->friends_list[num - 1].temp_secret_key,
len = decrypt_data(onion_c->mem, public_key, onion_c->friends_list[num - 1].temp_secret_key,
&packet[nonce_start], &packet[ciphertext_start], ciphertext_size, plain);
}
@ -1066,7 +1109,7 @@ static int handle_announce_response_old(void *object, const IP_Port *source, con
const uint16_t ciphertext_size = length - ciphertext_start;
if (num == 0) {
len = decrypt_data(public_key, nc_get_self_secret_key(onion_c->c),
len = decrypt_data(onion_c->mem, public_key, nc_get_self_secret_key(onion_c->c),
&packet[nonce_start], &packet[ciphertext_start], ciphertext_size, plain);
} else {
if (!onion_c->friends_list[num - 1].is_valid) {
@ -1074,7 +1117,7 @@ static int handle_announce_response_old(void *object, const IP_Port *source, con
return 1;
}
len = decrypt_data(public_key, onion_c->friends_list[num - 1].temp_secret_key,
len = decrypt_data(onion_c->mem, public_key, onion_c->friends_list[num - 1].temp_secret_key,
&packet[nonce_start], &packet[ciphertext_start], ciphertext_size, plain);
}
@ -1136,7 +1179,7 @@ static int handle_data_response(void *object, const IP_Port *source, const uint8
const uint16_t temp_plain_size = length - ONION_DATA_RESPONSE_MIN_SIZE;
VLA(uint8_t, temp_plain, temp_plain_size);
int len = decrypt_data(packet + 1 + CRYPTO_NONCE_SIZE, onion_c->temp_secret_key, packet + 1,
int len = decrypt_data(onion_c->mem, packet + 1 + CRYPTO_NONCE_SIZE, onion_c->temp_secret_key, packet + 1,
packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE,
length - (1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE), temp_plain);
@ -1146,7 +1189,7 @@ static int handle_data_response(void *object, const IP_Port *source, const uint8
const uint16_t plain_size = temp_plain_size - DATA_IN_RESPONSE_MIN_SIZE;
VLA(uint8_t, plain, plain_size);
len = decrypt_data(temp_plain, nc_get_self_secret_key(onion_c->c),
len = decrypt_data(onion_c->mem, temp_plain, nc_get_self_secret_key(onion_c->c),
packet + 1, temp_plain + CRYPTO_PUBLIC_KEY_SIZE,
temp_plain_size - CRYPTO_PUBLIC_KEY_SIZE, plain);
@ -1305,7 +1348,7 @@ int send_onion_data(Onion_Client *onion_c, int friend_num, const uint8_t *data,
const uint16_t packet_size = DATA_IN_RESPONSE_MIN_SIZE + length;
VLA(uint8_t, packet, packet_size);
memcpy(packet, nc_get_self_public_key(onion_c->c), CRYPTO_PUBLIC_KEY_SIZE);
int len = encrypt_data(onion_c->friends_list[friend_num].real_public_key,
int len = encrypt_data(onion_c->mem, onion_c->friends_list[friend_num].real_public_key,
nc_get_self_secret_key(onion_c->c), nonce, data,
length, packet + CRYPTO_PUBLIC_KEY_SIZE);
@ -1324,7 +1367,7 @@ int send_onion_data(Onion_Client *onion_c, int friend_num, const uint8_t *data,
uint8_t o_packet[ONION_MAX_PACKET_SIZE];
len = create_data_request(
onion_c->rng, o_packet, sizeof(o_packet), onion_c->friends_list[friend_num].real_public_key,
onion_c->mem, onion_c->rng, o_packet, sizeof(o_packet), onion_c->friends_list[friend_num].real_public_key,
node_list[good_nodes[i]].data_public_key, nonce, packet, packet_size);
if (len == -1) {
@ -1364,7 +1407,7 @@ static int send_dht_dhtpk(const Onion_Client *onion_c, int friend_num, const uin
VLA(uint8_t, temp, temp_size);
memcpy(temp, nc_get_self_public_key(onion_c->c), CRYPTO_PUBLIC_KEY_SIZE);
memcpy(temp + CRYPTO_PUBLIC_KEY_SIZE, nonce, CRYPTO_NONCE_SIZE);
int len = encrypt_data(onion_c->friends_list[friend_num].real_public_key,
int len = encrypt_data(onion_c->mem, onion_c->friends_list[friend_num].real_public_key,
nc_get_self_secret_key(onion_c->c), nonce, data,
length, temp + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE);
@ -1374,7 +1417,7 @@ static int send_dht_dhtpk(const Onion_Client *onion_c, int friend_num, const uin
uint8_t packet_data[MAX_CRYPTO_REQUEST_SIZE];
len = create_request(
onion_c->rng, dht_get_self_public_key(onion_c->dht), dht_get_self_secret_key(onion_c->dht), packet_data,
onion_c->mem, onion_c->rng, dht_get_self_public_key(onion_c->dht), dht_get_self_secret_key(onion_c->dht), packet_data,
onion_c->friends_list[friend_num].dht_public_key, temp, temp_size, CRYPTO_PACKET_DHTPK);
assert(len <= UINT16_MAX);
const Packet packet = {packet_data, (uint16_t)len};
@ -1401,7 +1444,7 @@ static int handle_dht_dhtpk(void *object, const IP_Port *source, const uint8_t *
}
uint8_t plain[DHTPK_DATA_MAX_LENGTH];
const int len = decrypt_data(packet, nc_get_self_secret_key(onion_c->c),
const int len = decrypt_data(onion_c->mem, packet, nc_get_self_secret_key(onion_c->c),
packet + CRYPTO_PUBLIC_KEY_SIZE,
packet + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE,
length - (CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE), plain);

View File

@ -31,6 +31,7 @@
struct Ping {
const Mono_Time *mono_time;
const Random *rng;
const Memory *mem;
DHT *dht;
Ping_Array *ping_array;
@ -72,7 +73,7 @@ void ping_send_request(Ping *ping, const IP_Port *ipp, const uint8_t *public_key
pk_copy(pk + 1, dht_get_self_public_key(ping->dht)); // Our pubkey
random_nonce(ping->rng, pk + 1 + CRYPTO_PUBLIC_KEY_SIZE); // Generate new nonce
rc = encrypt_data_symmetric(shared_key,
rc = encrypt_data_symmetric(ping->mem, shared_key,
pk + 1 + CRYPTO_PUBLIC_KEY_SIZE,
ping_plain, sizeof(ping_plain),
pk + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE);
@ -104,7 +105,7 @@ static int ping_send_response(const Ping *ping, const IP_Port *ipp, const uint8_
random_nonce(ping->rng, pk + 1 + CRYPTO_PUBLIC_KEY_SIZE); // Generate new nonce
// Encrypt ping_id using recipient privkey
const int rc = encrypt_data_symmetric(shared_encryption_key,
const int rc = encrypt_data_symmetric(ping->mem, shared_encryption_key,
pk + 1 + CRYPTO_PUBLIC_KEY_SIZE,
ping_plain, sizeof(ping_plain),
pk + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE);
@ -137,7 +138,7 @@ static int handle_ping_request(void *object, const IP_Port *source, const uint8_
uint8_t ping_plain[PING_PLAIN_SIZE];
// Decrypt ping_id
const int rc = decrypt_data_symmetric(shared_key,
const int rc = decrypt_data_symmetric(ping->mem, shared_key,
packet + 1 + CRYPTO_PUBLIC_KEY_SIZE,
packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE,
PING_PLAIN_SIZE + CRYPTO_MAC_SIZE,
@ -182,7 +183,7 @@ static int handle_ping_response(void *object, const IP_Port *source, const uint8
uint8_t ping_plain[PING_PLAIN_SIZE];
// Decrypt ping_id
rc = decrypt_data_symmetric(shared_key,
rc = decrypt_data_symmetric(ping->mem, shared_key,
packet + 1 + CRYPTO_PUBLIC_KEY_SIZE,
packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE,
PING_PLAIN_SIZE + CRYPTO_MAC_SIZE,
@ -348,6 +349,7 @@ Ping *ping_new(const Memory *mem, const Mono_Time *mono_time, const Random *rng,
ping->mono_time = mono_time;
ping->rng = rng;
ping->mem = mem;
ping->dht = dht;
networking_registerhandler(dht_get_net(ping->dht), NET_PACKET_PING_REQUEST, &handle_ping_request, dht);
networking_registerhandler(dht_get_net(ping->dht), NET_PACKET_PING_RESPONSE, &handle_ping_response, dht);

View File

@ -0,0 +1,182 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright © 2023-2024 The TokTok team.
*/
#include "sort.h"
#include <assert.h>
#include "attributes.h"
#include "ccompat.h"
#include "util.h"
/**
* @brief Threshold for when to switch to insertion sort.
*
* This is a trade-off between the complexity of insertion sort and the
* overhead of merge sort. The threshold is chosen to be the smallest value
* that gives a measurable speedup for insertion sort over merge sort. This is
* based on measurements done in sort_bench.cc. Starting from 32 elements,
* merge sort is faster than insertion sort in all our tests (both unsorted
* and mostly-sorted).
*
* Toxcore has a lot of small arrays it wants to sort, so this optimisation
* makes sense.
*/
#define SMALL_ARRAY_THRESHOLD 16
non_null()
static void merge_sort_merge_back(
void *arr,
const void *l_arr, uint32_t l_arr_size,
const void *r_arr, uint32_t r_arr_size,
uint32_t left_start,
const void *object, const Sort_Funcs *funcs)
{
uint32_t li = 0;
uint32_t ri = 0;
uint32_t k = left_start;
while (li < l_arr_size && ri < r_arr_size) {
const void *l = funcs->get_callback(l_arr, li);
const void *r = funcs->get_callback(r_arr, ri);
// !(r < l) <=> (r >= l) <=> (l <= r)
if (!funcs->less_callback(object, r, l)) {
funcs->set_callback(arr, k, l);
++li;
} else {
funcs->set_callback(arr, k, r);
++ri;
}
++k;
}
/* Copy the remaining elements of `l_arr[]`, if there are any. */
while (li < l_arr_size) {
funcs->set_callback(arr, k, funcs->get_callback(l_arr, li));
++li;
++k;
}
/* Copy the remaining elements of `r_arr[]`, if there are any. */
while (ri < r_arr_size) {
funcs->set_callback(arr, k, funcs->get_callback(r_arr, ri));
++ri;
++k;
}
}
/** Function to merge the two haves `arr[left_start..mid]` and `arr[mid+1..right_end]` of array `arr[]`. */
non_null()
static void merge_sort_merge(
void *arr, uint32_t left_start, uint32_t mid, uint32_t right_end, void *tmp,
const void *object, const Sort_Funcs *funcs)
{
const uint32_t l_arr_size = mid - left_start + 1;
const uint32_t r_arr_size = right_end - mid;
/* Temporary arrays, using the tmp buffer created in `merge_sort` below. */
void *l_arr = funcs->subarr_callback(tmp, 0, l_arr_size);
void *r_arr = funcs->subarr_callback(tmp, l_arr_size, r_arr_size);
/* Copy data to temp arrays `l_arr[]` and `r_arr[]`.
*
* This is iterating and repeatedly calling `get` and `set`, which sounds
* slow, but is only marginally slower than having a `copy` callback. With
* a `copy` callback, we'd save 3-4% in time.
*/
for (uint32_t i = 0; i < l_arr_size; ++i) {
funcs->set_callback(l_arr, i, funcs->get_callback(arr, left_start + i));
}
for (uint32_t i = 0; i < r_arr_size; ++i) {
funcs->set_callback(r_arr, i, funcs->get_callback(arr, mid + 1 + i));
}
/* Merge the temp arrays back into `arr[left_start..right_end]`. */
merge_sort_merge_back(arr, l_arr, l_arr_size, r_arr, r_arr_size, left_start, object, funcs);
}
non_null()
static void insertion_sort_step(void *arr, void *tmp, uint32_t i, const void *object, const Sort_Funcs *funcs)
{
funcs->set_callback(tmp, 0, funcs->get_callback(arr, i));
uint32_t j = i;
while (j > 0) {
if (!funcs->less_callback(object, tmp, funcs->get_callback(arr, j - 1))) {
break;
}
funcs->set_callback(arr, j, funcs->get_callback(arr, j - 1));
--j;
}
funcs->set_callback(arr, j, tmp);
}
non_null()
static void insertion_sort_with_buf(void *arr, uint32_t arr_size, void *tmp, uint32_t tmp_size, const void *object, const Sort_Funcs *funcs)
{
for (uint32_t i = 1; i < arr_size; ++i) {
insertion_sort_step(arr, tmp, i, object, funcs);
}
}
non_null()
static bool insertion_sort(void *arr, uint32_t arr_size, const void *object, const Sort_Funcs *funcs)
{
void *tmp = funcs->alloc_callback(object, 1);
if (tmp == nullptr) {
return false;
}
insertion_sort_with_buf(arr, arr_size, tmp, 1, object, funcs);
funcs->delete_callback(object, tmp, 1);
return true;
}
void merge_sort_with_buf(void *arr, uint32_t arr_size, void *tmp, uint32_t tmp_size, const void *object, const Sort_Funcs *funcs)
{
assert(tmp_size >= arr_size);
if (arr_size <= SMALL_ARRAY_THRESHOLD) {
assert(tmp_size >= 1);
insertion_sort_with_buf(arr, arr_size, tmp, tmp_size, object, funcs);
return;
}
// Merge subarrays in bottom up manner. First merge subarrays of
// size 1 to create sorted subarrays of size 2, then merge subarrays
// of size 2 to create sorted subarrays of size 4, and so on.
for (uint32_t curr_size = 1; curr_size <= arr_size - 1; curr_size = 2 * curr_size) {
// Pick starting point of different subarrays of current size
for (uint32_t left_start = 0; left_start < arr_size - 1; left_start += 2 * curr_size) {
// Find ending point of left subarray. mid+1 is starting
// point of right
const uint32_t mid = min_u32(left_start + curr_size - 1, arr_size - 1);
const uint32_t right_end = min_u32(left_start + 2 * curr_size - 1, arr_size - 1);
// Merge Subarrays arr[left_start...mid] & arr[mid+1...right_end]
merge_sort_merge(arr, left_start, mid, right_end, tmp, object, funcs);
}
}
}
bool merge_sort(void *arr, uint32_t arr_size, const void *object, const Sort_Funcs *funcs)
{
if (arr_size <= SMALL_ARRAY_THRESHOLD) {
return insertion_sort(arr, arr_size, object, funcs);
}
void *tmp = funcs->alloc_callback(object, arr_size);
if (tmp == nullptr) {
return false;
}
merge_sort_with_buf(arr, arr_size, tmp, arr_size, object, funcs);
funcs->delete_callback(object, tmp, arr_size);
return true;
}

View File

@ -0,0 +1,116 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright © 2023-2024 The TokTok team.
*/
#ifndef C_TOXCORE_TOXCORE_SORT_H
#define C_TOXCORE_TOXCORE_SORT_H
#include <stdbool.h>
#include <stdint.h>
#include "attributes.h"
#ifdef __cplusplus
extern "C" {
#endif
/** @brief Compare elements with a less-than ordering: `a < b`. */
typedef bool sort_less_cb(const void *object, const void *a, const void *b);
/** @brief Get element from array at index. */
typedef const void *sort_get_cb(const void *arr, uint32_t index);
/** @brief Set element in array at index to new value (perform copy). */
typedef void sort_set_cb(void *arr, uint32_t index, const void *val);
/** @brief Get a sub-array at an index of a given size (mutable pointer).
*
* Used to index in the temporary array allocated by `sort_alloc_cb` and get
* a sub-array for working memory.
*/
typedef void *sort_subarr_cb(void *arr, uint32_t index, uint32_t size);
/** @brief Allocate a new array of the element type.
*
* @param size The array size in elements of type T (not byte size). This value
* is always exactly the input array size as passed to `merge_sort`.
*/
typedef void *sort_alloc_cb(const void *object, uint32_t size);
/** @brief Free the element type array. */
typedef void sort_delete_cb(const void *object, void *arr, uint32_t size);
/** @brief Virtual function table for getting/setting elements in an array and
* comparing them.
*
* Only the `less`, `alloc`, and `delete` functions get a `this`-pointer. We
* assume that indexing in an array doesn't need any other information than the
* array itself.
*
* For now, the `this`-pointer is const, because we assume sorting doesn't need
* to mutate any state, but if necessary that can be changed in the future.
*/
typedef struct Sort_Funcs {
sort_less_cb *less_callback;
sort_get_cb *get_callback;
sort_set_cb *set_callback;
sort_subarr_cb *subarr_callback;
sort_alloc_cb *alloc_callback;
sort_delete_cb *delete_callback;
} Sort_Funcs;
/** @brief Non-recursive merge sort function to sort `arr[0...arr_size-1]`.
*
* Avoids `memcpy` and avoids treating elements as byte arrays. Instead, uses
* callbacks to index in arrays and copy elements. This makes it quite a bit
* slower than `qsort`, but works with elements that require special care when
* being copied (e.g. if they are part of a graph or other data structure that
* with pointers or other invariants).
*
* This function actually uses insertion sort for small arrays (up to 16
* elements), which is faster than merge sort for small arrays, especially
* when mostly sorted (a common use case in toxcore).
*
* Allocates a single temporary array with the provided alloc callback, and
* frees it at the end. This is significantly faster than an in-place
* implementation.
*
* Complexity:
* - Space: `O(n) where n = array_size`.
* - Time: `O(n * log n) where n = array_size`.
*
* Compared to `qsort`, this is about 60-70% slower for large arrays. For small
* arrays (up to 16 elements), it's about 50% faster than `qsort`.
*
* @param[in,out] arr An array of type T.
* @param arr_size Number of elements in @p arr (count, not byte size).
* @param[in] object Comparator object.
* @param[in] funcs Callback struct for elements of type T.
*/
non_null()
bool merge_sort(void *arr, uint32_t arr_size, const void *object, const Sort_Funcs *funcs);
/**
* @brief Merge sort like above but with a pre-allocated buffer.
*
* This function is the same as `merge_sort` but uses a pre-allocated buffer
* for temporary storage. This can be useful if the caller wants to avoid
* dynamic memory allocation.
*
* This function is 1-2% faster than `merge_sort` for small arrays up to 1000
* elements, and about 5-10% faster for large arrays (2000+ elements).
*
* The main upside is that `alloc` and `delete` callbacks don't need to be
* implemented, and the caller can use a stack-allocated buffer.
*
* @param[in,out] arr An array of type T.
* @param arr_size Number of elements in @p arr (count, not byte size).
* @param[in,out] tmp A buffer of size `tmp_size` for temporary storage.
* @param tmp_size Number of elements in @p tmp (count, not byte size). Must be
* at least as large as `arr_size`.
* @param[in] object Comparator object.
* @param[in] funcs Callback struct for elements of type T.
*/
non_null()
void merge_sort_with_buf(void *arr, uint32_t arr_size, void *tmp, uint32_t tmp_size, const void *object, const Sort_Funcs *funcs);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* C_TOXCORE_TOXCORE_SORT_H */

View File

@ -0,0 +1,140 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright © 2023-2024 The TokTok team.
*/
#include <benchmark/benchmark.h>
#include <algorithm>
#include <array>
#include <cstdint>
#include <random>
#include "mem.h"
#include "sort.h"
#include "sort_test_util.hh"
namespace {
std::pair<std::vector<Some_Type>, std::mt19937> random_vec(benchmark::State &state)
{
std::mt19937 rng;
// INT_MAX-1 so later we have room to add 1 larger element if needed.
std::uniform_int_distribution<uint32_t> dist{
std::numeric_limits<uint32_t>::min(), std::numeric_limits<uint32_t>::max() - 1};
std::vector<Some_Type> vec(state.range(0));
std::generate(std::begin(vec), std::end(vec), [&]() {
std::array<uint32_t, 8> compare_value;
std::generate(
std::begin(compare_value), std::end(compare_value), [&]() { return dist(rng); });
return Some_Type{nullptr, compare_value, "hello there"};
});
return {vec, rng};
}
std::vector<Some_Type> mostly_sorted_vec(benchmark::State &state)
{
auto [vec, rng] = random_vec(state);
std::sort(vec.begin(), vec.end());
// Randomly swap 5% of the vector.
std::uniform_int_distribution<std::size_t> dist{0, vec.size() - 1};
for (std::size_t i = 0; i < vec.size() / 20; ++i) {
const auto a = dist(rng);
const auto b = dist(rng);
std::swap(vec[a], vec[b]);
}
return vec;
}
void BM_merge_sort(benchmark::State &state)
{
const auto vec = random_vec(state).first;
for (auto _ : state) {
auto unsorted = vec;
merge_sort(unsorted.data(), unsorted.size(), &state, &Some_Type::funcs);
}
}
BENCHMARK(BM_merge_sort)->RangeMultiplier(2)->Range(8, 8 << 8);
void BM_merge_sort_with_buf(benchmark::State &state)
{
const auto vec = random_vec(state).first;
std::vector<Some_Type> buf(vec.size());
for (auto _ : state) {
auto unsorted = vec;
merge_sort_with_buf(
unsorted.data(), unsorted.size(), buf.data(), buf.size(), &state, &Some_Type::funcs);
}
}
BENCHMARK(BM_merge_sort_with_buf)->RangeMultiplier(2)->Range(8, 8 << 8);
void BM_merge_sort_mostly_sorted(benchmark::State &state)
{
auto vec = mostly_sorted_vec(state);
for (auto _ : state) {
auto unsorted = vec;
merge_sort(unsorted.data(), unsorted.size(), &state, &Some_Type::funcs);
}
}
BENCHMARK(BM_merge_sort_mostly_sorted)->RangeMultiplier(2)->Range(8, 8 << 8);
void BM_qsort(benchmark::State &state)
{
const auto vec = random_vec(state).first;
for (auto _ : state) {
auto unsorted = vec;
qsort(unsorted.data(), unsorted.size(), sizeof(unsorted[0]), my_type_cmp);
}
}
BENCHMARK(BM_qsort)->RangeMultiplier(2)->Range(8, 8 << 8);
void BM_qsort_mostly_sorted(benchmark::State &state)
{
auto vec = mostly_sorted_vec(state);
for (auto _ : state) {
auto unsorted = vec;
qsort(unsorted.data(), unsorted.size(), sizeof(unsorted[0]), my_type_cmp);
}
}
BENCHMARK(BM_qsort_mostly_sorted)->RangeMultiplier(2)->Range(8, 8 << 8);
void BM_std_sort(benchmark::State &state)
{
const auto vec = random_vec(state).first;
for (auto _ : state) {
auto unsorted = vec;
std::sort(unsorted.begin(), unsorted.end());
}
}
BENCHMARK(BM_std_sort)->RangeMultiplier(2)->Range(8, 8 << 8);
void BM_std_sort_mostly_sorted(benchmark::State &state)
{
auto vec = mostly_sorted_vec(state);
for (auto _ : state) {
auto unsorted = vec;
std::sort(unsorted.begin(), unsorted.end());
}
}
BENCHMARK(BM_std_sort_mostly_sorted)->RangeMultiplier(2)->Range(8, 8 << 8);
}
BENCHMARK_MAIN();

View File

@ -0,0 +1,79 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright © 2023-2024 The TokTok team.
*/
#include "sort.h"
#include <gtest/gtest.h>
#include <limits>
#include <random>
#include "sort_test_util.hh"
namespace {
TEST(MergeSort, BehavesLikeStdSort)
{
std::mt19937 rng;
// INT_MAX-1 so later we have room to add 1 larger element if needed.
std::uniform_int_distribution<int> dist{
std::numeric_limits<int>::min(), std::numeric_limits<int>::max() - 1};
constexpr auto int_funcs = sort_funcs<int>();
// Test with int arrays.
for (uint32_t i = 1; i < 500; ++i) {
std::vector<int> vec(i);
std::generate(std::begin(vec), std::end(vec), [&]() { return dist(rng); });
auto sorted = vec;
std::sort(sorted.begin(), sorted.end(), std::less<int>());
// If vec was accidentally sorted, add another larger element that almost definitely makes
// it not sorted.
if (vec == sorted) {
int const largest = *std::prev(sorted.end()) + 1;
sorted.push_back(largest);
vec.insert(vec.begin(), largest);
}
ASSERT_NE(vec, sorted);
// Just pass some arbitrary "self" to make sure the callbacks pass it through.
ASSERT_TRUE(merge_sort(vec.data(), vec.size(), &i, &int_funcs));
ASSERT_EQ(vec, sorted);
}
}
TEST(MergeSort, WorksWithNonTrivialTypes)
{
std::mt19937 rng;
std::uniform_int_distribution<int> dist{
std::numeric_limits<int>::min(), std::numeric_limits<int>::max()};
constexpr auto string_funcs = sort_funcs<std::string>();
// Test with std::string arrays.
for (uint32_t i = 1; i < 500; ++i) {
std::vector<std::string> vec(i);
std::generate(std::begin(vec), std::end(vec), [&]() { return std::to_string(dist(rng)); });
auto sorted = vec;
std::sort(sorted.begin(), sorted.end(), std::less<std::string>());
// If vec was accidentally sorted, add another larger element that almost definitely makes
// it not sorted.
if (vec == sorted) {
std::string const largest = "larger than largest int";
sorted.push_back(largest);
vec.insert(vec.begin(), largest);
}
ASSERT_NE(vec, sorted);
// Just pass some arbitrary "self" to make sure the callbacks pass it through.
ASSERT_TRUE(merge_sort(vec.data(), vec.size(), &i, &string_funcs));
ASSERT_EQ(vec, sorted);
}
}
} // namespace

View File

@ -0,0 +1,32 @@
#include "sort_test_util.hh"
#include <array>
#include <cstddef>
#include "sort.h"
#include "util.h"
namespace {
template <typename T, std::size_t N>
int cmp_uint_array(const std::array<T, N> &a, const std::array<T, N> &b)
{
for (std::size_t i = 0; i < a.size(); ++i) {
const int cmp = cmp_uint(a[i], b[i]);
if (cmp != 0) {
return cmp;
}
}
return 0;
}
}
const Sort_Funcs Some_Type::funcs = sort_funcs<Some_Type>();
int my_type_cmp(const void *va, const void *vb)
{
const auto *a = static_cast<const Some_Type *>(va);
const auto *b = static_cast<const Some_Type *>(vb);
return cmp_uint_array(a->compare_value, b->compare_value);
}
bool operator<(const Some_Type &a, const Some_Type &b) { return a.compare_value < b.compare_value; }

View File

@ -0,0 +1,54 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright © 2023-2024 The TokTok team.
*/
#ifndef C_TOXCORE_TOXCORE_SORT_TEST_UTIL_H
#define C_TOXCORE_TOXCORE_SORT_TEST_UTIL_H
#include <array>
#include "sort.h"
struct Memory;
template <typename T>
constexpr Sort_Funcs sort_funcs()
{
return {
[](const void *object, const void *va, const void *vb) {
const T *a = static_cast<const T *>(va);
const T *b = static_cast<const T *>(vb);
return *a < *b;
},
[](const void *arr, uint32_t index) -> const void * {
const T *vec = static_cast<const T *>(arr);
return &vec[index];
},
[](void *arr, uint32_t index, const void *val) {
T *vec = static_cast<T *>(arr);
const T *value = static_cast<const T *>(val);
vec[index] = *value;
},
[](void *arr, uint32_t index, uint32_t size) -> void * {
T *vec = static_cast<T *>(arr);
return &vec[index];
},
[](const void *object, uint32_t size) -> void * { return new T[size]; },
[](const void *object, void *arr, uint32_t size) { delete[] static_cast<T *>(arr); },
};
}
// A realistic test case where we have a struct with some stuff and an expensive value we compare.
struct Some_Type {
const Memory *mem;
std::array<uint32_t, 8> compare_value;
const char *name;
static const Sort_Funcs funcs;
};
int my_type_cmp(const void *va, const void *vb);
bool operator<(const Some_Type &a, const Some_Type &b);
#endif // C_TOXCORE_TOXCORE_SORT_TEST_UTIL_H

View File

@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright © 2016-2024 The TokTok team.
* Copyright © 2016-2018 The TokTok team.
* Copyright © 2013 Tox project.
*/

View File

@ -1722,120 +1722,3 @@ const char *tox_group_mod_event_to_string(Tox_Group_Mod_Event value)
return "<invalid Tox_Group_Mod_Event>";
}
const char *tox_netprof_packet_id_to_string(Tox_Netprof_Packet_Id value)
{
switch (value) {
case TOX_NETPROF_PACKET_ID_ZERO:
return "TOX_NETPROF_PACKET_ID_ZERO";
case TOX_NETPROF_PACKET_ID_ONE:
return "TOX_NETPROF_PACKET_ID_ONE";
case TOX_NETPROF_PACKET_ID_TWO:
return "TOX_NETPROF_PACKET_ID_TWO";
case TOX_NETPROF_PACKET_ID_TCP_DISCONNECT:
return "TOX_NETPROF_PACKET_ID_TCP_DISCONNECT";
case TOX_NETPROF_PACKET_ID_FOUR:
return "TOX_NETPROF_PACKET_ID_FOUR";
case TOX_NETPROF_PACKET_ID_TCP_PONG:
return "TOX_NETPROF_PACKET_ID_TCP_PONG";
case TOX_NETPROF_PACKET_ID_TCP_OOB_SEND:
return "TOX_NETPROF_PACKET_ID_TCP_OOB_SEND";
case TOX_NETPROF_PACKET_ID_TCP_OOB_RECV:
return "TOX_NETPROF_PACKET_ID_TCP_OOB_RECV";
case TOX_NETPROF_PACKET_ID_TCP_ONION_REQUEST:
return "TOX_NETPROF_PACKET_ID_TCP_ONION_REQUEST";
case TOX_NETPROF_PACKET_ID_TCP_ONION_RESPONSE:
return "TOX_NETPROF_PACKET_ID_TCP_ONION_RESPONSE";
case TOX_NETPROF_PACKET_ID_TCP_DATA:
return "TOX_NETPROF_PACKET_ID_TCP_DATA";
case TOX_NETPROF_PACKET_ID_COOKIE_REQUEST:
return "TOX_NETPROF_PACKET_ID_COOKIE_REQUEST";
case TOX_NETPROF_PACKET_ID_COOKIE_RESPONSE:
return "TOX_NETPROF_PACKET_ID_COOKIE_RESPONSE";
case TOX_NETPROF_PACKET_ID_CRYPTO_HS:
return "TOX_NETPROF_PACKET_ID_CRYPTO_HS";
case TOX_NETPROF_PACKET_ID_CRYPTO_DATA:
return "TOX_NETPROF_PACKET_ID_CRYPTO_DATA";
case TOX_NETPROF_PACKET_ID_CRYPTO:
return "TOX_NETPROF_PACKET_ID_CRYPTO";
case TOX_NETPROF_PACKET_ID_LAN_DISCOVERY:
return "TOX_NETPROF_PACKET_ID_LAN_DISCOVERY";
case TOX_NETPROF_PACKET_ID_GC_HANDSHAKE:
return "TOX_NETPROF_PACKET_ID_GC_HANDSHAKE";
case TOX_NETPROF_PACKET_ID_GC_LOSSLESS:
return "TOX_NETPROF_PACKET_ID_GC_LOSSLESS";
case TOX_NETPROF_PACKET_ID_GC_LOSSY:
return "TOX_NETPROF_PACKET_ID_GC_LOSSY";
case TOX_NETPROF_PACKET_ID_ONION_SEND_INITIAL:
return "TOX_NETPROF_PACKET_ID_ONION_SEND_INITIAL";
case TOX_NETPROF_PACKET_ID_ONION_SEND_1:
return "TOX_NETPROF_PACKET_ID_ONION_SEND_1";
case TOX_NETPROF_PACKET_ID_ONION_SEND_2:
return "TOX_NETPROF_PACKET_ID_ONION_SEND_2";
case TOX_NETPROF_PACKET_ID_ANNOUNCE_REQUEST_OLD:
return "TOX_NETPROF_PACKET_ID_ANNOUNCE_REQUEST_OLD";
case TOX_NETPROF_PACKET_ID_ANNOUNCE_RESPONSE_OLD:
return "TOX_NETPROF_PACKET_ID_ANNOUNCE_RESPONSE_OLD";
case TOX_NETPROF_PACKET_ID_ONION_DATA_REQUEST:
return "TOX_NETPROF_PACKET_ID_ONION_DATA_REQUEST";
case TOX_NETPROF_PACKET_ID_ONION_DATA_RESPONSE:
return "TOX_NETPROF_PACKET_ID_ONION_DATA_RESPONSE";
case TOX_NETPROF_PACKET_ID_ANNOUNCE_REQUEST:
return "TOX_NETPROF_PACKET_ID_ANNOUNCE_REQUEST";
case TOX_NETPROF_PACKET_ID_ANNOUNCE_RESPONSE:
return "TOX_NETPROF_PACKET_ID_ANNOUNCE_RESPONSE";
case TOX_NETPROF_PACKET_ID_ONION_RECV_3:
return "TOX_NETPROF_PACKET_ID_ONION_RECV_3";
case TOX_NETPROF_PACKET_ID_ONION_RECV_2:
return "TOX_NETPROF_PACKET_ID_ONION_RECV_2";
case TOX_NETPROF_PACKET_ID_ONION_RECV_1:
return "TOX_NETPROF_PACKET_ID_ONION_RECV_1";
case TOX_NETPROF_PACKET_ID_FORWARD_REQUEST:
return "TOX_NETPROF_PACKET_ID_FORWARD_REQUEST";
case TOX_NETPROF_PACKET_ID_FORWARDING:
return "TOX_NETPROF_PACKET_ID_FORWARDING";
case TOX_NETPROF_PACKET_ID_FORWARD_REPLY:
return "TOX_NETPROF_PACKET_ID_FORWARD_REPLY";
case TOX_NETPROF_PACKET_ID_DATA_SEARCH_REQUEST:
return "TOX_NETPROF_PACKET_ID_DATA_SEARCH_REQUEST";
case TOX_NETPROF_PACKET_ID_DATA_SEARCH_RESPONSE:
return "TOX_NETPROF_PACKET_ID_DATA_SEARCH_RESPONSE";
case TOX_NETPROF_PACKET_ID_DATA_RETRIEVE_REQUEST:
return "TOX_NETPROF_PACKET_ID_DATA_RETRIEVE_REQUEST";
case TOX_NETPROF_PACKET_ID_DATA_RETRIEVE_RESPONSE:
return "TOX_NETPROF_PACKET_ID_DATA_RETRIEVE_RESPONSE";
case TOX_NETPROF_PACKET_ID_STORE_ANNOUNCE_REQUEST:
return "TOX_NETPROF_PACKET_ID_STORE_ANNOUNCE_REQUEST";
case TOX_NETPROF_PACKET_ID_STORE_ANNOUNCE_RESPONSE:
return "TOX_NETPROF_PACKET_ID_STORE_ANNOUNCE_RESPONSE";
case TOX_NETPROF_PACKET_ID_BOOTSTRAP_INFO:
return "TOX_NETPROF_PACKET_ID_BOOTSTRAP_INFO";
}
return "<invalid Tox_Netprof_Packet_Id>";
}
const char *tox_netprof_packet_type_to_string(Tox_Netprof_Packet_Type value)
{
switch (value) {
case TOX_NETPROF_PACKET_TYPE_TCP_CLIENT:
return "TOX_NETPROF_PACKET_TYPE_TCP_CLIENT";
case TOX_NETPROF_PACKET_TYPE_TCP_SERVER:
return "TOX_NETPROF_PACKET_TYPE_TCP_SERVER";
case TOX_NETPROF_PACKET_TYPE_TCP:
return "TOX_NETPROF_PACKET_TYPE_TCP";
case TOX_NETPROF_PACKET_TYPE_UDP:
return "TOX_NETPROF_PACKET_TYPE_UDP";
}
return "<invalid Tox_Netprof_Packet_Type>";
}
const char *tox_netprof_direction_to_string(Tox_Netprof_Direction value)
{
switch (value) {
case TOX_NETPROF_DIRECTION_SENT:
return "TOX_NETPROF_DIRECTION_SENT";
case TOX_NETPROF_DIRECTION_RECV:
return "TOX_NETPROF_DIRECTION_RECV";
}
return "<invalid Tox_Netprof_Direction>";
}

View File

@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright © 2016-2024 The TokTok team.
* Copyright © 2016-2022 The TokTok team.
* Copyright © 2013 Tox project.
*/
@ -11,16 +11,13 @@
#include <assert.h>
#include "DHT.h"
#include "TCP_server.h"
#include "attributes.h"
#include "ccompat.h"
#include "crypto_core.h"
#include "group_chats.h"
#include "group_common.h"
#include "logger.h"
#include "mem.h"
#include "net_crypto.h"
#include "net_profile.h"
#include "network.h"
#include "tox.h"
#include "tox_struct.h"
@ -229,199 +226,3 @@ bool tox_group_peer_get_ip_address(const Tox *tox, uint32_t group_number, uint32
SET_ERROR_PARAMETER(error, TOX_ERR_GROUP_PEER_QUERY_OK);
return true;
}
uint64_t tox_netprof_get_packet_id_count(const Tox *tox, Tox_Netprof_Packet_Type type, uint8_t id,
Tox_Netprof_Direction direction)
{
assert(tox != nullptr);
tox_lock(tox);
const Net_Profile *tcp_c_profile = nc_get_tcp_client_net_profile(tox->m->net_crypto);
const Net_Profile *tcp_s_profile = tcp_server_get_net_profile(tox->m->tcp_server);
const Packet_Direction dir = (Packet_Direction) direction;
uint64_t count = 0;
switch (type) {
case TOX_NETPROF_PACKET_TYPE_TCP_CLIENT: {
count = netprof_get_packet_count_id(tcp_c_profile, id, dir);
break;
}
case TOX_NETPROF_PACKET_TYPE_TCP_SERVER: {
count = netprof_get_packet_count_id(tcp_s_profile, id, dir);
break;
}
case TOX_NETPROF_PACKET_TYPE_TCP: {
const uint64_t tcp_c_count = netprof_get_packet_count_id(tcp_c_profile, id, dir);
const uint64_t tcp_s_count = netprof_get_packet_count_id(tcp_s_profile, id, dir);
count = tcp_c_count + tcp_s_count;
break;
}
case TOX_NETPROF_PACKET_TYPE_UDP: {
const Net_Profile *udp_profile = net_get_net_profile(tox->m->net);
count = netprof_get_packet_count_id(udp_profile, id, dir);
break;
}
default: {
LOGGER_ERROR(tox->m->log, "invalid packet type: %d", type);
break;
}
}
tox_unlock(tox);
return count;
}
uint64_t tox_netprof_get_packet_total_count(const Tox *tox, Tox_Netprof_Packet_Type type,
Tox_Netprof_Direction direction)
{
assert(tox != nullptr);
tox_lock(tox);
const Net_Profile *tcp_c_profile = nc_get_tcp_client_net_profile(tox->m->net_crypto);
const Net_Profile *tcp_s_profile = tcp_server_get_net_profile(tox->m->tcp_server);
const Packet_Direction dir = (Packet_Direction) direction;
uint64_t count = 0;
switch (type) {
case TOX_NETPROF_PACKET_TYPE_TCP_CLIENT: {
count = netprof_get_packet_count_total(tcp_c_profile, dir);
break;
}
case TOX_NETPROF_PACKET_TYPE_TCP_SERVER: {
count = netprof_get_packet_count_total(tcp_s_profile, dir);
break;
}
case TOX_NETPROF_PACKET_TYPE_TCP: {
const uint64_t tcp_c_count = netprof_get_packet_count_total(tcp_c_profile, dir);
const uint64_t tcp_s_count = netprof_get_packet_count_total(tcp_s_profile, dir);
count = tcp_c_count + tcp_s_count;
break;
}
case TOX_NETPROF_PACKET_TYPE_UDP: {
const Net_Profile *udp_profile = net_get_net_profile(tox->m->net);
count = netprof_get_packet_count_total(udp_profile, dir);
break;
}
default: {
LOGGER_ERROR(tox->m->log, "invalid packet type: %d", type);
break;
}
}
tox_unlock(tox);
return count;
}
uint64_t tox_netprof_get_packet_id_bytes(const Tox *tox, Tox_Netprof_Packet_Type type, uint8_t id,
Tox_Netprof_Direction direction)
{
assert(tox != nullptr);
tox_lock(tox);
const Net_Profile *tcp_c_profile = nc_get_tcp_client_net_profile(tox->m->net_crypto);
const Net_Profile *tcp_s_profile = tcp_server_get_net_profile(tox->m->tcp_server);
const Packet_Direction dir = (Packet_Direction) direction;
uint64_t bytes = 0;
switch (type) {
case TOX_NETPROF_PACKET_TYPE_TCP_CLIENT: {
bytes = netprof_get_bytes_id(tcp_c_profile, id, dir);
break;
}
case TOX_NETPROF_PACKET_TYPE_TCP_SERVER: {
bytes = netprof_get_bytes_id(tcp_s_profile, id, dir);
break;
}
case TOX_NETPROF_PACKET_TYPE_TCP: {
const uint64_t tcp_c_bytes = netprof_get_bytes_id(tcp_c_profile, id, dir);
const uint64_t tcp_s_bytes = netprof_get_bytes_id(tcp_s_profile, id, dir);
bytes = tcp_c_bytes + tcp_s_bytes;
break;
}
case TOX_NETPROF_PACKET_TYPE_UDP: {
const Net_Profile *udp_profile = net_get_net_profile(tox->m->net);
bytes = netprof_get_bytes_id(udp_profile, id, dir);
break;
}
default: {
LOGGER_ERROR(tox->m->log, "invalid packet type: %d", type);
break;
}
}
tox_unlock(tox);
return bytes;
}
uint64_t tox_netprof_get_packet_total_bytes(const Tox *tox, Tox_Netprof_Packet_Type type,
Tox_Netprof_Direction direction)
{
assert(tox != nullptr);
tox_lock(tox);
const Net_Profile *tcp_c_profile = nc_get_tcp_client_net_profile(tox->m->net_crypto);
const Net_Profile *tcp_s_profile = tcp_server_get_net_profile(tox->m->tcp_server);
const Packet_Direction dir = (Packet_Direction) direction;
uint64_t bytes = 0;
switch (type) {
case TOX_NETPROF_PACKET_TYPE_TCP_CLIENT: {
bytes = netprof_get_bytes_total(tcp_c_profile, dir);
break;
}
case TOX_NETPROF_PACKET_TYPE_TCP_SERVER: {
bytes = netprof_get_bytes_total(tcp_s_profile, dir);
break;
}
case TOX_NETPROF_PACKET_TYPE_TCP: {
const uint64_t tcp_c_bytes = netprof_get_bytes_total(tcp_c_profile, dir);
const uint64_t tcp_s_bytes = netprof_get_bytes_total(tcp_s_profile, dir);
bytes = tcp_c_bytes + tcp_s_bytes;
break;
}
case TOX_NETPROF_PACKET_TYPE_UDP: {
const Net_Profile *udp_profile = net_get_net_profile(tox->m->net);
bytes = netprof_get_bytes_total(udp_profile, dir);
break;
}
default: {
LOGGER_ERROR(tox->m->log, "invalid packet type: %d", type);
break;
}
}
tox_unlock(tox);
return bytes;
}

View File

@ -169,267 +169,6 @@ uint16_t tox_dht_get_num_closelist(const Tox *tox);
*/
uint16_t tox_dht_get_num_closelist_announce_capable(const Tox *tox);
/*******************************************************************************
*
* :: Network profiler
*
******************************************************************************/
/**
* Represents all of the network packet identifiers that Toxcore uses.
*
* Notes:
* - Some packet ID's have different purposes depending on the
* packet type. These ID's are given numeral names.
*
* - Queries for invalid packet ID's return undefined results. For example,
* querying a TCP-exclusive packet ID for UDP, or querying an ID that
* doesn't exist in this enum.
*/
typedef enum Tox_Netprof_Packet_Id {
/**
* Ping request packet (UDP).
* Routing request (TCP).
*/
TOX_NETPROF_PACKET_ID_ZERO = 0x00,
/**
* Ping response packet (UDP).
* Routing response (TCP).
*/
TOX_NETPROF_PACKET_ID_ONE = 0x01,
/**
* Get nodes request packet (UDP).
* Connection notification (TCP).
*/
TOX_NETPROF_PACKET_ID_TWO = 0x02,
/**
* TCP disconnect notification.
*/
TOX_NETPROF_PACKET_ID_TCP_DISCONNECT = 0x03,
/**
* Send nodes response packet (UDP).
* Ping packet (TCP).
*/
TOX_NETPROF_PACKET_ID_FOUR = 0x04,
/**
* TCP pong packet.
*/
TOX_NETPROF_PACKET_ID_TCP_PONG = 0x05,
/**
* TCP out-of-band send packet.
*/
TOX_NETPROF_PACKET_ID_TCP_OOB_SEND = 0x06,
/**
* TCP out-of-band receive packet.
*/
TOX_NETPROF_PACKET_ID_TCP_OOB_RECV = 0x07,
/**
* TCP onion request packet.
*/
TOX_NETPROF_PACKET_ID_TCP_ONION_REQUEST = 0x08,
/**
* TCP onion response packet.
*/
TOX_NETPROF_PACKET_ID_TCP_ONION_RESPONSE = 0x09,
/**
* TCP data packet.
*/
TOX_NETPROF_PACKET_ID_TCP_DATA = 0x10,
/**
* Cookie request packet.
*/
TOX_NETPROF_PACKET_ID_COOKIE_REQUEST = 0x18,
/**
* Cookie response packet.
*/
TOX_NETPROF_PACKET_ID_COOKIE_RESPONSE = 0x19,
/**
* Crypto handshake packet.
*/
TOX_NETPROF_PACKET_ID_CRYPTO_HS = 0x1a,
/**
* Crypto data packet.
*/
TOX_NETPROF_PACKET_ID_CRYPTO_DATA = 0x1b,
/**
* Encrypted data packet.
*/
TOX_NETPROF_PACKET_ID_CRYPTO = 0x20,
/**
* LAN discovery packet.
*/
TOX_NETPROF_PACKET_ID_LAN_DISCOVERY = 0x21,
/**
* DHT groupchat packets.
*/
TOX_NETPROF_PACKET_ID_GC_HANDSHAKE = 0x5a,
TOX_NETPROF_PACKET_ID_GC_LOSSLESS = 0x5b,
TOX_NETPROF_PACKET_ID_GC_LOSSY = 0x5c,
/**
* Onion send packets.
*/
TOX_NETPROF_PACKET_ID_ONION_SEND_INITIAL = 0x80,
TOX_NETPROF_PACKET_ID_ONION_SEND_1 = 0x81,
TOX_NETPROF_PACKET_ID_ONION_SEND_2 = 0x82,
/**
* DHT announce request packet (deprecated).
*/
TOX_NETPROF_PACKET_ID_ANNOUNCE_REQUEST_OLD = 0x83,
/**
* DHT announce response packet (deprecated).
*/
TOX_NETPROF_PACKET_ID_ANNOUNCE_RESPONSE_OLD = 0x84,
/**
* Onion data request packet.
*/
TOX_NETPROF_PACKET_ID_ONION_DATA_REQUEST = 0x85,
/**
* Onion data response packet.
*/
TOX_NETPROF_PACKET_ID_ONION_DATA_RESPONSE = 0x86,
/**
* DHT announce request packet.
*/
TOX_NETPROF_PACKET_ID_ANNOUNCE_REQUEST = 0x87,
/**
* DHT announce response packet.
*/
TOX_NETPROF_PACKET_ID_ANNOUNCE_RESPONSE = 0x88,
/**
* Onion receive packets.
*/
TOX_NETPROF_PACKET_ID_ONION_RECV_3 = 0x8c,
TOX_NETPROF_PACKET_ID_ONION_RECV_2 = 0x8d,
TOX_NETPROF_PACKET_ID_ONION_RECV_1 = 0x8e,
TOX_NETPROF_PACKET_ID_FORWARD_REQUEST = 0x90,
TOX_NETPROF_PACKET_ID_FORWARDING = 0x91,
TOX_NETPROF_PACKET_ID_FORWARD_REPLY = 0x92,
TOX_NETPROF_PACKET_ID_DATA_SEARCH_REQUEST = 0x93,
TOX_NETPROF_PACKET_ID_DATA_SEARCH_RESPONSE = 0x94,
TOX_NETPROF_PACKET_ID_DATA_RETRIEVE_REQUEST = 0x95,
TOX_NETPROF_PACKET_ID_DATA_RETRIEVE_RESPONSE = 0x96,
TOX_NETPROF_PACKET_ID_STORE_ANNOUNCE_REQUEST = 0x97,
TOX_NETPROF_PACKET_ID_STORE_ANNOUNCE_RESPONSE = 0x98,
/**
* Bootstrap info packet.
*/
TOX_NETPROF_PACKET_ID_BOOTSTRAP_INFO = 0xf0,
} Tox_Netprof_Packet_Id;
const char *tox_netprof_packet_id_to_string(Tox_Netprof_Packet_Id value);
/**
* Specifies the packet type for a given query.
*/
typedef enum Tox_Netprof_Packet_Type {
/**
* TCP client packets.
*/
TOX_NETPROF_PACKET_TYPE_TCP_CLIENT,
/**
* TCP server packets.
*/
TOX_NETPROF_PACKET_TYPE_TCP_SERVER,
/**
* Combined TCP server and TCP client packets.
*/
TOX_NETPROF_PACKET_TYPE_TCP,
/**
* UDP packets.
*/
TOX_NETPROF_PACKET_TYPE_UDP,
} Tox_Netprof_Packet_Type;
const char *tox_netprof_packet_type_to_string(Tox_Netprof_Packet_Type value);
/**
* Specifies the packet direction for a given query.
*/
typedef enum Tox_Netprof_Direction {
/**
* Outbound packets.
*/
TOX_NETPROF_DIRECTION_SENT,
/**
* Inbound packets.
*/
TOX_NETPROF_DIRECTION_RECV,
} Tox_Netprof_Direction;
const char *tox_netprof_direction_to_string(Tox_Netprof_Direction value);
/**
* Return the number of packets sent or received for a specific packet ID.
*
* @param type The types of packets being queried.
* @param id The packet ID being queried.
* @param direction The packet direction.
*/
uint64_t tox_netprof_get_packet_id_count(const Tox *tox, Tox_Netprof_Packet_Type type, uint8_t id,
Tox_Netprof_Direction direction);
/**
* Return the total number of packets sent or received.
*
* @param type The types of packets being queried.
* @param direction The packet direction.
*/
uint64_t tox_netprof_get_packet_total_count(const Tox *tox, Tox_Netprof_Packet_Type type,
Tox_Netprof_Direction direction);
/**
* Return the number of bytes sent or received for a specific packet ID.
*
* @param type The types of packets being queried.
* @param id The packet ID being queried.
* @param direction The packet direction.
*/
uint64_t tox_netprof_get_packet_id_bytes(const Tox *tox, Tox_Netprof_Packet_Type type, uint8_t id,
Tox_Netprof_Direction direction);
/**
* Return the total number of bytes sent or received.
*
* @param type The types of packets being queried.
* @param direction The packet direction.
*/
uint64_t tox_netprof_get_packet_total_bytes(const Tox *tox, Tox_Netprof_Packet_Type type,
Tox_Netprof_Direction direction);
/*******************************************************************************
*
* :: DHT groupchat queries.

View File

@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright © 2016-2018 The TokTok team.
* Copyright © 2016-2024 The TokTok team.
* Copyright © 2013 Tox project.
* Copyright © 2013 plutooo
*/
@ -16,6 +16,7 @@
#include <stdlib.h>
#include <string.h>
#include "attributes.h"
#include "ccompat.h"
#include "mem.h"

View File

@ -1,39 +1,14 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright © 2016-2024 The TokTok team.
*/
#include "util.h"
#include <gtest/gtest.h>
#include "crypto_core.h"
#include "crypto_core_test_util.hh"
#include <climits>
namespace {
TEST(Util, TwoRandomIdsAreNotEqual)
{
Test_Random rng;
uint8_t pk1[CRYPTO_PUBLIC_KEY_SIZE];
uint8_t sk1[CRYPTO_SECRET_KEY_SIZE];
uint8_t pk2[CRYPTO_PUBLIC_KEY_SIZE];
uint8_t sk2[CRYPTO_SECRET_KEY_SIZE];
crypto_new_keypair(rng, pk1, sk1);
crypto_new_keypair(rng, pk2, sk2);
EXPECT_FALSE(pk_equal(pk1, pk2));
}
TEST(Util, IdCopyMakesKeysEqual)
{
Test_Random rng;
uint8_t pk1[CRYPTO_PUBLIC_KEY_SIZE];
uint8_t sk1[CRYPTO_SECRET_KEY_SIZE];
uint8_t pk2[CRYPTO_PUBLIC_KEY_SIZE] = {0};
crypto_new_keypair(rng, pk1, sk1);
pk_copy(pk2, pk1);
EXPECT_TRUE(pk_equal(pk1, pk2));
}
TEST(Cmp, OrdersNumbersCorrectly)
{
EXPECT_EQ(cmp_uint(1, 2), -1);

View File

@ -231,7 +231,7 @@ bool tox_pass_key_encrypt(const Tox_Pass_Key *key, const uint8_t plaintext[], si
ciphertext += crypto_box_NONCEBYTES;
/* now encrypt */
const int32_t encrypted_len = encrypt_data_symmetric(key->key, nonce, plaintext, plaintext_len, ciphertext);
const int32_t encrypted_len = encrypt_data_symmetric(os_memory(), key->key, nonce, plaintext, plaintext_len, ciphertext);
if (encrypted_len < 0 || (size_t)encrypted_len != plaintext_len + crypto_box_MACBYTES) {
SET_ERROR_PARAMETER(error, TOX_ERR_ENCRYPTION_FAILED);
return false;
@ -316,7 +316,7 @@ bool tox_pass_key_decrypt(const Tox_Pass_Key *key, const uint8_t ciphertext[], s
ciphertext += crypto_box_NONCEBYTES;
/* decrypt the ciphertext */
const int32_t decrypted_len = decrypt_data_symmetric(key->key, nonce, ciphertext, decrypt_length + crypto_box_MACBYTES, plaintext);
const int32_t decrypted_len = decrypt_data_symmetric(os_memory(), key->key, nonce, ciphertext, decrypt_length + crypto_box_MACBYTES, plaintext);
if (decrypted_len < 0 || (size_t)decrypted_len != decrypt_length) {
SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_FAILED);
return false;

View File

@ -56,6 +56,8 @@ target_sources(tomato PUBLIC
./tox_avatar_loader.cpp
./message_image_loader.hpp
./message_image_loader.cpp
./bitset_image_loader.hpp
./bitset_image_loader.cpp
./tox_avatar_manager.hpp
./tox_avatar_manager.cpp
@ -97,9 +99,6 @@ target_sources(tomato PUBLIC
./tox_dht_cap_histo.hpp
./tox_dht_cap_histo.cpp
./tox_netprof_ui.hpp
./tox_netprof_ui.cpp
./tox_friend_faux_offline_messaging.hpp
./tox_friend_faux_offline_messaging.cpp

153
src/bitset_image_loader.cpp Normal file
View File

@ -0,0 +1,153 @@
#include "./bitset_image_loader.hpp"
#include <solanaceae/object_store/object_store.hpp>
#include <solanaceae/object_store/meta_components_file.hpp>
#include "./os_comps.hpp"
#include <entt/entity/entity.hpp>
#include <SDL3/SDL.h>
#include <iostream>
// fwd
namespace Message {
uint64_t getTimeMS(void);
}
std::optional<TextureEntry> BitsetImageLoader::haveToTexture(TextureUploaderI& tu, BitSet& have, ObjectHandle o) {
assert(have.size_bits() > 0);
auto* surf = SDL_CreateSurfaceFrom(
have.size_bits(), 1,
SDL_PIXELFORMAT_INDEX1MSB, // LSB ?
have.data(), have.size_bytes()
);
if (surf == nullptr) {
std::cerr << "BIL error: bitset to 1bit surface creationg failed o:" << entt::to_integral(o.entity()) << "\n";
return std::nullopt;
}
SDL_Color colors[] {
{0, 0, 0, 0},
{255, 255, 255, 255},
};
SDL_Palette* palette = SDL_CreatePalette(2);
SDL_SetPaletteColors(palette, colors, 0, 2);
SDL_SetSurfacePalette(surf, palette);
auto* conv_surf = SDL_ConvertSurface(surf, SDL_PIXELFORMAT_RGBA32);
SDL_DestroySurface(surf);
SDL_DestroyPalette(palette);
if (conv_surf == nullptr) {
std::cerr << "BIL error: surface conversion failed o:" << entt::to_integral(o.entity()) << " : " << SDL_GetError() << "\n";
return std::nullopt;
}
SDL_LockSurface(conv_surf);
TextureEntry new_entry;
new_entry.timestamp_last_rendered = Message::getTimeMS();
new_entry.width = have.size_bits();
new_entry.height = 1;
const auto n_t = tu.upload(static_cast<uint8_t*>(conv_surf->pixels), conv_surf->w, conv_surf->h, TextureUploaderI::RGBA);
assert(n_t != 0);
new_entry.textures.push_back(n_t);
new_entry.frame_duration.push_back(1);
std::cout << "BIL: genereated bitset image o:" << entt::to_integral(o.entity()) << "\n";
SDL_UnlockSurface(conv_surf);
SDL_DestroySurface(conv_surf);
return new_entry;
}
BitsetImageLoader::BitsetImageLoader(void) {
}
TextureLoaderResult BitsetImageLoader::load(TextureUploaderI& tu, ObjectHandle o) {
if (!static_cast<bool>(o)) {
std::cerr << "BIL error: trying to load invalid object\n";
return {};
}
if (!o.any_of<ObjComp::F::LocalHaveBitset, ObjComp::F::RemoteHaveBitset>()) {
// after completion, this is called until the texture times out
//std::cout << "BIL: no have bitset\n";
return {};
}
if (o.all_of<ObjComp::F::LocalHaveBitset>()) {
auto& have = o.get<ObjComp::F::LocalHaveBitset>().have;
assert(have.size_bits() > 0);
return {haveToTexture(tu, have, o)};
} else if (o.all_of<ObjComp::F::RemoteHaveBitset>()) {
auto& list = o.get<ObjComp::F::RemoteHaveBitset>().others;
if (list.empty()) {
std::cout << "BIL: remote set list empty\n";
_tmp_bitset = {8};
return {haveToTexture(tu, _tmp_bitset, o)};
}
const auto& first_entry = list.begin()->second;
if (first_entry.have_all) {
_tmp_bitset = {8};
_tmp_bitset.invert();
std::cout << "BIL: remote first have all\n";
} else {
_tmp_bitset = first_entry.have;
assert(_tmp_bitset.size_bits() == first_entry.have.size_bits());
for (auto it = list.begin()+1; it != list.end(); it++) {
if (it->second.have_all) {
_tmp_bitset = {8};
_tmp_bitset.invert();
std::cout << "BIL: remote have all\n";
break;
}
_tmp_bitset.merge(it->second.have);
}
}
return {haveToTexture(tu, _tmp_bitset, o)};
}
return {};
}
std::optional<TextureEntry> BitsetImageLoader::load(TextureUploaderI& tu, ObjectContactSub ocs) {
if (!static_cast<bool>(ocs.o)) {
std::cerr << "BIL error: trying to load invalid object\n";
return std::nullopt;
}
if (!ocs.o.all_of<ObjComp::F::RemoteHaveBitset>()) {
// after completion, this is called until the texture times out
return std::nullopt;
}
auto& map = ocs.o.get<ObjComp::F::RemoteHaveBitset>().others;
auto it = map.find(ocs.c);
if (it == map.end()) {
// contact not found
return std::nullopt;
}
if (it->second.have_all) {
BitSet tmp{8}; // or 1?
tmp.invert();
return haveToTexture(tu, tmp, ocs.o);
} else if (it->second.have.size_bits() == 0) {
BitSet tmp{8}; // or 1?
return haveToTexture(tu, tmp, ocs.o);
} else {
return haveToTexture(tu, it->second.have, ocs.o);
}
}

View File

@ -0,0 +1,36 @@
#pragma once
#include <solanaceae/object_store/fwd.hpp>
#include <solanaceae/contact/contact_model3.hpp>
#include <solanaceae/util/bitset.hpp>
#include "./texture_cache.hpp"
#include <optional>
struct ObjectContactSub final {
ObjectHandle o;
Contact3 c{entt::null};
};
template<>
struct std::hash<ObjectContactSub> {
std::size_t operator()(ObjectContactSub const& ocs) const noexcept {
const std::size_t h1 = reinterpret_cast<std::size_t>(ocs.o.registry());
const std::size_t h2 = entt::to_integral(ocs.o.entity());
const std::size_t h3 = entt::to_integral(ocs.c);
return (h1 << 3) ^ (h3 << 7) ^ (h2 * 11400714819323198485llu);
}
};
class BitsetImageLoader {
BitSet _tmp_bitset;
std::optional<TextureEntry> haveToTexture(TextureUploaderI& tu, BitSet& have, ObjectHandle o);
public:
BitsetImageLoader(void);
TextureLoaderResult load(TextureUploaderI& tu, ObjectHandle o);
std::optional<TextureEntry> load(TextureUploaderI& tu, ObjectContactSub ocs);
};

View File

@ -11,6 +11,8 @@
#include <imgui/imgui.h>
#include <cmath>
// fwd
namespace Message {
uint64_t getTimeMS(void);
@ -91,7 +93,7 @@ bool SendImagePopup::load(void) {
preview_image.timestamp_last_rendered = Message::getTimeMS();
preview_image.current_texture = 0;
for (const auto& [ms, data] : original_image.frames) {
const auto n_t = _tu.uploadRGBA(data.data(), original_image.width, original_image.height);
const auto n_t = _tu.upload(data.data(), original_image.width, original_image.height);
preview_image.textures.push_back(n_t);
preview_image.frame_duration.push_back(ms);
}

View File

@ -1,7 +1,5 @@
#include "./chat_gui4.hpp"
#include <solanaceae/object_store/object_store.hpp>
#include <solanaceae/message3/components.hpp>
#include <solanaceae/tox_messages/msg_components.hpp>
#include <solanaceae/tox_messages/obj_components.hpp>
@ -18,6 +16,7 @@
#include <imgui/imgui.h>
#include <imgui/misc/cpp/imgui_stdlib.h>
#include <imgui/imgui_internal.h>
#include <SDL3/SDL.h>
@ -25,6 +24,7 @@
#include "./media_meta_info_loader.hpp"
#include "./sdl_clipboard_utils.hpp"
#include "os_comps.hpp"
#include <cctype>
#include <ctime>
@ -246,7 +246,19 @@ ChatGui4::ChatGui4(
ContactTextureCache& contact_tc,
MessageTextureCache& msg_tc,
Theme& theme
) : _conf(conf), _os(os), _rmm(rmm), _cr(cr), _contact_tc(contact_tc), _msg_tc(msg_tc), _theme(theme), _sip(tu) {
) :
_conf(conf),
_os(os),
_os_sr(_os.newSubRef(this)),
_rmm(rmm),
_cr(cr),
_contact_tc(contact_tc),
_msg_tc(msg_tc),
_b_tc(_bil, tu),
_theme(theme),
_sip(tu)
{
_os_sr.subscribe(ObjectStore_Event::object_update);
}
ChatGui4::~ChatGui4(void) {
@ -263,6 +275,8 @@ ChatGui4::~ChatGui4(void) {
float ChatGui4::render(float time_delta) {
_fss.render();
_sip.render(time_delta);
_b_tc.update();
_b_tc.workLoadQueue();
const ImGuiViewport* viewport = ImGui::GetMainViewport();
ImGui::SetNextWindowPos(viewport->WorkPos);
@ -1030,7 +1044,7 @@ void ChatGui4::renderMessageBodyText(Message3Registry& reg, const Message3 e) {
ImGui::BeginGroup();
do {
const auto current_line = msgtext_sv.substr(pos_prev, pos_next - pos_prev);
if (current_line.front() == '>') {
if (!current_line.empty() && current_line.front() == '>') {
// TODO: theming
ImGui::PushStyleColor(ImGuiCol_Text, {0.3f, 0.9f, 0.1f, 1.f});
ImGui::TextUnformatted(current_line.data(), current_line.data()+current_line.size());
@ -1162,6 +1176,8 @@ void ChatGui4::renderMessageBodyFile(Message3Registry& reg, const Message3 e) {
// hacky
const auto* fts = o.try_get<ObjComp::Ephemeral::File::TransferStats>();
if (fts != nullptr && o.any_of<ObjComp::F::SingleInfo, ObjComp::F::CollectionInfo>()) {
const bool upload = o.all_of<ObjComp::F::TagLocalHaveAll>() && fts->total_down <= 0;
const int64_t total_size =
o.all_of<ObjComp::F::SingleInfo>() ?
o.get<ObjComp::F::SingleInfo>().file_size :
@ -1170,7 +1186,7 @@ void ChatGui4::renderMessageBodyFile(Message3Registry& reg, const Message3 e) {
int64_t transfer_total {0u};
float transfer_rate {0.f};
if (o.all_of<ObjComp::F::TagLocalHaveAll>() && fts->total_down <= 0) {
if (upload) {
// if have all AND no dl -> show upload progress
ImGui::TextUnformatted(" up");
transfer_total = fts->total_up;
@ -1183,7 +1199,12 @@ void ChatGui4::renderMessageBodyFile(Message3Registry& reg, const Message3 e) {
}
ImGui::SameLine();
float fraction = float(transfer_total) / total_size;
float fraction{0.f};
if (total_size > 0) {
fraction = float(transfer_total) / total_size;
} else if (o.all_of<ObjComp::F::TagLocalHaveAll>()) {
fraction = 1.f;
}
char overlay_buf[128];
if (transfer_rate > 0.000001f) {
@ -1211,11 +1232,57 @@ void ChatGui4::renderMessageBodyFile(Message3Registry& reg, const Message3 e) {
std::snprintf(overlay_buf, sizeof(overlay_buf), "%.1f%%", fraction * 100 + 0.01f);
}
ImGui::ProgressBar(
fraction,
{-FLT_MIN, TEXT_BASE_HEIGHT},
overlay_buf
);
if (
(!upload && !o.all_of<ObjComp::F::TagLocalHaveAll>() && o.all_of<ObjComp::F::LocalHaveBitset>()) ||
(upload && o.all_of<ObjComp::F::RemoteHaveBitset>())
) {
ImGui::BeginGroup();
// TODO: hights are all off
ImGui::ProgressBar(
fraction,
{-FLT_MIN, TEXT_BASE_HEIGHT*0.66f},
overlay_buf
);
ImVec2 orig_curser_pos = ImGui::GetCursorPos();
const ImVec2 bar_size{ImGui::GetContentRegionAvail().x, TEXT_BASE_HEIGHT*0.15f};
// deploy dummy and check visibility
ImGui::Dummy(bar_size);
if (ImGui::IsItemVisible()) {
ImGui::SetCursorPos(orig_curser_pos); // reset before dummy
auto const cursor_start_vec = ImGui::GetCursorScreenPos();
// TODO: replace with own version, so we dont have to internal
ImGui::RenderFrame(
cursor_start_vec,
{
cursor_start_vec.x + bar_size.x,
cursor_start_vec.y + bar_size.y
},
ImGui::GetColorU32(ImGuiCol_FrameBg),
false
);
auto [id, img_width, img_height] = _b_tc.get(o);
ImGui::Image(
id,
bar_size,
{0.f, 0.f}, // default
{1.f, 1.f}, // default
ImGui::GetStyleColorVec4(ImGuiCol_PlotHistogram)
);
}
ImGui::EndGroup();
} else {
ImGui::ProgressBar(
fraction,
{-FLT_MIN, TEXT_BASE_HEIGHT},
overlay_buf
);
}
} else {
// infinite scrolling progressbar fallback
ImGui::TextUnformatted(" ??");
@ -1227,16 +1294,6 @@ void ChatGui4::renderMessageBodyFile(Message3Registry& reg, const Message3 e) {
);
}
if (!o.all_of<ObjComp::F::TagLocalHaveAll>() && o.all_of<ObjComp::F::LocalHaveBitset>()) {
// texture based on have bitset
// TODO: missing have chunks/chunksize to get the correct size
//const auto& bitest = o.get<ObjComp::F::LocalHaveBitset>().have;
// generate 1bit sdlsurface zerocopy using bitset.data() and bitset.size_bytes()
// optionally scale down filtered (would copy)
// update texture? in cache?
}
if (o.all_of<ObjComp::F::FrameDims>()) {
const auto& frame_dims = o.get<ObjComp::F::FrameDims>();
@ -1721,3 +1778,11 @@ void ChatGui4::sendFileList(const std::vector<std::string_view>& list) {
}
}
bool ChatGui4::onEvent(const ObjectStore::Events::ObjectUpdate& e) {
if (e.e.any_of<ObjComp::F::LocalHaveBitset, ObjComp::F::RemoteHaveBitset>()) {
_b_tc.stale(e.e);
}
return false;
}

View File

@ -1,6 +1,6 @@
#pragma once
#include <solanaceae/object_store/fwd.hpp>
#include <solanaceae/object_store/object_store.hpp>
#include <solanaceae/message3/registry_message_model.hpp>
#include <solanaceae/util/config_model.hpp>
@ -10,6 +10,7 @@
#include "./texture_cache.hpp"
#include "./tox_avatar_loader.hpp"
#include "./message_image_loader.hpp"
#include "./bitset_image_loader.hpp"
#include "./chat_gui/file_selector.hpp"
#include "./chat_gui/send_image_popup.hpp"
@ -23,15 +24,19 @@
using ContactTextureCache = TextureCache<void*, Contact3, ToxAvatarLoader>;
using MessageTextureCache = TextureCache<void*, Message3Handle, MessageImageLoader>;
using BitsetTextureCache = TextureCache<void*, ObjectHandle, BitsetImageLoader>;
class ChatGui4 {
class ChatGui4 : public ObjectStoreEventI {
ConfigModelI& _conf;
ObjectStore2& _os;
ObjectStoreEventProviderI::SubscriptionReference _os_sr;
RegistryMessageModelI& _rmm;
Contact3Registry& _cr;
ContactTextureCache& _contact_tc;
MessageTextureCache& _msg_tc;
BitsetImageLoader _bil;
BitsetTextureCache _b_tc;
Theme& _theme;
@ -86,6 +91,9 @@ class ChatGui4 {
//bool renderSubContactListContact(const Contact3 c, const bool selected) const;
void pasteFile(const char* mime_type);
protected:
bool onEvent(const ObjectStore::Events::ObjectUpdate&) override;
};

View File

@ -85,6 +85,7 @@ struct DebugVideoTapSink : public FrameStream2SinkI<SDLVideoFrame> {
};
struct DebugVideoTestSource : public FrameStream2SourceI<SDLVideoFrame> {
std::mutex _readers_mutex;
std::vector<std::shared_ptr<LockedFrameStream2<SDLVideoFrame>>> _readers;
std::atomic_bool _stop {false};
@ -94,6 +95,9 @@ struct DebugVideoTestSource : public FrameStream2SourceI<SDLVideoFrame> {
std::cout << "DVTS: starting new test video source\n";
_thread = std::thread([this](void) {
while (!_stop) {
std::this_thread::sleep_for(std::chrono::milliseconds(50));
std::lock_guard lg{_readers_mutex};
if (!_readers.empty()) {
auto* surf = SDL_CreateSurface(960, 720, SDL_PIXELFORMAT_RGBA32);
@ -113,8 +117,6 @@ struct DebugVideoTestSource : public FrameStream2SourceI<SDLVideoFrame> {
SDL_DestroySurface(surf);
}
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
});
}
@ -124,10 +126,12 @@ struct DebugVideoTestSource : public FrameStream2SourceI<SDLVideoFrame> {
}
std::shared_ptr<FrameStream2I<SDLVideoFrame>> subscribe(void) override {
std::lock_guard lg{_readers_mutex};
return _readers.emplace_back(std::make_shared<LockedFrameStream2<SDLVideoFrame>>());
}
bool unsubscribe(const std::shared_ptr<FrameStream2I<SDLVideoFrame>>& sub) override {
std::lock_guard lg{_readers_mutex};
for (auto it = _readers.cbegin(); it != _readers.cend(); it++) {
if (it->get() == sub.get()) {
_readers.erase(it);

View File

@ -55,6 +55,7 @@ ImageLoaderSDLImage::ImageInfo ImageLoaderSDLImage::loadInfoFromMemory(const uin
// we ignore tga
auto ext_opt = getExt(ios);
if (!ext_opt.has_value()) {
SDL_CloseIO(ios);
return res;
}
@ -80,6 +81,7 @@ ImageLoaderSDLImage::ImageResult ImageLoaderSDLImage::loadFromMemoryRGBA(const u
// we ignore tga
auto ext_opt = getExt(ios);
if (!ext_opt.has_value()) {
SDL_CloseIO(ios);
return res;
}

View File

@ -48,7 +48,6 @@ MainScreen::MainScreen(SimpleConfigModel&& conf_, SDL_Renderer* renderer_, Theme
osui(os),
tuiu(tc, conf, &tpi),
tdch(tpi),
tnui(tpi),
smui(os, sm),
dvt(os, sm, sdlrtu)
{
@ -363,7 +362,6 @@ Screen* MainScreen::render(float time_delta, bool&) {
osui.render();
tuiu.render(); // render
tdch.render(); // render
const float tnui_interval = tnui.render(time_delta);
smui.render();
const float dvt_interval = dvt.render();
@ -554,7 +552,6 @@ Screen* MainScreen::render(float time_delta, bool&) {
if (!_window_hidden && _time_since_event < curr_profile.low_delay_window) {
_render_interval = std::min<float>(_render_interval, ctc_interval);
_render_interval = std::min<float>(_render_interval, msgtc_interval);
_render_interval = std::min<float>(_render_interval, tnui_interval);
_render_interval = std::clamp(
_render_interval,
@ -565,7 +562,6 @@ Screen* MainScreen::render(float time_delta, bool&) {
} else if (!_window_hidden && _time_since_event < curr_profile.mid_delay_window) {
_render_interval = std::min<float>(_render_interval, ctc_interval);
_render_interval = std::min<float>(_render_interval, msgtc_interval);
_render_interval = std::min<float>(_render_interval, tnui_interval);
_render_interval = std::clamp(
_render_interval,
@ -611,7 +607,6 @@ Screen* MainScreen::tick(float time_delta, bool& quit) {
const float pm_interval = pm.tick(time_delta); // compute
tdch.tick(time_delta); // compute
tnui.tick(time_delta); // compute
mts.iterate(); // compute (after mfs)

View File

@ -34,7 +34,6 @@
#include "./object_store_ui.hpp"
#include "./tox_ui_utils.hpp"
#include "./tox_dht_cap_histo.hpp"
#include "./tox_netprof_ui.hpp"
#include "./tox_friend_faux_offline_messaging.hpp"
#include "./stream_manager_ui.hpp"
#include "./debug_video_tap.hpp"
@ -97,7 +96,6 @@ struct MainScreen final : public Screen {
ObjectStoreUI osui;
ToxUIUtils tuiu;
ToxDHTCapHisto tdch;
ToxNetprofUI tnui;
StreamManagerUI smui;
DebugVideoTap dvt;

View File

@ -30,29 +30,29 @@ MessageImageLoader::MessageImageLoader(void) {
_image_loaders.push_back(std::make_unique<ImageLoaderSDLImage>());
}
std::optional<TextureEntry> MessageImageLoader::load(TextureUploaderI& tu, Message3Handle m) {
TextureLoaderResult MessageImageLoader::load(TextureUploaderI& tu, Message3Handle m) {
if (!static_cast<bool>(m)) {
return std::nullopt;
return {std::nullopt};
}
if (m.all_of<Message::Components::TagNotImage>()) {
return std::nullopt;
return {std::nullopt};
}
if (!m.all_of<Message::Components::MessageFileObject>()) {
// not a file message
return std::nullopt;
return {std::nullopt};
}
const auto& o = m.get<Message::Components::MessageFileObject>().o;
if (!static_cast<bool>(o)) {
std::cerr << "MIL error: invalid object in file message\n";
return std::nullopt;
return {std::nullopt};
}
if (!o.all_of<ObjComp::Ephemeral::Backend, ObjComp::F::SingleInfo>()) {
std::cerr << "MIL error: object missing backend (?)\n";
return std::nullopt;
return {std::nullopt};
}
// TODO: handle collections
@ -60,40 +60,40 @@ std::optional<TextureEntry> MessageImageLoader::load(TextureUploaderI& tu, Messa
if (file_size > 50*1024*1024) {
std::cerr << "MIL error: image file too large\n";
return std::nullopt;
return {std::nullopt};
}
if (file_size == 0) {
std::cerr << "MIL warning: empty file\n";
return std::nullopt;
return {std::nullopt};
}
if (!o.all_of<ObjComp::F::TagLocalHaveAll>()) {
// not ready yet
return std::nullopt;
return {std::nullopt};
}
auto* file_backend = o.get<ObjComp::Ephemeral::Backend>().ptr;
if (file_backend == nullptr) {
std::cerr << "MIL error: object backend nullptr\n";
return std::nullopt;
return {std::nullopt};
}
auto file2 = file_backend->file2(o, StorageBackendI::FILE2_READ);
if (!file2 || !file2->isGood() || !file2->can_read) {
std::cerr << "MIL error: creating file2 from object via backendI\n";
return std::nullopt;
return {std::nullopt};
}
auto read_data = file2->read(file_size, 0);
if (read_data.ptr == nullptr) {
std::cerr << "MMIL error: reading from file2 returned nullptr\n";
return std::nullopt;
return {std::nullopt};
}
if (read_data.size != file_size) {
std::cerr << "MIL error: reading from file2 size missmatch, should be " << file_size << ", is " << read_data.size << "\n";
return std::nullopt;
return {std::nullopt};
}
// try all loaders after another
@ -107,7 +107,7 @@ std::optional<TextureEntry> MessageImageLoader::load(TextureUploaderI& tu, Messa
new_entry.timestamp_last_rendered = Message::getTimeMS();
new_entry.current_texture = 0;
for (const auto& [ms, data] : res.frames) {
const auto n_t = tu.uploadRGBA(data.data(), res.width, res.height);
const auto n_t = tu.upload(data.data(), res.width, res.height);
new_entry.textures.push_back(n_t);
new_entry.frame_duration.push_back(ms);
}
@ -117,10 +117,10 @@ std::optional<TextureEntry> MessageImageLoader::load(TextureUploaderI& tu, Messa
std::cout << "MIL: loaded image file o:" << /*file_path*/ entt::to_integral(o.entity()) << "\n";
return new_entry;
return {new_entry};
}
std::cerr << "MIL error: failed to load message (unhandled format)\n";
return std::nullopt;
return {std::nullopt};
}

View File

@ -12,6 +12,6 @@ class MessageImageLoader {
public:
MessageImageLoader(void);
std::optional<TextureEntry> load(TextureUploaderI& tu, Message3Handle c);
TextureLoaderResult load(TextureUploaderI& tu, Message3Handle m);
};

View File

@ -8,21 +8,6 @@
namespace ObjectStore::Components {
// until i find a better name
namespace File {
// ephemeral?, not sure saving this to disk makes sense
// tag remove have all?
struct RemoteHaveBitset {
struct Entry {
bool have_all {false};
BitSet have;
};
entt::dense_map<Contact3, Entry> others;
};
} // File
namespace Ephemeral {
namespace File {

View File

@ -18,8 +18,6 @@ constexpr std::string_view entt::type_name<x>::value() noexcept { \
// cross compile(r) stable ids
DEFINE_COMP_ID(ObjComp::F::RemoteHaveBitset)
DEFINE_COMP_ID(ObjComp::Ephemeral::File::TransferStatsSeparated)
#undef DEFINE_COMP_ID

View File

@ -46,7 +46,7 @@ TextureEntry generateTestAnim(TextureUploaderI& tu) {
}
}
const auto n_t = tu.uploadRGBA(pixels.data(), width, height);
const auto n_t = tu.upload(pixels.data(), width, height);
// this is so ugly
new_entry.textures.emplace_back(n_t);

View File

@ -5,6 +5,10 @@
#include <entt/container/dense_map.hpp>
#include <entt/container/dense_set.hpp>
#include <optional>
#include <vector>
#include <cassert>
#include <iostream>
struct TextureEntry {
@ -70,6 +74,11 @@ struct TextureEntry {
}
};
struct TextureLoaderResult {
std::optional<TextureEntry> texture;
bool keep_trying{false}; // if set, cant be cleared, as some async might be going on
};
TextureEntry generateTestAnim(TextureUploaderI& tu);
// fwd
@ -91,6 +100,7 @@ struct TextureCache {
entt::dense_map<KeyType, TextureEntry> _cache;
entt::dense_set<KeyType> _to_load;
// to_reload // to_update? _marked_stale?
const uint64_t ms_before_purge {60 * 1000ull};
const size_t min_count_before_purge {0}; // starts purging after that
@ -134,6 +144,18 @@ struct TextureCache {
}
}
// markes a texture as stale and will reload it
// only if it already is loaded, does not update ts
bool stale(const KeyType& key) {
auto it = _cache.find(key);
if (it == _cache.end()) {
return false;
}
_to_load.insert(key);
return true;
}
float update(void) {
const uint64_t ts_now = Message::getTimeMS();
uint64_t ts_min_next = ts_now + ms_before_purge;
@ -144,7 +166,10 @@ struct TextureCache {
const uint64_t ts_next = te.doAnimation(ts_now);
te.rendered_this_frame = false;
ts_min_next = std::min(ts_min_next, ts_next);
} else if (_cache.size() > min_count_before_purge && ts_now - te.timestamp_last_rendered >= ms_before_purge) {
} else if (
_cache.size() > min_count_before_purge &&
ts_now - te.timestamp_last_rendered >= ms_before_purge
) {
to_purge.push_back(key);
}
}
@ -159,31 +184,64 @@ struct TextureCache {
void invalidate(const std::vector<KeyType>& to_purge) {
for (const auto& key : to_purge) {
if (_to_load.count(key)) {
// TODO: only remove if not keep trying
_to_load.erase(key);
}
if (_cache.count(key)) {
for (const auto& tex_id : _cache.at(key).textures) {
_tu.destroy(tex_id);
}
_cache.erase(key);
}
_cache.erase(key);
}
}
// returns true if there is still work queued up
bool workLoadQueue(void) {
auto it = _to_load.begin();
for (; it != _to_load.end(); it++) {
auto it = _to_load.cbegin();
for (; it != _to_load.cend(); it++) {
auto new_entry_opt = _l.load(_tu, *it);
if (new_entry_opt.has_value()) {
_cache.emplace(*it, new_entry_opt.value());
it = _to_load.erase(it);
if (_cache.count(*it)) {
if (new_entry_opt.texture.has_value()) {
auto old_entry = _cache.at(*it); // copy
assert(!old_entry.textures.empty());
for (const auto& tex_id : old_entry.textures) {
_tu.destroy(tex_id);
}
// TODO: not a good idea?
break; // end load from queue/onlyload 1 per update
_cache.erase(*it);
auto& new_entry = _cache[*it] = new_entry_opt.texture.value();
// TODO: make update interface and let loader handle this
//new_entry.current_texture = old_entry.current_texture; // ??
new_entry.rendered_this_frame = old_entry.rendered_this_frame;
new_entry.timestamp_last_rendered = old_entry.timestamp_last_rendered;
it = _to_load.erase(it);
// TODO: not a good idea?
break; // end load from queue/onlyload 1 per update
} else if (!new_entry_opt.keep_trying) {
// failed to load and the loader is done
it = _to_load.erase(it);
}
} else {
if (new_entry_opt.texture.has_value()) {
_cache.emplace(*it, new_entry_opt.texture.value());
_cache.at(*it).rendered_this_frame = true; // ?
it = _to_load.erase(it);
// TODO: not a good idea?
break; // end load from queue/onlyload 1 per update
} else if (!new_entry_opt.keep_trying) {
// failed to load and the loader is done
it = _to_load.erase(it);
}
}
}
// peak
return it != _to_load.end();
// peek
return it != _to_load.cend();
}
};

View File

@ -4,6 +4,7 @@
#include "./image_loader_qoi.hpp"
#include "./image_loader_webp.hpp"
#include "./image_loader_sdl_image.hpp"
#include "texture_uploader.hpp"
#include <solanaceae/contact/components.hpp>
#include <solanaceae/tox_contacts/components.hpp>
@ -119,9 +120,9 @@ static std::vector<uint8_t> generateToxIdenticon(const ToxKey& key) {
return pixels;
}
std::optional<TextureEntry> ToxAvatarLoader::load(TextureUploaderI& tu, Contact3 c) {
TextureLoaderResult ToxAvatarLoader::load(TextureUploaderI& tu, Contact3 c) {
if (!_cr.valid(c)) {
return std::nullopt;
return {std::nullopt};
}
if (_cr.all_of<Contact::Components::AvatarMemory>(c)) {
@ -134,13 +135,13 @@ std::optional<TextureEntry> ToxAvatarLoader::load(TextureUploaderI& tu, Contact3
new_entry.width = a_m.width;
new_entry.height = a_m.height;
const auto n_t = tu.uploadRGBA(a_m.data.data(), a_m.width, a_m.height);
const auto n_t = tu.upload(a_m.data.data(), a_m.width, a_m.height);
new_entry.textures.push_back(n_t);
new_entry.frame_duration.push_back(250);
std::cout << "TAL: loaded memory buffer\n";
return new_entry;
return {new_entry};
}
if (_cr.all_of<Contact::Components::AvatarFile>(c)) {
@ -169,7 +170,7 @@ std::optional<TextureEntry> ToxAvatarLoader::load(TextureUploaderI& tu, Contact3
new_entry.timestamp_last_rendered = Message::getTimeMS();
new_entry.current_texture = 0;
for (const auto& [ms, data] : res.frames) {
const auto n_t = tu.uploadRGBA(data.data(), res.width, res.height);
const auto n_t = tu.upload(data.data(), res.width, res.height);
new_entry.textures.push_back(n_t);
new_entry.frame_duration.push_back(ms);
}
@ -179,7 +180,7 @@ std::optional<TextureEntry> ToxAvatarLoader::load(TextureUploaderI& tu, Contact3
std::cout << "TAL: loaded image file " << a_f.file_path << "\n";
return new_entry;
return {new_entry};
}
}
} // continues if loading img fails
@ -190,7 +191,7 @@ std::optional<TextureEntry> ToxAvatarLoader::load(TextureUploaderI& tu, Contact3
Contact::Components::ToxGroupPeerPersistent,
Contact::Components::ID
>(c)) {
return std::nullopt;
return {std::nullopt};
}
std::vector<uint8_t> pixels;
@ -212,7 +213,7 @@ std::optional<TextureEntry> ToxAvatarLoader::load(TextureUploaderI& tu, Contact3
new_entry.timestamp_last_rendered = Message::getTimeMS();
new_entry.current_texture = 0;
const auto n_t = tu.uploadRGBA(pixels.data(), 5, 5, TextureUploaderI::NEAREST);
const auto n_t = tu.upload(pixels.data(), 5, 5, TextureUploaderI::RGBA, TextureUploaderI::NEAREST);
new_entry.textures.push_back(n_t);
new_entry.frame_duration.push_back(250);
@ -221,6 +222,6 @@ std::optional<TextureEntry> ToxAvatarLoader::load(TextureUploaderI& tu, Contact3
std::cout << "TAL: generated ToxIdenticon\n";
return new_entry;
return {new_entry};
}

View File

@ -14,6 +14,6 @@ class ToxAvatarLoader {
public:
ToxAvatarLoader(Contact3Registry& cr);
std::optional<TextureEntry> load(TextureUploaderI& tu, Contact3 c);
TextureLoaderResult load(TextureUploaderI& tu, Contact3 c);
};

View File

@ -1,310 +0,0 @@
#include "./tox_netprof_ui.hpp"
#include <imgui/imgui.h>
static const char* typedPkgIDToString(Tox_Netprof_Packet_Type type, uint8_t id) {
// pain
if (type == TOX_NETPROF_PACKET_TYPE_UDP) {
switch (id) {
case TOX_NETPROF_PACKET_ID_ZERO: return "Ping request";
case TOX_NETPROF_PACKET_ID_ONE: return "Ping response";
case TOX_NETPROF_PACKET_ID_TWO: return "Get nodes request";
case TOX_NETPROF_PACKET_ID_FOUR: return "Send nodes response";
case TOX_NETPROF_PACKET_ID_COOKIE_REQUEST: return "Cookie request";
case TOX_NETPROF_PACKET_ID_COOKIE_RESPONSE: return "Cookie response";
case TOX_NETPROF_PACKET_ID_CRYPTO_HS: return "Crypto handshake";
case TOX_NETPROF_PACKET_ID_CRYPTO_DATA: return "Crypto data";
case TOX_NETPROF_PACKET_ID_CRYPTO: return "Encrypted data";
case TOX_NETPROF_PACKET_ID_LAN_DISCOVERY: return "LAN discovery";
case TOX_NETPROF_PACKET_ID_GC_HANDSHAKE: return "DHT groupchat handshake";
case TOX_NETPROF_PACKET_ID_GC_LOSSLESS: return "DHT groupchat lossless";
case TOX_NETPROF_PACKET_ID_GC_LOSSY: return "DHT groupchat lossy";
case TOX_NETPROF_PACKET_ID_ONION_SEND_INITIAL: return "Onion send init";
case TOX_NETPROF_PACKET_ID_ONION_SEND_1: return "Onion send 1";
case TOX_NETPROF_PACKET_ID_ONION_SEND_2: return "Onion send 2";
case TOX_NETPROF_PACKET_ID_ANNOUNCE_REQUEST_OLD: return "DHT announce request (old)";
case TOX_NETPROF_PACKET_ID_ANNOUNCE_RESPONSE_OLD: return "DHT announce response (old)";
case TOX_NETPROF_PACKET_ID_ONION_DATA_REQUEST: return "Onion data request";
case TOX_NETPROF_PACKET_ID_ONION_DATA_RESPONSE: return "Onion data response";
case TOX_NETPROF_PACKET_ID_ANNOUNCE_REQUEST: return "DHT announce request";
case TOX_NETPROF_PACKET_ID_ANNOUNCE_RESPONSE: return "DHT announce response";
case TOX_NETPROF_PACKET_ID_ONION_RECV_3: return "Onion receive 3";
case TOX_NETPROF_PACKET_ID_ONION_RECV_2: return "Onion receive 2";
case TOX_NETPROF_PACKET_ID_ONION_RECV_1: return "Onion receive 1";
case TOX_NETPROF_PACKET_ID_FORWARD_REQUEST: return "DHT forwarding request";
case TOX_NETPROF_PACKET_ID_FORWARDING: return "DHT forwarding";
case TOX_NETPROF_PACKET_ID_FORWARD_REPLY: return "DHT forward reply";
case TOX_NETPROF_PACKET_ID_DATA_SEARCH_REQUEST: return "DHT data search request";
case TOX_NETPROF_PACKET_ID_DATA_SEARCH_RESPONSE: return "DHT data search response";
case TOX_NETPROF_PACKET_ID_DATA_RETRIEVE_REQUEST: return "DHT data retrieve request";
case TOX_NETPROF_PACKET_ID_DATA_RETRIEVE_RESPONSE: return "DHT data retrieve response";
case TOX_NETPROF_PACKET_ID_STORE_ANNOUNCE_REQUEST: return "DHT store announce request";
case TOX_NETPROF_PACKET_ID_STORE_ANNOUNCE_RESPONSE: return "DHT store announce response";
case TOX_NETPROF_PACKET_ID_BOOTSTRAP_INFO: return "Bootstrap info";
}
} else if (type == TOX_NETPROF_PACKET_TYPE_TCP) { // TODO: or client/server
switch (id) {
case TOX_NETPROF_PACKET_ID_ZERO: return "Routing request";
case TOX_NETPROF_PACKET_ID_ONE: return "Routing response";
case TOX_NETPROF_PACKET_ID_TWO: return "Connection notification";
case TOX_NETPROF_PACKET_ID_TCP_DISCONNECT: return "disconnect notification";
case TOX_NETPROF_PACKET_ID_FOUR: return "Ping packet";
case TOX_NETPROF_PACKET_ID_TCP_PONG: return "pong packet";
case TOX_NETPROF_PACKET_ID_TCP_OOB_SEND: return "out-of-band send";
case TOX_NETPROF_PACKET_ID_TCP_OOB_RECV: return "out-of-band receive";
case TOX_NETPROF_PACKET_ID_TCP_ONION_REQUEST: return "onion request";
case TOX_NETPROF_PACKET_ID_TCP_ONION_RESPONSE: return "onion response";
case TOX_NETPROF_PACKET_ID_TCP_DATA: return "data";
//case TOX_NETPROF_PACKET_ID_BOOTSTRAP_INFO: return "Bootstrap info";
}
}
return "UNK";
}
void ToxNetprofUI::tick(float time_delta) {
if (!_enabled) {
return;
}
_time_since_last_add += time_delta;
if (_time_since_last_add >= _value_add_interval) {
_time_since_last_add = 0.f; // very loose
if (_udp_tctx.empty()) {
_udp_tctx.push_back(0.f);
_udp_tctx_prev = _tpi.toxNetprofGetPacketTotalCount(TOX_NETPROF_PACKET_TYPE_UDP, TOX_NETPROF_DIRECTION_SENT);
} else {
const auto new_value = _tpi.toxNetprofGetPacketTotalCount(TOX_NETPROF_PACKET_TYPE_UDP, TOX_NETPROF_DIRECTION_SENT);
_udp_tctx.push_back(new_value - _udp_tctx_prev);
_udp_tctx_prev = new_value;
}
if (_udp_tcrx.empty()) {
_udp_tcrx.push_back(0.f);
_udp_tcrx_prev = _tpi.toxNetprofGetPacketTotalCount(TOX_NETPROF_PACKET_TYPE_UDP, TOX_NETPROF_DIRECTION_RECV);
} else {
const auto new_value = _tpi.toxNetprofGetPacketTotalCount(TOX_NETPROF_PACKET_TYPE_UDP, TOX_NETPROF_DIRECTION_RECV);
_udp_tcrx.push_back(new_value - _udp_tcrx_prev);
_udp_tcrx_prev = new_value;
}
if (_udp_tbtx.empty()) {
_udp_tbtx.push_back(0.f);
_udp_tbtx_prev = _tpi.toxNetprofGetPacketTotalBytes(TOX_NETPROF_PACKET_TYPE_UDP, TOX_NETPROF_DIRECTION_SENT);
} else {
const auto new_value = _tpi.toxNetprofGetPacketTotalBytes(TOX_NETPROF_PACKET_TYPE_UDP, TOX_NETPROF_DIRECTION_SENT);
_udp_tbtx.push_back(new_value - _udp_tbtx_prev);
_udp_tbtx_prev = new_value;
}
if (_udp_tbrx.empty()) {
_udp_tbrx.push_back(0.f);
_udp_tbrx_prev = _tpi.toxNetprofGetPacketTotalBytes(TOX_NETPROF_PACKET_TYPE_UDP, TOX_NETPROF_DIRECTION_RECV);
} else {
const auto new_value = _tpi.toxNetprofGetPacketTotalBytes(TOX_NETPROF_PACKET_TYPE_UDP, TOX_NETPROF_DIRECTION_RECV);
_udp_tbrx.push_back(new_value - _udp_tbrx_prev);
_udp_tbrx_prev = new_value;
}
if (_udp_tbrx.empty()) {
}
// TODO: limit
while (_udp_tctx.size() > 5*60) {
_udp_tctx.erase(_udp_tctx.begin());
}
while (_udp_tcrx.size() > 5*60) {
_udp_tcrx.erase(_udp_tcrx.begin());
}
while (_udp_tbtx.size() > 5*60) {
_udp_tbtx.erase(_udp_tbtx.begin());
}
while (_udp_tbrx.size() > 5*60) {
_udp_tbrx.erase(_udp_tbrx.begin());
}
}
}
float ToxNetprofUI::render(float time_delta) {
{ // main window menubar injection
// assumes the window "tomato" was rendered already by cg
if (ImGui::Begin("tomato")) {
if (ImGui::BeginMenuBar()) {
if (ImGui::BeginMenu("Tox")) {
ImGui::SeparatorText("Net diagnostics");
if (ImGui::MenuItem("Breakdown table", nullptr, _show_window_table)) {
_show_window_table = !_show_window_table;
}
ImGui::Checkbox("histogram logging", &_enabled);
if (ImGui::MenuItem("Netprof histograms", nullptr, _show_window_histo)) {
_show_window_histo = !_show_window_histo;
}
ImGui::EndMenu();
}
ImGui::EndMenuBar();
}
}
ImGui::End();
}
if (_show_window_table) {
if (ImGui::Begin("Tox Netprof table", &_show_window_table)) {
ImGui::Text("UDP total Count tx/rx: %zu/%zu",
_tpi.toxNetprofGetPacketTotalCount(TOX_NETPROF_PACKET_TYPE_UDP, TOX_NETPROF_DIRECTION_SENT),
_tpi.toxNetprofGetPacketTotalCount(TOX_NETPROF_PACKET_TYPE_UDP, TOX_NETPROF_DIRECTION_RECV)
);
ImGui::Text("UDP total Bytes tx/rx: %zu/%zu",
_tpi.toxNetprofGetPacketTotalBytes(TOX_NETPROF_PACKET_TYPE_UDP, TOX_NETPROF_DIRECTION_SENT),
_tpi.toxNetprofGetPacketTotalBytes(TOX_NETPROF_PACKET_TYPE_UDP, TOX_NETPROF_DIRECTION_RECV)
);
ImGui::Text("TCP total Count tx/rx: %zu/%zu (client: %zu/%zu; server: %zu/%zu)",
_tpi.toxNetprofGetPacketTotalCount(TOX_NETPROF_PACKET_TYPE_TCP, TOX_NETPROF_DIRECTION_SENT),
_tpi.toxNetprofGetPacketTotalCount(TOX_NETPROF_PACKET_TYPE_TCP, TOX_NETPROF_DIRECTION_RECV),
_tpi.toxNetprofGetPacketTotalCount(TOX_NETPROF_PACKET_TYPE_TCP_CLIENT, TOX_NETPROF_DIRECTION_SENT),
_tpi.toxNetprofGetPacketTotalCount(TOX_NETPROF_PACKET_TYPE_TCP_CLIENT, TOX_NETPROF_DIRECTION_RECV),
_tpi.toxNetprofGetPacketTotalCount(TOX_NETPROF_PACKET_TYPE_TCP_SERVER, TOX_NETPROF_DIRECTION_SENT),
_tpi.toxNetprofGetPacketTotalCount(TOX_NETPROF_PACKET_TYPE_TCP_SERVER, TOX_NETPROF_DIRECTION_RECV)
);
ImGui::Text("TCP total Bytes tx/rx: %zu/%zu (client: %zu/%zu; server: %zu/%zu)",
_tpi.toxNetprofGetPacketTotalBytes(TOX_NETPROF_PACKET_TYPE_TCP, TOX_NETPROF_DIRECTION_SENT),
_tpi.toxNetprofGetPacketTotalBytes(TOX_NETPROF_PACKET_TYPE_TCP, TOX_NETPROF_DIRECTION_RECV),
_tpi.toxNetprofGetPacketTotalBytes(TOX_NETPROF_PACKET_TYPE_TCP_CLIENT, TOX_NETPROF_DIRECTION_SENT),
_tpi.toxNetprofGetPacketTotalBytes(TOX_NETPROF_PACKET_TYPE_TCP_CLIENT, TOX_NETPROF_DIRECTION_RECV),
_tpi.toxNetprofGetPacketTotalBytes(TOX_NETPROF_PACKET_TYPE_TCP_SERVER, TOX_NETPROF_DIRECTION_SENT),
_tpi.toxNetprofGetPacketTotalBytes(TOX_NETPROF_PACKET_TYPE_TCP_SERVER, TOX_NETPROF_DIRECTION_RECV)
);
// TODO: color types (tcp/udp and maybe dht)
static float decay_rate = 3.f;
ImGui::SliderFloat("heat decay (/s)", &decay_rate, 0.f, 50.0f);
// type (udp/tcp), id/name, count tx, count rx, bytes tx, bytes rx
if (ImGui::BeginTable("per packet", 6, ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY)) {
ImGui::TableSetupScrollFreeze(0, 1); // Make top row always visible
ImGui::TableSetupColumn("type");
ImGui::TableSetupColumn("pkt type");
ImGui::TableSetupColumn("count tx");
ImGui::TableSetupColumn("count rx");
ImGui::TableSetupColumn("bytes tx");
ImGui::TableSetupColumn("bytes rx");
ImGui::TableHeadersRow();
auto value_fn = [time_delta](size_t i, uint64_t value, auto& prev_map, auto& heat_map, const float scale = 0.2f) {
ImGui::TableNextColumn();
ImGui::Text("%zu", value);
if (prev_map.count(i)) {
const auto delta = value - prev_map[i];
float& heat = heat_map[i];
heat += delta * scale; // count 0.1, bytes 0.02?
// TODO: actual color function
float green = 0.7f;
if (heat > 1.f) {
green -= (heat - 1.f) * 0.1f;
}
ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg, ImGui::GetColorU32(ImVec4(0.9f, green, 0.0f, heat)));
//ImGui::SameLine();
//ImGui::Text("%.2f", heat);
//heat *= 0.94f;
float decay = decay_rate * time_delta;
if (decay > 0.999f) {
decay = 0.999f;
}
heat *= (1.f - decay);
}
prev_map[i] = value;
};
for (size_t i = 0; i < 0xff; i++) {
if (i == 0x10) {
continue;
}
const auto count_sent = _tpi.toxNetprofGetPacketIdCount(TOX_NETPROF_PACKET_TYPE_UDP, i, TOX_NETPROF_DIRECTION_SENT);
const auto count_received = _tpi.toxNetprofGetPacketIdCount(TOX_NETPROF_PACKET_TYPE_UDP, i, TOX_NETPROF_DIRECTION_RECV);
if (count_sent == 0 && count_received == 0) {
continue; // skip empty
}
ImGui::TableNextColumn();
ImGui::TextUnformatted("UDP");
ImGui::TableNextColumn();
ImGui::Text("%02zx(%s)", i, typedPkgIDToString(TOX_NETPROF_PACKET_TYPE_UDP, i));
value_fn(i, count_sent, _udp_ctx_prev, _udp_ctx_heat);
value_fn(i, count_received, _udp_crx_prev, _udp_crx_heat);
value_fn(i, _tpi.toxNetprofGetPacketIdBytes(TOX_NETPROF_PACKET_TYPE_UDP, i, TOX_NETPROF_DIRECTION_SENT), _udp_btx_prev, _udp_btx_heat, 0.005f);
value_fn(i, _tpi.toxNetprofGetPacketIdBytes(TOX_NETPROF_PACKET_TYPE_UDP, i, TOX_NETPROF_DIRECTION_RECV), _udp_brx_prev, _udp_brx_heat, 0.005f);
}
for (size_t i = 0; i <= 0x10; i++) {
const auto count_sent = _tpi.toxNetprofGetPacketIdCount(TOX_NETPROF_PACKET_TYPE_TCP, i, TOX_NETPROF_DIRECTION_SENT);
const auto count_received = _tpi.toxNetprofGetPacketIdCount(TOX_NETPROF_PACKET_TYPE_TCP, i, TOX_NETPROF_DIRECTION_RECV);
if (count_sent == 0 && count_received == 0) {
continue; // skip empty
}
ImGui::TableNextColumn();
ImGui::TextUnformatted("TCP");
ImGui::TableNextColumn();
ImGui::Text("%02zx(%s)", i, typedPkgIDToString(TOX_NETPROF_PACKET_TYPE_TCP, i));
value_fn(i, count_sent, _tcp_ctx_prev, _tcp_ctx_heat);
value_fn(i, count_received, _tcp_crx_prev, _tcp_crx_heat);
value_fn(i, _tpi.toxNetprofGetPacketIdBytes(TOX_NETPROF_PACKET_TYPE_TCP, i, TOX_NETPROF_DIRECTION_SENT), _tcp_btx_prev, _tcp_btx_heat, 0.005f);
value_fn(i, _tpi.toxNetprofGetPacketIdBytes(TOX_NETPROF_PACKET_TYPE_TCP, i, TOX_NETPROF_DIRECTION_RECV), _tcp_brx_prev, _tcp_brx_heat, 0.005f);
}
ImGui::EndTable();
}
}
ImGui::End();
}
if (_show_window_histo) {
if (ImGui::Begin("Tox Netprof histograms", &_show_window_histo)) {
if (_enabled) {
const float line_height = ImGui::GetTextLineHeight();
ImGui::PlotHistogram("udp total count sent##histograms", _udp_tctx.data(), _udp_tctx.size(), 0, nullptr, 0.f, FLT_MAX, {0, 3*line_height});
ImGui::PlotHistogram("udp total count received##histograms", _udp_tcrx.data(), _udp_tcrx.size(), 0, nullptr, 0.f, FLT_MAX, {0, 3*line_height});
ImGui::PlotHistogram("udp total bytes sent##histograms", _udp_tbtx.data(), _udp_tbtx.size(), 0, nullptr, 0.f, FLT_MAX, {0, 3*line_height});
ImGui::PlotHistogram("udp total bytes received##histograms", _udp_tbrx.data(), _udp_tbrx.size(), 0, nullptr, 0.f, FLT_MAX, {0, 3*line_height});
} else {
ImGui::TextUnformatted("logging disabled!");
if (ImGui::Button("enable")) {
_enabled = true;
}
}
}
ImGui::End();
}
if (_show_window_table) {
return 0.1f; // min 10fps
}
return 2.f;
}

View File

@ -1,54 +0,0 @@
#pragma once
#include "./tox_private_impl.hpp"
#include <cstdint>
#include <vector>
#include <map>
class ToxNetprofUI {
ToxPrivateImpl& _tpi;
bool _enabled {true};
bool _show_window_table {false};
bool _show_window_histo {false};
// table delta
std::map<uint8_t, uint64_t> _udp_ctx_prev;
std::map<uint8_t, uint64_t> _udp_crx_prev;
std::map<uint8_t, uint64_t> _udp_btx_prev;
std::map<uint8_t, uint64_t> _udp_brx_prev;
std::map<uint8_t, uint64_t> _tcp_ctx_prev;
std::map<uint8_t, uint64_t> _tcp_crx_prev;
std::map<uint8_t, uint64_t> _tcp_btx_prev;
std::map<uint8_t, uint64_t> _tcp_brx_prev;
// table heat
std::map<uint8_t, float> _udp_ctx_heat;
std::map<uint8_t, float> _udp_crx_heat;
std::map<uint8_t, float> _udp_btx_heat;
std::map<uint8_t, float> _udp_brx_heat;
std::map<uint8_t, float> _tcp_ctx_heat;
std::map<uint8_t, float> _tcp_crx_heat;
std::map<uint8_t, float> _tcp_btx_heat;
std::map<uint8_t, float> _tcp_brx_heat;
// histogram totals
uint64_t _udp_tctx_prev;
uint64_t _udp_tcrx_prev;
uint64_t _udp_tbtx_prev;
uint64_t _udp_tbrx_prev;
std::vector<float> _udp_tctx;
std::vector<float> _udp_tcrx;
std::vector<float> _udp_tbtx;
std::vector<float> _udp_tbrx;
const float _value_add_interval {1.f}; // every second
float _time_since_last_add {0.f};
public:
ToxNetprofUI(ToxPrivateImpl& tpi) : _tpi(tpi) {}
void tick(float time_delta);
float render(float time_delta);
};

View File

@ -32,22 +32,4 @@ struct ToxPrivateImpl : public ToxPrivateI {
return {std::nullopt, err};
}
}
// TODO: add to interface
uint64_t toxNetprofGetPacketIdCount(Tox_Netprof_Packet_Type type, uint8_t id, Tox_Netprof_Direction direction) {
return tox_netprof_get_packet_id_count(_tox, type, id, direction);
}
uint64_t toxNetprofGetPacketTotalCount(Tox_Netprof_Packet_Type type, Tox_Netprof_Direction direction) {
return tox_netprof_get_packet_total_count(_tox, type, direction);
}
uint64_t toxNetprofGetPacketIdBytes(Tox_Netprof_Packet_Type type, uint8_t id, Tox_Netprof_Direction direction) {
return tox_netprof_get_packet_id_bytes(_tox, type, id, direction);
}
uint64_t toxNetprofGetPacketTotalBytes(Tox_Netprof_Packet_Type type, Tox_Netprof_Direction direction) {
return tox_netprof_get_packet_total_bytes(_tox, type, direction);
}
};