Squashed 'external/toxcore/c-toxcore/' changes from 67badf694..82460b212

82460b212 feat: add ngc events
24b54722a fix: Ensure we have allocators available for the error paths.
48dbcfebc cleanup: Remove redundant `-DSODIUM_EXPORT` from definitions.
0cef46ee9 cleanup: Fix a few more clang-tidy warnings.
0c5b918e9 cleanup: Fix a few more clang-tidy warnings.
4d3c97f49 cleanup: Enforce stricter identifier naming using clang-tidy.
a549807df refactor: Add `mem` module to allow tests to override allocators.
6133fb153 chore: Add devcontainer setup for codespaces.
620e07ecd chore: Set a timeout for tests started using Conan
c0ec33b16 chore: Migrate Windows CI from Appveyor to Azure DevOps
8ed47f3ef fix incorrect documentation
a1e245841 docs: Fix doxygen config and remove some redundant comments.
b0f633185 chore: Fix the Android CI job
7469a529b fix: Add missing `#include <array>`.
2b1a6b0d2 add missing ngc constants getter declarations and definitions
2e02d5637 chore: Add missing module dependencies.
REVERT: 67badf694 feat: add ngc events

git-subtree-dir: external/toxcore/c-toxcore
git-subtree-split: 82460b2124216af1ac9d63060de310a682a2fd15
This commit is contained in:
Green Sky 2023-10-10 19:37:39 +02:00
parent 227425b90e
commit a3126d581b
114 changed files with 2090 additions and 1653 deletions

14
.circleci/bazel-test Executable file
View File

@ -0,0 +1,14 @@
#!/bin/sh
set -eux
git submodule update --init --recursive
/src/workspace/tools/inject-repo c-toxcore
cd /src/workspace && bazel test -k \
--config=remote \
--build_tag_filters=-haskell \
--test_tag_filters=-haskell \
--remote_download_minimal \
-- \
//c-toxcore/... \
"$@"

View File

@ -5,7 +5,10 @@ workflows:
version: 2 version: 2
program-analysis: program-analysis:
jobs: jobs:
# Dynamic analysis # Dynamic analysis in the Bazel build
- bazel-asan
- bazel-tsan
# Dynamic analysis with CMake
- asan - asan
- tsan - tsan
- msan - msan
@ -18,6 +21,28 @@ workflows:
- static-analysis - static-analysis
jobs: jobs:
bazel-asan:
working_directory: /tmp/cirrus-ci-build
docker:
- image: toxchat/toktok-stack:latest-asan
steps:
- checkout
- run: .circleci/bazel-test
bazel-tsan:
working_directory: /tmp/cirrus-ci-build
docker:
- image: toxchat/toktok-stack:latest-tsan
steps:
- checkout
- run: .circleci/bazel-test
-//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
asan: asan:
working_directory: ~/work working_directory: ~/work
docker: docker:
@ -144,10 +169,9 @@ jobs:
- run: - run:
apt-get install -y --no-install-recommends apt-get install -y --no-install-recommends
ca-certificates ca-certificates
clang-tidy-12 clang-tidy-14
- checkout - checkout
- run: git submodule update --init --recursive - run: git submodule update --init --recursive
- run: cmake . -B_build -GNinja -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
- run: - run:
other/analysis/run-clang-tidy || other/analysis/run-clang-tidy ||
other/analysis/run-clang-tidy || other/analysis/run-clang-tidy ||

View File

@ -35,68 +35,6 @@ bazel-dbg_task:
//c-toxcore/... //c-toxcore/...
-//c-toxcore/auto_tests:tcp_relay_test # TODO(robinlinden): Why does this pass locally but not in Cirrus? -//c-toxcore/auto_tests:tcp_relay_test # TODO(robinlinden): Why does this pass locally but not in Cirrus?
bazel-asan_task:
container:
image: toxchat/toktok-stack:latest-asan
cpu: 2
memory: 4G
configure_script:
- git submodule update --init --recursive
- /src/workspace/tools/inject-repo c-toxcore
test_all_script:
- cd /src/workspace && bazel test -k
--remote_http_cache=http://$CIRRUS_HTTP_CACHE_HOST
--build_tag_filters=-haskell
--test_tag_filters=-haskell
--remote_download_minimal
--
//c-toxcore/...
-//c-toxcore/auto_tests:tcp_relay_test # TODO(robinlinden): Why does this pass locally but not in Cirrus?
# TODO(iphydf): Enable once this works properly.
#bazel-msan_task:
# container:
# image: toxchat/toktok-stack:latest-msan
# cpu: 2
# memory: 4G
# configure_script:
# - git submodule update --init --recursive
# - /src/workspace/tools/inject-repo c-toxcore
# test_all_script:
# - cd /src/workspace && bazel test -k
# --remote_http_cache=http://$CIRRUS_HTTP_CACHE_HOST
# --build_tag_filters=-haskell
# --test_tag_filters=-haskell
# --remote_download_minimal
# --
# //c-toxcore/...
# -//c-toxcore/auto_tests:tcp_relay_test # TODO(robinlinden): Why does this pass locally but not in Cirrus?
# TODO(iphydf): Fix test timeouts.
bazel-tsan_task:
container:
image: toxchat/toktok-stack:latest-tsan
cpu: 2
memory: 4G
configure_script:
- git submodule update --init --recursive
- /src/workspace/tools/inject-repo c-toxcore
test_all_script:
- cd /src/workspace && bazel test -k
--remote_http_cache=http://$CIRRUS_HTTP_CACHE_HOST
--build_tag_filters=-haskell
--test_tag_filters=-haskell
--remote_download_minimal
--
//c-toxcore/...
-//c-toxcore/auto_tests:conference_av_test
-//c-toxcore/auto_tests:conference_test
-//c-toxcore/auto_tests:file_transfer_test
-//c-toxcore/auto_tests:group_tcp_test
-//c-toxcore/auto_tests:onion_test
-//c-toxcore/auto_tests:tcp_relay_test
-//c-toxcore/auto_tests:tox_many_test
cimple_task: cimple_task:
container: container:
image: toxchat/toktok-stack:latest-release image: toxchat/toktok-stack:latest-release

40
.clang-tidy Normal file
View File

@ -0,0 +1,40 @@
# vim:ft=yaml
CheckOptions:
- key: readability-identifier-naming.ClassCase
value: Camel_Snake_Case
- key: readability-identifier-naming.ConstantCase
value: lower_case
# bootstrap-daemon has these.
- key: readability-identifier-naming.ConstantIgnoredRegexp
value: "^NAME_.*"
- key: readability-identifier-naming.EnumCase
value: Camel_Snake_Case
- key: readability-identifier-naming.EnumConstantCase
value: UPPER_CASE
- key: readability-identifier-naming.FunctionCase
value: lower_case
- key: readability-identifier-naming.GlobalConstantCase
value: lower_case
- key: readability-identifier-naming.MemberCase
value: lower_case
- key: readability-identifier-naming.MacroDefinitionCase
value: UPPER_CASE
- key: readability-identifier-naming.MacroDefinitionIgnoredRegexp
value: "^_.*|nullable|non_null|nullptr|static_assert|ck_.*"
- key: readability-identifier-naming.ParameterCase
value: lower_case
- key: readability-identifier-naming.StructCase
value: Camel_Snake_Case
- key: readability-identifier-naming.TypedefCase
value: Camel_Snake_Case
- key: readability-identifier-naming.TypedefIgnoredRegexp
value: ".*_cb"
- key: readability-identifier-naming.UnionCase
value: Camel_Snake_Case
- key: readability-identifier-naming.VariableCase
value: lower_case
- key: llvmlibc-restrict-system-libc-headers.Includes
value: "arpa/inet.h,assert.h,ctype.h,errno.h,fcntl.h,getopt.h,libconfig.h,linux/netdevice.h,math.h,netdb.h,netinet/in.h,opus.h,pthread.h,signal.h,sodium/crypto_scalarmult_curve25519.h,sodium.h,sodium/randombytes.h,stdio.h,stdlib.h,string.h,sys/ioctl.h,syslog.h,sys/resource.h,sys/socket.h,sys/stat.h,sys/time.h,sys/types.h,time.h,unistd.h,vpx/vp8cx.h,vpx/vp8dx.h,vpx/vpx_decoder.h,vpx/vpx_encoder.h,vpx/vpx_image.h"
- key: hicpp-signed-bitwise.IgnorePositiveIntegerLiterals
value: true

View File

@ -0,0 +1,11 @@
{
"image": "mcr.microsoft.com/devcontainers/universal:2",
"features": {
"ghcr.io/devcontainers-contrib/features/bash-command:1": {
"command": "git submodule update --init --recursive"
},
"ghcr.io/devcontainers-contrib/features/apt-packages:1": {
"packages": "libconfig-dev,libopus-dev,libvpx-dev,ninja-build"
}
}
}

View File

@ -10,7 +10,7 @@ ABI=${1:-"armeabi-v7a"}
case $ABI in case $ABI in
armeabi-v7a) armeabi-v7a)
TARGET=armv7a-linux-androideabi TARGET=armv7a-linux-androideabi
NDK_API=16 NDK_API=19
;; ;;
arm64-v8a) arm64-v8a)
TARGET=aarch64-linux-android TARGET=aarch64-linux-android
@ -18,7 +18,7 @@ case $ABI in
;; ;;
x86) x86)
TARGET=i686-linux-android TARGET=i686-linux-android
NDK_API=16 NDK_API=19
;; ;;
x86_64) x86_64)
TARGET=x86_64-linux-android TARGET=x86_64-linux-android
@ -47,7 +47,7 @@ fi
cd libsodium cd libsodium
git clean -ffdx git clean -ffdx
autoreconf -fi autoreconf -fi
./configure --prefix="$PREFIX" --host="$TARGET" --with-sysroot="$SYSROOT" --disable-shared ./configure --prefix="$PREFIX" --host="$TARGET" --with-sysroot="$SYSROOT" --disable-shared --disable-pie
make -j"$(nproc)" install make -j"$(nproc)" install
cd .. cd ..

View File

@ -9,7 +9,7 @@ sudo apt-get install -y --no-install-recommends \
libopus-dev \ libopus-dev \
libsodium-dev \ libsodium-dev \
libvpx-dev \ libvpx-dev \
llvm-11 \ llvm-14 \
ninja-build ninja-build
git clone --depth=1 https://github.com/ralight/mallocfail /tmp/mallocfail git clone --depth=1 https://github.com/ralight/mallocfail /tmp/mallocfail
cd /tmp/mallocfail # pushd cd /tmp/mallocfail # pushd
@ -21,7 +21,7 @@ export CC=clang
export CXX=clang++ export CXX=clang++
sudo install other/docker/coverage/run_mallocfail /usr/local/bin/run_mallocfail sudo install other/docker/coverage/run_mallocfail /usr/local/bin/run_mallocfail
(cd other/proxy && go build) (cd other/proxy && go get && go build)
other/proxy/proxy & other/proxy/proxy &
. ".github/scripts/flags-coverage.sh" . ".github/scripts/flags-coverage.sh"
@ -58,4 +58,4 @@ cd - # popd
# --exclude testing \ # --exclude testing \
# --gcov-options '\-lp' # --gcov-options '\-lp'
bash <(curl -s https://codecov.io/bash) -x "llvm-cov-11 gcov" bash <(curl -s https://codecov.io/bash) -x "llvm-cov-14 gcov"

View File

@ -156,7 +156,7 @@ endif()
if(MSVC) if(MSVC)
option(MSVC_STATIC_SODIUM "Whether to link libsodium statically for MSVC" OFF) option(MSVC_STATIC_SODIUM "Whether to link libsodium statically for MSVC" OFF)
if(MSVC_STATIC_SODIUM) if(MSVC_STATIC_SODIUM)
add_definitions(-DSODIUM_STATIC=1 -DSODIUM_EXPORT) add_definitions(-DSODIUM_STATIC=1)
endif() endif()
endif() endif()
@ -286,6 +286,8 @@ set(toxcore_SOURCES
toxcore/logger.h toxcore/logger.h
toxcore/Messenger.c toxcore/Messenger.c
toxcore/Messenger.h toxcore/Messenger.h
toxcore/mem.c
toxcore/mem.h
toxcore/mono_time.c toxcore/mono_time.c
toxcore/mono_time.h toxcore/mono_time.h
toxcore/net_crypto.c toxcore/net_crypto.c
@ -452,6 +454,7 @@ unit_test(toxcore bin_pack)
unit_test(toxcore crypto_core) unit_test(toxcore crypto_core)
unit_test(toxcore group_announce) unit_test(toxcore group_announce)
unit_test(toxcore group_moderation) unit_test(toxcore group_moderation)
unit_test(toxcore mem)
unit_test(toxcore mono_time) unit_test(toxcore mono_time)
unit_test(toxcore ping_array) unit_test(toxcore ping_array)
unit_test(toxcore tox) unit_test(toxcore tox)

View File

@ -1,32 +0,0 @@
---
image: Visual Studio 2019
cache:
- '%USERPROFILE%\.conan -> conanfile.py'
environment:
matrix:
- job_name: static
- job_name: shared
install:
- set PATH=C:\Python311-x64\Scripts;%PATH%
- py -3 -m pip install conan==1.59.0
- git submodule update --init --recursive
for:
- matrix:
only:
- job_name: static
before_build:
- conan install -if _build -o with_tests=False .
- matrix:
only:
- job_name: shared
before_build:
- conan install -if _build -o with_tests=False -o shared=True .
build_script:
- set CONAN_CPU_COUNT=50
- set CTEST_OUTPUT_ON_FAILURE=1
- conan build -bf _build -if _build .

View File

@ -34,20 +34,25 @@ static IP get_loopback(void)
return ip; return ip;
} }
static void do_TCP_server_delay(TCP_Server *tcp_s, Mono_Time *mono_time, int delay) static void do_tcp_server_delay(TCP_Server *tcp_s, Mono_Time *mono_time, int delay)
{ {
c_sleep(delay); c_sleep(delay);
mono_time_update(mono_time); mono_time_update(mono_time);
do_TCP_server(tcp_s, mono_time); do_tcp_server(tcp_s, mono_time);
c_sleep(delay); c_sleep(delay);
} }
static uint16_t ports[NUM_PORTS] = {13215, 33445, 25643}; static uint16_t ports[NUM_PORTS] = {13215, 33445, 25643};
static void test_basic(void) static void test_basic(void)
{ {
Mono_Time *mono_time = mono_time_new(nullptr, nullptr);
const Random *rng = system_random(); const Random *rng = system_random();
ck_assert(rng != nullptr); ck_assert(rng != nullptr);
const Network *ns = system_network();
ck_assert(ns != nullptr);
const Memory *mem = system_memory();
ck_assert(mem != nullptr);
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
Logger *logger = logger_new(); Logger *logger = logger_new();
logger_callback_log(logger, print_debug_logger, nullptr, nullptr); logger_callback_log(logger, print_debug_logger, nullptr, nullptr);
@ -55,8 +60,7 @@ static void test_basic(void)
uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE];
uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE]; uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE];
crypto_new_keypair(rng, self_public_key, self_secret_key); crypto_new_keypair(rng, self_public_key, self_secret_key);
const Network *ns = system_network(); TCP_Server *tcp_s = new_tcp_server(logger, mem, rng, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr, nullptr);
TCP_Server *tcp_s = new_TCP_server(logger, rng, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr, nullptr);
ck_assert_msg(tcp_s != nullptr, "Failed to create a TCP relay server."); ck_assert_msg(tcp_s != nullptr, "Failed to create a TCP relay server.");
ck_assert_msg(tcp_server_listen_count(tcp_s) == NUM_PORTS, ck_assert_msg(tcp_server_listen_count(tcp_s) == NUM_PORTS,
"Failed to bind a TCP relay server to all %d attempted ports.", NUM_PORTS); "Failed to bind a TCP relay server to all %d attempted ports.", NUM_PORTS);
@ -70,7 +74,7 @@ static void test_basic(void)
for (uint8_t i = 0; i < NUM_PORTS; i++) { for (uint8_t i = 0; i < NUM_PORTS; i++) {
sock = net_socket(ns, net_family_ipv6(), TOX_SOCK_STREAM, TOX_PROTO_TCP); sock = net_socket(ns, net_family_ipv6(), TOX_SOCK_STREAM, TOX_PROTO_TCP);
localhost.port = net_htons(ports[i]); localhost.port = net_htons(ports[i]);
bool ret = net_connect(logger, sock, &localhost); bool ret = net_connect(mem, logger, sock, &localhost);
ck_assert_msg(ret, "Failed to connect to created TCP relay server on port %d (%d).", ports[i], errno); ck_assert_msg(ret, "Failed to connect to created TCP relay server on port %d (%d).", ports[i], errno);
// Leave open one connection for the next test. // Leave open one connection for the next test.
@ -110,14 +114,14 @@ static void test_basic(void)
&localhost) == TCP_CLIENT_HANDSHAKE_SIZE - 1, &localhost) == TCP_CLIENT_HANDSHAKE_SIZE - 1,
"An attempt to send the initial handshake minus last byte failed."); "An attempt to send the initial handshake minus last byte failed.");
do_TCP_server_delay(tcp_s, mono_time, 50); 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) == 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."); "The attempt to send the last byte of handshake failed.");
free(handshake); free(handshake);
do_TCP_server_delay(tcp_s, mono_time, 50); do_tcp_server_delay(tcp_s, mono_time, 50);
// Receiving server response and decrypting it // Receiving server response and decrypting it
uint8_t response[TCP_SERVER_HANDSHAKE_SIZE]; uint8_t response[TCP_SERVER_HANDSHAKE_SIZE];
@ -157,7 +161,7 @@ static void test_basic(void)
c_sleep(50); c_sleep(50);
mono_time_update(mono_time); mono_time_update(mono_time);
do_TCP_server(tcp_s, mono_time); do_tcp_server(tcp_s, mono_time);
} }
// Receiving the second response and verifying its validity // Receiving the second response and verifying its validity
@ -181,33 +185,35 @@ static void test_basic(void)
// Closing connections. // Closing connections.
kill_sock(ns, sock); kill_sock(ns, sock);
kill_TCP_server(tcp_s); kill_tcp_server(tcp_s);
logger_kill(logger); logger_kill(logger);
mono_time_free(mono_time); mono_time_free(mem, mono_time);
} }
struct sec_TCP_con { struct sec_TCP_con {
Socket sock; Socket sock;
const Network *ns; const Network *ns;
const Memory *mem;
uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE];
uint8_t recv_nonce[CRYPTO_NONCE_SIZE]; uint8_t recv_nonce[CRYPTO_NONCE_SIZE];
uint8_t sent_nonce[CRYPTO_NONCE_SIZE]; uint8_t sent_nonce[CRYPTO_NONCE_SIZE];
uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE]; uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE];
}; };
static struct sec_TCP_con *new_TCP_con(const Logger *logger, const Random *rng, const Network *ns, TCP_Server *tcp_s, Mono_Time *mono_time) static struct sec_TCP_con *new_tcp_con(const Logger *logger, const Memory *mem, const Random *rng, const Network *ns, TCP_Server *tcp_s, Mono_Time *mono_time)
{ {
struct sec_TCP_con *sec_c = (struct sec_TCP_con *)malloc(sizeof(struct sec_TCP_con)); struct sec_TCP_con *sec_c = (struct sec_TCP_con *)malloc(sizeof(struct sec_TCP_con));
ck_assert(sec_c != nullptr); ck_assert(sec_c != nullptr);
sec_c->ns = ns; sec_c->ns = ns;
sec_c->mem = mem;
Socket sock = net_socket(ns, net_family_ipv6(), TOX_SOCK_STREAM, TOX_PROTO_TCP); Socket sock = net_socket(ns, net_family_ipv6(), TOX_SOCK_STREAM, TOX_PROTO_TCP);
IP_Port localhost; IP_Port localhost;
localhost.ip = get_loopback(); localhost.ip = get_loopback();
localhost.port = net_htons(ports[random_u32(rng) % NUM_PORTS]); localhost.port = net_htons(ports[random_u32(rng) % NUM_PORTS]);
bool ok = net_connect(logger, sock, &localhost); bool ok = net_connect(mem, logger, sock, &localhost);
ck_assert_msg(ok, "Failed to connect to the test TCP relay server."); ck_assert_msg(ok, "Failed to connect to the test TCP relay server.");
uint8_t f_secret_key[CRYPTO_SECRET_KEY_SIZE]; uint8_t f_secret_key[CRYPTO_SECRET_KEY_SIZE];
@ -231,12 +237,12 @@ static struct sec_TCP_con *new_TCP_con(const Logger *logger, const Random *rng,
&localhost) == 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."); "Failed to send the first portion of the handshake to the TCP relay server.");
do_TCP_server_delay(tcp_s, mono_time, 50); 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) == 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."); "Failed to send last byte of handshake.");
do_TCP_server_delay(tcp_s, mono_time, 50); do_tcp_server_delay(tcp_s, mono_time, 50);
uint8_t response[TCP_SERVER_HANDSHAKE_SIZE]; uint8_t response[TCP_SERVER_HANDSHAKE_SIZE];
uint8_t response_plain[TCP_HANDSHAKE_PLAIN_SIZE]; uint8_t response_plain[TCP_HANDSHAKE_PLAIN_SIZE];
@ -251,13 +257,13 @@ static struct sec_TCP_con *new_TCP_con(const Logger *logger, const Random *rng,
return sec_c; return sec_c;
} }
static void kill_TCP_con(struct sec_TCP_con *con) static void kill_tcp_con(struct sec_TCP_con *con)
{ {
kill_sock(con->ns, con->sock); kill_sock(con->ns, con->sock);
free(con); free(con);
} }
static int write_packet_TCP_test_connection(const Logger *logger, struct sec_TCP_con *con, const uint8_t *data, static int write_packet_tcp_test_connection(const Logger *logger, struct sec_TCP_con *con, const uint8_t *data,
uint16_t length) uint16_t length)
{ {
VLA(uint8_t, packet, sizeof(uint16_t) + length + CRYPTO_MAC_SIZE); VLA(uint8_t, packet, sizeof(uint16_t) + length + CRYPTO_MAC_SIZE);
@ -281,7 +287,7 @@ static int write_packet_TCP_test_connection(const Logger *logger, struct sec_TCP
return 0; return 0;
} }
static int read_packet_sec_TCP(const Logger *logger, struct sec_TCP_con *con, uint8_t *data, uint16_t length) static int read_packet_sec_tcp(const Logger *logger, struct sec_TCP_con *con, uint8_t *data, uint16_t length)
{ {
IP_Port localhost; IP_Port localhost;
localhost.ip = get_loopback(); localhost.ip = get_loopback();
@ -297,44 +303,48 @@ static int read_packet_sec_TCP(const Logger *logger, struct sec_TCP_con *con, ui
static void test_some(void) static void test_some(void)
{ {
Mono_Time *mono_time = mono_time_new(nullptr, nullptr);
const Random *rng = system_random(); const Random *rng = system_random();
ck_assert(rng != nullptr); ck_assert(rng != nullptr);
Logger *logger = logger_new();
const Network *ns = system_network(); const Network *ns = system_network();
ck_assert(ns != nullptr);
const Memory *mem = system_memory();
ck_assert(mem != nullptr);
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
Logger *logger = logger_new();
uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE];
uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE]; uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE];
crypto_new_keypair(rng, self_public_key, self_secret_key); crypto_new_keypair(rng, self_public_key, self_secret_key);
TCP_Server *tcp_s = new_TCP_server(logger, rng, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr, nullptr); TCP_Server *tcp_s = new_tcp_server(logger, mem, rng, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr, nullptr);
ck_assert_msg(tcp_s != nullptr, "Failed to create TCP relay server"); ck_assert_msg(tcp_s != nullptr, "Failed to create TCP relay server");
ck_assert_msg(tcp_server_listen_count(tcp_s) == NUM_PORTS, "Failed to bind to all ports."); ck_assert_msg(tcp_server_listen_count(tcp_s) == NUM_PORTS, "Failed to bind to all ports.");
struct sec_TCP_con *con1 = new_TCP_con(logger, rng, ns, tcp_s, mono_time); struct sec_TCP_con *con1 = new_tcp_con(logger, mem, rng, ns, tcp_s, mono_time);
struct sec_TCP_con *con2 = new_TCP_con(logger, rng, ns, tcp_s, mono_time); struct sec_TCP_con *con2 = new_tcp_con(logger, mem, rng, ns, tcp_s, mono_time);
struct sec_TCP_con *con3 = new_TCP_con(logger, rng, ns, tcp_s, mono_time); struct sec_TCP_con *con3 = new_tcp_con(logger, mem, rng, ns, tcp_s, mono_time);
uint8_t requ_p[1 + CRYPTO_PUBLIC_KEY_SIZE]; uint8_t requ_p[1 + CRYPTO_PUBLIC_KEY_SIZE];
requ_p[0] = TCP_PACKET_ROUTING_REQUEST; requ_p[0] = TCP_PACKET_ROUTING_REQUEST;
// Sending wrong public keys to test server response. // Sending wrong public keys to test server response.
memcpy(requ_p + 1, con3->public_key, CRYPTO_PUBLIC_KEY_SIZE); memcpy(requ_p + 1, con3->public_key, CRYPTO_PUBLIC_KEY_SIZE);
write_packet_TCP_test_connection(logger, con1, requ_p, sizeof(requ_p)); write_packet_tcp_test_connection(logger, con1, requ_p, sizeof(requ_p));
memcpy(requ_p + 1, con1->public_key, CRYPTO_PUBLIC_KEY_SIZE); memcpy(requ_p + 1, con1->public_key, CRYPTO_PUBLIC_KEY_SIZE);
write_packet_TCP_test_connection(logger, con3, requ_p, sizeof(requ_p)); write_packet_tcp_test_connection(logger, con3, requ_p, sizeof(requ_p));
do_TCP_server_delay(tcp_s, mono_time, 50); do_tcp_server_delay(tcp_s, mono_time, 50);
// Testing response from connection 1 // Testing response from connection 1
uint8_t data[2048]; uint8_t data[2048];
int len = read_packet_sec_TCP(logger, con1, data, 2 + 1 + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE); int len = read_packet_sec_tcp(logger, con1, data, 2 + 1 + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE);
ck_assert_msg(len == 1 + 1 + CRYPTO_PUBLIC_KEY_SIZE, "Wrong response packet length of %d.", len); ck_assert_msg(len == 1 + 1 + CRYPTO_PUBLIC_KEY_SIZE, "Wrong response packet length of %d.", len);
ck_assert_msg(data[0] == TCP_PACKET_ROUTING_RESPONSE, "Wrong response packet id of %d.", data[0]); ck_assert_msg(data[0] == TCP_PACKET_ROUTING_RESPONSE, "Wrong response packet id of %d.", data[0]);
ck_assert_msg(data[1] == 16, "Server didn't refuse connection using wrong public key."); ck_assert_msg(data[1] == 16, "Server didn't refuse connection using wrong public key.");
ck_assert_msg(pk_equal(data + 2, con3->public_key), "Key in response packet wrong."); ck_assert_msg(pk_equal(data + 2, con3->public_key), "Key in response packet wrong.");
// Connection 3 // Connection 3
len = read_packet_sec_TCP(logger, con3, data, 2 + 1 + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE); len = read_packet_sec_tcp(logger, con3, data, 2 + 1 + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE);
ck_assert_msg(len == 1 + 1 + CRYPTO_PUBLIC_KEY_SIZE, "Wrong response packet length of %d.", len); ck_assert_msg(len == 1 + 1 + CRYPTO_PUBLIC_KEY_SIZE, "Wrong response packet length of %d.", len);
ck_assert_msg(data[0] == TCP_PACKET_ROUTING_RESPONSE, "Wrong response packet id of %d.", data[0]); ck_assert_msg(data[0] == TCP_PACKET_ROUTING_RESPONSE, "Wrong response packet id of %d.", data[0]);
ck_assert_msg(data[1] == 16, "Server didn't refuse connection using wrong public key."); ck_assert_msg(data[1] == 16, "Server didn't refuse connection using wrong public key.");
@ -342,67 +352,67 @@ static void test_some(void)
uint8_t test_packet[512] = {16, 17, 16, 86, 99, 127, 255, 189, 78}; // What is this packet???? uint8_t test_packet[512] = {16, 17, 16, 86, 99, 127, 255, 189, 78}; // What is this packet????
write_packet_TCP_test_connection(logger, con3, test_packet, sizeof(test_packet)); write_packet_tcp_test_connection(logger, con3, test_packet, sizeof(test_packet));
write_packet_TCP_test_connection(logger, con3, test_packet, sizeof(test_packet)); write_packet_tcp_test_connection(logger, con3, test_packet, sizeof(test_packet));
write_packet_TCP_test_connection(logger, con3, test_packet, sizeof(test_packet)); write_packet_tcp_test_connection(logger, con3, test_packet, sizeof(test_packet));
do_TCP_server_delay(tcp_s, mono_time, 50); do_tcp_server_delay(tcp_s, mono_time, 50);
len = read_packet_sec_TCP(logger, con1, data, 2 + 2 + CRYPTO_MAC_SIZE); len = read_packet_sec_tcp(logger, con1, data, 2 + 2 + CRYPTO_MAC_SIZE);
ck_assert_msg(len == 2, "wrong len %d", len); ck_assert_msg(len == 2, "wrong len %d", len);
ck_assert_msg(data[0] == TCP_PACKET_CONNECTION_NOTIFICATION, "wrong packet id %u", data[0]); ck_assert_msg(data[0] == TCP_PACKET_CONNECTION_NOTIFICATION, "wrong packet id %u", data[0]);
ck_assert_msg(data[1] == 16, "wrong peer id %u", data[1]); ck_assert_msg(data[1] == 16, "wrong peer id %u", data[1]);
len = read_packet_sec_TCP(logger, con3, data, 2 + 2 + CRYPTO_MAC_SIZE); len = read_packet_sec_tcp(logger, con3, data, 2 + 2 + CRYPTO_MAC_SIZE);
ck_assert_msg(len == 2, "wrong len %d", len); ck_assert_msg(len == 2, "wrong len %d", len);
ck_assert_msg(data[0] == TCP_PACKET_CONNECTION_NOTIFICATION, "wrong packet id %u", data[0]); ck_assert_msg(data[0] == TCP_PACKET_CONNECTION_NOTIFICATION, "wrong packet id %u", data[0]);
ck_assert_msg(data[1] == 16, "wrong peer id %u", data[1]); ck_assert_msg(data[1] == 16, "wrong peer id %u", data[1]);
len = read_packet_sec_TCP(logger, con1, data, 2 + sizeof(test_packet) + CRYPTO_MAC_SIZE); len = read_packet_sec_tcp(logger, con1, data, 2 + sizeof(test_packet) + CRYPTO_MAC_SIZE);
ck_assert_msg(len == sizeof(test_packet), "wrong len %d", len); ck_assert_msg(len == sizeof(test_packet), "wrong len %d", len);
ck_assert_msg(memcmp(data, test_packet, sizeof(test_packet)) == 0, "packet is wrong %u %u %u %u", data[0], data[1], ck_assert_msg(memcmp(data, test_packet, sizeof(test_packet)) == 0, "packet is wrong %u %u %u %u", data[0], data[1],
data[sizeof(test_packet) - 2], data[sizeof(test_packet) - 1]); data[sizeof(test_packet) - 2], data[sizeof(test_packet) - 1]);
len = read_packet_sec_TCP(logger, con1, data, 2 + sizeof(test_packet) + CRYPTO_MAC_SIZE); len = read_packet_sec_tcp(logger, con1, data, 2 + sizeof(test_packet) + CRYPTO_MAC_SIZE);
ck_assert_msg(len == sizeof(test_packet), "wrong len %d", len); ck_assert_msg(len == sizeof(test_packet), "wrong len %d", len);
ck_assert_msg(memcmp(data, test_packet, sizeof(test_packet)) == 0, "packet is wrong %u %u %u %u", data[0], data[1], ck_assert_msg(memcmp(data, test_packet, sizeof(test_packet)) == 0, "packet is wrong %u %u %u %u", data[0], data[1],
data[sizeof(test_packet) - 2], data[sizeof(test_packet) - 1]); data[sizeof(test_packet) - 2], data[sizeof(test_packet) - 1]);
len = read_packet_sec_TCP(logger, con1, data, 2 + sizeof(test_packet) + CRYPTO_MAC_SIZE); len = read_packet_sec_tcp(logger, con1, data, 2 + sizeof(test_packet) + CRYPTO_MAC_SIZE);
ck_assert_msg(len == sizeof(test_packet), "wrong len %d", len); ck_assert_msg(len == sizeof(test_packet), "wrong len %d", len);
ck_assert_msg(memcmp(data, test_packet, sizeof(test_packet)) == 0, "packet is wrong %u %u %u %u", data[0], data[1], ck_assert_msg(memcmp(data, test_packet, sizeof(test_packet)) == 0, "packet is wrong %u %u %u %u", data[0], data[1],
data[sizeof(test_packet) - 2], data[sizeof(test_packet) - 1]); data[sizeof(test_packet) - 2], data[sizeof(test_packet) - 1]);
write_packet_TCP_test_connection(logger, con1, test_packet, sizeof(test_packet)); write_packet_tcp_test_connection(logger, con1, test_packet, sizeof(test_packet));
write_packet_TCP_test_connection(logger, con1, test_packet, sizeof(test_packet)); write_packet_tcp_test_connection(logger, con1, test_packet, sizeof(test_packet));
write_packet_TCP_test_connection(logger, con1, test_packet, sizeof(test_packet)); write_packet_tcp_test_connection(logger, con1, test_packet, sizeof(test_packet));
do_TCP_server_delay(tcp_s, mono_time, 50); do_tcp_server_delay(tcp_s, mono_time, 50);
len = read_packet_sec_TCP(logger, con3, data, 2 + sizeof(test_packet) + CRYPTO_MAC_SIZE); len = read_packet_sec_tcp(logger, con3, data, 2 + sizeof(test_packet) + CRYPTO_MAC_SIZE);
ck_assert_msg(len == sizeof(test_packet), "wrong len %d", len); ck_assert_msg(len == sizeof(test_packet), "wrong len %d", len);
ck_assert_msg(memcmp(data, test_packet, sizeof(test_packet)) == 0, "packet is wrong %u %u %u %u", data[0], data[1], ck_assert_msg(memcmp(data, test_packet, sizeof(test_packet)) == 0, "packet is wrong %u %u %u %u", data[0], data[1],
data[sizeof(test_packet) - 2], data[sizeof(test_packet) - 1]); data[sizeof(test_packet) - 2], data[sizeof(test_packet) - 1]);
len = read_packet_sec_TCP(logger, con3, data, 2 + sizeof(test_packet) + CRYPTO_MAC_SIZE); len = read_packet_sec_tcp(logger, con3, data, 2 + sizeof(test_packet) + CRYPTO_MAC_SIZE);
ck_assert_msg(len == sizeof(test_packet), "wrong len %d", len); ck_assert_msg(len == sizeof(test_packet), "wrong len %d", len);
ck_assert_msg(memcmp(data, test_packet, sizeof(test_packet)) == 0, "packet is wrong %u %u %u %u", data[0], data[1], ck_assert_msg(memcmp(data, test_packet, sizeof(test_packet)) == 0, "packet is wrong %u %u %u %u", data[0], data[1],
data[sizeof(test_packet) - 2], data[sizeof(test_packet) - 1]); data[sizeof(test_packet) - 2], data[sizeof(test_packet) - 1]);
len = read_packet_sec_TCP(logger, con3, data, 2 + sizeof(test_packet) + CRYPTO_MAC_SIZE); len = read_packet_sec_tcp(logger, con3, data, 2 + sizeof(test_packet) + CRYPTO_MAC_SIZE);
ck_assert_msg(len == sizeof(test_packet), "wrong len %d", len); ck_assert_msg(len == sizeof(test_packet), "wrong len %d", len);
ck_assert_msg(memcmp(data, test_packet, sizeof(test_packet)) == 0, "packet is wrong %u %u %u %u", data[0], data[1], ck_assert_msg(memcmp(data, test_packet, sizeof(test_packet)) == 0, "packet is wrong %u %u %u %u", data[0], data[1],
data[sizeof(test_packet) - 2], data[sizeof(test_packet) - 1]); data[sizeof(test_packet) - 2], data[sizeof(test_packet) - 1]);
uint8_t ping_packet[1 + sizeof(uint64_t)] = {TCP_PACKET_PING, 8, 6, 9, 67}; uint8_t ping_packet[1 + sizeof(uint64_t)] = {TCP_PACKET_PING, 8, 6, 9, 67};
write_packet_TCP_test_connection(logger, con1, ping_packet, sizeof(ping_packet)); write_packet_tcp_test_connection(logger, con1, ping_packet, sizeof(ping_packet));
do_TCP_server_delay(tcp_s, mono_time, 50); do_tcp_server_delay(tcp_s, mono_time, 50);
len = read_packet_sec_TCP(logger, con1, data, 2 + sizeof(ping_packet) + CRYPTO_MAC_SIZE); len = read_packet_sec_tcp(logger, con1, data, 2 + sizeof(ping_packet) + CRYPTO_MAC_SIZE);
ck_assert_msg(len == sizeof(ping_packet), "wrong len %d", len); ck_assert_msg(len == sizeof(ping_packet), "wrong len %d", len);
ck_assert_msg(data[0] == TCP_PACKET_PONG, "wrong packet id %u", data[0]); ck_assert_msg(data[0] == TCP_PACKET_PONG, "wrong packet id %u", data[0]);
ck_assert_msg(memcmp(ping_packet + 1, data + 1, sizeof(uint64_t)) == 0, "wrong packet data"); ck_assert_msg(memcmp(ping_packet + 1, data + 1, sizeof(uint64_t)) == 0, "wrong packet data");
// Kill off the connections // Kill off the connections
kill_TCP_server(tcp_s); kill_tcp_server(tcp_s);
kill_TCP_con(con1); kill_tcp_con(con1);
kill_TCP_con(con2); kill_tcp_con(con2);
kill_TCP_con(con3); kill_tcp_con(con3);
logger_kill(logger); logger_kill(logger);
mono_time_free(mono_time); mono_time_free(mem, mono_time);
} }
static int response_callback_good; static int response_callback_good;
@ -488,16 +498,20 @@ static int oob_data_callback(void *object, const uint8_t *public_key, const uint
static void test_client(void) static void test_client(void)
{ {
Mono_Time *mono_time = mono_time_new(nullptr, nullptr);
const Random *rng = system_random(); const Random *rng = system_random();
ck_assert(rng != nullptr); ck_assert(rng != nullptr);
const Network *ns = system_network();
ck_assert(ns != nullptr);
const Memory *mem = system_memory();
ck_assert(mem != nullptr);
Logger *logger = logger_new(); Logger *logger = logger_new();
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE];
uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE]; uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE];
crypto_new_keypair(rng, self_public_key, self_secret_key); crypto_new_keypair(rng, self_public_key, self_secret_key);
const Network *ns = system_network(); TCP_Server *tcp_s = new_tcp_server(logger, mem, rng, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr, nullptr);
TCP_Server *tcp_s = new_TCP_server(logger, rng, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr, nullptr);
ck_assert_msg(tcp_s != nullptr, "Failed to create a TCP relay server."); ck_assert_msg(tcp_s != nullptr, "Failed to create a TCP relay server.");
ck_assert_msg(tcp_server_listen_count(tcp_s) == NUM_PORTS, "Failed to bind the relay server to all ports."); ck_assert_msg(tcp_server_listen_count(tcp_s) == NUM_PORTS, "Failed to bind the relay server to all ports.");
@ -509,9 +523,8 @@ static void test_client(void)
ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]); ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]);
ip_port_tcp_s.ip = get_loopback(); ip_port_tcp_s.ip = get_loopback();
TCP_Client_Connection *conn = new_TCP_connection(logger, mono_time, rng, ns, &ip_port_tcp_s, self_public_key, f_public_key, 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);
f_secret_key, nullptr); do_tcp_connection(logger, mono_time, conn, nullptr);
do_TCP_connection(logger, mono_time, conn, nullptr);
c_sleep(50); c_sleep(50);
// The connection status should be unconfirmed here because we have finished // The connection status should be unconfirmed here because we have finished
@ -519,22 +532,22 @@ static void test_client(void)
ck_assert_msg(tcp_con_status(conn) == TCP_CLIENT_UNCONFIRMED, "Wrong connection status. Expected: %d, is: %d.", ck_assert_msg(tcp_con_status(conn) == TCP_CLIENT_UNCONFIRMED, "Wrong connection status. Expected: %d, is: %d.",
TCP_CLIENT_UNCONFIRMED, tcp_con_status(conn)); TCP_CLIENT_UNCONFIRMED, tcp_con_status(conn));
do_TCP_server_delay(tcp_s, mono_time, 50); // Now let the server handle requests... do_tcp_server_delay(tcp_s, mono_time, 50); // Now let the server handle requests...
const uint8_t LOOP_SIZE = 3; const uint8_t loop_size = 3;
for (uint8_t i = 0; i < LOOP_SIZE; i++) { for (uint8_t i = 0; i < loop_size; i++) {
mono_time_update(mono_time); mono_time_update(mono_time);
do_TCP_connection(logger, mono_time, conn, nullptr); // Run the connection loop. do_tcp_connection(logger, mono_time, conn, nullptr); // Run the connection loop.
// The status of the connection should continue to be TCP_CLIENT_CONFIRMED after multiple subsequent do_TCP_connection() calls. // The status of the connection should continue to be TCP_CLIENT_CONFIRMED after multiple subsequent do_tcp_connection() calls.
ck_assert_msg(tcp_con_status(conn) == TCP_CLIENT_CONFIRMED, "Wrong connection status. Expected: %d, is: %d", ck_assert_msg(tcp_con_status(conn) == TCP_CLIENT_CONFIRMED, "Wrong connection status. Expected: %d, is: %d",
TCP_CLIENT_CONFIRMED, tcp_con_status(conn)); TCP_CLIENT_CONFIRMED, tcp_con_status(conn));
c_sleep(i == LOOP_SIZE - 1 ? 0 : 500); // Sleep for 500ms on all except third loop. c_sleep(i == loop_size - 1 ? 0 : 500); // Sleep for 500ms on all except third loop.
} }
do_TCP_server_delay(tcp_s, mono_time, 50); do_tcp_server_delay(tcp_s, mono_time, 50);
// And still after the server runs again. // And still after the server runs again.
ck_assert_msg(tcp_con_status(conn) == TCP_CLIENT_CONFIRMED, "Wrong status. Expected: %d, is: %d", TCP_CLIENT_CONFIRMED, ck_assert_msg(tcp_con_status(conn) == TCP_CLIENT_CONFIRMED, "Wrong status. Expected: %d, is: %d", TCP_CLIENT_CONFIRMED,
@ -544,7 +557,7 @@ static void test_client(void)
uint8_t f2_secret_key[CRYPTO_SECRET_KEY_SIZE]; uint8_t f2_secret_key[CRYPTO_SECRET_KEY_SIZE];
crypto_new_keypair(rng, f2_public_key, f2_secret_key); crypto_new_keypair(rng, f2_public_key, f2_secret_key);
ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]); ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]);
TCP_Client_Connection *conn2 = new_TCP_connection(logger, mono_time, rng, ns, &ip_port_tcp_s, self_public_key, f2_public_key, 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); f2_secret_key, nullptr);
// The client should call this function (defined earlier) during the routing process. // The client should call this function (defined earlier) during the routing process.
@ -559,13 +572,13 @@ static void test_client(void)
// These integers will increment per successful callback. // These integers will increment per successful callback.
oob_data_callback_good = response_callback_good = status_callback_good = data_callback_good = 0; oob_data_callback_good = response_callback_good = status_callback_good = data_callback_good = 0;
do_TCP_connection(logger, mono_time, conn, nullptr); do_tcp_connection(logger, mono_time, conn, nullptr);
do_TCP_connection(logger, mono_time, conn2, nullptr); do_tcp_connection(logger, mono_time, conn2, nullptr);
do_TCP_server_delay(tcp_s, mono_time, 50); do_tcp_server_delay(tcp_s, mono_time, 50);
do_TCP_connection(logger, mono_time, conn, nullptr); do_tcp_connection(logger, mono_time, conn, nullptr);
do_TCP_connection(logger, mono_time, conn2, nullptr); do_tcp_connection(logger, mono_time, conn2, nullptr);
c_sleep(50); c_sleep(50);
uint8_t data[5] = {1, 2, 3, 4, 5}; uint8_t data[5] = {1, 2, 3, 4, 5};
@ -574,10 +587,10 @@ static void test_client(void)
send_routing_request(logger, conn, f2_public_key); send_routing_request(logger, conn, f2_public_key);
send_routing_request(logger, conn2, f_public_key); send_routing_request(logger, conn2, f_public_key);
do_TCP_server_delay(tcp_s, mono_time, 50); do_tcp_server_delay(tcp_s, mono_time, 50);
do_TCP_connection(logger, mono_time, conn, nullptr); do_tcp_connection(logger, mono_time, conn, nullptr);
do_TCP_connection(logger, mono_time, conn2, nullptr); do_tcp_connection(logger, mono_time, conn2, nullptr);
// All callback methods save data should have run during the above network prodding. // All callback methods save data should have run during the above network prodding.
ck_assert_msg(oob_data_callback_good == 1, "OOB callback not called"); ck_assert_msg(oob_data_callback_good == 1, "OOB callback not called");
@ -588,42 +601,46 @@ static void test_client(void)
ck_assert_msg(status_callback_connection_id == response_callback_connection_id, ck_assert_msg(status_callback_connection_id == response_callback_connection_id,
"Status and response callback connection IDs are not equal."); "Status and response callback connection IDs are not equal.");
do_TCP_server_delay(tcp_s, mono_time, 50); do_tcp_server_delay(tcp_s, mono_time, 50);
ck_assert_msg(send_data(logger, conn2, 0, data, 5) == 1, "Failed a send_data() call."); ck_assert_msg(send_data(logger, conn2, 0, data, 5) == 1, "Failed a send_data() call.");
do_TCP_server_delay(tcp_s, mono_time, 50); do_tcp_server_delay(tcp_s, mono_time, 50);
do_TCP_connection(logger, mono_time, conn, nullptr); do_tcp_connection(logger, mono_time, conn, nullptr);
do_TCP_connection(logger, mono_time, conn2, nullptr); do_tcp_connection(logger, mono_time, conn2, nullptr);
ck_assert_msg(data_callback_good == 1, "Data callback was not called."); ck_assert_msg(data_callback_good == 1, "Data callback was not called.");
status_callback_good = 0; status_callback_good = 0;
send_disconnect_request(logger, conn2, 0); send_disconnect_request(logger, conn2, 0);
do_TCP_server_delay(tcp_s, mono_time, 50); do_tcp_server_delay(tcp_s, mono_time, 50);
do_TCP_connection(logger, mono_time, conn, nullptr); do_tcp_connection(logger, mono_time, conn, nullptr);
do_TCP_connection(logger, mono_time, conn2, nullptr); do_tcp_connection(logger, mono_time, conn2, nullptr);
ck_assert_msg(status_callback_good == 1, "Status callback not called"); ck_assert_msg(status_callback_good == 1, "Status callback not called");
ck_assert_msg(status_callback_status == 1, "Wrong status callback status."); ck_assert_msg(status_callback_status == 1, "Wrong status callback status.");
// Kill off all connections and servers. // Kill off all connections and servers.
kill_TCP_server(tcp_s); kill_tcp_server(tcp_s);
kill_TCP_connection(conn); kill_tcp_connection(conn);
kill_TCP_connection(conn2); kill_tcp_connection(conn2);
logger_kill(logger); logger_kill(logger);
mono_time_free(mono_time); mono_time_free(mem, mono_time);
} }
// Test how the client handles servers that don't respond. // Test how the client handles servers that don't respond.
static void test_client_invalid(void) static void test_client_invalid(void)
{ {
Mono_Time *mono_time = mono_time_new(nullptr, nullptr);
const Random *rng = system_random(); const Random *rng = system_random();
ck_assert(rng != nullptr); ck_assert(rng != nullptr);
Logger *logger = logger_new();
const Network *ns = system_network(); const Network *ns = system_network();
ck_assert(ns != nullptr);
const Memory *mem = system_memory();
ck_assert(mem != nullptr);
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
Logger *logger = logger_new();
uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE];
uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE]; uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE];
@ -636,12 +653,12 @@ static void test_client_invalid(void)
ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]); ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]);
ip_port_tcp_s.ip = get_loopback(); ip_port_tcp_s.ip = get_loopback();
TCP_Client_Connection *conn = new_TCP_connection(logger, mono_time, rng, ns, &ip_port_tcp_s, 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); self_public_key, f_public_key, f_secret_key, nullptr);
// Run the client's main loop but not the server. // Run the client's main loop but not the server.
mono_time_update(mono_time); mono_time_update(mono_time);
do_TCP_connection(logger, mono_time, conn, nullptr); do_tcp_connection(logger, mono_time, conn, nullptr);
c_sleep(50); c_sleep(50);
// After 50ms of no response... // After 50ms of no response...
@ -650,20 +667,20 @@ static void test_client_invalid(void)
// After 5s... // After 5s...
c_sleep(5000); c_sleep(5000);
mono_time_update(mono_time); mono_time_update(mono_time);
do_TCP_connection(logger, mono_time, conn, nullptr); do_tcp_connection(logger, mono_time, conn, nullptr);
ck_assert_msg(tcp_con_status(conn) == TCP_CLIENT_CONNECTING, "Wrong status. Expected: %d, is: %d.", ck_assert_msg(tcp_con_status(conn) == TCP_CLIENT_CONNECTING, "Wrong status. Expected: %d, is: %d.",
TCP_CLIENT_CONNECTING, tcp_con_status(conn)); TCP_CLIENT_CONNECTING, tcp_con_status(conn));
// 11s... (Should wait for 10 before giving up.) // 11s... (Should wait for 10 before giving up.)
c_sleep(6000); c_sleep(6000);
mono_time_update(mono_time); mono_time_update(mono_time);
do_TCP_connection(logger, mono_time, conn, nullptr); do_tcp_connection(logger, mono_time, conn, nullptr);
ck_assert_msg(tcp_con_status(conn) == TCP_CLIENT_DISCONNECTED, "Wrong status. Expected: %d, is: %d.", ck_assert_msg(tcp_con_status(conn) == TCP_CLIENT_DISCONNECTED, "Wrong status. Expected: %d, is: %d.",
TCP_CLIENT_DISCONNECTED, tcp_con_status(conn)); TCP_CLIENT_DISCONNECTED, tcp_con_status(conn));
kill_TCP_connection(conn); kill_tcp_connection(conn);
logger_kill(logger); logger_kill(logger);
mono_time_free(mono_time); mono_time_free(mem, mono_time);
} }
#include "../toxcore/TCP_connection.h" #include "../toxcore/TCP_connection.h"
@ -694,27 +711,31 @@ static int tcp_data_callback(void *object, int id, const uint8_t *data, uint16_t
static void test_tcp_connection(void) static void test_tcp_connection(void)
{ {
Mono_Time *mono_time = mono_time_new(nullptr, nullptr);
Logger *logger = logger_new();
const Random *rng = system_random(); const Random *rng = system_random();
ck_assert(rng != nullptr); ck_assert(rng != nullptr);
const Network *ns = system_network(); const Network *ns = system_network();
ck_assert(ns != nullptr);
const Memory *mem = system_memory();
ck_assert(mem != nullptr);
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
Logger *logger = logger_new();
tcp_data_callback_called = 0; tcp_data_callback_called = 0;
uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE];
uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE]; uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE];
crypto_new_keypair(rng, self_public_key, self_secret_key); crypto_new_keypair(rng, self_public_key, self_secret_key);
TCP_Server *tcp_s = new_TCP_server(logger, rng, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr, nullptr); TCP_Server *tcp_s = new_tcp_server(logger, mem, rng, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr, nullptr);
ck_assert_msg(pk_equal(tcp_server_public_key(tcp_s), self_public_key), "Wrong public key"); ck_assert_msg(pk_equal(tcp_server_public_key(tcp_s), self_public_key), "Wrong public key");
TCP_Proxy_Info proxy_info; TCP_Proxy_Info proxy_info;
proxy_info.proxy_type = TCP_PROXY_NONE; proxy_info.proxy_type = TCP_PROXY_NONE;
crypto_new_keypair(rng, self_public_key, self_secret_key); crypto_new_keypair(rng, self_public_key, self_secret_key);
TCP_Connections *tc_1 = new_tcp_connections(logger, rng, ns, mono_time, self_secret_key, &proxy_info); TCP_Connections *tc_1 = new_tcp_connections(logger, mem, rng, ns, mono_time, self_secret_key, &proxy_info);
ck_assert_msg(pk_equal(tcp_connections_public_key(tc_1), self_public_key), "Wrong public key"); ck_assert_msg(pk_equal(tcp_connections_public_key(tc_1), self_public_key), "Wrong public key");
crypto_new_keypair(rng, self_public_key, self_secret_key); crypto_new_keypair(rng, self_public_key, self_secret_key);
TCP_Connections *tc_2 = new_tcp_connections(logger, rng, ns, mono_time, self_secret_key, &proxy_info); TCP_Connections *tc_2 = new_tcp_connections(logger, mem, rng, ns, mono_time, self_secret_key, &proxy_info);
ck_assert_msg(pk_equal(tcp_connections_public_key(tc_2), self_public_key), "Wrong public key"); ck_assert_msg(pk_equal(tcp_connections_public_key(tc_2), self_public_key), "Wrong public key");
IP_Port ip_port_tcp_s; IP_Port ip_port_tcp_s;
@ -736,17 +757,17 @@ static void test_tcp_connection(void)
ck_assert_msg(new_tcp_connection_to(tc_2, tcp_connections_public_key(tc_1), 123) == -1, ck_assert_msg(new_tcp_connection_to(tc_2, tcp_connections_public_key(tc_1), 123) == -1,
"Managed to read same connection\n"); "Managed to read same connection\n");
do_TCP_server_delay(tcp_s, mono_time, 50); do_tcp_server_delay(tcp_s, mono_time, 50);
do_tcp_connections(logger, tc_1, nullptr); do_tcp_connections(logger, tc_1, nullptr);
do_tcp_connections(logger, tc_2, nullptr); do_tcp_connections(logger, tc_2, nullptr);
do_TCP_server_delay(tcp_s, mono_time, 50); do_tcp_server_delay(tcp_s, mono_time, 50);
do_tcp_connections(logger, tc_1, nullptr); do_tcp_connections(logger, tc_1, nullptr);
do_tcp_connections(logger, tc_2, nullptr); do_tcp_connections(logger, tc_2, nullptr);
do_TCP_server_delay(tcp_s, mono_time, 50); do_tcp_server_delay(tcp_s, mono_time, 50);
do_tcp_connections(logger, tc_1, nullptr); do_tcp_connections(logger, tc_1, nullptr);
do_tcp_connections(logger, tc_2, nullptr); do_tcp_connections(logger, tc_2, nullptr);
@ -755,7 +776,7 @@ static void test_tcp_connection(void)
ck_assert_msg(ret == 0, "could not send packet."); ck_assert_msg(ret == 0, "could not send packet.");
set_packet_tcp_connection_callback(tc_2, &tcp_data_callback, (void *) 120397); set_packet_tcp_connection_callback(tc_2, &tcp_data_callback, (void *) 120397);
do_TCP_server_delay(tcp_s, mono_time, 50); do_tcp_server_delay(tcp_s, mono_time, 50);
do_tcp_connections(logger, tc_1, nullptr); do_tcp_connections(logger, tc_1, nullptr);
do_tcp_connections(logger, tc_2, nullptr); do_tcp_connections(logger, tc_2, nullptr);
@ -764,7 +785,7 @@ static void test_tcp_connection(void)
ck_assert_msg(tcp_connection_to_online_tcp_relays(tc_1, 0) == 1, "Wrong number of connected relays"); ck_assert_msg(tcp_connection_to_online_tcp_relays(tc_1, 0) == 1, "Wrong number of connected relays");
ck_assert_msg(kill_tcp_connection_to(tc_1, 0) == 0, "could not kill connection to\n"); ck_assert_msg(kill_tcp_connection_to(tc_1, 0) == 0, "could not kill connection to\n");
do_TCP_server_delay(tcp_s, mono_time, 50); do_tcp_server_delay(tcp_s, mono_time, 50);
do_tcp_connections(logger, tc_1, nullptr); do_tcp_connections(logger, tc_1, nullptr);
do_tcp_connections(logger, tc_2, nullptr); do_tcp_connections(logger, tc_2, nullptr);
@ -772,12 +793,12 @@ static void test_tcp_connection(void)
ck_assert_msg(send_packet_tcp_connection(tc_1, 0, (const uint8_t *)"Gentoo", 6) == -1, "could send packet."); ck_assert_msg(send_packet_tcp_connection(tc_1, 0, (const uint8_t *)"Gentoo", 6) == -1, "could send packet.");
ck_assert_msg(kill_tcp_connection_to(tc_2, 0) == 0, "could not kill connection to\n"); ck_assert_msg(kill_tcp_connection_to(tc_2, 0) == 0, "could not kill connection to\n");
kill_TCP_server(tcp_s); kill_tcp_server(tcp_s);
kill_tcp_connections(tc_1); kill_tcp_connections(tc_1);
kill_tcp_connections(tc_2); kill_tcp_connections(tc_2);
logger_kill(logger); logger_kill(logger);
mono_time_free(mono_time); mono_time_free(mem, mono_time);
} }
static bool tcp_oobdata_callback_called; static bool tcp_oobdata_callback_called;
@ -803,11 +824,15 @@ static int tcp_oobdata_callback(void *object, const uint8_t *public_key, unsigne
static void test_tcp_connection2(void) static void test_tcp_connection2(void)
{ {
Mono_Time *mono_time = mono_time_new(nullptr, nullptr);
Logger *logger = logger_new();
const Random *rng = system_random(); const Random *rng = system_random();
ck_assert(rng != nullptr); ck_assert(rng != nullptr);
const Network *ns = system_network(); const Network *ns = system_network();
ck_assert(ns != nullptr);
const Memory *mem = system_memory();
ck_assert(mem != nullptr);
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
Logger *logger = logger_new();
tcp_oobdata_callback_called = 0; tcp_oobdata_callback_called = 0;
tcp_data_callback_called = 0; tcp_data_callback_called = 0;
@ -815,17 +840,17 @@ static void test_tcp_connection2(void)
uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE];
uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE]; uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE];
crypto_new_keypair(rng, self_public_key, self_secret_key); crypto_new_keypair(rng, self_public_key, self_secret_key);
TCP_Server *tcp_s = new_TCP_server(logger, rng, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr, nullptr); TCP_Server *tcp_s = new_tcp_server(logger, mem, rng, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr, nullptr);
ck_assert_msg(pk_equal(tcp_server_public_key(tcp_s), self_public_key), "Wrong public key"); ck_assert_msg(pk_equal(tcp_server_public_key(tcp_s), self_public_key), "Wrong public key");
TCP_Proxy_Info proxy_info; TCP_Proxy_Info proxy_info;
proxy_info.proxy_type = TCP_PROXY_NONE; proxy_info.proxy_type = TCP_PROXY_NONE;
crypto_new_keypair(rng, self_public_key, self_secret_key); crypto_new_keypair(rng, self_public_key, self_secret_key);
TCP_Connections *tc_1 = new_tcp_connections(logger, rng, ns, mono_time, self_secret_key, &proxy_info); TCP_Connections *tc_1 = new_tcp_connections(logger, mem, rng, ns, mono_time, self_secret_key, &proxy_info);
ck_assert_msg(pk_equal(tcp_connections_public_key(tc_1), self_public_key), "Wrong public key"); ck_assert_msg(pk_equal(tcp_connections_public_key(tc_1), self_public_key), "Wrong public key");
crypto_new_keypair(rng, self_public_key, self_secret_key); crypto_new_keypair(rng, self_public_key, self_secret_key);
TCP_Connections *tc_2 = new_tcp_connections(logger, rng, ns, mono_time, self_secret_key, &proxy_info); TCP_Connections *tc_2 = new_tcp_connections(logger, mem, rng, ns, mono_time, self_secret_key, &proxy_info);
ck_assert_msg(pk_equal(tcp_connections_public_key(tc_2), self_public_key), "Wrong public key"); ck_assert_msg(pk_equal(tcp_connections_public_key(tc_2), self_public_key), "Wrong public key");
IP_Port ip_port_tcp_s; IP_Port ip_port_tcp_s;
@ -841,17 +866,17 @@ static void test_tcp_connection2(void)
ck_assert_msg(add_tcp_relay_global(tc_2, &ip_port_tcp_s, tcp_server_public_key(tcp_s)) == 0, ck_assert_msg(add_tcp_relay_global(tc_2, &ip_port_tcp_s, tcp_server_public_key(tcp_s)) == 0,
"Could not add global relay"); "Could not add global relay");
do_TCP_server_delay(tcp_s, mono_time, 50); do_tcp_server_delay(tcp_s, mono_time, 50);
do_tcp_connections(logger, tc_1, nullptr); do_tcp_connections(logger, tc_1, nullptr);
do_tcp_connections(logger, tc_2, nullptr); do_tcp_connections(logger, tc_2, nullptr);
do_TCP_server_delay(tcp_s, mono_time, 50); do_tcp_server_delay(tcp_s, mono_time, 50);
do_tcp_connections(logger, tc_1, nullptr); do_tcp_connections(logger, tc_1, nullptr);
do_tcp_connections(logger, tc_2, nullptr); do_tcp_connections(logger, tc_2, nullptr);
do_TCP_server_delay(tcp_s, mono_time, 50); do_tcp_server_delay(tcp_s, mono_time, 50);
do_tcp_connections(logger, tc_1, nullptr); do_tcp_connections(logger, tc_1, nullptr);
do_tcp_connections(logger, tc_2, nullptr); do_tcp_connections(logger, tc_2, nullptr);
@ -861,14 +886,14 @@ static void test_tcp_connection2(void)
set_oob_packet_tcp_connection_callback(tc_2, &tcp_oobdata_callback, tc_2); set_oob_packet_tcp_connection_callback(tc_2, &tcp_oobdata_callback, tc_2);
set_packet_tcp_connection_callback(tc_1, &tcp_data_callback, (void *) 120397); set_packet_tcp_connection_callback(tc_1, &tcp_data_callback, (void *) 120397);
do_TCP_server_delay(tcp_s, mono_time, 50); do_tcp_server_delay(tcp_s, mono_time, 50);
do_tcp_connections(logger, tc_1, nullptr); do_tcp_connections(logger, tc_1, nullptr);
do_tcp_connections(logger, tc_2, nullptr); do_tcp_connections(logger, tc_2, nullptr);
ck_assert_msg(tcp_oobdata_callback_called, "could not recv packet."); ck_assert_msg(tcp_oobdata_callback_called, "could not recv packet.");
do_TCP_server_delay(tcp_s, mono_time, 50); do_tcp_server_delay(tcp_s, mono_time, 50);
do_tcp_connections(logger, tc_1, nullptr); do_tcp_connections(logger, tc_1, nullptr);
do_tcp_connections(logger, tc_2, nullptr); do_tcp_connections(logger, tc_2, nullptr);
@ -876,15 +901,15 @@ static void test_tcp_connection2(void)
ck_assert_msg(tcp_data_callback_called, "could not recv packet."); ck_assert_msg(tcp_data_callback_called, "could not recv packet.");
ck_assert_msg(kill_tcp_connection_to(tc_1, 0) == 0, "could not kill connection to\n"); ck_assert_msg(kill_tcp_connection_to(tc_1, 0) == 0, "could not kill connection to\n");
kill_TCP_server(tcp_s); kill_tcp_server(tcp_s);
kill_tcp_connections(tc_1); kill_tcp_connections(tc_1);
kill_tcp_connections(tc_2); kill_tcp_connections(tc_2);
logger_kill(logger); logger_kill(logger);
mono_time_free(mono_time); mono_time_free(mem, mono_time);
} }
static void TCP_suite(void) static void tcp_suite(void)
{ {
test_basic(); test_basic();
test_some(); test_some();
@ -897,6 +922,6 @@ static void TCP_suite(void)
int main(void) int main(void)
{ {
setvbuf(stdout, nullptr, _IONBF, 0); setvbuf(stdout, nullptr, _IONBF, 0);
TCP_suite(); tcp_suite();
return 0; return 0;
} }

View File

@ -54,14 +54,17 @@ static void test_store_data(void)
ck_assert(rng != nullptr); ck_assert(rng != nullptr);
const Network *ns = system_network(); const Network *ns = system_network();
ck_assert(ns != nullptr); ck_assert(ns != nullptr);
const Memory *mem = system_memory();
ck_assert(mem != nullptr);
Logger *log = logger_new(); Logger *log = logger_new();
ck_assert(log != nullptr); ck_assert(log != nullptr);
logger_callback_log(log, print_debug_logger, nullptr, nullptr); logger_callback_log(log, print_debug_logger, nullptr, nullptr);
Mono_Time *mono_time = mono_time_new(nullptr, nullptr); Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
Networking_Core *net = new_networking_no_udp(log, ns); Networking_Core *net = new_networking_no_udp(log, mem, ns);
DHT *dht = new_dht(log, rng, ns, mono_time, net, true, true); DHT *dht = new_dht(log, mem, rng, ns, mono_time, net, true, true);
Forwarding *forwarding = new_forwarding(log, rng, mono_time, dht); Forwarding *forwarding = new_forwarding(log, rng, mono_time, dht);
Announcements *announce = new_announcements(log, rng, mono_time, forwarding); Announcements *announce = new_announcements(log, mem, rng, mono_time, forwarding);
ck_assert(announce != nullptr); ck_assert(announce != nullptr);
/* Just to prevent CI from complaining that set_synch_offset is unused: */ /* Just to prevent CI from complaining that set_synch_offset is unused: */
@ -103,7 +106,7 @@ static void test_store_data(void)
kill_forwarding(forwarding); kill_forwarding(forwarding);
kill_dht(dht); kill_dht(dht);
kill_networking(net); kill_networking(net);
mono_time_free(mono_time); mono_time_free(mem, mono_time);
logger_kill(log); logger_kill(log);
} }

View File

@ -13,7 +13,7 @@
#define ABORT_ON_LOG_ERROR true #define ABORT_ON_LOG_ERROR true
#endif #endif
Run_Auto_Options default_run_auto_options() Run_Auto_Options default_run_auto_options(void)
{ {
return (Run_Auto_Options) { return (Run_Auto_Options) {
.graph = GRAPH_COMPLETE, .graph = GRAPH_COMPLETE,
@ -27,7 +27,7 @@ static const struct BootstrapNodes {
const char *ip; const char *ip;
uint16_t port; uint16_t port;
const uint8_t key[32]; const uint8_t key[32];
} BootstrapNodes[] = { } bootstrap_nodes[] = {
#ifndef USE_TEST_NETWORK #ifndef USE_TEST_NETWORK
{ {
"tox.abilinski.com", 33445, "tox.abilinski.com", 33445,
@ -80,10 +80,10 @@ void bootstrap_tox_live_network(Tox *tox, bool enable_tcp)
{ {
ck_assert(tox != nullptr); ck_assert(tox != nullptr);
for (size_t j = 0; BootstrapNodes[j].ip != nullptr; ++j) { for (size_t j = 0; bootstrap_nodes[j].ip != nullptr; ++j) {
const char *ip = BootstrapNodes[j].ip; const char *ip = bootstrap_nodes[j].ip;
uint16_t port = BootstrapNodes[j].port; uint16_t port = bootstrap_nodes[j].port;
const uint8_t *key = BootstrapNodes[j].key; const uint8_t *key = bootstrap_nodes[j].key;
Tox_Err_Bootstrap err; Tox_Err_Bootstrap err;
tox_bootstrap(tox, ip, port, key, &err); tox_bootstrap(tox, ip, port, key, &err);

View File

@ -217,7 +217,7 @@ static bool test_audio(AutoTox *autotoxes, const bool *disabled, bool quiet)
printf("testing sending and receiving audio\n"); printf("testing sending and receiving audio\n");
} }
const int16_t PCM[GROUP_AV_TEST_SAMPLES] = {0}; const int16_t pcm[GROUP_AV_TEST_SAMPLES] = {0};
reset_received_audio(autotoxes); reset_received_audio(autotoxes);
@ -227,7 +227,7 @@ static bool test_audio(AutoTox *autotoxes, const bool *disabled, bool quiet)
continue; continue;
} }
if (toxav_group_send_audio(autotoxes[i].tox, 0, PCM, GROUP_AV_TEST_SAMPLES, 1, 48000) != 0) { if (toxav_group_send_audio(autotoxes[i].tox, 0, pcm, GROUP_AV_TEST_SAMPLES, 1, 48000) != 0) {
if (!quiet) { if (!quiet) {
ck_abort_msg("#%u failed to send audio", autotoxes[i].index); ck_abort_msg("#%u failed to send audio", autotoxes[i].index);
} }
@ -255,8 +255,12 @@ static void test_eventual_audio(AutoTox *autotoxes, const bool *disabled, uint64
uint64_t start = autotoxes[0].clock; uint64_t start = autotoxes[0].clock;
while (autotoxes[0].clock < start + timeout) { while (autotoxes[0].clock < start + timeout) {
if (test_audio(autotoxes, disabled, true) if (!test_audio(autotoxes, disabled, true)) {
&& test_audio(autotoxes, disabled, true)) { continue;
}
// It needs to succeed twice in a row for the test to pass.
if (test_audio(autotoxes, disabled, true)) {
printf("audio test successful after %d seconds\n", (int)((autotoxes[0].clock - start) / 1000)); printf("audio test successful after %d seconds\n", (int)((autotoxes[0].clock - start) / 1000));
return; return;
} }
@ -268,12 +272,12 @@ static void test_eventual_audio(AutoTox *autotoxes, const bool *disabled, uint64
static void do_audio(AutoTox *autotoxes, uint32_t iterations) static void do_audio(AutoTox *autotoxes, uint32_t iterations)
{ {
const int16_t PCM[GROUP_AV_TEST_SAMPLES] = {0}; const int16_t pcm[GROUP_AV_TEST_SAMPLES] = {0};
printf("running audio for %u iterations\n", iterations); printf("running audio for %u iterations\n", iterations);
for (uint32_t f = 0; f < iterations; ++f) { for (uint32_t f = 0; f < iterations; ++f) {
for (uint32_t i = 0; i < NUM_AV_GROUP_TOX; ++i) { for (uint32_t i = 0; i < NUM_AV_GROUP_TOX; ++i) {
ck_assert_msg(toxav_group_send_audio(autotoxes[i].tox, 0, PCM, GROUP_AV_TEST_SAMPLES, 1, 48000) == 0, ck_assert_msg(toxav_group_send_audio(autotoxes[i].tox, 0, pcm, GROUP_AV_TEST_SAMPLES, 1, 48000) == 0,
"#%u failed to send audio", autotoxes[i].index); "#%u failed to send audio", autotoxes[i].index);
iterate_all_wait(autotoxes, NUM_AV_GROUP_TOX, ITERATION_INTERVAL); iterate_all_wait(autotoxes, NUM_AV_GROUP_TOX, ITERATION_INTERVAL);
} }

View File

@ -9,9 +9,7 @@
static void rand_bytes(const Random *rng, uint8_t *b, size_t blen) static void rand_bytes(const Random *rng, uint8_t *b, size_t blen)
{ {
size_t i; for (size_t i = 0; i < blen; i++) {
for (i = 0; i < blen; i++) {
b[i] = random_u08(rng); b[i] = random_u08(rng);
} }
} }
@ -84,19 +82,18 @@ static void test_known(void)
{ {
uint8_t c[147]; uint8_t c[147];
uint8_t m[131]; uint8_t m[131];
uint16_t clen, mlen;
ck_assert_msg(sizeof(c) == sizeof(m) + CRYPTO_MAC_SIZE * sizeof(uint8_t), ck_assert_msg(sizeof(c) == sizeof(m) + CRYPTO_MAC_SIZE * sizeof(uint8_t),
"cyphertext should be CRYPTO_MAC_SIZE bytes longer than plaintext"); "cyphertext should be CRYPTO_MAC_SIZE bytes longer than plaintext");
ck_assert_msg(sizeof(test_c) == sizeof(c), "sanity check failed"); ck_assert_msg(sizeof(test_c) == sizeof(c), "sanity check failed");
ck_assert_msg(sizeof(test_m) == sizeof(m), "sanity check failed"); ck_assert_msg(sizeof(test_m) == sizeof(m), "sanity check failed");
clen = encrypt_data(bobpk, alicesk, test_nonce, test_m, sizeof(test_m) / sizeof(uint8_t), c); const uint16_t clen = encrypt_data(bobpk, alicesk, test_nonce, test_m, sizeof(test_m) / sizeof(uint8_t), c);
ck_assert_msg(memcmp(test_c, c, sizeof(c)) == 0, "cyphertext doesn't match test vector"); 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"); ck_assert_msg(clen == sizeof(c) / sizeof(uint8_t), "wrong ciphertext length");
mlen = decrypt_data(bobpk, alicesk, test_nonce, test_c, sizeof(test_c) / sizeof(uint8_t), m); const uint16_t mlen = decrypt_data(bobpk, alicesk, test_nonce, test_c, sizeof(test_c) / sizeof(uint8_t), m);
ck_assert_msg(memcmp(test_m, m, sizeof(m)) == 0, "decrypted text doesn't match test vector"); 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"); ck_assert_msg(mlen == sizeof(m) / sizeof(uint8_t), "wrong plaintext length");
@ -107,7 +104,6 @@ static void test_fast_known(void)
uint8_t k[CRYPTO_SHARED_KEY_SIZE]; uint8_t k[CRYPTO_SHARED_KEY_SIZE];
uint8_t c[147]; uint8_t c[147];
uint8_t m[131]; uint8_t m[131];
uint16_t clen, mlen;
encrypt_precompute(bobpk, alicesk, k); encrypt_precompute(bobpk, alicesk, k);
@ -116,12 +112,12 @@ static void test_fast_known(void)
ck_assert_msg(sizeof(test_c) == sizeof(c), "sanity check failed"); ck_assert_msg(sizeof(test_c) == sizeof(c), "sanity check failed");
ck_assert_msg(sizeof(test_m) == sizeof(m), "sanity check failed"); ck_assert_msg(sizeof(test_m) == sizeof(m), "sanity check failed");
clen = encrypt_data_symmetric(k, test_nonce, test_m, sizeof(test_m) / sizeof(uint8_t), c); const uint16_t clen = encrypt_data_symmetric(k, test_nonce, test_m, sizeof(test_m) / sizeof(uint8_t), c);
ck_assert_msg(memcmp(test_c, c, sizeof(c)) == 0, "cyphertext doesn't match test vector"); 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"); ck_assert_msg(clen == sizeof(c) / sizeof(uint8_t), "wrong ciphertext length");
mlen = decrypt_data_symmetric(k, test_nonce, test_c, sizeof(test_c) / sizeof(uint8_t), m); const uint16_t mlen = decrypt_data_symmetric(k, test_nonce, test_c, sizeof(test_c) / sizeof(uint8_t), m);
ck_assert_msg(memcmp(test_m, m, sizeof(m)) == 0, "decrypted text doesn't match test vector"); 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"); ck_assert_msg(mlen == sizeof(m) / sizeof(uint8_t), "wrong plaintext length");
@ -275,10 +271,10 @@ static void test_large_data_symmetric(void)
static void increment_nonce_number_cmp(uint8_t *nonce, uint32_t num) static void increment_nonce_number_cmp(uint8_t *nonce, uint32_t num)
{ {
uint32_t num1, num2; uint32_t num1 = 0;
memcpy(&num1, nonce + (CRYPTO_NONCE_SIZE - sizeof(num1)), sizeof(num1)); memcpy(&num1, nonce + (CRYPTO_NONCE_SIZE - sizeof(num1)), sizeof(num1));
num1 = net_ntohl(num1); num1 = net_ntohl(num1);
num2 = num + num1; uint32_t num2 = num + num1;
if (num2 < num1) { if (num2 < num1) {
for (uint16_t i = CRYPTO_NONCE_SIZE - sizeof(num1); i != 0; --i) { for (uint16_t i = CRYPTO_NONCE_SIZE - sizeof(num1); i != 0; --i) {
@ -299,11 +295,9 @@ static void test_increment_nonce(void)
const Random *rng = system_random(); const Random *rng = system_random();
ck_assert(rng != nullptr); ck_assert(rng != nullptr);
uint32_t i;
uint8_t n[CRYPTO_NONCE_SIZE]; uint8_t n[CRYPTO_NONCE_SIZE];
for (i = 0; i < CRYPTO_NONCE_SIZE; ++i) { for (uint32_t i = 0; i < CRYPTO_NONCE_SIZE; ++i) {
n[i] = random_u08(rng); n[i] = random_u08(rng);
} }
@ -311,13 +305,13 @@ static void test_increment_nonce(void)
memcpy(n1, n, CRYPTO_NONCE_SIZE); memcpy(n1, n, CRYPTO_NONCE_SIZE);
for (i = 0; i < (1 << 18); ++i) { for (uint32_t i = 0; i < (1 << 18); ++i) {
increment_nonce_number_cmp(n, 1); increment_nonce_number_cmp(n, 1);
increment_nonce(n1); increment_nonce(n1);
ck_assert_msg(memcmp(n, n1, CRYPTO_NONCE_SIZE) == 0, "Bad increment_nonce function"); ck_assert_msg(memcmp(n, n1, CRYPTO_NONCE_SIZE) == 0, "Bad increment_nonce function");
} }
for (i = 0; i < (1 << 18); ++i) { for (uint32_t i = 0; i < (1 << 18); ++i) {
const uint32_t r = random_u32(rng); const uint32_t r = random_u32(rng);
increment_nonce_number_cmp(n, r); increment_nonce_number_cmp(n, r);
increment_nonce_number(n1, r); increment_nonce_number(n1, r);
@ -331,9 +325,8 @@ static void test_memzero(void)
memcpy(src, test_c, sizeof(test_c)); memcpy(src, test_c, sizeof(test_c));
crypto_memzero(src, sizeof(src)); crypto_memzero(src, sizeof(src));
size_t i;
for (i = 0; i < sizeof(src); i++) { for (size_t i = 0; i < sizeof(src); i++) {
ck_assert_msg(src[i] == 0, "Memory is not zeroed"); ck_assert_msg(src[i] == 0, "Memory is not zeroed");
} }
} }

View File

@ -172,12 +172,12 @@ static void file_transfer_test(void)
uint32_t test = tox_friend_add(tox3, address, (const uint8_t *)"Gentoo", 7, nullptr); uint32_t test = tox_friend_add(tox3, address, (const uint8_t *)"Gentoo", 7, nullptr);
ck_assert_msg(test == 0, "Failed to add friend error code: %u", test); ck_assert_msg(test == 0, "Failed to add friend error code: %u", test);
uint8_t dhtKey[TOX_PUBLIC_KEY_SIZE]; uint8_t dht_key[TOX_PUBLIC_KEY_SIZE];
tox_self_get_dht_id(tox1, dhtKey); tox_self_get_dht_id(tox1, dht_key);
uint16_t dhtPort = tox_self_get_udp_port(tox1, nullptr); uint16_t dht_port = tox_self_get_udp_port(tox1, nullptr);
tox_bootstrap(tox2, TOX_LOCALHOST, dhtPort, dhtKey, nullptr); tox_bootstrap(tox2, TOX_LOCALHOST, dht_port, dht_key, nullptr);
tox_bootstrap(tox3, TOX_LOCALHOST, dhtPort, dhtKey, nullptr); tox_bootstrap(tox3, TOX_LOCALHOST, dht_port, dht_key, nullptr);
printf("Waiting for toxes to come online\n"); printf("Waiting for toxes to come online\n");

View File

@ -102,56 +102,58 @@ typedef struct Forwarding_Subtox {
Announcements *announce; Announcements *announce;
} Forwarding_Subtox; } Forwarding_Subtox;
static Forwarding_Subtox *new_forwarding_subtox(bool no_udp, uint32_t *index, uint16_t port) static Forwarding_Subtox *new_forwarding_subtox(const Memory *mem, bool no_udp, uint32_t *index, uint16_t port)
{ {
const Random *rng = system_random();
ck_assert(rng != nullptr);
const Network *ns = system_network();
ck_assert(ns != nullptr);
Forwarding_Subtox *subtox = (Forwarding_Subtox *)calloc(1, sizeof(Forwarding_Subtox)); Forwarding_Subtox *subtox = (Forwarding_Subtox *)calloc(1, sizeof(Forwarding_Subtox));
ck_assert(subtox != nullptr); ck_assert(subtox != nullptr);
subtox->log = logger_new(); subtox->log = logger_new();
ck_assert(subtox->log != nullptr); ck_assert(subtox->log != nullptr);
logger_callback_log(subtox->log, print_debug_logger, nullptr, index); logger_callback_log(subtox->log, print_debug_logger, nullptr, index);
subtox->mono_time = mono_time_new(nullptr, nullptr); subtox->mono_time = mono_time_new(mem, nullptr, nullptr);
const Random *rng= system_random();
ck_assert(rng != nullptr);
const Network *ns = system_network();
ck_assert(ns != nullptr);
if (no_udp) { if (no_udp) {
subtox->net = new_networking_no_udp(subtox->log, ns); subtox->net = new_networking_no_udp(subtox->log, mem, ns);
} else { } else {
const IP ip = get_loopback(); const IP ip = get_loopback();
subtox->net = new_networking_ex(subtox->log, ns, &ip, port, port, nullptr); subtox->net = new_networking_ex(subtox->log, mem, ns, &ip, port, port, nullptr);
} }
subtox->dht = new_dht(subtox->log, rng, ns, subtox->mono_time, subtox->net, true, true); subtox->dht = new_dht(subtox->log, mem, rng, ns, subtox->mono_time, subtox->net, true, true);
const TCP_Proxy_Info inf = {{{{0}}}}; const TCP_Proxy_Info inf = {{{{0}}}};
subtox->c = new_net_crypto(subtox->log, rng, ns, subtox->mono_time, subtox->dht, &inf); subtox->c = new_net_crypto(subtox->log, mem, rng, ns, subtox->mono_time, subtox->dht, &inf);
subtox->forwarding = new_forwarding(subtox->log, rng, subtox->mono_time, subtox->dht); subtox->forwarding = new_forwarding(subtox->log, rng, subtox->mono_time, subtox->dht);
ck_assert(subtox->forwarding != nullptr); ck_assert(subtox->forwarding != nullptr);
subtox->announce = new_announcements(subtox->log, rng, subtox->mono_time, subtox->forwarding); subtox->announce = new_announcements(subtox->log, mem, rng, subtox->mono_time, subtox->forwarding);
ck_assert(subtox->announce != nullptr); ck_assert(subtox->announce != nullptr);
return subtox; return subtox;
} }
static void kill_forwarding_subtox(Forwarding_Subtox *subtox) static void kill_forwarding_subtox(const Memory *mem, Forwarding_Subtox *subtox)
{ {
kill_announcements(subtox->announce); kill_announcements(subtox->announce);
kill_forwarding(subtox->forwarding); kill_forwarding(subtox->forwarding);
kill_net_crypto(subtox->c); kill_net_crypto(subtox->c);
kill_dht(subtox->dht); kill_dht(subtox->dht);
kill_networking(subtox->net); kill_networking(subtox->net);
mono_time_free(subtox->mono_time); mono_time_free(mem, subtox->mono_time);
logger_kill(subtox->log); logger_kill(subtox->log);
free(subtox); free(subtox);
} }
static void test_forwarding(void) static void test_forwarding(void)
{ {
const Memory *mem = system_memory();
ck_assert(mem != nullptr);
const Random *rng = system_random(); const Random *rng = system_random();
ck_assert(rng != nullptr); ck_assert(rng != nullptr);
const Network *ns = system_network(); const Network *ns = system_network();
@ -165,7 +167,7 @@ static void test_forwarding(void)
for (uint32_t i = 0; i < NUM_FORWARDER; ++i) { for (uint32_t i = 0; i < NUM_FORWARDER; ++i) {
index[i] = i + 1; index[i] = i + 1;
subtoxes[i] = new_forwarding_subtox(i < NUM_FORWARDER_TCP, &index[i], FORWARDING_BASE_PORT + i); subtoxes[i] = new_forwarding_subtox(mem, i < NUM_FORWARDER_TCP, &index[i], FORWARDING_BASE_PORT + i);
test_data[i].net = subtoxes[i]->net; test_data[i].net = subtoxes[i]->net;
test_data[i].send_back = 0; test_data[i].send_back = 0;
@ -317,7 +319,7 @@ static void test_forwarding(void)
for (uint32_t i = 0; i < NUM_FORWARDER; ++i) { for (uint32_t i = 0; i < NUM_FORWARDER; ++i) {
kill_forwarding_subtox(subtoxes[i]); kill_forwarding_subtox(mem, subtoxes[i]);
} }
tox_kill(relay); tox_kill(relay);

View File

@ -215,29 +215,32 @@ static void send_onion_packet(const Networking_Core *net, const Random *rng, con
/** Initialize networking. /** Initialize networking.
* Added for reverse compatibility with old new_networking calls. * Added for reverse compatibility with old new_networking calls.
*/ */
static Networking_Core *new_networking(const Logger *log, const Network *ns, const IP *ip, uint16_t port) static Networking_Core *new_networking(const Logger *log, const Memory *mem, const Network *ns, const IP *ip, uint16_t port)
{ {
return new_networking_ex(log, ns, ip, port, port + (TOX_PORTRANGE_TO - TOX_PORTRANGE_FROM), nullptr); return new_networking_ex(log, mem, ns, ip, port, port + (TOX_PORTRANGE_TO - TOX_PORTRANGE_FROM), nullptr);
} }
static void test_basic(void) static void test_basic(void)
{ {
uint32_t index[] = { 1, 2, 3 }; uint32_t index[] = { 1, 2, 3 };
const Network *ns = system_network(); const Network *ns = system_network();
ck_assert(ns != nullptr);
const Memory *mem = system_memory();
ck_assert(mem != nullptr);
const Random *rng = system_random();
ck_assert(rng != nullptr);
Logger *log1 = logger_new(); Logger *log1 = logger_new();
logger_callback_log(log1, print_debug_logger, nullptr, &index[0]); logger_callback_log(log1, print_debug_logger, nullptr, &index[0]);
Logger *log2 = logger_new(); Logger *log2 = logger_new();
logger_callback_log(log2, print_debug_logger, nullptr, &index[1]); logger_callback_log(log2, print_debug_logger, nullptr, &index[1]);
const Random *rng = system_random(); Mono_Time *mono_time1 = mono_time_new(mem, nullptr, nullptr);
ck_assert(rng != nullptr); Mono_Time *mono_time2 = mono_time_new(mem, nullptr, nullptr);
Mono_Time *mono_time1 = mono_time_new(nullptr, nullptr);
Mono_Time *mono_time2 = mono_time_new(nullptr, nullptr);
IP ip = get_loopback(); IP ip = get_loopback();
Onion *onion1 = new_onion(log1, mono_time1, rng, new_dht(log1, rng, ns, mono_time1, new_networking(log1, ns, &ip, 36567), true, false)); Onion *onion1 = new_onion(log1, mem, mono_time1, rng, new_dht(log1, mem, rng, ns, mono_time1, new_networking(log1, mem, ns, &ip, 36567), true, false));
Onion *onion2 = new_onion(log2, mono_time2, rng, new_dht(log2, rng, ns, mono_time2, new_networking(log2, ns, &ip, 36568), true, false)); Onion *onion2 = new_onion(log2, mem, mono_time2, rng, new_dht(log2, mem, rng, ns, mono_time2, new_networking(log2, mem, ns, &ip, 36568), true, false));
ck_assert_msg((onion1 != nullptr) && (onion2 != nullptr), "Onion failed initializing."); ck_assert_msg((onion1 != nullptr) && (onion2 != nullptr), "Onion failed initializing.");
networking_registerhandler(onion2->net, NET_PACKET_ANNOUNCE_REQUEST, &handle_test_1, onion2); networking_registerhandler(onion2->net, NET_PACKET_ANNOUNCE_REQUEST, &handle_test_1, onion2);
@ -280,8 +283,8 @@ static void test_basic(void)
do_onion(mono_time2, onion2); do_onion(mono_time2, onion2);
} while (handled_test_2 == 0); } while (handled_test_2 == 0);
Onion_Announce *onion1_a = new_onion_announce(log1, rng, mono_time1, onion1->dht); Onion_Announce *onion1_a = new_onion_announce(log1, mem, rng, mono_time1, onion1->dht);
Onion_Announce *onion2_a = new_onion_announce(log2, rng, mono_time2, onion2->dht); Onion_Announce *onion2_a = new_onion_announce(log2, mem, rng, mono_time2, onion2->dht);
networking_registerhandler(onion1->net, NET_PACKET_ANNOUNCE_RESPONSE, &handle_test_3, onion1); networking_registerhandler(onion1->net, NET_PACKET_ANNOUNCE_RESPONSE, &handle_test_3, onion1);
networking_registerhandler(onion1->net, NET_PACKET_ANNOUNCE_RESPONSE_OLD, &handle_test_3_old, onion1); networking_registerhandler(onion1->net, NET_PACKET_ANNOUNCE_RESPONSE_OLD, &handle_test_3_old, onion1);
ck_assert_msg((onion1_a != nullptr) && (onion2_a != nullptr), "Onion_Announce failed initializing."); ck_assert_msg((onion1_a != nullptr) && (onion2_a != nullptr), "Onion_Announce failed initializing.");
@ -331,9 +334,9 @@ static void test_basic(void)
Logger *log3 = logger_new(); Logger *log3 = logger_new();
logger_callback_log(log3, print_debug_logger, nullptr, &index[2]); logger_callback_log(log3, print_debug_logger, nullptr, &index[2]);
Mono_Time *mono_time3 = mono_time_new(nullptr, nullptr); Mono_Time *mono_time3 = mono_time_new(mem, nullptr, nullptr);
Onion *onion3 = new_onion(log3, mono_time3, rng, new_dht(log3, rng, ns, mono_time3, new_networking(log3, ns, &ip, 36569), true, false)); Onion *onion3 = new_onion(log3, mem, mono_time3, rng, new_dht(log3, mem, rng, ns, mono_time3, new_networking(log3, mem, ns, &ip, 36569), true, false));
ck_assert_msg((onion3 != nullptr), "Onion failed initializing."); ck_assert_msg((onion3 != nullptr), "Onion failed initializing.");
random_nonce(rng, nonce); random_nonce(rng, nonce);
@ -363,7 +366,7 @@ static void test_basic(void)
kill_onion(onion); kill_onion(onion);
kill_dht(dht); kill_dht(dht);
kill_networking(net); kill_networking(net);
mono_time_free(mono_time3); mono_time_free(mem, mono_time3);
logger_kill(log3); logger_kill(log3);
} }
@ -375,7 +378,7 @@ static void test_basic(void)
kill_onion(onion); kill_onion(onion);
kill_dht(dht); kill_dht(dht);
kill_networking(net); kill_networking(net);
mono_time_free(mono_time2); mono_time_free(mem, mono_time2);
logger_kill(log2); logger_kill(log2);
} }
@ -387,7 +390,7 @@ static void test_basic(void)
kill_onion(onion); kill_onion(onion);
kill_dht(dht); kill_dht(dht);
kill_networking(net); kill_networking(net);
mono_time_free(mono_time1); mono_time_free(mem, mono_time1);
logger_kill(log1); logger_kill(log1);
} }
} }
@ -400,7 +403,7 @@ typedef struct {
Onion_Client *onion_c; Onion_Client *onion_c;
} Onions; } Onions;
static Onions *new_onions(const Random *rng, uint16_t port, uint32_t *index) static Onions *new_onions(const Memory *mem, const Random *rng, uint16_t port, uint32_t *index)
{ {
IP ip = get_loopback(); IP ip = get_loopback();
ip.ip.v6.uint8[15] = 1; ip.ip.v6.uint8[15] = 1;
@ -420,7 +423,7 @@ static Onions *new_onions(const Random *rng, uint16_t port, uint32_t *index)
logger_callback_log(on->log, print_debug_logger, nullptr, index); logger_callback_log(on->log, print_debug_logger, nullptr, index);
on->mono_time = mono_time_new(nullptr, nullptr); on->mono_time = mono_time_new(mem, nullptr, nullptr);
if (!on->mono_time) { if (!on->mono_time) {
logger_kill(on->log); logger_kill(on->log);
@ -428,57 +431,57 @@ static Onions *new_onions(const Random *rng, uint16_t port, uint32_t *index)
return nullptr; return nullptr;
} }
Networking_Core *net = new_networking(on->log, ns, &ip, port); Networking_Core *net = new_networking(on->log, mem, ns, &ip, port);
if (!net) { if (!net) {
mono_time_free(on->mono_time); mono_time_free(mem, on->mono_time);
logger_kill(on->log); logger_kill(on->log);
free(on); free(on);
return nullptr; return nullptr;
} }
DHT *dht = new_dht(on->log, rng, ns, on->mono_time, net, true, false); DHT *dht = new_dht(on->log, mem, rng, ns, on->mono_time, net, true, false);
if (!dht) { if (!dht) {
kill_networking(net); kill_networking(net);
mono_time_free(on->mono_time); mono_time_free(mem, on->mono_time);
logger_kill(on->log); logger_kill(on->log);
free(on); free(on);
return nullptr; return nullptr;
} }
on->onion = new_onion(on->log, on->mono_time, rng, dht); on->onion = new_onion(on->log, mem, on->mono_time, rng, dht);
if (!on->onion) { if (!on->onion) {
kill_dht(dht); kill_dht(dht);
kill_networking(net); kill_networking(net);
mono_time_free(on->mono_time); mono_time_free(mem, on->mono_time);
logger_kill(on->log); logger_kill(on->log);
free(on); free(on);
return nullptr; return nullptr;
} }
on->onion_a = new_onion_announce(on->log, rng, on->mono_time, dht); on->onion_a = new_onion_announce(on->log, mem, rng, on->mono_time, dht);
if (!on->onion_a) { if (!on->onion_a) {
kill_onion(on->onion); kill_onion(on->onion);
kill_dht(dht); kill_dht(dht);
kill_networking(net); kill_networking(net);
mono_time_free(on->mono_time); mono_time_free(mem, on->mono_time);
logger_kill(on->log); logger_kill(on->log);
free(on); free(on);
return nullptr; return nullptr;
} }
TCP_Proxy_Info inf = {{{{0}}}}; TCP_Proxy_Info inf = {{{{0}}}};
on->onion_c = new_onion_client(on->log, rng, on->mono_time, new_net_crypto(on->log, rng, ns, on->mono_time, dht, &inf)); on->onion_c = new_onion_client(on->log, mem, rng, on->mono_time, new_net_crypto(on->log, mem, rng, ns, on->mono_time, dht, &inf));
if (!on->onion_c) { if (!on->onion_c) {
kill_onion_announce(on->onion_a); kill_onion_announce(on->onion_a);
kill_onion(on->onion); kill_onion(on->onion);
kill_dht(dht); kill_dht(dht);
kill_networking(net); kill_networking(net);
mono_time_free(on->mono_time); mono_time_free(mem, on->mono_time);
logger_kill(on->log); logger_kill(on->log);
free(on); free(on);
return nullptr; return nullptr;
@ -496,7 +499,7 @@ static void do_onions(Onions *on)
do_onion_client(on->onion_c); do_onion_client(on->onion_c);
} }
static void kill_onions(Onions *on) static void kill_onions(const Memory *mem, Onions *on)
{ {
Networking_Core *net = dht_get_net(on->onion->dht); Networking_Core *net = dht_get_net(on->onion->dht);
DHT *dht = on->onion->dht; DHT *dht = on->onion->dht;
@ -507,7 +510,7 @@ static void kill_onions(Onions *on)
kill_net_crypto(c); kill_net_crypto(c);
kill_dht(dht); kill_dht(dht);
kill_networking(net); kill_networking(net);
mono_time_free(on->mono_time); mono_time_free(mem, on->mono_time);
logger_kill(on->log); logger_kill(on->log);
free(on); free(on);
} }
@ -571,21 +574,22 @@ static void dht_pk_callback(void *object, int32_t number, const uint8_t *dht_pub
static void test_announce(void) static void test_announce(void)
{ {
uint32_t i, j;
uint32_t index[NUM_ONIONS]; uint32_t index[NUM_ONIONS];
Onions *onions[NUM_ONIONS]; Onions *onions[NUM_ONIONS];
const Random *rng = system_random(); const Random *rng = system_random();
ck_assert(rng != nullptr); ck_assert(rng != nullptr);
const Memory *mem = system_memory();
ck_assert(mem != nullptr);
for (i = 0; i < NUM_ONIONS; ++i) { for (uint32_t i = 0; i < NUM_ONIONS; ++i) {
index[i] = i + 1; index[i] = i + 1;
onions[i] = new_onions(rng, i + 36655, &index[i]); onions[i] = new_onions(mem, rng, i + 36655, &index[i]);
ck_assert_msg(onions[i] != nullptr, "Failed to create onions. %u", i); ck_assert_msg(onions[i] != nullptr, "Failed to create onions. %u", i);
} }
IP ip = get_loopback(); IP ip = get_loopback();
for (i = 3; i < NUM_ONIONS; ++i) { for (uint32_t i = 3; i < NUM_ONIONS; ++i) {
IP_Port ip_port = {ip, net_port(onions[i - 1]->onion->net)}; IP_Port ip_port = {ip, net_port(onions[i - 1]->onion->net)};
dht_bootstrap(onions[i]->onion->dht, &ip_port, dht_get_self_public_key(onions[i - 1]->onion->dht)); dht_bootstrap(onions[i]->onion->dht, &ip_port, dht_get_self_public_key(onions[i - 1]->onion->dht));
IP_Port ip_port1 = {ip, net_port(onions[i - 2]->onion->net)}; IP_Port ip_port1 = {ip, net_port(onions[i - 2]->onion->net)};
@ -599,7 +603,7 @@ static void test_announce(void)
do { do {
connected = 0; connected = 0;
for (i = 0; i < NUM_ONIONS; ++i) { for (uint32_t i = 0; i < NUM_ONIONS; ++i) {
do_onions(onions[i]); do_onions(onions[i]);
connected += dht_isconnected(onions[i]->onion->dht); connected += dht_isconnected(onions[i]->onion->dht);
} }
@ -609,8 +613,8 @@ static void test_announce(void)
printf("connected\n"); printf("connected\n");
for (i = 0; i < 25 * 2; ++i) { for (uint32_t i = 0; i < 25 * 2; ++i) {
for (j = 0; j < NUM_ONIONS; ++j) { for (uint32_t j = 0; j < NUM_ONIONS; ++j) {
do_onions(onions[j]); do_onions(onions[j]);
} }
@ -632,7 +636,7 @@ static void test_announce(void)
IP_Port ip_port; IP_Port ip_port;
do { do {
for (i = 0; i < NUM_ONIONS; ++i) { for (uint32_t i = 0; i < NUM_ONIONS; ++i) {
do_onions(onions[i]); do_onions(onions[i]);
} }
@ -642,7 +646,7 @@ static void test_announce(void)
printf("Waiting for ips\n"); printf("Waiting for ips\n");
do { do {
for (i = 0; i < NUM_ONIONS; ++i) { for (uint32_t i = 0; i < NUM_ONIONS; ++i) {
do_onions(onions[i]); do_onions(onions[i]);
} }
@ -652,8 +656,8 @@ static void test_announce(void)
onion_getfriendip(onions[NUM_LAST]->onion_c, frnum, &ip_port); onion_getfriendip(onions[NUM_LAST]->onion_c, frnum, &ip_port);
ck_assert_msg(ip_port.port == net_port(onions[NUM_FIRST]->onion->net), "Port in returned ip not correct."); ck_assert_msg(ip_port.port == net_port(onions[NUM_FIRST]->onion->net), "Port in returned ip not correct.");
for (i = 0; i < NUM_ONIONS; ++i) { for (uint32_t i = 0; i < NUM_ONIONS; ++i) {
kill_onions(onions[i]); kill_onions(mem, onions[i]);
} }
} }

View File

@ -43,7 +43,7 @@ static void dump_events(const char *path, const Tox_Events *events)
} }
} }
static void print_events(Tox_Events *events) static void print_events(const Tox_System *sys, Tox_Events *events)
{ {
const uint32_t size = tox_events_bytes_size(events); const uint32_t size = tox_events_bytes_size(events);
@ -52,11 +52,11 @@ static void print_events(Tox_Events *events)
tox_events_get_bytes(events, bytes); tox_events_get_bytes(events, bytes);
Tox_Events *events_copy = tox_events_load(bytes, size); Tox_Events *events_copy = tox_events_load(sys, bytes, size);
ck_assert(events_copy != nullptr); ck_assert(events_copy != nullptr);
free(bytes); free(bytes);
ck_assert(tox_events_equal(events, events_copy)); ck_assert(tox_events_equal(sys, events, events_copy));
tox_events_free(events_copy); tox_events_free(events_copy);
tox_events_free(events); tox_events_free(events);
@ -64,9 +64,11 @@ static void print_events(Tox_Events *events)
static bool await_message(Tox **toxes, const Tox_Dispatch *dispatch) static bool await_message(Tox **toxes, const Tox_Dispatch *dispatch)
{ {
const Tox_System *sys = tox_get_system(toxes[0]);
for (uint32_t i = 0; i < 100; ++i) { for (uint32_t i = 0; i < 100; ++i) {
// Ignore events on tox 1. // Ignore events on tox 1.
print_events(tox_events_iterate(toxes[0], false, nullptr)); print_events(sys, tox_events_iterate(toxes[0], false, nullptr));
// Check if tox 2 got the message from tox 1. // Check if tox 2 got the message from tox 1.
Tox_Events *events = tox_events_iterate(toxes[1], false, nullptr); Tox_Events *events = tox_events_iterate(toxes[1], false, nullptr);
@ -74,7 +76,7 @@ static bool await_message(Tox **toxes, const Tox_Dispatch *dispatch)
bool success = false; bool success = false;
tox_dispatch_invoke(dispatch, events, toxes[1], &success); tox_dispatch_invoke(dispatch, events, toxes[1], &success);
print_events(events); print_events(sys, events);
if (success) { if (success) {
return true; return true;
@ -101,6 +103,8 @@ static void test_tox_events(void)
ck_assert_msg(toxes[i] != nullptr, "failed to create tox instances %u", i); ck_assert_msg(toxes[i] != nullptr, "failed to create tox instances %u", i);
} }
const Tox_System *sys = tox_get_system(toxes[0]);
Tox_Err_Dispatch_New err_new; Tox_Err_Dispatch_New err_new;
Tox_Dispatch *dispatch = tox_dispatch_new(&err_new); Tox_Dispatch *dispatch = tox_dispatch_new(&err_new);
ck_assert_msg(dispatch != nullptr, "failed to create event dispatcher"); ck_assert_msg(dispatch != nullptr, "failed to create event dispatcher");
@ -123,8 +127,8 @@ static void test_tox_events(void)
while (tox_self_get_connection_status(toxes[0]) == TOX_CONNECTION_NONE || while (tox_self_get_connection_status(toxes[0]) == TOX_CONNECTION_NONE ||
tox_self_get_connection_status(toxes[1]) == TOX_CONNECTION_NONE) { tox_self_get_connection_status(toxes[1]) == TOX_CONNECTION_NONE) {
// Ignore connection events for now. // Ignore connection events for now.
print_events(tox_events_iterate(toxes[0], false, nullptr)); print_events(sys, tox_events_iterate(toxes[0], false, nullptr));
print_events(tox_events_iterate(toxes[1], false, nullptr)); print_events(sys, tox_events_iterate(toxes[1], false, nullptr));
c_sleep(tox_iteration_interval(toxes[0])); c_sleep(tox_iteration_interval(toxes[0]));
} }
@ -134,8 +138,8 @@ static void test_tox_events(void)
while (tox_friend_get_connection_status(toxes[0], 0, nullptr) == TOX_CONNECTION_NONE || while (tox_friend_get_connection_status(toxes[0], 0, nullptr) == TOX_CONNECTION_NONE ||
tox_friend_get_connection_status(toxes[1], 0, nullptr) == TOX_CONNECTION_NONE) { tox_friend_get_connection_status(toxes[1], 0, nullptr) == TOX_CONNECTION_NONE) {
// Ignore connection events for now. // Ignore connection events for now.
print_events(tox_events_iterate(toxes[0], false, nullptr)); print_events(sys, tox_events_iterate(toxes[0], false, nullptr));
print_events(tox_events_iterate(toxes[1], false, nullptr)); print_events(sys, tox_events_iterate(toxes[1], false, nullptr));
c_sleep(tox_iteration_interval(toxes[0])); c_sleep(tox_iteration_interval(toxes[0]));
} }

View File

@ -46,10 +46,9 @@ static void test_many_clients_tcp(void)
long long unsigned int cur_time = time(nullptr); long long unsigned int cur_time = time(nullptr);
Tox *toxes[NUM_TOXES_TCP]; Tox *toxes[NUM_TOXES_TCP];
uint32_t index[NUM_TOXES_TCP]; uint32_t index[NUM_TOXES_TCP];
uint32_t i, j;
uint32_t to_comp = 974536; uint32_t to_comp = 974536;
for (i = 0; i < NUM_TOXES_TCP; ++i) { for (uint32_t i = 0; i < NUM_TOXES_TCP; ++i) {
struct Tox_Options *opts = tox_options_new(nullptr); struct Tox_Options *opts = tox_options_new(nullptr);
if (i == 0) { if (i == 0) {
@ -72,7 +71,7 @@ static void test_many_clients_tcp(void)
tox_callback_friend_request(toxes[i], accept_friend_request); tox_callback_friend_request(toxes[i], accept_friend_request);
uint8_t dpk[TOX_PUBLIC_KEY_SIZE]; uint8_t dpk[TOX_PUBLIC_KEY_SIZE];
tox_self_get_dht_id(toxes[0], dpk); tox_self_get_dht_id(toxes[0], dpk);
Tox_Err_Bootstrap error = TOX_ERR_BOOTSTRAP_OK; Tox_Err_Bootstrap error;
ck_assert_msg(tox_add_tcp_relay(toxes[i], TOX_LOCALHOST, tcp_relay_port, dpk, &error), "add relay error, %u, %d", i, ck_assert_msg(tox_add_tcp_relay(toxes[i], TOX_LOCALHOST, tcp_relay_port, dpk, &error), "add relay error, %u, %d", i,
error); error);
uint16_t first_port = tox_self_get_udp_port(toxes[0], nullptr); uint16_t first_port = tox_self_get_udp_port(toxes[0], nullptr);
@ -88,12 +87,12 @@ static void test_many_clients_tcp(void)
uint8_t address[TOX_ADDRESS_SIZE]; uint8_t address[TOX_ADDRESS_SIZE];
for (i = 0; i < NUM_FRIENDS; ++i) { for (uint32_t i = 0; i < NUM_FRIENDS; ++i) {
loop_top: loop_top:
pairs[i].tox1 = random_u32(rng) % NUM_TOXES_TCP; pairs[i].tox1 = random_u32(rng) % NUM_TOXES_TCP;
pairs[i].tox2 = (pairs[i].tox1 + random_u32(rng) % (NUM_TOXES_TCP - 1) + 1) % NUM_TOXES_TCP; pairs[i].tox2 = (pairs[i].tox1 + random_u32(rng) % (NUM_TOXES_TCP - 1) + 1) % NUM_TOXES_TCP;
for (j = 0; j < i; ++j) { for (uint32_t j = 0; j < i; ++j) {
if (pairs[j].tox2 == pairs[i].tox1 && pairs[j].tox1 == pairs[i].tox2) { if (pairs[j].tox2 == pairs[i].tox1 && pairs[j].tox1 == pairs[i].tox2) {
goto loop_top; goto loop_top;
} }
@ -114,8 +113,8 @@ loop_top:
while (true) { while (true) {
uint16_t counter = 0; uint16_t counter = 0;
for (i = 0; i < NUM_TOXES_TCP; ++i) { for (uint32_t i = 0; i < NUM_TOXES_TCP; ++i) {
for (j = 0; j < tox_self_get_friend_list_size(toxes[i]); ++j) { for (uint32_t j = 0; j < tox_self_get_friend_list_size(toxes[i]); ++j) {
if (tox_friend_get_connection_status(toxes[i], j, nullptr) == TOX_CONNECTION_TCP) { if (tox_friend_get_connection_status(toxes[i], j, nullptr) == TOX_CONNECTION_TCP) {
++counter; ++counter;
} }
@ -126,14 +125,14 @@ loop_top:
break; break;
} }
for (i = 0; i < NUM_TOXES_TCP; ++i) { for (uint32_t i = 0; i < NUM_TOXES_TCP; ++i) {
tox_iterate(toxes[i], &to_comp); tox_iterate(toxes[i], &to_comp);
} }
c_sleep(50); c_sleep(50);
} }
for (i = 0; i < NUM_TOXES_TCP; ++i) { for (uint32_t i = 0; i < NUM_TOXES_TCP; ++i) {
tox_kill(toxes[i]); tox_kill(toxes[i]);
} }
@ -149,10 +148,9 @@ static void test_many_clients_tcp_b(void)
long long unsigned int cur_time = time(nullptr); long long unsigned int cur_time = time(nullptr);
Tox *toxes[NUM_TOXES_TCP]; Tox *toxes[NUM_TOXES_TCP];
uint32_t index[NUM_TOXES_TCP]; uint32_t index[NUM_TOXES_TCP];
uint32_t i, j;
uint32_t to_comp = 974536; uint32_t to_comp = 974536;
for (i = 0; i < NUM_TOXES_TCP; ++i) { for (uint32_t i = 0; i < NUM_TOXES_TCP; ++i) {
struct Tox_Options *opts = tox_options_new(nullptr); struct Tox_Options *opts = tox_options_new(nullptr);
if (i < NUM_TCP_RELAYS) { if (i < NUM_TCP_RELAYS) {
@ -183,12 +181,12 @@ static void test_many_clients_tcp_b(void)
uint8_t address[TOX_ADDRESS_SIZE]; uint8_t address[TOX_ADDRESS_SIZE];
for (i = 0; i < NUM_FRIENDS; ++i) { for (uint32_t i = 0; i < NUM_FRIENDS; ++i) {
loop_top: loop_top:
pairs[i].tox1 = random_u32(rng) % NUM_TOXES_TCP; pairs[i].tox1 = random_u32(rng) % NUM_TOXES_TCP;
pairs[i].tox2 = (pairs[i].tox1 + random_u32(rng) % (NUM_TOXES_TCP - 1) + 1) % NUM_TOXES_TCP; pairs[i].tox2 = (pairs[i].tox1 + random_u32(rng) % (NUM_TOXES_TCP - 1) + 1) % NUM_TOXES_TCP;
for (j = 0; j < i; ++j) { for (uint32_t j = 0; j < i; ++j) {
if (pairs[j].tox2 == pairs[i].tox1 && pairs[j].tox1 == pairs[i].tox2) { if (pairs[j].tox2 == pairs[i].tox1 && pairs[j].tox1 == pairs[i].tox2) {
goto loop_top; goto loop_top;
} }
@ -211,8 +209,8 @@ loop_top:
while (true) { while (true) {
uint16_t counter = 0; uint16_t counter = 0;
for (i = 0; i < NUM_TOXES_TCP; ++i) { for (uint32_t i = 0; i < NUM_TOXES_TCP; ++i) {
for (j = 0; j < tox_self_get_friend_list_size(toxes[i]); ++j) { for (uint32_t j = 0; j < tox_self_get_friend_list_size(toxes[i]); ++j) {
if (tox_friend_get_connection_status(toxes[i], j, nullptr) == TOX_CONNECTION_TCP) { if (tox_friend_get_connection_status(toxes[i], j, nullptr) == TOX_CONNECTION_TCP) {
++counter; ++counter;
} }
@ -228,14 +226,14 @@ loop_top:
break; break;
} }
for (i = 0; i < NUM_TOXES_TCP; ++i) { for (uint32_t i = 0; i < NUM_TOXES_TCP; ++i) {
tox_iterate(toxes[i], &to_comp); tox_iterate(toxes[i], &to_comp);
} }
c_sleep(30); c_sleep(30);
} }
for (i = 0; i < NUM_TOXES_TCP; ++i) { for (uint32_t i = 0; i < NUM_TOXES_TCP; ++i) {
tox_kill(toxes[i]); tox_kill(toxes[i]);
} }

View File

@ -10,7 +10,7 @@ typedef enum {
POSITIVE POSITIVE
} Comparison; } Comparison;
static const char *Comparison_Str[] = { "NEGATIVE", "ZERO", "POSITIVE" }; static const char *comparison_str[] = { "NEGATIVE", "ZERO", "POSITIVE" };
static void verify(const char *s1, const char *s2, size_t n, Comparison expected) static void verify(const char *s1, const char *s2, size_t n, Comparison expected)
{ {
@ -19,7 +19,7 @@ static void verify(const char *s1, const char *s2, size_t n, Comparison expected
ck_assert_msg(actual == expected, ck_assert_msg(actual == expected,
"tox_strncasecmp(\"%s\", \"%s\", %u) == %s, but expected %s.", "tox_strncasecmp(\"%s\", \"%s\", %u) == %s, but expected %s.",
s1, s2, (unsigned)n, Comparison_Str[actual], Comparison_Str[expected]); s1, s2, (unsigned)n, comparison_str[actual], comparison_str[expected]);
} }
static void test_general(void) static void test_general(void)

View File

@ -93,67 +93,67 @@ static void t_accept_friend_request_cb(Tox *m, const uint8_t *public_key, const
/** /**
* Iterate helper * Iterate helper
*/ */
static void iterate_tox(Tox *bootstrap, Tox *Alice, Tox *Bob) static void iterate_tox(Tox *bootstrap, Tox *alice, Tox *bob)
{ {
c_sleep(100); c_sleep(100);
tox_iterate(bootstrap, nullptr); tox_iterate(bootstrap, nullptr);
tox_iterate(Alice, nullptr); tox_iterate(alice, nullptr);
tox_iterate(Bob, nullptr); tox_iterate(bob, nullptr);
} }
static bool toxav_audio_send_frame_helper(ToxAV *av, uint32_t friend_number, Toxav_Err_Send_Frame *error) static bool toxav_audio_send_frame_helper(ToxAV *av, uint32_t friend_number, Toxav_Err_Send_Frame *error)
{ {
static const int16_t PCM[960] = {0}; static const int16_t pcm[960] = {0};
return toxav_audio_send_frame(av, 0, PCM, 960, 1, 48000, nullptr); return toxav_audio_send_frame(av, 0, pcm, 960, 1, 48000, nullptr);
} }
static void regular_call_flow( static void regular_call_flow(
Tox *Alice, Tox *Bob, Tox *bootstrap, Tox *alice, Tox *bob, Tox *bootstrap,
ToxAV *AliceAV, ToxAV *BobAV, ToxAV *alice_av, ToxAV *bob_av,
CallControl *AliceCC, CallControl *BobCC, CallControl *alice_cc, CallControl *bob_cc,
int a_br, int v_br) int a_br, int v_br)
{ {
clear_call_control(AliceCC); clear_call_control(alice_cc);
clear_call_control(BobCC); clear_call_control(bob_cc);
Toxav_Err_Call call_err; Toxav_Err_Call call_err;
toxav_call(AliceAV, 0, a_br, v_br, &call_err); toxav_call(alice_av, 0, a_br, v_br, &call_err);
ck_assert_msg(call_err == TOXAV_ERR_CALL_OK, "toxav_call failed: %d\n", call_err); ck_assert_msg(call_err == TOXAV_ERR_CALL_OK, "toxav_call failed: %d\n", call_err);
const time_t start_time = time(nullptr); const time_t start_time = time(nullptr);
do { do {
if (BobCC->incoming) { if (bob_cc->incoming) {
Toxav_Err_Answer answer_err; Toxav_Err_Answer answer_err;
toxav_answer(BobAV, 0, a_br, v_br, &answer_err); toxav_answer(bob_av, 0, a_br, v_br, &answer_err);
ck_assert_msg(answer_err == TOXAV_ERR_ANSWER_OK, "toxav_answer failed: %d\n", answer_err); ck_assert_msg(answer_err == TOXAV_ERR_ANSWER_OK, "toxav_answer failed: %d\n", answer_err);
BobCC->incoming = false; bob_cc->incoming = false;
} else { /* TODO(mannol): rtp */ } else { /* TODO(mannol): rtp */
if (time(nullptr) - start_time >= 1) { if (time(nullptr) - start_time >= 1) {
Toxav_Err_Call_Control cc_err; Toxav_Err_Call_Control cc_err;
toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_CANCEL, &cc_err); toxav_call_control(alice_av, 0, TOXAV_CALL_CONTROL_CANCEL, &cc_err);
ck_assert_msg(cc_err == TOXAV_ERR_CALL_CONTROL_OK, "toxav_call_control failed: %d\n", cc_err); ck_assert_msg(cc_err == TOXAV_ERR_CALL_CONTROL_OK, "toxav_call_control failed: %d\n", cc_err);
} }
} }
iterate_tox(bootstrap, Alice, Bob); iterate_tox(bootstrap, alice, bob);
} while (BobCC->state != TOXAV_FRIEND_CALL_STATE_FINISHED); } while (bob_cc->state != TOXAV_FRIEND_CALL_STATE_FINISHED);
printf("Success!\n"); printf("Success!\n");
} }
static void test_av_flows(void) static void test_av_flows(void)
{ {
Tox *Alice, *Bob, *bootstrap; Tox *alice, *bob, *bootstrap;
ToxAV *AliceAV, *BobAV; ToxAV *alice_av, *bob_av;
uint32_t index[] = { 1, 2, 3 }; uint32_t index[] = { 1, 2, 3 };
CallControl AliceCC, BobCC; CallControl alice_cc, bob_cc;
{ {
Tox_Err_New error; Tox_Err_New error;
@ -161,10 +161,10 @@ static void test_av_flows(void)
bootstrap = tox_new_log(nullptr, &error, &index[0]); bootstrap = tox_new_log(nullptr, &error, &index[0]);
ck_assert(error == TOX_ERR_NEW_OK); ck_assert(error == TOX_ERR_NEW_OK);
Alice = tox_new_log(nullptr, &error, &index[1]); alice = tox_new_log(nullptr, &error, &index[1]);
ck_assert(error == TOX_ERR_NEW_OK); ck_assert(error == TOX_ERR_NEW_OK);
Bob = tox_new_log(nullptr, &error, &index[2]); bob = tox_new_log(nullptr, &error, &index[2]);
ck_assert(error == TOX_ERR_NEW_OK); ck_assert(error == TOX_ERR_NEW_OK);
} }
@ -174,33 +174,33 @@ static void test_av_flows(void)
uint8_t address[TOX_ADDRESS_SIZE]; uint8_t address[TOX_ADDRESS_SIZE];
tox_callback_friend_request(Alice, t_accept_friend_request_cb); tox_callback_friend_request(alice, t_accept_friend_request_cb);
tox_self_get_address(Alice, address); tox_self_get_address(alice, address);
printf("bootstrapping Alice and Bob off a third bootstrap node\n"); printf("bootstrapping Alice and Bob off a third bootstrap node\n");
uint8_t dht_key[TOX_PUBLIC_KEY_SIZE]; uint8_t dht_key[TOX_PUBLIC_KEY_SIZE];
tox_self_get_dht_id(bootstrap, dht_key); tox_self_get_dht_id(bootstrap, dht_key);
const uint16_t dht_port = tox_self_get_udp_port(bootstrap, nullptr); const uint16_t dht_port = tox_self_get_udp_port(bootstrap, nullptr);
tox_bootstrap(Alice, "localhost", dht_port, dht_key, nullptr); tox_bootstrap(alice, "localhost", dht_port, dht_key, nullptr);
tox_bootstrap(Bob, "localhost", dht_port, dht_key, nullptr); tox_bootstrap(bob, "localhost", dht_port, dht_key, nullptr);
ck_assert(tox_friend_add(Bob, address, (const uint8_t *)"gentoo", 7, nullptr) != (uint32_t) -1); ck_assert(tox_friend_add(bob, address, (const uint8_t *)"gentoo", 7, nullptr) != (uint32_t) -1);
uint8_t off = 1; uint8_t off = 1;
while (true) { while (true) {
iterate_tox(bootstrap, Alice, Bob); iterate_tox(bootstrap, alice, bob);
if (tox_self_get_connection_status(bootstrap) && if (tox_self_get_connection_status(bootstrap) &&
tox_self_get_connection_status(Alice) && tox_self_get_connection_status(alice) &&
tox_self_get_connection_status(Bob) && off) { tox_self_get_connection_status(bob) && off) {
printf("Toxes are online, took %llu seconds\n", time(nullptr) - cur_time); printf("Toxes are online, took %llu seconds\n", time(nullptr) - cur_time);
off = 0; off = 0;
} }
if (tox_friend_get_connection_status(Alice, 0, nullptr) == TOX_CONNECTION_UDP && if (tox_friend_get_connection_status(alice, 0, nullptr) == TOX_CONNECTION_UDP &&
tox_friend_get_connection_status(Bob, 0, nullptr) == TOX_CONNECTION_UDP) { tox_friend_get_connection_status(bob, 0, nullptr) == TOX_CONNECTION_UDP) {
break; break;
} }
@ -210,72 +210,72 @@ static void test_av_flows(void)
{ {
Toxav_Err_New error; Toxav_Err_New error;
AliceAV = toxav_new(Alice, &error); alice_av = toxav_new(alice, &error);
ck_assert(error == TOXAV_ERR_NEW_OK); ck_assert(error == TOXAV_ERR_NEW_OK);
BobAV = toxav_new(Bob, &error); bob_av = toxav_new(bob, &error);
ck_assert(error == TOXAV_ERR_NEW_OK); ck_assert(error == TOXAV_ERR_NEW_OK);
} }
toxav_callback_call(AliceAV, t_toxav_call_cb, &AliceCC); toxav_callback_call(alice_av, t_toxav_call_cb, &alice_cc);
toxav_callback_call_state(AliceAV, t_toxav_call_state_cb, &AliceCC); toxav_callback_call_state(alice_av, t_toxav_call_state_cb, &alice_cc);
toxav_callback_video_receive_frame(AliceAV, t_toxav_receive_video_frame_cb, &AliceCC); toxav_callback_video_receive_frame(alice_av, t_toxav_receive_video_frame_cb, &alice_cc);
toxav_callback_audio_receive_frame(AliceAV, t_toxav_receive_audio_frame_cb, &AliceCC); toxav_callback_audio_receive_frame(alice_av, t_toxav_receive_audio_frame_cb, &alice_cc);
toxav_callback_call(BobAV, t_toxav_call_cb, &BobCC); toxav_callback_call(bob_av, t_toxav_call_cb, &bob_cc);
toxav_callback_call_state(BobAV, t_toxav_call_state_cb, &BobCC); toxav_callback_call_state(bob_av, t_toxav_call_state_cb, &bob_cc);
toxav_callback_video_receive_frame(BobAV, t_toxav_receive_video_frame_cb, &BobCC); toxav_callback_video_receive_frame(bob_av, t_toxav_receive_video_frame_cb, &bob_cc);
toxav_callback_audio_receive_frame(BobAV, t_toxav_receive_audio_frame_cb, &BobCC); toxav_callback_audio_receive_frame(bob_av, t_toxav_receive_audio_frame_cb, &bob_cc);
printf("Created 2 instances of ToxAV\n"); printf("Created 2 instances of ToxAV\n");
printf("All set after %llu seconds!\n", time(nullptr) - cur_time); printf("All set after %llu seconds!\n", time(nullptr) - cur_time);
if (TEST_REGULAR_AV) { if (TEST_REGULAR_AV) {
printf("\nTrying regular call (Audio and Video)...\n"); printf("\nTrying regular call (Audio and Video)...\n");
regular_call_flow(Alice, Bob, bootstrap, AliceAV, BobAV, &AliceCC, &BobCC, regular_call_flow(alice, bob, bootstrap, alice_av, bob_av, &alice_cc, &bob_cc,
48, 4000); 48, 4000);
} }
if (TEST_REGULAR_A) { if (TEST_REGULAR_A) {
printf("\nTrying regular call (Audio only)...\n"); printf("\nTrying regular call (Audio only)...\n");
regular_call_flow(Alice, Bob, bootstrap, AliceAV, BobAV, &AliceCC, &BobCC, regular_call_flow(alice, bob, bootstrap, alice_av, bob_av, &alice_cc, &bob_cc,
48, 0); 48, 0);
} }
if (TEST_REGULAR_V) { if (TEST_REGULAR_V) {
printf("\nTrying regular call (Video only)...\n"); printf("\nTrying regular call (Video only)...\n");
regular_call_flow(Alice, Bob, bootstrap, AliceAV, BobAV, &AliceCC, &BobCC, regular_call_flow(alice, bob, bootstrap, alice_av, bob_av, &alice_cc, &bob_cc,
0, 4000); 0, 4000);
} }
if (TEST_REJECT) { /* Alice calls; Bob rejects */ if (TEST_REJECT) { /* Alice calls; Bob rejects */
printf("\nTrying reject flow...\n"); printf("\nTrying reject flow...\n");
clear_call_control(&AliceCC); clear_call_control(&alice_cc);
clear_call_control(&BobCC); clear_call_control(&bob_cc);
{ {
Toxav_Err_Call rc; Toxav_Err_Call rc;
toxav_call(AliceAV, 0, 48, 0, &rc); toxav_call(alice_av, 0, 48, 0, &rc);
ck_assert_msg(rc == TOXAV_ERR_CALL_OK, "toxav_call failed: %d\n", rc); ck_assert_msg(rc == TOXAV_ERR_CALL_OK, "toxav_call failed: %d\n", rc);
} }
do { do {
iterate_tox(bootstrap, Alice, Bob); iterate_tox(bootstrap, alice, bob);
} while (!BobCC.incoming); } while (!bob_cc.incoming);
/* Reject */ /* Reject */
{ {
Toxav_Err_Call_Control rc; Toxav_Err_Call_Control rc;
toxav_call_control(BobAV, 0, TOXAV_CALL_CONTROL_CANCEL, &rc); toxav_call_control(bob_av, 0, TOXAV_CALL_CONTROL_CANCEL, &rc);
ck_assert_msg(rc == TOXAV_ERR_CALL_CONTROL_OK, "toxav_call_control failed: %d\n", rc); ck_assert_msg(rc == TOXAV_ERR_CALL_CONTROL_OK, "toxav_call_control failed: %d\n", rc);
} }
do { do {
iterate_tox(bootstrap, Alice, Bob); iterate_tox(bootstrap, alice, bob);
} while (AliceCC.state != TOXAV_FRIEND_CALL_STATE_FINISHED); } while (alice_cc.state != TOXAV_FRIEND_CALL_STATE_FINISHED);
printf("Success!\n"); printf("Success!\n");
} }
@ -283,32 +283,32 @@ static void test_av_flows(void)
if (TEST_CANCEL) { /* Alice calls; Alice cancels while ringing */ if (TEST_CANCEL) { /* Alice calls; Alice cancels while ringing */
printf("\nTrying cancel (while ringing) flow...\n"); printf("\nTrying cancel (while ringing) flow...\n");
clear_call_control(&AliceCC); clear_call_control(&alice_cc);
clear_call_control(&BobCC); clear_call_control(&bob_cc);
{ {
Toxav_Err_Call rc; Toxav_Err_Call rc;
toxav_call(AliceAV, 0, 48, 0, &rc); toxav_call(alice_av, 0, 48, 0, &rc);
ck_assert_msg(rc == TOXAV_ERR_CALL_OK, "toxav_call failed: %d\n", rc); ck_assert_msg(rc == TOXAV_ERR_CALL_OK, "toxav_call failed: %d\n", rc);
} }
do { do {
iterate_tox(bootstrap, Alice, Bob); iterate_tox(bootstrap, alice, bob);
} while (!BobCC.incoming); } while (!bob_cc.incoming);
/* Cancel */ /* Cancel */
{ {
Toxav_Err_Call_Control rc; Toxav_Err_Call_Control rc;
toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_CANCEL, &rc); toxav_call_control(alice_av, 0, TOXAV_CALL_CONTROL_CANCEL, &rc);
ck_assert_msg(rc == TOXAV_ERR_CALL_CONTROL_OK, "toxav_call_control failed: %d\n", rc); ck_assert_msg(rc == TOXAV_ERR_CALL_CONTROL_OK, "toxav_call_control failed: %d\n", rc);
} }
/* Alice will not receive end state */ /* Alice will not receive end state */
do { do {
iterate_tox(bootstrap, Alice, Bob); iterate_tox(bootstrap, alice, bob);
} while (BobCC.state != TOXAV_FRIEND_CALL_STATE_FINISHED); } while (bob_cc.state != TOXAV_FRIEND_CALL_STATE_FINISHED);
printf("Success!\n"); printf("Success!\n");
} }
@ -316,80 +316,80 @@ static void test_av_flows(void)
if (TEST_MUTE_UNMUTE) { /* Check Mute-Unmute etc */ if (TEST_MUTE_UNMUTE) { /* Check Mute-Unmute etc */
printf("\nTrying mute functionality...\n"); printf("\nTrying mute functionality...\n");
clear_call_control(&AliceCC); clear_call_control(&alice_cc);
clear_call_control(&BobCC); clear_call_control(&bob_cc);
/* Assume sending audio and video */ /* Assume sending audio and video */
{ {
Toxav_Err_Call rc; Toxav_Err_Call rc;
toxav_call(AliceAV, 0, 48, 1000, &rc); toxav_call(alice_av, 0, 48, 1000, &rc);
ck_assert_msg(rc == TOXAV_ERR_CALL_OK, "toxav_call failed: %d\n", rc); ck_assert_msg(rc == TOXAV_ERR_CALL_OK, "toxav_call failed: %d\n", rc);
} }
do { do {
iterate_tox(bootstrap, Alice, Bob); iterate_tox(bootstrap, alice, bob);
} while (!BobCC.incoming); } while (!bob_cc.incoming);
/* At first try all stuff while in invalid state */ /* At first try all stuff while in invalid state */
ck_assert(!toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_PAUSE, nullptr)); ck_assert(!toxav_call_control(alice_av, 0, TOXAV_CALL_CONTROL_PAUSE, nullptr));
ck_assert(!toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_RESUME, nullptr)); ck_assert(!toxav_call_control(alice_av, 0, TOXAV_CALL_CONTROL_RESUME, nullptr));
ck_assert(!toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_MUTE_AUDIO, nullptr)); ck_assert(!toxav_call_control(alice_av, 0, TOXAV_CALL_CONTROL_MUTE_AUDIO, nullptr));
ck_assert(!toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_UNMUTE_AUDIO, nullptr)); ck_assert(!toxav_call_control(alice_av, 0, TOXAV_CALL_CONTROL_UNMUTE_AUDIO, nullptr));
ck_assert(!toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_HIDE_VIDEO, nullptr)); ck_assert(!toxav_call_control(alice_av, 0, TOXAV_CALL_CONTROL_HIDE_VIDEO, nullptr));
ck_assert(!toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_SHOW_VIDEO, nullptr)); ck_assert(!toxav_call_control(alice_av, 0, TOXAV_CALL_CONTROL_SHOW_VIDEO, nullptr));
{ {
Toxav_Err_Answer rc; Toxav_Err_Answer rc;
toxav_answer(BobAV, 0, 48, 4000, &rc); toxav_answer(bob_av, 0, 48, 4000, &rc);
ck_assert_msg(rc == TOXAV_ERR_ANSWER_OK, "toxav_answer failed: %d\n", rc); ck_assert_msg(rc == TOXAV_ERR_ANSWER_OK, "toxav_answer failed: %d\n", rc);
} }
iterate_tox(bootstrap, Alice, Bob); iterate_tox(bootstrap, alice, bob);
/* Pause and Resume */ /* Pause and Resume */
printf("Pause and Resume\n"); printf("Pause and Resume\n");
ck_assert_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_PAUSE); ck_assert_call_control(alice_av, 0, TOXAV_CALL_CONTROL_PAUSE);
iterate_tox(bootstrap, Alice, Bob); iterate_tox(bootstrap, alice, bob);
ck_assert(BobCC.state == 0); ck_assert(bob_cc.state == 0);
ck_assert_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_RESUME); ck_assert_call_control(alice_av, 0, TOXAV_CALL_CONTROL_RESUME);
iterate_tox(bootstrap, Alice, Bob); iterate_tox(bootstrap, alice, bob);
ck_assert(BobCC.state & (TOXAV_FRIEND_CALL_STATE_SENDING_A | TOXAV_FRIEND_CALL_STATE_SENDING_V)); ck_assert(bob_cc.state & (TOXAV_FRIEND_CALL_STATE_SENDING_A | TOXAV_FRIEND_CALL_STATE_SENDING_V));
/* Mute/Unmute single */ /* Mute/Unmute single */
printf("Mute/Unmute single\n"); printf("Mute/Unmute single\n");
ck_assert_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_MUTE_AUDIO); ck_assert_call_control(alice_av, 0, TOXAV_CALL_CONTROL_MUTE_AUDIO);
iterate_tox(bootstrap, Alice, Bob); iterate_tox(bootstrap, alice, bob);
ck_assert(BobCC.state ^ TOXAV_FRIEND_CALL_STATE_ACCEPTING_A); ck_assert(bob_cc.state ^ TOXAV_FRIEND_CALL_STATE_ACCEPTING_A);
ck_assert_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_UNMUTE_AUDIO); ck_assert_call_control(alice_av, 0, TOXAV_CALL_CONTROL_UNMUTE_AUDIO);
iterate_tox(bootstrap, Alice, Bob); iterate_tox(bootstrap, alice, bob);
ck_assert(BobCC.state & TOXAV_FRIEND_CALL_STATE_ACCEPTING_A); ck_assert(bob_cc.state & TOXAV_FRIEND_CALL_STATE_ACCEPTING_A);
/* Mute/Unmute both */ /* Mute/Unmute both */
printf("Mute/Unmute both\n"); printf("Mute/Unmute both\n");
ck_assert_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_MUTE_AUDIO); ck_assert_call_control(alice_av, 0, TOXAV_CALL_CONTROL_MUTE_AUDIO);
iterate_tox(bootstrap, Alice, Bob); iterate_tox(bootstrap, alice, bob);
ck_assert(BobCC.state ^ TOXAV_FRIEND_CALL_STATE_ACCEPTING_A); ck_assert(bob_cc.state ^ TOXAV_FRIEND_CALL_STATE_ACCEPTING_A);
ck_assert_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_HIDE_VIDEO); ck_assert_call_control(alice_av, 0, TOXAV_CALL_CONTROL_HIDE_VIDEO);
iterate_tox(bootstrap, Alice, Bob); iterate_tox(bootstrap, alice, bob);
ck_assert(BobCC.state ^ TOXAV_FRIEND_CALL_STATE_ACCEPTING_V); ck_assert(bob_cc.state ^ TOXAV_FRIEND_CALL_STATE_ACCEPTING_V);
ck_assert_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_UNMUTE_AUDIO); ck_assert_call_control(alice_av, 0, TOXAV_CALL_CONTROL_UNMUTE_AUDIO);
iterate_tox(bootstrap, Alice, Bob); iterate_tox(bootstrap, alice, bob);
ck_assert(BobCC.state & TOXAV_FRIEND_CALL_STATE_ACCEPTING_A); ck_assert(bob_cc.state & TOXAV_FRIEND_CALL_STATE_ACCEPTING_A);
ck_assert_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_SHOW_VIDEO); ck_assert_call_control(alice_av, 0, TOXAV_CALL_CONTROL_SHOW_VIDEO);
iterate_tox(bootstrap, Alice, Bob); iterate_tox(bootstrap, alice, bob);
ck_assert(BobCC.state & TOXAV_FRIEND_CALL_STATE_ACCEPTING_V); ck_assert(bob_cc.state & TOXAV_FRIEND_CALL_STATE_ACCEPTING_V);
{ {
Toxav_Err_Call_Control rc; Toxav_Err_Call_Control rc;
toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_CANCEL, &rc); toxav_call_control(alice_av, 0, TOXAV_CALL_CONTROL_CANCEL, &rc);
ck_assert_msg(rc == TOXAV_ERR_CALL_CONTROL_OK, "toxav_call_control failed: %d\n", rc); ck_assert_msg(rc == TOXAV_ERR_CALL_CONTROL_OK, "toxav_call_control failed: %d\n", rc);
} }
iterate_tox(bootstrap, Alice, Bob); iterate_tox(bootstrap, alice, bob);
ck_assert(BobCC.state == TOXAV_FRIEND_CALL_STATE_FINISHED); ck_assert(bob_cc.state == TOXAV_FRIEND_CALL_STATE_FINISHED);
printf("Success!\n"); printf("Success!\n");
} }
@ -397,58 +397,58 @@ static void test_av_flows(void)
if (TEST_STOP_RESUME_PAYLOAD) { /* Stop and resume audio/video payload */ if (TEST_STOP_RESUME_PAYLOAD) { /* Stop and resume audio/video payload */
printf("\nTrying stop/resume functionality...\n"); printf("\nTrying stop/resume functionality...\n");
clear_call_control(&AliceCC); clear_call_control(&alice_cc);
clear_call_control(&BobCC); clear_call_control(&bob_cc);
/* Assume sending audio and video */ /* Assume sending audio and video */
{ {
Toxav_Err_Call rc; Toxav_Err_Call rc;
toxav_call(AliceAV, 0, 48, 0, &rc); toxav_call(alice_av, 0, 48, 0, &rc);
ck_assert_msg(rc == TOXAV_ERR_CALL_OK, "toxav_call failed: %d\n", rc); ck_assert_msg(rc == TOXAV_ERR_CALL_OK, "toxav_call failed: %d\n", rc);
} }
do { do {
iterate_tox(bootstrap, Alice, Bob); iterate_tox(bootstrap, alice, bob);
} while (!BobCC.incoming); } while (!bob_cc.incoming);
{ {
Toxav_Err_Answer rc; Toxav_Err_Answer rc;
toxav_answer(BobAV, 0, 48, 0, &rc); toxav_answer(bob_av, 0, 48, 0, &rc);
ck_assert_msg(rc == TOXAV_ERR_ANSWER_OK, "toxav_answer failed: %d\n", rc); ck_assert_msg(rc == TOXAV_ERR_ANSWER_OK, "toxav_answer failed: %d\n", rc);
} }
iterate_tox(bootstrap, Alice, Bob); iterate_tox(bootstrap, alice, bob);
printf("Call started as audio only\n"); printf("Call started as audio only\n");
printf("Turning on video for Alice...\n"); printf("Turning on video for Alice...\n");
ck_assert(toxav_video_set_bit_rate(AliceAV, 0, 1000, nullptr)); ck_assert(toxav_video_set_bit_rate(alice_av, 0, 1000, nullptr));
iterate_tox(bootstrap, Alice, Bob); iterate_tox(bootstrap, alice, bob);
ck_assert(BobCC.state & TOXAV_FRIEND_CALL_STATE_SENDING_V); ck_assert(bob_cc.state & TOXAV_FRIEND_CALL_STATE_SENDING_V);
printf("Turning off video for Alice...\n"); printf("Turning off video for Alice...\n");
ck_assert(toxav_video_set_bit_rate(AliceAV, 0, 0, nullptr)); ck_assert(toxav_video_set_bit_rate(alice_av, 0, 0, nullptr));
iterate_tox(bootstrap, Alice, Bob); iterate_tox(bootstrap, alice, bob);
ck_assert(!(BobCC.state & TOXAV_FRIEND_CALL_STATE_SENDING_V)); ck_assert(!(bob_cc.state & TOXAV_FRIEND_CALL_STATE_SENDING_V));
printf("Turning off audio for Alice...\n"); printf("Turning off audio for Alice...\n");
ck_assert(toxav_audio_set_bit_rate(AliceAV, 0, 0, nullptr)); ck_assert(toxav_audio_set_bit_rate(alice_av, 0, 0, nullptr));
iterate_tox(bootstrap, Alice, Bob); iterate_tox(bootstrap, alice, bob);
ck_assert(!(BobCC.state & TOXAV_FRIEND_CALL_STATE_SENDING_A)); ck_assert(!(bob_cc.state & TOXAV_FRIEND_CALL_STATE_SENDING_A));
{ {
Toxav_Err_Call_Control rc; Toxav_Err_Call_Control rc;
toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_CANCEL, &rc); toxav_call_control(alice_av, 0, TOXAV_CALL_CONTROL_CANCEL, &rc);
ck_assert_msg(rc == TOXAV_ERR_CALL_CONTROL_OK, "toxav_call_control failed: %d\n", rc); ck_assert_msg(rc == TOXAV_ERR_CALL_CONTROL_OK, "toxav_call_control failed: %d\n", rc);
} }
iterate_tox(bootstrap, Alice, Bob); iterate_tox(bootstrap, alice, bob);
ck_assert(BobCC.state == TOXAV_FRIEND_CALL_STATE_FINISHED); ck_assert(bob_cc.state == TOXAV_FRIEND_CALL_STATE_FINISHED);
printf("Success!\n"); printf("Success!\n");
} }
@ -456,56 +456,56 @@ static void test_av_flows(void)
if (TEST_PAUSE_RESUME_SEND) { /* Stop and resume audio/video payload and test send options */ if (TEST_PAUSE_RESUME_SEND) { /* Stop and resume audio/video payload and test send options */
printf("\nTrying stop/resume functionality...\n"); printf("\nTrying stop/resume functionality...\n");
clear_call_control(&AliceCC); clear_call_control(&alice_cc);
clear_call_control(&BobCC); clear_call_control(&bob_cc);
/* Assume sending audio and video */ /* Assume sending audio and video */
{ {
Toxav_Err_Call rc; Toxav_Err_Call rc;
toxav_call(AliceAV, 0, 48, 0, &rc); toxav_call(alice_av, 0, 48, 0, &rc);
ck_assert_msg(rc == TOXAV_ERR_CALL_OK, "toxav_call failed: %d\n", rc); ck_assert_msg(rc == TOXAV_ERR_CALL_OK, "toxav_call failed: %d\n", rc);
} }
do { do {
iterate_tox(bootstrap, Alice, Bob); iterate_tox(bootstrap, alice, bob);
} while (!BobCC.incoming); } while (!bob_cc.incoming);
{ {
Toxav_Err_Answer rc; Toxav_Err_Answer rc;
toxav_answer(BobAV, 0, 48, 0, &rc); toxav_answer(bob_av, 0, 48, 0, &rc);
ck_assert_msg(rc == TOXAV_ERR_ANSWER_OK, "toxav_answer failed: %d\n", rc); ck_assert_msg(rc == TOXAV_ERR_ANSWER_OK, "toxav_answer failed: %d\n", rc);
} }
iterate_tox(bootstrap, Alice, Bob); iterate_tox(bootstrap, alice, bob);
ck_assert_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_PAUSE); ck_assert_call_control(alice_av, 0, TOXAV_CALL_CONTROL_PAUSE);
iterate_tox(bootstrap, Alice, Bob); iterate_tox(bootstrap, alice, bob);
ck_assert(!toxav_audio_send_frame_helper(AliceAV, 0, nullptr)); ck_assert(!toxav_audio_send_frame_helper(alice_av, 0, nullptr));
ck_assert(!toxav_audio_send_frame_helper(BobAV, 0, nullptr)); ck_assert(!toxav_audio_send_frame_helper(bob_av, 0, nullptr));
ck_assert_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_RESUME); ck_assert_call_control(alice_av, 0, TOXAV_CALL_CONTROL_RESUME);
iterate_tox(bootstrap, Alice, Bob); iterate_tox(bootstrap, alice, bob);
ck_assert(toxav_audio_send_frame_helper(AliceAV, 0, nullptr)); ck_assert(toxav_audio_send_frame_helper(alice_av, 0, nullptr));
ck_assert(toxav_audio_send_frame_helper(BobAV, 0, nullptr)); ck_assert(toxav_audio_send_frame_helper(bob_av, 0, nullptr));
iterate_tox(bootstrap, Alice, Bob); iterate_tox(bootstrap, alice, bob);
{ {
Toxav_Err_Call_Control rc; Toxav_Err_Call_Control rc;
toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_CANCEL, &rc); toxav_call_control(alice_av, 0, TOXAV_CALL_CONTROL_CANCEL, &rc);
ck_assert_msg(rc == TOXAV_ERR_CALL_CONTROL_OK, "toxav_call_control failed: %d\n", rc); ck_assert_msg(rc == TOXAV_ERR_CALL_CONTROL_OK, "toxav_call_control failed: %d\n", rc);
} }
iterate_tox(bootstrap, Alice, Bob); iterate_tox(bootstrap, alice, bob);
ck_assert(BobCC.state == TOXAV_FRIEND_CALL_STATE_FINISHED); ck_assert(bob_cc.state == TOXAV_FRIEND_CALL_STATE_FINISHED);
printf("Success!\n"); printf("Success!\n");
} }
toxav_kill(BobAV); toxav_kill(bob_av);
toxav_kill(AliceAV); toxav_kill(alice_av);
tox_kill(Bob); tox_kill(bob);
tox_kill(Alice); tox_kill(alice);
tox_kill(bootstrap); tox_kill(bootstrap);
printf("\nTest successful!\n"); printf("\nTest successful!\n");

View File

@ -21,18 +21,18 @@
#include "auto_test_support.h" #include "auto_test_support.h"
#include "check_compat.h" #include "check_compat.h"
typedef struct { typedef struct CallControl {
bool incoming; bool incoming;
uint32_t state; uint32_t state;
} CallControl; } CallControl;
typedef struct { typedef struct Thread_Data {
ToxAV *AliceAV; ToxAV *alice_av;
ToxAV *BobAV; ToxAV *bob_av;
CallControl *AliceCC; CallControl *alice_cc;
CallControl *BobCC; CallControl *bob_cc;
uint32_t friend_number; uint32_t friend_number;
} thread_data; } Thread_Data;
/** /**
* Callbacks * Callbacks
@ -78,28 +78,28 @@ static void t_accept_friend_request_cb(Tox *m, const uint8_t *public_key, const
/** /**
* Iterate helper * Iterate helper
*/ */
static ToxAV *setup_av_instance(Tox *tox, CallControl *CC) static ToxAV *setup_av_instance(Tox *tox, CallControl *cc)
{ {
Toxav_Err_New error; Toxav_Err_New error;
ToxAV *av = toxav_new(tox, &error); ToxAV *av = toxav_new(tox, &error);
ck_assert(error == TOXAV_ERR_NEW_OK); ck_assert(error == TOXAV_ERR_NEW_OK);
toxav_callback_call(av, t_toxav_call_cb, CC); toxav_callback_call(av, t_toxav_call_cb, cc);
toxav_callback_call_state(av, t_toxav_call_state_cb, CC); toxav_callback_call_state(av, t_toxav_call_state_cb, cc);
toxav_callback_video_receive_frame(av, t_toxav_receive_video_frame_cb, CC); toxav_callback_video_receive_frame(av, t_toxav_receive_video_frame_cb, cc);
toxav_callback_audio_receive_frame(av, t_toxav_receive_audio_frame_cb, CC); toxav_callback_audio_receive_frame(av, t_toxav_receive_audio_frame_cb, cc);
return av; return av;
} }
static void *call_thread(void *pd) static void *call_thread(void *pd)
{ {
ToxAV *AliceAV = ((thread_data *) pd)->AliceAV; ToxAV *alice_av = ((Thread_Data *) pd)->alice_av;
ToxAV *BobAV = ((thread_data *) pd)->BobAV; ToxAV *bob_av = ((Thread_Data *) pd)->bob_av;
uint32_t friend_number = ((thread_data *) pd)->friend_number; uint32_t friend_number = ((Thread_Data *) pd)->friend_number;
int16_t *PCM = (int16_t *)calloc(960, sizeof(int16_t)); int16_t *pcm = (int16_t *)calloc(960, sizeof(int16_t));
uint8_t *video_y = (uint8_t *)calloc(800 * 600, sizeof(uint8_t)); uint8_t *video_y = (uint8_t *)calloc(800 * 600, sizeof(uint8_t));
uint8_t *video_u = (uint8_t *)calloc(800 * 600 / 4, sizeof(uint8_t)); uint8_t *video_u = (uint8_t *)calloc(800 * 600 / 4, sizeof(uint8_t));
uint8_t *video_v = (uint8_t *)calloc(800 * 600 / 4, sizeof(uint8_t)); uint8_t *video_v = (uint8_t *)calloc(800 * 600 / 4, sizeof(uint8_t));
@ -107,19 +107,19 @@ static void *call_thread(void *pd)
time_t start_time = time(nullptr); time_t start_time = time(nullptr);
do { do {
toxav_iterate(AliceAV); toxav_iterate(alice_av);
toxav_iterate(BobAV); toxav_iterate(bob_av);
toxav_audio_send_frame(AliceAV, friend_number, PCM, 960, 1, 48000, nullptr); toxav_audio_send_frame(alice_av, friend_number, pcm, 960, 1, 48000, nullptr);
toxav_audio_send_frame(BobAV, 0, PCM, 960, 1, 48000, nullptr); toxav_audio_send_frame(bob_av, 0, pcm, 960, 1, 48000, nullptr);
toxav_video_send_frame(AliceAV, friend_number, 800, 600, video_y, video_u, video_v, nullptr); toxav_video_send_frame(alice_av, friend_number, 800, 600, video_y, video_u, video_v, nullptr);
toxav_video_send_frame(BobAV, 0, 800, 600, video_y, video_u, video_v, nullptr); toxav_video_send_frame(bob_av, 0, 800, 600, video_y, video_u, video_v, nullptr);
c_sleep(10); c_sleep(10);
} while (time(nullptr) - start_time < 4); } while (time(nullptr) - start_time < 4);
free(PCM); free(pcm);
free(video_y); free(video_y);
free(video_u); free(video_u);
free(video_v); free(video_v);
@ -160,11 +160,11 @@ static void set_current_time_callback(Tox *tox, Time_Data *time_data)
static void test_av_three_calls(void) static void test_av_three_calls(void)
{ {
uint32_t index[] = { 1, 2, 3, 4, 5 }; uint32_t index[] = { 1, 2, 3, 4, 5 };
Tox *Alice, *bootstrap, *Bobs[3]; Tox *alice, *bootstrap, *bobs[3];
ToxAV *AliceAV, *BobsAV[3]; ToxAV *alice_av, *bobs_av[3];
void *retval; void *retval;
CallControl AliceCC[3], BobsCC[3]; CallControl alice_cc[3], bobs_cc[3];
Time_Data time_data; Time_Data time_data;
pthread_mutex_init(&time_data.lock, nullptr); pthread_mutex_init(&time_data.lock, nullptr);
@ -177,21 +177,21 @@ static void test_av_three_calls(void)
time_data.clock = current_time_monotonic(bootstrap->mono_time); time_data.clock = current_time_monotonic(bootstrap->mono_time);
set_current_time_callback(bootstrap, &time_data); set_current_time_callback(bootstrap, &time_data);
Alice = tox_new_log(nullptr, &error, &index[1]); alice = tox_new_log(nullptr, &error, &index[1]);
ck_assert(error == TOX_ERR_NEW_OK); ck_assert(error == TOX_ERR_NEW_OK);
set_current_time_callback(Alice, &time_data); set_current_time_callback(alice, &time_data);
Bobs[0] = tox_new_log(nullptr, &error, &index[2]); bobs[0] = tox_new_log(nullptr, &error, &index[2]);
ck_assert(error == TOX_ERR_NEW_OK); ck_assert(error == TOX_ERR_NEW_OK);
set_current_time_callback(Bobs[0], &time_data); set_current_time_callback(bobs[0], &time_data);
Bobs[1] = tox_new_log(nullptr, &error, &index[3]); bobs[1] = tox_new_log(nullptr, &error, &index[3]);
ck_assert(error == TOX_ERR_NEW_OK); ck_assert(error == TOX_ERR_NEW_OK);
set_current_time_callback(Bobs[1], &time_data); set_current_time_callback(bobs[1], &time_data);
Bobs[2] = tox_new_log(nullptr, &error, &index[4]); bobs[2] = tox_new_log(nullptr, &error, &index[4]);
ck_assert(error == TOX_ERR_NEW_OK); ck_assert(error == TOX_ERR_NEW_OK);
set_current_time_callback(Bobs[2], &time_data); set_current_time_callback(bobs[2], &time_data);
} }
printf("Created 5 instances of Tox\n"); printf("Created 5 instances of Tox\n");
@ -200,48 +200,48 @@ static void test_av_three_calls(void)
uint8_t address[TOX_ADDRESS_SIZE]; uint8_t address[TOX_ADDRESS_SIZE];
tox_callback_friend_request(Alice, t_accept_friend_request_cb); tox_callback_friend_request(alice, t_accept_friend_request_cb);
tox_self_get_address(Alice, address); tox_self_get_address(alice, address);
printf("bootstrapping Alice and the %u Bobs off a third bootstrap node\n", printf("bootstrapping Alice and the %u Bobs off a third bootstrap node\n",
(unsigned)(sizeof(Bobs) / sizeof(Bobs[0]))); (unsigned)(sizeof(bobs) / sizeof(bobs[0])));
uint8_t dht_key[TOX_PUBLIC_KEY_SIZE]; uint8_t dht_key[TOX_PUBLIC_KEY_SIZE];
tox_self_get_dht_id(bootstrap, dht_key); tox_self_get_dht_id(bootstrap, dht_key);
const uint16_t dht_port = tox_self_get_udp_port(bootstrap, nullptr); const uint16_t dht_port = tox_self_get_udp_port(bootstrap, nullptr);
tox_bootstrap(Alice, "localhost", dht_port, dht_key, nullptr); tox_bootstrap(alice, "localhost", dht_port, dht_key, nullptr);
tox_bootstrap(Bobs[0], "localhost", dht_port, dht_key, nullptr); tox_bootstrap(bobs[0], "localhost", dht_port, dht_key, nullptr);
tox_bootstrap(Bobs[1], "localhost", dht_port, dht_key, nullptr); tox_bootstrap(bobs[1], "localhost", dht_port, dht_key, nullptr);
tox_bootstrap(Bobs[2], "localhost", dht_port, dht_key, nullptr); tox_bootstrap(bobs[2], "localhost", dht_port, dht_key, nullptr);
ck_assert(tox_friend_add(Bobs[0], address, (const uint8_t *)"gentoo", 7, nullptr) != (uint32_t) -1); ck_assert(tox_friend_add(bobs[0], address, (const uint8_t *)"gentoo", 7, nullptr) != (uint32_t) -1);
ck_assert(tox_friend_add(Bobs[1], address, (const uint8_t *)"gentoo", 7, nullptr) != (uint32_t) -1); ck_assert(tox_friend_add(bobs[1], address, (const uint8_t *)"gentoo", 7, nullptr) != (uint32_t) -1);
ck_assert(tox_friend_add(Bobs[2], address, (const uint8_t *)"gentoo", 7, nullptr) != (uint32_t) -1); ck_assert(tox_friend_add(bobs[2], address, (const uint8_t *)"gentoo", 7, nullptr) != (uint32_t) -1);
uint8_t off = 1; uint8_t off = 1;
while (true) { while (true) {
tox_iterate(bootstrap, nullptr); tox_iterate(bootstrap, nullptr);
tox_iterate(Alice, nullptr); tox_iterate(alice, nullptr);
tox_iterate(Bobs[0], nullptr); tox_iterate(bobs[0], nullptr);
tox_iterate(Bobs[1], nullptr); tox_iterate(bobs[1], nullptr);
tox_iterate(Bobs[2], nullptr); tox_iterate(bobs[2], nullptr);
if (tox_self_get_connection_status(bootstrap) && if (tox_self_get_connection_status(bootstrap) &&
tox_self_get_connection_status(Alice) && tox_self_get_connection_status(alice) &&
tox_self_get_connection_status(Bobs[0]) && tox_self_get_connection_status(bobs[0]) &&
tox_self_get_connection_status(Bobs[1]) && tox_self_get_connection_status(bobs[1]) &&
tox_self_get_connection_status(Bobs[2]) && off) { tox_self_get_connection_status(bobs[2]) && off) {
printf("Toxes are online, took %lu seconds\n", (unsigned long)(time(nullptr) - cur_time)); printf("Toxes are online, took %lu seconds\n", (unsigned long)(time(nullptr) - cur_time));
off = 0; off = 0;
} }
if (tox_friend_get_connection_status(Alice, 0, nullptr) == TOX_CONNECTION_UDP && if (tox_friend_get_connection_status(alice, 0, nullptr) == TOX_CONNECTION_UDP &&
tox_friend_get_connection_status(Alice, 1, nullptr) == TOX_CONNECTION_UDP && tox_friend_get_connection_status(alice, 1, nullptr) == TOX_CONNECTION_UDP &&
tox_friend_get_connection_status(Alice, 2, nullptr) == TOX_CONNECTION_UDP && tox_friend_get_connection_status(alice, 2, nullptr) == TOX_CONNECTION_UDP &&
tox_friend_get_connection_status(Bobs[0], 0, nullptr) == TOX_CONNECTION_UDP && tox_friend_get_connection_status(bobs[0], 0, nullptr) == TOX_CONNECTION_UDP &&
tox_friend_get_connection_status(Bobs[1], 0, nullptr) == TOX_CONNECTION_UDP && tox_friend_get_connection_status(bobs[1], 0, nullptr) == TOX_CONNECTION_UDP &&
tox_friend_get_connection_status(Bobs[2], 0, nullptr) == TOX_CONNECTION_UDP) { tox_friend_get_connection_status(bobs[2], 0, nullptr) == TOX_CONNECTION_UDP) {
break; break;
} }
@ -249,24 +249,24 @@ static void test_av_three_calls(void)
c_sleep(5); c_sleep(5);
} }
AliceAV = setup_av_instance(Alice, AliceCC); alice_av = setup_av_instance(alice, alice_cc);
BobsAV[0] = setup_av_instance(Bobs[0], &BobsCC[0]); bobs_av[0] = setup_av_instance(bobs[0], &bobs_cc[0]);
BobsAV[1] = setup_av_instance(Bobs[1], &BobsCC[1]); bobs_av[1] = setup_av_instance(bobs[1], &bobs_cc[1]);
BobsAV[2] = setup_av_instance(Bobs[2], &BobsCC[2]); bobs_av[2] = setup_av_instance(bobs[2], &bobs_cc[2]);
printf("Created 4 instances of ToxAV\n"); printf("Created 4 instances of ToxAV\n");
printf("All set after %lu seconds!\n", (unsigned long)(time(nullptr) - cur_time)); printf("All set after %lu seconds!\n", (unsigned long)(time(nullptr) - cur_time));
thread_data tds[3]; Thread_Data tds[3];
for (size_t i = 0; i < 3; i++) { for (size_t i = 0; i < 3; i++) {
tds[i].AliceAV = AliceAV; tds[i].alice_av = alice_av;
tds[i].BobAV = BobsAV[i]; tds[i].bob_av = bobs_av[i];
tds[i].AliceCC = &AliceCC[i]; tds[i].alice_cc = &alice_cc[i];
tds[i].BobCC = &BobsCC[i]; tds[i].bob_cc = &bobs_cc[i];
tds[i].friend_number = i; tds[i].friend_number = i;
memset(tds[i].AliceCC, 0, sizeof(CallControl)); memset(tds[i].alice_cc, 0, sizeof(CallControl));
memset(tds[i].BobCC, 0, sizeof(CallControl)); memset(tds[i].bob_cc, 0, sizeof(CallControl));
} }
pthread_t tids[3]; pthread_t tids[3];
@ -279,10 +279,10 @@ static void test_av_three_calls(void)
do { do {
tox_iterate(bootstrap, nullptr); tox_iterate(bootstrap, nullptr);
tox_iterate(Alice, nullptr); tox_iterate(alice, nullptr);
tox_iterate(Bobs[0], nullptr); tox_iterate(bobs[0], nullptr);
tox_iterate(Bobs[1], nullptr); tox_iterate(bobs[1], nullptr);
tox_iterate(Bobs[2], nullptr); tox_iterate(bobs[2], nullptr);
increment_clock(&time_data, 100); increment_clock(&time_data, 100);
c_sleep(5); c_sleep(5);
@ -291,7 +291,7 @@ static void test_av_three_calls(void)
/* Call */ /* Call */
for (size_t i = 0; i < 3; i++) { for (size_t i = 0; i < 3; i++) {
Toxav_Err_Call rc; Toxav_Err_Call rc;
toxav_call(AliceAV, tds[i].friend_number, 48, 3000, &rc); toxav_call(alice_av, tds[i].friend_number, 48, 3000, &rc);
if (rc != TOXAV_ERR_CALL_OK) { if (rc != TOXAV_ERR_CALL_OK) {
printf("toxav_call failed: %d\n", rc); printf("toxav_call failed: %d\n", rc);
@ -302,23 +302,23 @@ static void test_av_three_calls(void)
do { do {
tox_iterate(bootstrap, nullptr); tox_iterate(bootstrap, nullptr);
tox_iterate(Alice, nullptr); tox_iterate(alice, nullptr);
tox_iterate(Bobs[0], nullptr); tox_iterate(bobs[0], nullptr);
tox_iterate(Bobs[1], nullptr); tox_iterate(bobs[1], nullptr);
tox_iterate(Bobs[2], nullptr); tox_iterate(bobs[2], nullptr);
for (size_t i = 0; i < 3; i++) { for (size_t i = 0; i < 3; i++) {
if (BobsCC[i].incoming) { if (bobs_cc[i].incoming) {
/* Answer */ /* Answer */
Toxav_Err_Answer rc; Toxav_Err_Answer rc;
toxav_answer(BobsAV[i], 0, 8, 500, &rc); toxav_answer(bobs_av[i], 0, 8, 500, &rc);
if (rc != TOXAV_ERR_ANSWER_OK) { if (rc != TOXAV_ERR_ANSWER_OK) {
printf("toxav_answer failed: %d\n", rc); printf("toxav_answer failed: %d\n", rc);
ck_assert(0); ck_assert(0);
} }
BobsCC[i].incoming = false; bobs_cc[i].incoming = false;
} }
} }
@ -329,19 +329,19 @@ static void test_av_three_calls(void)
/* Hangup */ /* Hangup */
for (size_t i = 0; i < 3; i++) { for (size_t i = 0; i < 3; i++) {
Toxav_Err_Call_Control rc; Toxav_Err_Call_Control rc;
toxav_call_control(AliceAV, i, TOXAV_CALL_CONTROL_CANCEL, &rc); toxav_call_control(alice_av, i, TOXAV_CALL_CONTROL_CANCEL, &rc);
if (rc != TOXAV_ERR_CALL_CONTROL_OK) { if (rc != TOXAV_ERR_CALL_CONTROL_OK) {
printf("toxav_call_control failed: %d %p %p\n", rc, (void *)AliceAV, (void *)&BobsAV[i]); printf("toxav_call_control failed: %d %p %p\n", rc, (void *)alice_av, (void *)&bobs_av[i]);
} }
} }
do { do {
tox_iterate(bootstrap, nullptr); tox_iterate(bootstrap, nullptr);
tox_iterate(Alice, nullptr); tox_iterate(alice, nullptr);
tox_iterate(Bobs[0], nullptr); tox_iterate(bobs[0], nullptr);
tox_iterate(Bobs[1], nullptr); tox_iterate(bobs[1], nullptr);
tox_iterate(Bobs[2], nullptr); tox_iterate(bobs[2], nullptr);
increment_clock(&time_data, 100); increment_clock(&time_data, 100);
c_sleep(5); c_sleep(5);
@ -357,14 +357,14 @@ static void test_av_three_calls(void)
ck_assert(retval == nullptr); ck_assert(retval == nullptr);
printf("Killing all instances\n"); printf("Killing all instances\n");
toxav_kill(BobsAV[2]); toxav_kill(bobs_av[2]);
toxav_kill(BobsAV[1]); toxav_kill(bobs_av[1]);
toxav_kill(BobsAV[0]); toxav_kill(bobs_av[0]);
toxav_kill(AliceAV); toxav_kill(alice_av);
tox_kill(Bobs[2]); tox_kill(bobs[2]);
tox_kill(Bobs[1]); tox_kill(bobs[1]);
tox_kill(Bobs[0]); tox_kill(bobs[0]);
tox_kill(Alice); tox_kill(alice);
tox_kill(bootstrap); tox_kill(bootstrap);
pthread_mutex_destroy(&time_data.lock); pthread_mutex_destroy(&time_data.lock);

View File

@ -1,7 +1,7 @@
#include "../toxcore/tox.h" #include "../toxcore/tox.h"
#include "check_compat.h" #include "check_compat.h"
#define check(major, minor, patch, expected) \ #define CHECK(major, minor, patch, expected) \
do_check(TOX_VERSION_MAJOR, TOX_VERSION_MINOR, TOX_VERSION_PATCH, \ do_check(TOX_VERSION_MAJOR, TOX_VERSION_MINOR, TOX_VERSION_PATCH, \
major, minor, patch, \ major, minor, patch, \
TOX_VERSION_IS_API_COMPATIBLE(major, minor, patch), expected) TOX_VERSION_IS_API_COMPATIBLE(major, minor, patch), expected)
@ -26,11 +26,11 @@ int main(void)
#define TOX_VERSION_MINOR 0 #define TOX_VERSION_MINOR 0
#define TOX_VERSION_PATCH 4 #define TOX_VERSION_PATCH 4
// Tox versions from 0.0.* are only compatible with themselves. // Tox versions from 0.0.* are only compatible with themselves.
check(0, 0, 0, false); CHECK(0, 0, 0, false);
check(0, 0, 3, false); CHECK(0, 0, 3, false);
check(0, 0, 4, true); CHECK(0, 0, 4, true);
check(0, 0, 5, false); CHECK(0, 0, 5, false);
check(1, 0, 4, false); CHECK(1, 0, 4, false);
#undef TOX_VERSION_MAJOR #undef TOX_VERSION_MAJOR
#undef TOX_VERSION_MINOR #undef TOX_VERSION_MINOR
#undef TOX_VERSION_PATCH #undef TOX_VERSION_PATCH
@ -39,19 +39,19 @@ int main(void)
#define TOX_VERSION_MINOR 1 #define TOX_VERSION_MINOR 1
#define TOX_VERSION_PATCH 4 #define TOX_VERSION_PATCH 4
// Tox versions from 0.1.* are only compatible with themselves or 0.1.<* // Tox versions from 0.1.* are only compatible with themselves or 0.1.<*
check(0, 0, 0, false); CHECK(0, 0, 0, false);
check(0, 0, 4, false); CHECK(0, 0, 4, false);
check(0, 0, 5, false); CHECK(0, 0, 5, false);
check(0, 1, 0, true); CHECK(0, 1, 0, true);
check(0, 1, 4, true); CHECK(0, 1, 4, true);
check(0, 1, 5, false); CHECK(0, 1, 5, false);
check(0, 2, 0, false); CHECK(0, 2, 0, false);
check(0, 2, 4, false); CHECK(0, 2, 4, false);
check(0, 2, 5, false); CHECK(0, 2, 5, false);
check(1, 0, 0, false); CHECK(1, 0, 0, false);
check(1, 0, 4, false); CHECK(1, 0, 4, false);
check(1, 0, 5, false); CHECK(1, 0, 5, false);
check(1, 1, 4, false); CHECK(1, 1, 4, false);
#undef TOX_VERSION_MAJOR #undef TOX_VERSION_MAJOR
#undef TOX_VERSION_MINOR #undef TOX_VERSION_MINOR
#undef TOX_VERSION_PATCH #undef TOX_VERSION_PATCH
@ -60,14 +60,14 @@ int main(void)
#define TOX_VERSION_MINOR 0 #define TOX_VERSION_MINOR 0
#define TOX_VERSION_PATCH 4 #define TOX_VERSION_PATCH 4
// Beyond 0.*.* Tox is comfortable with any lower version within their major // Beyond 0.*.* Tox is comfortable with any lower version within their major
check(0, 0, 4, false); CHECK(0, 0, 4, false);
check(1, 0, 0, true); CHECK(1, 0, 0, true);
check(1, 0, 1, true); CHECK(1, 0, 1, true);
check(1, 0, 4, true); CHECK(1, 0, 4, true);
check(1, 0, 5, false); CHECK(1, 0, 5, false);
check(1, 1, 0, false); CHECK(1, 1, 0, false);
check(2, 0, 0, false); CHECK(2, 0, 0, false);
check(2, 0, 4, false); CHECK(2, 0, 4, false);
#undef TOX_VERSION_MAJOR #undef TOX_VERSION_MAJOR
#undef TOX_VERSION_MINOR #undef TOX_VERSION_MINOR
#undef TOX_VERSION_PATCH #undef TOX_VERSION_PATCH
@ -75,19 +75,19 @@ int main(void)
#define TOX_VERSION_MAJOR 1 #define TOX_VERSION_MAJOR 1
#define TOX_VERSION_MINOR 1 #define TOX_VERSION_MINOR 1
#define TOX_VERSION_PATCH 4 #define TOX_VERSION_PATCH 4
check(0, 0, 4, false); CHECK(0, 0, 4, false);
check(1, 0, 0, true); CHECK(1, 0, 0, true);
check(1, 0, 4, true); CHECK(1, 0, 4, true);
check(1, 0, 5, true); CHECK(1, 0, 5, true);
check(1, 1, 0, true); CHECK(1, 1, 0, true);
check(1, 1, 1, true); CHECK(1, 1, 1, true);
check(1, 1, 4, true); CHECK(1, 1, 4, true);
check(1, 1, 5, false); CHECK(1, 1, 5, false);
check(1, 2, 0, false); CHECK(1, 2, 0, false);
check(1, 2, 4, false); CHECK(1, 2, 4, false);
check(1, 2, 5, false); CHECK(1, 2, 5, false);
check(2, 0, 0, false); CHECK(2, 0, 0, false);
check(2, 1, 4, false); CHECK(2, 1, 4, false);
#undef TOX_VERSION_MAJOR #undef TOX_VERSION_MAJOR
#undef TOX_VERSION_MINOR #undef TOX_VERSION_MINOR
#undef TOX_VERSION_PATCH #undef TOX_VERSION_PATCH

15
azure-pipelines.yml Normal file
View File

@ -0,0 +1,15 @@
pool:
vmImage: "windows-2019"
jobs:
- job: "windows_msvc_conan"
strategy:
matrix:
static:
conan.shared: "False"
shared:
conan.shared: "True"
steps:
- bash: python -m pip install conan==1.59.0
- bash: git submodule update --init --recursive
- bash: conan install -if _build -o with_tests=True -o shared=$(conan.shared) .
- bash: CONAN_CPU_COUNT=50 CTEST_OUTPUT_ON_FAILURE=1 conan build -bf _build -if _build .

View File

@ -11,3 +11,7 @@ coverage:
# because of the above range, but toxcore coverage fluctuates a lot due # because of the above range, but toxcore coverage fluctuates a lot due
# to low coverage of error paths that sometimes happen. # to low coverage of error paths that sometimes happen.
threshold: 2% threshold: 2%
ignore:
- "auto_tests" # ignore tests in coverage analysis
- "other" # we don't test the bootstrap daemon

View File

@ -36,6 +36,7 @@ class ToxConan(ConanFile):
self._cmake = CMake(self) self._cmake = CMake(self)
self._cmake.definitions["AUTOTEST"] = self.options.with_tests self._cmake.definitions["AUTOTEST"] = self.options.with_tests
self._cmake.definitions["BUILD_MISC_TESTS"] = self.options.with_tests self._cmake.definitions["BUILD_MISC_TESTS"] = self.options.with_tests
self._cmake.definitions["TEST_TIMEOUT_SECONDS"] = "300"
self._cmake.definitions[ self._cmake.definitions[
"CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS"] = self.options.shared "CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS"] = self.options.shared

View File

@ -1614,17 +1614,6 @@ HTML_FORMULA_FORMAT = png
FORMULA_FONTSIZE = 10 FORMULA_FONTSIZE = 10
# Use the FORMULA_TRANSPARENT tag to determine whether or not the images
# generated for formulas are transparent PNGs. Transparent PNGs are not
# supported properly for IE 6.0, but are supported on all modern browsers.
#
# Note that when changing this option you need to delete any form_*.png files in
# the HTML output directory before the changes have effect.
# The default value is: YES.
# This tag requires that the tag GENERATE_HTML is set to YES.
FORMULA_TRANSPARENT = YES
# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands # The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands
# to create new LaTeX commands to be used in formulas as building blocks. See # to create new LaTeX commands to be used in formulas as building blocks. See
# the section "Including formulas" for details. # the section "Including formulas" for details.
@ -2307,15 +2296,6 @@ EXTERNAL_PAGES = YES
# Configuration options related to the dot tool # Configuration options related to the dot tool
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram
# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
# NO turns the diagrams off. Note that this option also works with HAVE_DOT
# disabled, but it is recommended to install and use dot, since it yields more
# powerful graphs.
# The default value is: YES.
CLASS_DIAGRAMS = YES
# You can include diagrams made with dia in doxygen documentation. Doxygen will # You can include diagrams made with dia in doxygen documentation. Doxygen will
# then run dia to produce the diagram and insert it in the documentation. The # then run dia to produce the diagram and insert it in the documentation. The
# DIA_PATH tag allows you to specify the directory where the dia binary resides. # DIA_PATH tag allows you to specify the directory where the dia binary resides.
@ -2348,23 +2328,6 @@ HAVE_DOT = NO
DOT_NUM_THREADS = 0 DOT_NUM_THREADS = 0
# When you want a differently looking font in the dot files that doxygen
# generates you can specify the font name using DOT_FONTNAME. You need to make
# sure dot is able to find the font, which can be done by putting it in a
# standard location or by setting the DOTFONTPATH environment variable or by
# setting DOT_FONTPATH to the directory containing the font.
# The default value is: Helvetica.
# This tag requires that the tag HAVE_DOT is set to YES.
DOT_FONTNAME = Helvetica
# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
# dot graphs.
# Minimum value: 4, maximum value: 24, default value: 10.
# This tag requires that the tag HAVE_DOT is set to YES.
DOT_FONTSIZE = 10
# By default doxygen will tell dot to use the default font as specified with # By default doxygen will tell dot to use the default font as specified with
# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set # DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
# the path where dot can find it using this tag. # the path where dot can find it using this tag.
@ -2599,18 +2562,6 @@ DOT_GRAPH_MAX_NODES = 50
MAX_DOT_GRAPH_DEPTH = 0 MAX_DOT_GRAPH_DEPTH = 0
# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
# background. This is disabled by default, because dot on Windows does not seem
# to support this out of the box.
#
# Warning: Depending on the platform used, enabling this option may lead to
# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
# read).
# The default value is: NO.
# This tag requires that the tag HAVE_DOT is set to YES.
DOT_TRANSPARENT = NO
# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output # Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output
# files in one run (i.e. multiple -o and -T options on the command line). This # files in one run (i.e. multiple -o and -T options on the command line). This
# makes dot run faster, but since only newer versions of dot (>1.8.10) support # makes dot run faster, but since only newer versions of dot (>1.8.10) support

View File

@ -82,38 +82,33 @@ static void manage_keys(DHT *dht)
fclose(keys_file); fclose(keys_file);
} }
static const char *strlevel(Logger_Level level)
{
switch (level) {
case LOGGER_LEVEL_TRACE:
return "TRACE";
case LOGGER_LEVEL_DEBUG:
return "DEBUG";
case LOGGER_LEVEL_INFO:
return "INFO";
case LOGGER_LEVEL_WARNING:
return "WARNING";
case LOGGER_LEVEL_ERROR:
return "ERROR";
default:
return "<unknown>";
}
}
static void print_log(void *context, Logger_Level level, const char *file, int line, static void print_log(void *context, Logger_Level level, const char *file, int line,
const char *func, const char *message, void *userdata) const char *func, const char *message, void *userdata)
{ {
const char *strlevel; fprintf(stderr, "[%s] %s:%d(%s) %s\n", strlevel(level), file, line, func, message);
switch (level) {
case LOGGER_LEVEL_TRACE:
strlevel = "TRACE";
break;
case LOGGER_LEVEL_DEBUG:
strlevel = "DEBUG";
break;
case LOGGER_LEVEL_INFO:
strlevel = "INFO";
break;
case LOGGER_LEVEL_WARNING:
strlevel = "WARNING";
break;
case LOGGER_LEVEL_ERROR:
strlevel = "ERROR";
break;
default:
strlevel = "<unknown>";
break;
}
fprintf(stderr, "[%s] %s:%d(%s) %s\n", strlevel, file, line, func, message);
} }
int main(int argc, char *argv[]) int main(int argc, char *argv[])
@ -139,20 +134,22 @@ int main(int argc, char *argv[])
Logger *logger = logger_new(); Logger *logger = logger_new();
if (MIN_LOGGER_LEVEL == LOGGER_LEVEL_TRACE || MIN_LOGGER_LEVEL == LOGGER_LEVEL_DEBUG) { if (MIN_LOGGER_LEVEL <= LOGGER_LEVEL_DEBUG) {
logger_callback_log(logger, print_log, nullptr, nullptr); logger_callback_log(logger, print_log, nullptr, nullptr);
} }
const Random *rng = system_random(); const Random *rng = system_random();
Mono_Time *mono_time = mono_time_new(nullptr, nullptr); const Network *ns = system_network();
const Memory *mem = system_memory();
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
const uint16_t start_port = PORT; const uint16_t start_port = PORT;
const uint16_t end_port = start_port + (TOX_PORTRANGE_TO - TOX_PORTRANGE_FROM); const uint16_t end_port = start_port + (TOX_PORTRANGE_TO - TOX_PORTRANGE_FROM);
const Network *ns = system_network(); DHT *dht = new_dht(logger, mem, rng, ns, mono_time, new_networking_ex(logger, mem, ns, &ip, start_port, end_port, nullptr), true, true);
DHT *dht = new_dht(logger, rng, ns, mono_time, new_networking_ex(logger, ns, &ip, start_port, end_port, nullptr), true, true); Onion *onion = new_onion(logger, mem, mono_time, rng, dht);
Onion *onion = new_onion(logger, mono_time, rng, dht);
Forwarding *forwarding = new_forwarding(logger, rng, mono_time, dht); Forwarding *forwarding = new_forwarding(logger, rng, mono_time, dht);
GC_Announces_List *gc_announces_list = new_gca_list(); GC_Announces_List *gc_announces_list = new_gca_list();
Onion_Announce *onion_a = new_onion_announce(logger, rng, mono_time, dht); Onion_Announce *onion_a = new_onion_announce(logger, mem, rng, mono_time, dht);
#ifdef DHT_NODE_EXTRA_PACKETS #ifdef DHT_NODE_EXTRA_PACKETS
bootstrap_set_callbacks(dht_get_net(dht), DHT_VERSION_NUMBER, DHT_MOTD, sizeof(DHT_MOTD)); bootstrap_set_callbacks(dht_get_net(dht), DHT_VERSION_NUMBER, DHT_MOTD, sizeof(DHT_MOTD));
@ -173,7 +170,7 @@ int main(int argc, char *argv[])
#ifdef TCP_RELAY_ENABLED #ifdef TCP_RELAY_ENABLED
#define NUM_PORTS 3 #define NUM_PORTS 3
uint16_t ports[NUM_PORTS] = {443, 3389, PORT}; uint16_t ports[NUM_PORTS] = {443, 3389, PORT};
TCP_Server *tcp_s = new_TCP_server(logger, rng, ns, ipv6enabled, NUM_PORTS, ports, dht_get_self_secret_key(dht), onion, forwarding); TCP_Server *tcp_s = new_tcp_server(logger, mem, rng, ns, ipv6enabled, NUM_PORTS, ports, dht_get_self_secret_key(dht), onion, forwarding);
if (tcp_s == nullptr) { if (tcp_s == nullptr) {
printf("TCP server failed to initialize.\n"); printf("TCP server failed to initialize.\n");
@ -226,7 +223,7 @@ int main(int argc, char *argv[])
int is_waiting_for_dht_connection = 1; int is_waiting_for_dht_connection = 1;
uint64_t last_LANdiscovery = 0; uint64_t last_lan_discovery = 0;
const Broadcast_Info *broadcast = lan_discovery_init(ns); const Broadcast_Info *broadcast = lan_discovery_init(ns);
while (1) { while (1) {
@ -239,13 +236,13 @@ int main(int argc, char *argv[])
do_dht(dht); do_dht(dht);
if (mono_time_is_timeout(mono_time, last_LANdiscovery, is_waiting_for_dht_connection ? 5 : LAN_DISCOVERY_INTERVAL)) { if (mono_time_is_timeout(mono_time, last_lan_discovery, is_waiting_for_dht_connection ? 5 : LAN_DISCOVERY_INTERVAL)) {
lan_discovery_send(dht_get_net(dht), broadcast, dht_get_self_public_key(dht), net_htons(PORT)); lan_discovery_send(dht_get_net(dht), broadcast, dht_get_self_public_key(dht), net_htons(PORT));
last_LANdiscovery = mono_time_get(mono_time); last_lan_discovery = mono_time_get(mono_time);
} }
#ifdef TCP_RELAY_ENABLED #ifdef TCP_RELAY_ENABLED
do_TCP_server(tcp_s, mono_time); do_tcp_server(tcp_s, mono_time);
#endif #endif
networking_poll(dht_get_net(dht), nullptr); networking_poll(dht_get_net(dht), nullptr);

View File

@ -6,61 +6,92 @@ CHECKS="*"
CHECKS="$CHECKS,-clang-diagnostic-pointer-bool-conversion" CHECKS="$CHECKS,-clang-diagnostic-pointer-bool-conversion"
CHECKS="$CHECKS,-clang-diagnostic-tautological-pointer-compare" CHECKS="$CHECKS,-clang-diagnostic-tautological-pointer-compare"
# TODO(iphydf): We might want some of these. For the ones we don't want, add a # Conflicts with "Variable is assigned a value that is never used."
# comment explaining why not. # [unreadVariable]
CHECKS="$CHECKS,-altera-unroll-loops"
CHECKS="$CHECKS,-android-cloexec-accept"
CHECKS="$CHECKS,-android-cloexec-fopen"
CHECKS="$CHECKS,-bugprone-not-null-terminated-result"
CHECKS="$CHECKS,-bugprone-reserved-identifier"
CHECKS="$CHECKS,-bugprone-sizeof-expression"
CHECKS="$CHECKS,-cert-dcl37-c"
CHECKS="$CHECKS,-cert-dcl51-cpp"
CHECKS="$CHECKS,-clang-analyzer-optin.performance.Padding"
CHECKS="$CHECKS,-cppcoreguidelines-avoid-magic-numbers"
CHECKS="$CHECKS,-cppcoreguidelines-init-variables" CHECKS="$CHECKS,-cppcoreguidelines-init-variables"
CHECKS="$CHECKS,-hicpp-multiway-paths-covered"
CHECKS="$CHECKS,-hicpp-signed-bitwise"
CHECKS="$CHECKS,-llvm-else-after-return"
CHECKS="$CHECKS,-llvmlibc-restrict-system-libc-headers"
CHECKS="$CHECKS,-misc-redundant-expression"
CHECKS="$CHECKS,-misc-unused-parameters"
CHECKS="$CHECKS,-readability-else-after-return"
CHECKS="$CHECKS,-readability-function-cognitive-complexity"
CHECKS="$CHECKS,-readability-inconsistent-declaration-parameter-name"
CHECKS="$CHECKS,-readability-magic-numbers"
CHECKS="$CHECKS,-readability-redundant-control-flow"
# TODO(iphydf): Maybe fix these? # Short variable names are used quite a lot, and we don't consider them a
# readability issue.
CHECKS="$CHECKS,-readability-identifier-length"
# Altera checks are for GPUs (OpenCL). Our code doesn't run on GPUs.
CHECKS="$CHECKS,-altera-id-dependent-backward-branch" CHECKS="$CHECKS,-altera-id-dependent-backward-branch"
CHECKS="$CHECKS,-altera-struct-pack-align" CHECKS="$CHECKS,-altera-struct-pack-align"
CHECKS="$CHECKS,-altera-unroll-loops"
# We target systems other than Android, so we don't want to use non-standard
# functions from the Android libc.
CHECKS="$CHECKS,-android-cloexec-accept"
CHECKS="$CHECKS,-android-cloexec-fopen"
# This catches all the feature test macros (_POSIX_SOURCE etc.).
CHECKS="$CHECKS,-bugprone-reserved-identifier"
CHECKS="$CHECKS,-cert-dcl37-c"
CHECKS="$CHECKS,-cert-dcl51-cpp"
# Too restrictive. This makes sense if the branch clone is very large, but not
# if it's a single line. It can make the code less readable.
CHECKS="$CHECKS,-bugprone-branch-clone" CHECKS="$CHECKS,-bugprone-branch-clone"
# We intentionally send some not null-terminated strings in tests and use it for
# the toxencryptsave magic number.
CHECKS="$CHECKS,-bugprone-not-null-terminated-result"
# We don't want default labels in enum switches.
CHECKS="$CHECKS,-hicpp-multiway-paths-covered"
# This can make readability quite a bit worse when the 2 cases look very
# similar.
CHECKS="$CHECKS,-llvm-else-after-return"
CHECKS="$CHECKS,-readability-else-after-return"
# We need 'return;' in empty functions because cimple won't allow empty
# functions otherwise.
CHECKS="$CHECKS,-readability-redundant-control-flow"
# These are incredibly annoying, because things like
# uint16_t a = 0, b = 1, c = a > b ? a : b;
# ^
# Trip the checker, which is true, because of integer promotion, but also not
# very helpful as a diagnostic.
CHECKS="$CHECKS,-bugprone-narrowing-conversions"
CHECKS="$CHECKS,-cppcoreguidelines-narrowing-conversions"
# TODO(iphydf): We might want some of these. For the ones we don't want, add a
# comment explaining why not.
CHECKS="$CHECKS,-clang-analyzer-optin.performance.Padding"
CHECKS="$CHECKS,-hicpp-signed-bitwise"
CHECKS="$CHECKS,-misc-unused-parameters"
CHECKS="$CHECKS,-readability-function-cognitive-complexity"
# TODO(iphydf): Maybe fix these?
CHECKS="$CHECKS,-bugprone-easily-swappable-parameters" CHECKS="$CHECKS,-bugprone-easily-swappable-parameters"
CHECKS="$CHECKS,-bugprone-implicit-widening-of-multiplication-result" CHECKS="$CHECKS,-bugprone-implicit-widening-of-multiplication-result"
CHECKS="$CHECKS,-bugprone-integer-division" CHECKS="$CHECKS,-bugprone-integer-division"
CHECKS="$CHECKS,-bugprone-narrowing-conversions"
CHECKS="$CHECKS,-clang-analyzer-core.NonNullParamChecker"
CHECKS="$CHECKS,-clang-analyzer-core.NullDereference" CHECKS="$CHECKS,-clang-analyzer-core.NullDereference"
CHECKS="$CHECKS,-clang-analyzer-optin.portability.UnixAPI"
CHECKS="$CHECKS,-clang-analyzer-unix.Malloc"
CHECKS="$CHECKS,-clang-analyzer-valist.Uninitialized" CHECKS="$CHECKS,-clang-analyzer-valist.Uninitialized"
CHECKS="$CHECKS,-concurrency-mt-unsafe" CHECKS="$CHECKS,-concurrency-mt-unsafe"
CHECKS="$CHECKS,-cppcoreguidelines-avoid-non-const-global-variables" CHECKS="$CHECKS,-cppcoreguidelines-avoid-non-const-global-variables"
CHECKS="$CHECKS,-cppcoreguidelines-narrowing-conversions"
CHECKS="$CHECKS,-google-readability-casting"
CHECKS="$CHECKS,-misc-no-recursion" CHECKS="$CHECKS,-misc-no-recursion"
# TODO(iphydf): Probably fix these.
CHECKS="$CHECKS,-cert-err33-c"
CHECKS="$CHECKS,-cppcoreguidelines-avoid-magic-numbers"
CHECKS="$CHECKS,-google-readability-casting"
CHECKS="$CHECKS,-modernize-macro-to-enum"
CHECKS="$CHECKS,-readability-magic-numbers"
# TODO(iphydf): These two trip on list.c. Investigate why.
CHECKS="$CHECKS,-clang-analyzer-core.NonNullParamChecker"
CHECKS="$CHECKS,-clang-analyzer-unix.Malloc"
ERRORS="*" ERRORS="*"
# TODO(iphydf): Fix these. # TODO(iphydf): Fix these.
ERRORS="$ERRORS,-bugprone-macro-parentheses" ERRORS="$ERRORS,-bugprone-macro-parentheses"
ERRORS="$ERRORS,-bugprone-posix-return"
ERRORS="$ERRORS,-bugprone-signed-char-misuse"
ERRORS="$ERRORS,-cert-err34-c" ERRORS="$ERRORS,-cert-err34-c"
ERRORS="$ERRORS,-cert-str34-c" ERRORS="$ERRORS,-cert-str34-c"
ERRORS="$ERRORS,-hicpp-uppercase-literal-suffix"
ERRORS="$ERRORS,-readability-suspicious-call-argument" ERRORS="$ERRORS,-readability-suspicious-call-argument"
ERRORS="$ERRORS,-readability-uppercase-literal-suffix"
set -eux set -eux
@ -70,7 +101,7 @@ run() {
for i in "${!EXTRA_ARGS[@]}"; do for i in "${!EXTRA_ARGS[@]}"; do
EXTRA_ARGS[$i]="--extra-arg=${EXTRA_ARGS[$i]}" EXTRA_ARGS[$i]="--extra-arg=${EXTRA_ARGS[$i]}"
done done
clang-tidy-12 \ clang-tidy-14 \
-p=_build \ -p=_build \
--extra-arg=-DMIN_LOGGER_LEVEL=LOGGER_LEVEL_TRACE \ --extra-arg=-DMIN_LOGGER_LEVEL=LOGGER_LEVEL_TRACE \
"${EXTRA_ARGS[@]}" \ "${EXTRA_ARGS[@]}" \
@ -84,4 +115,6 @@ run() {
toxencryptsave/*.c toxencryptsave/*.c
} }
cmake . -B_build -GNinja -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
. other/analysis/variants.sh . other/analysis/variants.sh

View File

@ -29,7 +29,7 @@
*/ */
static void parse_tcp_relay_ports_config(config_t *cfg, uint16_t **tcp_relay_ports, int *tcp_relay_port_count) static void parse_tcp_relay_ports_config(config_t *cfg, uint16_t **tcp_relay_ports, int *tcp_relay_port_count)
{ {
const char *NAME_TCP_RELAY_PORTS = "tcp_relay_ports"; const char *const NAME_TCP_RELAY_PORTS = "tcp_relay_ports";
*tcp_relay_port_count = 0; *tcp_relay_port_count = 0;
@ -129,15 +129,15 @@ int get_general_config(const char *cfg_file_path, char **pid_file_path, char **k
{ {
config_t cfg; config_t cfg;
const char *NAME_PORT = "port"; const char *const NAME_PORT = "port";
const char *NAME_PID_FILE_PATH = "pid_file_path"; const char *const NAME_PID_FILE_PATH = "pid_file_path";
const char *NAME_KEYS_FILE_PATH = "keys_file_path"; const char *const NAME_KEYS_FILE_PATH = "keys_file_path";
const char *NAME_ENABLE_IPV6 = "enable_ipv6"; const char *const NAME_ENABLE_IPV6 = "enable_ipv6";
const char *NAME_ENABLE_IPV4_FALLBACK = "enable_ipv4_fallback"; const char *const NAME_ENABLE_IPV4_FALLBACK = "enable_ipv4_fallback";
const char *NAME_ENABLE_LAN_DISCOVERY = "enable_lan_discovery"; const char *const NAME_ENABLE_LAN_DISCOVERY = "enable_lan_discovery";
const char *NAME_ENABLE_TCP_RELAY = "enable_tcp_relay"; const char *const NAME_ENABLE_TCP_RELAY = "enable_tcp_relay";
const char *NAME_ENABLE_MOTD = "enable_motd"; const char *const NAME_ENABLE_MOTD = "enable_motd";
const char *NAME_MOTD = "motd"; const char *const NAME_MOTD = "motd";
config_init(&cfg); config_init(&cfg);
@ -307,11 +307,11 @@ static uint8_t *bootstrap_hex_string_to_bin(const char *hex_string)
int bootstrap_from_config(const char *cfg_file_path, DHT *dht, int enable_ipv6) int bootstrap_from_config(const char *cfg_file_path, DHT *dht, int enable_ipv6)
{ {
const char *NAME_BOOTSTRAP_NODES = "bootstrap_nodes"; const char *const NAME_BOOTSTRAP_NODES = "bootstrap_nodes";
const char *NAME_PUBLIC_KEY = "public_key"; const char *const NAME_PUBLIC_KEY = "public_key";
const char *NAME_PORT = "port"; const char *const NAME_PORT = "port";
const char *NAME_ADDRESS = "address"; const char *const NAME_ADDRESS = "address";
config_t cfg; config_t cfg;

View File

@ -61,10 +61,9 @@ static int manage_keys(DHT *dht, char *keys_file_path)
{ {
enum { KEYS_SIZE = CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SECRET_KEY_SIZE }; enum { KEYS_SIZE = CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SECRET_KEY_SIZE };
uint8_t keys[KEYS_SIZE]; uint8_t keys[KEYS_SIZE];
FILE *keys_file;
// Check if file exits, proceed to open and load keys // Check if file exits, proceed to open and load keys
keys_file = fopen(keys_file_path, "rb"); FILE *keys_file = fopen(keys_file_path, "rb");
if (keys_file != nullptr) { if (keys_file != nullptr) {
const size_t read_size = fread(keys, sizeof(uint8_t), KEYS_SIZE, keys_file); const size_t read_size = fread(keys, sizeof(uint8_t), KEYS_SIZE, keys_file);
@ -120,9 +119,9 @@ static void print_public_key(const uint8_t *public_key)
static void daemonize(LOG_BACKEND log_backend, char *pid_file_path) static void daemonize(LOG_BACKEND log_backend, char *pid_file_path)
{ {
// Check if the PID file exists // Check if the PID file exists
FILE *pid_file; FILE *pid_file = fopen(pid_file_path, "r");
if ((pid_file = fopen(pid_file_path, "r"))) { if (pid_file != nullptr) {
log_write(LOG_LEVEL_WARNING, "Another instance of the daemon is already running, PID file %s exists.\n", pid_file_path); log_write(LOG_LEVEL_WARNING, "Another instance of the daemon is already running, PID file %s exists.\n", pid_file_path);
fclose(pid_file); fclose(pid_file);
} }
@ -175,38 +174,29 @@ static void daemonize(LOG_BACKEND log_backend, char *pid_file_path)
// Logs toxcore logger message using our logger facility // Logs toxcore logger message using our logger facility
static LOG_LEVEL logger_level_to_log_level(Logger_Level level)
{
switch (level) {
case LOGGER_LEVEL_TRACE:
case LOGGER_LEVEL_DEBUG:
case LOGGER_LEVEL_INFO:
return LOG_LEVEL_INFO;
case LOGGER_LEVEL_WARNING:
return LOG_LEVEL_WARNING;
case LOGGER_LEVEL_ERROR:
return LOG_LEVEL_ERROR;
default:
return LOG_LEVEL_INFO;
}
}
static void toxcore_logger_callback(void *context, Logger_Level level, const char *file, int line, static void toxcore_logger_callback(void *context, Logger_Level level, const char *file, int line,
const char *func, const char *message, void *userdata) const char *func, const char *message, void *userdata)
{ {
LOG_LEVEL log_level; log_write(logger_level_to_log_level(level), "%s:%d(%s) %s\n", file, line, func, message);
switch (level) {
case LOGGER_LEVEL_TRACE:
log_level = LOG_LEVEL_INFO;
break;
case LOGGER_LEVEL_DEBUG:
log_level = LOG_LEVEL_INFO;
break;
case LOGGER_LEVEL_INFO:
log_level = LOG_LEVEL_INFO;
break;
case LOGGER_LEVEL_WARNING:
log_level = LOG_LEVEL_WARNING;
break;
case LOGGER_LEVEL_ERROR:
log_level = LOG_LEVEL_ERROR;
break;
default:
log_level = LOG_LEVEL_INFO;
break;
}
log_write(log_level, "%s:%d(%s) %s\n", file, line, func, message);
} }
static volatile sig_atomic_t caught_signal = 0; static volatile sig_atomic_t caught_signal = 0;
@ -220,11 +210,10 @@ int main(int argc, char *argv[])
{ {
umask(077); umask(077);
char *cfg_file_path = nullptr; char *cfg_file_path = nullptr;
LOG_BACKEND log_backend; bool run_in_foreground = false;
bool run_in_foreground;
// choose backend for printing command line argument parsing output based on whether the daemon is being run from a terminal // choose backend for printing command line argument parsing output based on whether the daemon is being run from a terminal
log_backend = isatty(STDOUT_FILENO) ? LOG_BACKEND_STDOUT : LOG_BACKEND_SYSLOG; LOG_BACKEND log_backend = isatty(STDOUT_FILENO) ? LOG_BACKEND_STDOUT : LOG_BACKEND_SYSLOG;
log_open(log_backend); log_open(log_backend);
handle_command_line_arguments(argc, argv, &cfg_file_path, &log_backend, &run_in_foreground); handle_command_line_arguments(argc, argv, &cfg_file_path, &log_backend, &run_in_foreground);
@ -236,14 +225,14 @@ int main(int argc, char *argv[])
char *pid_file_path = nullptr; char *pid_file_path = nullptr;
char *keys_file_path = nullptr; char *keys_file_path = nullptr;
int start_port; int start_port = 0;
int enable_ipv6; int enable_ipv6 = 0;
int enable_ipv4_fallback; int enable_ipv4_fallback = 0;
int enable_lan_discovery; int enable_lan_discovery = 0;
int enable_tcp_relay; int enable_tcp_relay = 0;
uint16_t *tcp_relay_ports = nullptr; uint16_t *tcp_relay_ports = nullptr;
int tcp_relay_port_count; int tcp_relay_port_count = 0;
int enable_motd; int enable_motd = 0;
char *motd = nullptr; char *motd = nullptr;
if (get_general_config(cfg_file_path, &pid_file_path, &keys_file_path, &start_port, &enable_ipv6, &enable_ipv4_fallback, if (get_general_config(cfg_file_path, &pid_file_path, &keys_file_path, &start_port, &enable_ipv6, &enable_ipv4_fallback,
@ -275,20 +264,22 @@ int main(int argc, char *argv[])
Logger *logger = logger_new(); Logger *logger = logger_new();
if (MIN_LOGGER_LEVEL == LOGGER_LEVEL_TRACE || MIN_LOGGER_LEVEL == LOGGER_LEVEL_DEBUG) { if (MIN_LOGGER_LEVEL <= LOGGER_LEVEL_DEBUG) {
logger_callback_log(logger, toxcore_logger_callback, nullptr, nullptr); logger_callback_log(logger, toxcore_logger_callback, nullptr, nullptr);
} }
const uint16_t end_port = start_port + (TOX_PORTRANGE_TO - TOX_PORTRANGE_FROM); const uint16_t end_port = start_port + (TOX_PORTRANGE_TO - TOX_PORTRANGE_FROM);
const Memory *mem = system_memory();
const Random *rng = system_random();
const Network *ns = system_network(); const Network *ns = system_network();
Networking_Core *net = new_networking_ex(logger, ns, &ip, start_port, end_port, nullptr); Networking_Core *net = new_networking_ex(logger, mem, ns, &ip, start_port, end_port, nullptr);
if (net == nullptr) { if (net == nullptr) {
if (enable_ipv6 && enable_ipv4_fallback) { if (enable_ipv6 && enable_ipv4_fallback) {
log_write(LOG_LEVEL_WARNING, "Couldn't initialize IPv6 networking. Falling back to using IPv4.\n"); log_write(LOG_LEVEL_WARNING, "Couldn't initialize IPv6 networking. Falling back to using IPv4.\n");
enable_ipv6 = 0; enable_ipv6 = 0;
ip_init(&ip, enable_ipv6); ip_init(&ip, enable_ipv6);
net = new_networking_ex(logger, ns, &ip, start_port, end_port, nullptr); net = new_networking_ex(logger, mem, ns, &ip, start_port, end_port, nullptr);
if (net == nullptr) { if (net == nullptr) {
log_write(LOG_LEVEL_ERROR, "Couldn't fallback to IPv4. Exiting.\n"); log_write(LOG_LEVEL_ERROR, "Couldn't fallback to IPv4. Exiting.\n");
@ -308,7 +299,7 @@ int main(int argc, char *argv[])
} }
} }
Mono_Time *const mono_time = mono_time_new(nullptr, nullptr); Mono_Time *const mono_time = mono_time_new(mem, nullptr, nullptr);
if (mono_time == nullptr) { if (mono_time == nullptr) {
log_write(LOG_LEVEL_ERROR, "Couldn't initialize monotonic timer. Exiting.\n"); log_write(LOG_LEVEL_ERROR, "Couldn't initialize monotonic timer. Exiting.\n");
@ -322,12 +313,11 @@ int main(int argc, char *argv[])
mono_time_update(mono_time); mono_time_update(mono_time);
const Random *rng = system_random(); DHT *const dht = new_dht(logger, mem, rng, ns, mono_time, net, true, enable_lan_discovery);
DHT *const dht = new_dht(logger, rng, ns, mono_time, net, true, enable_lan_discovery);
if (dht == nullptr) { if (dht == nullptr) {
log_write(LOG_LEVEL_ERROR, "Couldn't initialize Tox DHT instance. Exiting.\n"); log_write(LOG_LEVEL_ERROR, "Couldn't initialize Tox DHT instance. Exiting.\n");
mono_time_free(mono_time); mono_time_free(mem, mono_time);
kill_networking(net); kill_networking(net);
logger_kill(logger); logger_kill(logger);
free(motd); free(motd);
@ -341,7 +331,7 @@ int main(int argc, char *argv[])
if (forwarding == nullptr) { if (forwarding == nullptr) {
log_write(LOG_LEVEL_ERROR, "Couldn't initialize forwarding. Exiting.\n"); log_write(LOG_LEVEL_ERROR, "Couldn't initialize forwarding. Exiting.\n");
kill_dht(dht); kill_dht(dht);
mono_time_free(mono_time); mono_time_free(mem, mono_time);
kill_networking(net); kill_networking(net);
logger_kill(logger); logger_kill(logger);
free(motd); free(motd);
@ -350,13 +340,13 @@ int main(int argc, char *argv[])
return 1; return 1;
} }
Announcements *announce = new_announcements(logger, rng, mono_time, forwarding); Announcements *announce = new_announcements(logger, mem, rng, mono_time, forwarding);
if (announce == nullptr) { if (announce == nullptr) {
log_write(LOG_LEVEL_ERROR, "Couldn't initialize DHT announcements. Exiting.\n"); log_write(LOG_LEVEL_ERROR, "Couldn't initialize DHT announcements. Exiting.\n");
kill_forwarding(forwarding); kill_forwarding(forwarding);
kill_dht(dht); kill_dht(dht);
mono_time_free(mono_time); mono_time_free(mem, mono_time);
kill_networking(net); kill_networking(net);
logger_kill(logger); logger_kill(logger);
free(motd); free(motd);
@ -372,7 +362,7 @@ int main(int argc, char *argv[])
kill_announcements(announce); kill_announcements(announce);
kill_forwarding(forwarding); kill_forwarding(forwarding);
kill_dht(dht); kill_dht(dht);
mono_time_free(mono_time); mono_time_free(mem, mono_time);
kill_networking(net); kill_networking(net);
logger_kill(logger); logger_kill(logger);
free(motd); free(motd);
@ -381,14 +371,14 @@ int main(int argc, char *argv[])
return 1; return 1;
} }
Onion *onion = new_onion(logger, mono_time, rng, dht); Onion *onion = new_onion(logger, mem, mono_time, rng, dht);
if (!onion) { if (!onion) {
log_write(LOG_LEVEL_ERROR, "Couldn't initialize Tox Onion. Exiting.\n"); log_write(LOG_LEVEL_ERROR, "Couldn't initialize Tox Onion. Exiting.\n");
kill_announcements(announce); kill_announcements(announce);
kill_forwarding(forwarding); kill_forwarding(forwarding);
kill_dht(dht); kill_dht(dht);
mono_time_free(mono_time); mono_time_free(mem, mono_time);
kill_networking(net); kill_networking(net);
logger_kill(logger); logger_kill(logger);
free(motd); free(motd);
@ -397,7 +387,7 @@ int main(int argc, char *argv[])
return 1; return 1;
} }
Onion_Announce *onion_a = new_onion_announce(logger, rng, mono_time, dht); Onion_Announce *onion_a = new_onion_announce(logger, mem, rng, mono_time, dht);
if (!onion_a) { if (!onion_a) {
log_write(LOG_LEVEL_ERROR, "Couldn't initialize Tox Onion Announce. Exiting.\n"); log_write(LOG_LEVEL_ERROR, "Couldn't initialize Tox Onion Announce. Exiting.\n");
@ -406,7 +396,7 @@ int main(int argc, char *argv[])
kill_announcements(announce); kill_announcements(announce);
kill_forwarding(forwarding); kill_forwarding(forwarding);
kill_dht(dht); kill_dht(dht);
mono_time_free(mono_time); mono_time_free(mem, mono_time);
kill_networking(net); kill_networking(net);
logger_kill(logger); logger_kill(logger);
free(motd); free(motd);
@ -429,7 +419,7 @@ int main(int argc, char *argv[])
kill_announcements(announce); kill_announcements(announce);
kill_forwarding(forwarding); kill_forwarding(forwarding);
kill_dht(dht); kill_dht(dht);
mono_time_free(mono_time); mono_time_free(mem, mono_time);
kill_networking(net); kill_networking(net);
logger_kill(logger); logger_kill(logger);
free(motd); free(motd);
@ -450,7 +440,7 @@ int main(int argc, char *argv[])
kill_announcements(announce); kill_announcements(announce);
kill_forwarding(forwarding); kill_forwarding(forwarding);
kill_dht(dht); kill_dht(dht);
mono_time_free(mono_time); mono_time_free(mem, mono_time);
kill_networking(net); kill_networking(net);
logger_kill(logger); logger_kill(logger);
free(tcp_relay_ports); free(tcp_relay_ports);
@ -469,14 +459,15 @@ int main(int argc, char *argv[])
kill_forwarding(forwarding); kill_forwarding(forwarding);
kill_onion(onion); kill_onion(onion);
kill_dht(dht); kill_dht(dht);
mono_time_free(mono_time); mono_time_free(mem, mono_time);
kill_networking(net); kill_networking(net);
logger_kill(logger); logger_kill(logger);
free(tcp_relay_ports); free(tcp_relay_ports);
return 1; return 1;
} }
tcp_server = new_TCP_server(logger, rng, ns, enable_ipv6, tcp_relay_port_count, tcp_relay_ports, tcp_server = new_tcp_server(logger, mem, rng, ns, enable_ipv6,
tcp_relay_port_count, tcp_relay_ports,
dht_get_self_secret_key(dht), onion, forwarding); dht_get_self_secret_key(dht), onion, forwarding);
free(tcp_relay_ports); free(tcp_relay_ports);
@ -515,7 +506,7 @@ int main(int argc, char *argv[])
kill_announcements(announce); kill_announcements(announce);
kill_forwarding(forwarding); kill_forwarding(forwarding);
kill_dht(dht); kill_dht(dht);
mono_time_free(mono_time); mono_time_free(mem, mono_time);
kill_networking(net); kill_networking(net);
logger_kill(logger); logger_kill(logger);
return 1; return 1;
@ -526,14 +517,14 @@ int main(int argc, char *argv[])
log_write(LOG_LEVEL_INFO, "List of bootstrap nodes read successfully.\n"); log_write(LOG_LEVEL_INFO, "List of bootstrap nodes read successfully.\n");
} else { } else {
log_write(LOG_LEVEL_ERROR, "Couldn't read list of bootstrap nodes in %s. Exiting.\n", cfg_file_path); log_write(LOG_LEVEL_ERROR, "Couldn't read list of bootstrap nodes in %s. Exiting.\n", cfg_file_path);
kill_TCP_server(tcp_server); kill_tcp_server(tcp_server);
kill_onion_announce(onion_a); kill_onion_announce(onion_a);
kill_gca(group_announce); kill_gca(group_announce);
kill_onion(onion); kill_onion(onion);
kill_announcements(announce); kill_announcements(announce);
kill_forwarding(forwarding); kill_forwarding(forwarding);
kill_dht(dht); kill_dht(dht);
mono_time_free(mono_time); mono_time_free(mem, mono_time);
kill_networking(net); kill_networking(net);
logger_kill(logger); logger_kill(logger);
return 1; return 1;
@ -541,7 +532,7 @@ int main(int argc, char *argv[])
print_public_key(dht_get_self_public_key(dht)); print_public_key(dht_get_self_public_key(dht));
uint64_t last_LANdiscovery = 0; uint64_t last_lan_discovery = 0;
const uint16_t net_htons_port = net_htons(start_port); const uint16_t net_htons_port = net_htons(start_port);
int waiting_for_dht_connection = 1; int waiting_for_dht_connection = 1;
@ -576,13 +567,13 @@ int main(int argc, char *argv[])
do_dht(dht); do_dht(dht);
if (enable_lan_discovery && mono_time_is_timeout(mono_time, last_LANdiscovery, LAN_DISCOVERY_INTERVAL)) { if (enable_lan_discovery && mono_time_is_timeout(mono_time, last_lan_discovery, LAN_DISCOVERY_INTERVAL)) {
lan_discovery_send(dht_get_net(dht), broadcast, dht_get_self_public_key(dht), net_htons_port); lan_discovery_send(dht_get_net(dht), broadcast, dht_get_self_public_key(dht), net_htons_port);
last_LANdiscovery = mono_time_get(mono_time); last_lan_discovery = mono_time_get(mono_time);
} }
if (enable_tcp_relay) { if (enable_tcp_relay) {
do_TCP_server(tcp_server, mono_time); do_tcp_server(tcp_server, mono_time);
} }
networking_poll(dht_get_net(dht), nullptr); networking_poll(dht_get_net(dht), nullptr);
@ -609,14 +600,14 @@ int main(int argc, char *argv[])
} }
lan_discovery_kill(broadcast); lan_discovery_kill(broadcast);
kill_TCP_server(tcp_server); kill_tcp_server(tcp_server);
kill_onion_announce(onion_a); kill_onion_announce(onion_a);
kill_gca(group_announce); kill_gca(group_announce);
kill_onion(onion); kill_onion(onion);
kill_announcements(announce); kill_announcements(announce);
kill_forwarding(forwarding); kill_forwarding(forwarding);
kill_dht(dht); kill_dht(dht);
mono_time_free(mono_time); mono_time_free(mem, mono_time);
kill_networking(net); kill_networking(net);
logger_kill(logger); logger_kill(logger);

View File

@ -1,5 +1,5 @@
FROM toxchat/haskell:hs-cimple AS cimple FROM toxchat/haskell:hs-cimple AS cimple
FROM ubuntu:20.04 FROM ubuntu:22.04
COPY --from=cimple /bin/cimplefmt /bin/ COPY --from=cimple /bin/cimplefmt /bin/
WORKDIR /work WORKDIR /work

View File

@ -1,5 +1,5 @@
FROM toxchat/c-toxcore:sources AS src FROM toxchat/c-toxcore:sources AS src
FROM ubuntu:20.04 AS build FROM ubuntu:22.04 AS build
RUN apt-get update && \ RUN apt-get update && \
DEBIAN_FRONTEND="noninteractive" apt-get install -y --no-install-recommends \ DEBIAN_FRONTEND="noninteractive" apt-get install -y --no-install-recommends \
@ -31,8 +31,8 @@ SHELL ["/bin/bash", "-c"]
WORKDIR /work WORKDIR /work
COPY --from=src /src/ /work/ COPY --from=src /src/ /work/
RUN source .github/scripts/flags-coverage.sh \ RUN source .github/scripts/flags-coverage.sh \
&& go get github.com/things-go/go-socks5 \ && go version \
&& go build other/proxy/proxy_server.go \ && (cd other/proxy && go get github.com/things-go/go-socks5 && go build proxy_server.go) \
&& cmake -B_build -H. -GNinja \ && cmake -B_build -H. -GNinja \
-DCMAKE_C_FLAGS="$C_FLAGS" \ -DCMAKE_C_FLAGS="$C_FLAGS" \
-DCMAKE_CXX_FLAGS="$CXX_FLAGS" \ -DCMAKE_CXX_FLAGS="$CXX_FLAGS" \
@ -46,6 +46,7 @@ RUN source .github/scripts/flags-coverage.sh \
-DAUTOTEST=ON \ -DAUTOTEST=ON \
-DPROXY_TEST=ON \ -DPROXY_TEST=ON \
-DUSE_IPV6=OFF \ -DUSE_IPV6=OFF \
-DTEST_TIMEOUT_SECONDS=30 \
&& cmake --build _build --parallel 8 --target install && cmake --build _build --parallel 8 --target install
WORKDIR /work/_build WORKDIR /work/_build

View File

@ -1,5 +1,5 @@
FROM toxchat/haskell:hs-tokstyle AS tokstyle FROM toxchat/haskell:hs-tokstyle AS tokstyle
FROM ubuntu:20.04 FROM ubuntu:22.04
RUN apt-get update && apt-get install --no-install-recommends -y \ RUN apt-get update && apt-get install --no-install-recommends -y \
ca-certificates \ ca-certificates \

View File

@ -1,5 +1,5 @@
module github.com/TokTok/c-toxcore/other/proxy module github.com/TokTok/c-toxcore/other/proxy
go 1.16 go 1.18
require github.com/things-go/go-socks5 v0.0.2 require github.com/things-go/go-socks5 v0.0.3

View File

@ -4,6 +4,8 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/things-go/go-socks5 v0.0.2 h1:dFi5iZ/LqgHRTQ6n3XlipTLDWHAQsejvJ300bH2VFWo= github.com/things-go/go-socks5 v0.0.2 h1:dFi5iZ/LqgHRTQ6n3XlipTLDWHAQsejvJ300bH2VFWo=
github.com/things-go/go-socks5 v0.0.2/go.mod h1:dhnDTBbIg31cbJdROP4/Zz6Iw7JPEpiMvOl2LdHSSjE= github.com/things-go/go-socks5 v0.0.2/go.mod h1:dhnDTBbIg31cbJdROP4/Zz6Iw7JPEpiMvOl2LdHSSjE=
github.com/things-go/go-socks5 v0.0.3 h1:QtlIhkwDuLNCwW3wnt2uTjn1mQzpyjnwct2xdPuqroI=
github.com/things-go/go-socks5 v0.0.3/go.mod h1:f8Zx+n8kfzyT90hXM767cP6sysAud93+t9rV90IgMcg=
golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

View File

@ -15,9 +15,7 @@ sh_test(
args = ["$(locations %s)" % f for f in CIMPLE_FILES] + [ args = ["$(locations %s)" % f for f in CIMPLE_FILES] + [
"-Wno-boolean-return", "-Wno-boolean-return",
"-Wno-callback-names", "-Wno-callback-names",
"-Wno-callgraph",
"-Wno-enum-names", "-Wno-enum-names",
"-Wno-type-check",
"+RTS", "+RTS",
"-N3", "-N3",
"-RTS", "-RTS",

View File

@ -92,7 +92,8 @@ int main(int argc, char *argv[])
exit(0); exit(0);
} }
Mono_Time *const mono_time = mono_time_new(nullptr, nullptr); const Memory *mem = system_memory();
Mono_Time *const mono_time = mono_time_new(mem, nullptr, nullptr);
if (mono_time == nullptr) { if (mono_time == nullptr) {
fputs("Failed to allocate monotonic timer datastructure\n", stderr); fputs("Failed to allocate monotonic timer datastructure\n", stderr);
@ -102,7 +103,7 @@ int main(int argc, char *argv[])
Messenger_Options options = {0}; Messenger_Options options = {0};
options.ipv6enabled = ipv6enabled; options.ipv6enabled = ipv6enabled;
Messenger_Error err; Messenger_Error err;
m = new_messenger(mono_time, system_random(), system_network(), &options, &err); m = new_messenger(mono_time, mem, system_random(), system_network(), &options, &err);
if (!m) { if (!m) {
fprintf(stderr, "Failed to allocate messenger datastructure: %d\n", err); fprintf(stderr, "Failed to allocate messenger datastructure: %d\n", err);

View File

@ -28,6 +28,7 @@ cc_library(
cc_fuzz_test( cc_fuzz_test(
name = "bootstrap_fuzz_test", name = "bootstrap_fuzz_test",
#size = "small",
srcs = ["bootstrap_harness.cc"], srcs = ["bootstrap_harness.cc"],
copts = ["-UNDEBUG"], copts = ["-UNDEBUG"],
corpus = ["//tools/toktok-fuzzer/corpus:bootstrap_fuzzer"], corpus = ["//tools/toktok-fuzzer/corpus:bootstrap_fuzzer"],
@ -42,6 +43,7 @@ cc_fuzz_test(
cc_fuzz_test( cc_fuzz_test(
name = "e2e_fuzz_test", name = "e2e_fuzz_test",
#size = "small",
srcs = ["e2e_fuzz_test.cc"], srcs = ["e2e_fuzz_test.cc"],
copts = ["-UNDEBUG"], copts = ["-UNDEBUG"],
corpus = ["//tools/toktok-fuzzer/corpus:e2e_fuzz_test"], corpus = ["//tools/toktok-fuzzer/corpus:e2e_fuzz_test"],
@ -57,6 +59,7 @@ cc_fuzz_test(
cc_fuzz_test( cc_fuzz_test(
name = "toxsave_fuzz_test", name = "toxsave_fuzz_test",
#size = "small",
srcs = ["toxsave_harness.cc"], srcs = ["toxsave_harness.cc"],
copts = ["-UNDEBUG"], copts = ["-UNDEBUG"],
corpus = ["//tools/toktok-fuzzer/corpus:toxsave_fuzzer"], corpus = ["//tools/toktok-fuzzer/corpus:toxsave_fuzzer"],
@ -89,6 +92,7 @@ fuzzing_binary(
cc_fuzz_test( cc_fuzz_test(
name = "protodump_reduce", name = "protodump_reduce",
#size = "small",
srcs = ["protodump_reduce.cc"], srcs = ["protodump_reduce.cc"],
copts = ["-UNDEBUG"], copts = ["-UNDEBUG"],
deps = [ deps = [

View File

@ -107,6 +107,9 @@ void setup_callbacks(Tox_Dispatch *dispatch)
void TestBootstrap(Fuzz_Data &input) void TestBootstrap(Fuzz_Data &input)
{ {
// Null system for regularly working memory allocations needed in
// tox_events_equal.
Null_System null_sys;
Fuzz_System sys(input); Fuzz_System sys(input);
Ptr<Tox_Options> opts(tox_options_new(nullptr), tox_options_free); Ptr<Tox_Options> opts(tox_options_new(nullptr), tox_options_free);
@ -154,11 +157,9 @@ void TestBootstrap(Fuzz_Data &input)
uint8_t pub_key[TOX_PUBLIC_KEY_SIZE] = {0}; uint8_t pub_key[TOX_PUBLIC_KEY_SIZE] = {0};
const bool udp_success = tox_bootstrap(tox, "127.0.0.2", 33446, pub_key, nullptr); // These may fail, but that's ok. We ignore their return values.
assert(udp_success); tox_bootstrap(tox, "127.0.0.2", 33446, pub_key, nullptr);
tox_add_tcp_relay(tox, "127.0.0.2", 33446, pub_key, nullptr);
const bool tcp_success = tox_add_tcp_relay(tox, "127.0.0.2", 33446, pub_key, nullptr);
assert(tcp_success);
tox_events_init(tox); tox_events_init(tox);
@ -169,7 +170,7 @@ void TestBootstrap(Fuzz_Data &input)
while (input.size > 0) { while (input.size > 0) {
Tox_Err_Events_Iterate error_iterate; Tox_Err_Events_Iterate error_iterate;
Tox_Events *events = tox_events_iterate(tox, true, &error_iterate); Tox_Events *events = tox_events_iterate(tox, true, &error_iterate);
assert(tox_events_equal(events, events)); assert(tox_events_equal(null_sys.sys.get(), events, events));
tox_dispatch_invoke(dispatch, events, tox, nullptr); tox_dispatch_invoke(dispatch, events, tox, nullptr);
tox_events_free(events); tox_events_free(events);
// Move the clock forward a decent amount so all the time-based checks // Move the clock forward a decent amount so all the time-based checks

View File

@ -24,7 +24,7 @@ void setup_callbacks(Tox_Dispatch *dispatch)
}); });
tox_events_callback_conference_connected( tox_events_callback_conference_connected(
dispatch, [](Tox *tox, const Tox_Event_Conference_Connected *event, void *user_data) { dispatch, [](Tox *tox, const Tox_Event_Conference_Connected *event, void *user_data) {
assert(event == nullptr); assert(event != nullptr);
}); });
tox_events_callback_conference_invite( tox_events_callback_conference_invite(
dispatch, [](Tox *tox, const Tox_Event_Conference_Invite *event, void *user_data) { dispatch, [](Tox *tox, const Tox_Event_Conference_Invite *event, void *user_data) {
@ -35,19 +35,19 @@ void setup_callbacks(Tox_Dispatch *dispatch)
}); });
tox_events_callback_conference_message( tox_events_callback_conference_message(
dispatch, [](Tox *tox, const Tox_Event_Conference_Message *event, void *user_data) { dispatch, [](Tox *tox, const Tox_Event_Conference_Message *event, void *user_data) {
assert(event == nullptr); assert(event != nullptr);
}); });
tox_events_callback_conference_peer_list_changed(dispatch, tox_events_callback_conference_peer_list_changed(dispatch,
[](Tox *tox, const Tox_Event_Conference_Peer_List_Changed *event, void *user_data) { [](Tox *tox, const Tox_Event_Conference_Peer_List_Changed *event, void *user_data) {
assert(event == nullptr); assert(event != nullptr);
}); });
tox_events_callback_conference_peer_name( tox_events_callback_conference_peer_name(
dispatch, [](Tox *tox, const Tox_Event_Conference_Peer_Name *event, void *user_data) { dispatch, [](Tox *tox, const Tox_Event_Conference_Peer_Name *event, void *user_data) {
assert(event == nullptr); assert(event != nullptr);
}); });
tox_events_callback_conference_title( tox_events_callback_conference_title(
dispatch, [](Tox *tox, const Tox_Event_Conference_Title *event, void *user_data) { dispatch, [](Tox *tox, const Tox_Event_Conference_Title *event, void *user_data) {
assert(event == nullptr); assert(event != nullptr);
}); });
tox_events_callback_file_chunk_request( tox_events_callback_file_chunk_request(
dispatch, [](Tox *tox, const Tox_Event_File_Chunk_Request *event, void *user_data) { dispatch, [](Tox *tox, const Tox_Event_File_Chunk_Request *event, void *user_data) {
@ -61,11 +61,11 @@ void setup_callbacks(Tox_Dispatch *dispatch)
}); });
tox_events_callback_file_recv_chunk( tox_events_callback_file_recv_chunk(
dispatch, [](Tox *tox, const Tox_Event_File_Recv_Chunk *event, void *user_data) { dispatch, [](Tox *tox, const Tox_Event_File_Recv_Chunk *event, void *user_data) {
assert(event == nullptr); assert(event != nullptr);
}); });
tox_events_callback_file_recv_control( tox_events_callback_file_recv_control(
dispatch, [](Tox *tox, const Tox_Event_File_Recv_Control *event, void *user_data) { dispatch, [](Tox *tox, const Tox_Event_File_Recv_Control *event, void *user_data) {
assert(event == nullptr); assert(event != nullptr);
}); });
tox_events_callback_friend_connection_status( tox_events_callback_friend_connection_status(
dispatch, [](Tox *tox, const Tox_Event_Friend_Connection_Status *event, void *user_data) { dispatch, [](Tox *tox, const Tox_Event_Friend_Connection_Status *event, void *user_data) {
@ -134,6 +134,8 @@ void setup_callbacks(Tox_Dispatch *dispatch)
void TestEndToEnd(Fuzz_Data &input) void TestEndToEnd(Fuzz_Data &input)
{ {
Fuzz_System sys(input); Fuzz_System sys(input);
// Used for places where we want all allocations to succeed.
Null_System null_sys;
Ptr<Tox_Options> opts(tox_options_new(nullptr), tox_options_free); Ptr<Tox_Options> opts(tox_options_new(nullptr), tox_options_free);
assert(opts != nullptr); assert(opts != nullptr);
@ -170,7 +172,7 @@ void TestEndToEnd(Fuzz_Data &input)
while (input.size > 0) { while (input.size > 0) {
Tox_Err_Events_Iterate error_iterate; Tox_Err_Events_Iterate error_iterate;
Tox_Events *events = tox_events_iterate(tox, true, &error_iterate); Tox_Events *events = tox_events_iterate(tox, true, &error_iterate);
assert(tox_events_equal(events, events)); assert(tox_events_equal(null_sys.sys.get(), events, events));
tox_dispatch_invoke(dispatch, events, tox, nullptr); tox_dispatch_invoke(dispatch, events, tox, nullptr);
tox_events_free(events); tox_events_free(events);
// Move the clock forward a decent amount so all the time-based checks // Move the clock forward a decent amount so all the time-based checks

View File

@ -62,6 +62,33 @@ static int recv_common(Fuzz_Data &input, uint8_t *buf, size_t buf_len)
return res; return res;
} }
template <typename F>
static void *alloc_common(Fuzz_Data &data, F func)
{
CONSUME1_OR_RETURN_VAL(const uint8_t want_alloc, data, func());
if (!want_alloc) {
return nullptr;
}
return func();
}
static constexpr Memory_Funcs fuzz_memory_funcs = {
/* .malloc = */
![](Fuzz_System *self, uint32_t size) {
return alloc_common(self->data, [=]() { return std::malloc(size); });
},
/* .calloc = */
![](Fuzz_System *self, uint32_t nmemb, uint32_t size) {
return alloc_common(self->data, [=]() { return std::calloc(nmemb, size); });
},
/* .realloc = */
![](Fuzz_System *self, void *ptr, uint32_t size) {
return alloc_common(self->data, [=]() { return std::realloc(ptr, size); });
},
/* .free = */
![](Fuzz_System *self, void *ptr) { std::free(ptr); },
};
static constexpr Network_Funcs fuzz_network_funcs = { static constexpr Network_Funcs fuzz_network_funcs = {
/* .close = */ ![](Fuzz_System *self, int sock) { return 0; }, /* .close = */ ![](Fuzz_System *self, int sock) { return 0; },
/* .accept = */ ![](Fuzz_System *self, int sock) { return 1337; }, /* .accept = */ ![](Fuzz_System *self, int sock) { return 1337; },
@ -149,6 +176,7 @@ static constexpr Random_Funcs fuzz_random_funcs = {
Fuzz_System::Fuzz_System(Fuzz_Data &input) Fuzz_System::Fuzz_System(Fuzz_Data &input)
: System{ : System{
std::make_unique<Tox_System>(), std::make_unique<Tox_System>(),
std::make_unique<Memory>(Memory{&fuzz_memory_funcs, this}),
std::make_unique<Network>(Network{&fuzz_network_funcs, this}), std::make_unique<Network>(Network{&fuzz_network_funcs, this}),
std::make_unique<Random>(Random{&fuzz_random_funcs, this}), std::make_unique<Random>(Random{&fuzz_random_funcs, this}),
} }
@ -156,10 +184,22 @@ Fuzz_System::Fuzz_System(Fuzz_Data &input)
{ {
sys->mono_time_callback = ![](Fuzz_System *self) { return self->clock; }; sys->mono_time_callback = ![](Fuzz_System *self) { return self->clock; };
sys->mono_time_user_data = this; sys->mono_time_user_data = this;
sys->mem = mem.get();
sys->ns = ns.get(); sys->ns = ns.get();
sys->rng = rng.get(); sys->rng = rng.get();
} }
static constexpr Memory_Funcs null_memory_funcs = {
/* .malloc = */
![](Null_System *self, uint32_t size) { return std::malloc(size); },
/* .calloc = */
![](Null_System *self, uint32_t nmemb, uint32_t size) { return std::calloc(nmemb, size); },
/* .realloc = */
![](Null_System *self, void *ptr, uint32_t size) { return std::realloc(ptr, size); },
/* .free = */
![](Null_System *self, void *ptr) { std::free(ptr); },
};
static constexpr Network_Funcs null_network_funcs = { static constexpr Network_Funcs null_network_funcs = {
/* .close = */ ![](Null_System *self, int sock) { return 0; }, /* .close = */ ![](Null_System *self, int sock) { return 0; },
/* .accept = */ ![](Null_System *self, int sock) { return 1337; }, /* .accept = */ ![](Null_System *self, int sock) { return 1337; },
@ -224,12 +264,14 @@ static constexpr Random_Funcs null_random_funcs = {
Null_System::Null_System() Null_System::Null_System()
: System{ : System{
std::make_unique<Tox_System>(), std::make_unique<Tox_System>(),
std::make_unique<Memory>(Memory{&null_memory_funcs, this}),
std::make_unique<Network>(Network{&null_network_funcs, this}), std::make_unique<Network>(Network{&null_network_funcs, this}),
std::make_unique<Random>(Random{&null_random_funcs, this}), std::make_unique<Random>(Random{&null_random_funcs, this}),
} }
{ {
sys->mono_time_callback = ![](Fuzz_System *self) { return self->clock; }; sys->mono_time_callback = ![](Fuzz_System *self) { return self->clock; };
sys->mono_time_user_data = this; sys->mono_time_user_data = this;
sys->mem = mem.get();
sys->ns = ns.get(); sys->ns = ns.get();
sys->rng = rng.get(); sys->rng = rng.get();
} }
@ -244,6 +286,8 @@ static uint16_t get_port(const Network_Addr *addr)
} }
} }
static constexpr Memory_Funcs record_memory_funcs = null_memory_funcs;
static constexpr Network_Funcs record_network_funcs = { static constexpr Network_Funcs record_network_funcs = {
/* .close = */ ![](Record_System *self, int sock) { return 0; }, /* .close = */ ![](Record_System *self, int sock) { return 0; },
/* .accept = */ ![](Record_System *self, int sock) { return 2; }, /* .accept = */ ![](Record_System *self, int sock) { return 2; },
@ -348,6 +392,7 @@ static constexpr Random_Funcs record_random_funcs = {
Record_System::Record_System(Global &global, uint64_t seed, const char *name) Record_System::Record_System(Global &global, uint64_t seed, const char *name)
: System{ : System{
std::make_unique<Tox_System>(), std::make_unique<Tox_System>(),
std::make_unique<Memory>(Memory{&record_memory_funcs, this}),
std::make_unique<Network>(Network{&record_network_funcs, this}), std::make_unique<Network>(Network{&record_network_funcs, this}),
std::make_unique<Random>(Random{&record_random_funcs, this}), std::make_unique<Random>(Random{&record_random_funcs, this}),
} }
@ -357,6 +402,7 @@ Record_System::Record_System(Global &global, uint64_t seed, const char *name)
{ {
sys->mono_time_callback = ![](Fuzz_System *self) { return self->clock; }; sys->mono_time_callback = ![](Fuzz_System *self) { return self->clock; };
sys->mono_time_user_data = this; sys->mono_time_user_data = this;
sys->mem = mem.get();
sys->ns = ns.get(); sys->ns = ns.get();
sys->rng = rng.get(); sys->rng = rng.get();
} }

View File

@ -59,6 +59,23 @@ struct Fuzz_Data {
} \ } \
DECL = INPUT.consume1() DECL = INPUT.consume1()
/** @brief Consumes 1 byte of the fuzzer input or returns a value if no data
* available.
*
* This advances the fuzzer input data by 1 byte and consumes that byte in the
* declaration.
*
* @example
* @code
* CONSUME1_OR_RETURN_VAL(const uint8_t one_byte, input, nullptr);
* @endcode
*/
#define CONSUME1_OR_RETURN_VAL(DECL, INPUT, VAL) \
if (INPUT.size < 1) { \
return VAL; \
} \
DECL = INPUT.consume1()
/** @brief Consumes SIZE bytes of the fuzzer input or returns if not enough data available. /** @brief Consumes SIZE bytes of the fuzzer input or returns if not enough data available.
* *
* This advances the fuzzer input data by SIZE byte and consumes those bytes in * This advances the fuzzer input data by SIZE byte and consumes those bytes in
@ -100,11 +117,13 @@ void fuzz_select_target(const uint8_t *data, std::size_t size, Args &&... args)
return fuzz_select_target(selector, input, std::forward<Args>(args)...); return fuzz_select_target(selector, input, std::forward<Args>(args)...);
} }
struct Memory;
struct Network; struct Network;
struct Random; struct Random;
struct System { struct System {
std::unique_ptr<Tox_System> sys; std::unique_ptr<Tox_System> sys;
std::unique_ptr<Memory> mem;
std::unique_ptr<Network> ns; std::unique_ptr<Network> ns;
std::unique_ptr<Random> rng; std::unique_ptr<Random> rng;

View File

@ -62,13 +62,14 @@ struct with<IP_Port> {
/** @brief Construct a Networking_Core object using the Network vtable passed. /** @brief Construct a Networking_Core object using the Network vtable passed.
* *
* Use `with<Logger>{} >> with<Networking_Core>{input, ns} >> ...` to construct * Use `with<Logger>{} >> with<Networking_Core>{input, ns, mem} >> ...` to construct
* a logger and pass it to the Networking_Core constructor function. * a logger and pass it to the Networking_Core constructor function.
*/ */
template <> template <>
struct with<Networking_Core> { struct with<Networking_Core> {
Fuzz_Data &input_; Fuzz_Data &input_;
const Network *ns_; const Network *ns_;
const Memory *mem_;
Ptr<Logger> logger_{nullptr, logger_kill}; Ptr<Logger> logger_{nullptr, logger_kill};
friend with operator>>(with<Logger> f, with self) friend with operator>>(with<Logger> f, with self)
@ -82,7 +83,7 @@ struct with<Networking_Core> {
{ {
with<IP_Port>{input_} >> [&f, this](const IP_Port &ipp) { with<IP_Port>{input_} >> [&f, this](const IP_Port &ipp) {
Ptr<Networking_Core> net( Ptr<Networking_Core> net(
new_networking_ex(logger_.get(), ns_, &ipp.ip, ipp.port, ipp.port + 100, nullptr), new_networking_ex(logger_.get(), mem_, ns_, &ipp.ip, ipp.port, ipp.port + 100, nullptr),
kill_networking); kill_networking);
if (net == nullptr) { if (net == nullptr) {
return; return;

View File

@ -20,6 +20,7 @@
* bazel build //c-toxcore/testing/fuzzing:protodump_bin && \ * bazel build //c-toxcore/testing/fuzzing:protodump_bin && \
* bazel-bin/c-toxcore/testing/fuzzing/protodump_bin * bazel-bin/c-toxcore/testing/fuzzing/protodump_bin
*/ */
#include <array>
#include <cassert> #include <cassert>
#include <cstdio> #include <cstdio>
#include <cstring> #include <cstring>
@ -243,12 +244,12 @@ void RecordBootstrap()
Tox_Events *events; Tox_Events *events;
events = tox_events_iterate(tox1, true, &error_iterate); events = tox_events_iterate(tox1, true, &error_iterate);
assert(tox_events_equal(events, events)); assert(tox_events_equal(sys1.sys.get(), events, events));
tox_dispatch_invoke(dispatch, events, tox1, &done1); tox_dispatch_invoke(dispatch, events, tox1, &done1);
tox_events_free(events); tox_events_free(events);
events = tox_events_iterate(tox2, true, &error_iterate); events = tox_events_iterate(tox2, true, &error_iterate);
assert(tox_events_equal(events, events)); assert(tox_events_equal(sys2.sys.get(), events, events));
tox_dispatch_invoke(dispatch, events, tox2, &done2); tox_dispatch_invoke(dispatch, events, tox2, &done2);
tox_events_free(events); tox_events_free(events);

View File

@ -172,7 +172,7 @@ void TestEndToEnd(Fuzz_Data &input)
while (input.size > 0) { while (input.size > 0) {
Tox_Err_Events_Iterate error_iterate; Tox_Err_Events_Iterate error_iterate;
Tox_Events *events = tox_events_iterate(tox, true, &error_iterate); Tox_Events *events = tox_events_iterate(tox, true, &error_iterate);
assert(tox_events_equal(events, events)); assert(tox_events_equal(tox_get_system(tox), events, events));
tox_dispatch_invoke(dispatch, events, tox, nullptr); tox_dispatch_invoke(dispatch, events, tox, nullptr);
tox_events_free(events); tox_events_free(events);
sys.clock += std::max(System::MIN_ITERATION_INTERVAL, random_u08(sys.rng.get())); sys.clock += std::max(System::MIN_ITERATION_INTERVAL, random_u08(sys.rng.get()));

View File

@ -54,6 +54,7 @@ cc_library(
"//c-toxcore/toxcore:ccompat", "//c-toxcore/toxcore:ccompat",
"//c-toxcore/toxcore:logger", "//c-toxcore/toxcore:logger",
"//c-toxcore/toxcore:mono_time", "//c-toxcore/toxcore:mono_time",
"//c-toxcore/toxcore:tox",
"//c-toxcore/toxcore:util", "//c-toxcore/toxcore:util",
], ],
) )
@ -68,6 +69,7 @@ cc_library(
"//c-toxcore/toxcore:ccompat", "//c-toxcore/toxcore:ccompat",
"//c-toxcore/toxcore:logger", "//c-toxcore/toxcore:logger",
"//c-toxcore/toxcore:mono_time", "//c-toxcore/toxcore:mono_time",
"//c-toxcore/toxcore:tox",
"//c-toxcore/toxcore:util", "//c-toxcore/toxcore:util",
], ],
) )
@ -94,6 +96,7 @@ cc_library(
"//c-toxcore/toxcore:ccompat", "//c-toxcore/toxcore:ccompat",
"//c-toxcore/toxcore:logger", "//c-toxcore/toxcore:logger",
"//c-toxcore/toxcore:mono_time", "//c-toxcore/toxcore:mono_time",
"//c-toxcore/toxcore:util",
"@opus", "@opus",
], ],
) )
@ -113,6 +116,7 @@ cc_library(
":public_api", ":public_api",
":ring_buffer", ":ring_buffer",
":rtp", ":rtp",
"//c-toxcore/toxcore:Messenger",
"//c-toxcore/toxcore:ccompat", "//c-toxcore/toxcore:ccompat",
"//c-toxcore/toxcore:logger", "//c-toxcore/toxcore:logger",
"//c-toxcore/toxcore:mono_time", "//c-toxcore/toxcore:mono_time",
@ -129,6 +133,7 @@ cc_library(
deps = [ deps = [
"//c-toxcore/toxcore", "//c-toxcore/toxcore",
"//c-toxcore/toxcore:ccompat", "//c-toxcore/toxcore:ccompat",
"//c-toxcore/toxcore:group",
"//c-toxcore/toxcore:logger", "//c-toxcore/toxcore:logger",
"//c-toxcore/toxcore:mono_time", "//c-toxcore/toxcore:mono_time",
"//c-toxcore/toxcore:tox", "//c-toxcore/toxcore:tox",

View File

@ -536,7 +536,7 @@ bool groupchat_av_enabled(const Group_Chats *g_c, uint32_t groupnumber)
*/ */
int add_av_groupchat(const Logger *log, Tox *tox, Group_Chats *g_c, audio_data_cb *audio_callback, void *userdata) int add_av_groupchat(const Logger *log, Tox *tox, Group_Chats *g_c, audio_data_cb *audio_callback, void *userdata)
{ {
const int groupnumber = add_groupchat(g_c, &tox->rng, GROUPCHAT_TYPE_AV); const int groupnumber = add_groupchat(g_c, tox->sys.rng, GROUPCHAT_TYPE_AV);
if (groupnumber == -1) { if (groupnumber == -1) {
return -1; return -1;

View File

@ -181,7 +181,7 @@ ToxAV *toxav_new(Tox *tox, Toxav_Err_New *error)
av->tox = tox; av->tox = tox;
av->m = m; av->m = m;
av->toxav_mono_time = mono_time_new(nullptr, nullptr); av->toxav_mono_time = mono_time_new(tox->sys.mem, nullptr, nullptr);
av->msi = msi_new(av->m); av->msi = msi_new(av->m);
if (av->msi == nullptr) { if (av->msi == nullptr) {
@ -239,7 +239,7 @@ void toxav_kill(ToxAV *av)
} }
} }
mono_time_free(av->toxav_mono_time); mono_time_free(av->tox->sys.mem, av->toxav_mono_time);
pthread_mutex_unlock(av->mutex); pthread_mutex_unlock(av->mutex);
pthread_mutex_destroy(av->mutex); pthread_mutex_destroy(av->mutex);

View File

@ -16,64 +16,23 @@ int toxav_add_av_groupchat(Tox *tox, audio_data_cb *audio_callback, void *userda
return add_av_groupchat(tox->m->log, tox, tox->m->conferences_object, audio_callback, userdata); return add_av_groupchat(tox->m->log, tox, tox->m->conferences_object, audio_callback, userdata);
} }
/** @brief Join a AV group (you need to have been invited first).
*
* @return group number on success.
* @retval -1 on failure.
*
* Note that total size of pcm in bytes is equal to `samples * channels * sizeof(int16_t)`.
*/
int toxav_join_av_groupchat(Tox *tox, uint32_t friendnumber, const uint8_t *data, uint16_t length, int toxav_join_av_groupchat(Tox *tox, uint32_t friendnumber, const uint8_t *data, uint16_t length,
audio_data_cb *audio_callback, void *userdata) audio_data_cb *audio_callback, void *userdata)
{ {
return join_av_groupchat(tox->m->log, tox, tox->m->conferences_object, friendnumber, data, length, audio_callback, userdata); return join_av_groupchat(tox->m->log, tox, tox->m->conferences_object, friendnumber, data, length, audio_callback, userdata);
} }
/** @brief Send audio to the group chat.
*
* @retval 0 on success.
* @retval -1 on failure.
*
* Note that total size of pcm in bytes is equal to `samples * channels * sizeof(int16_t)`.
*
* Valid number of samples are `(sample rate) * (audio length) / 1000`
* (Valid values for audio length are: 2.5, 5, 10, 20, 40 or 60 ms)
* Valid number of channels are 1 or 2.
* Valid sample rates are 8000, 12000, 16000, 24000, or 48000.
*
* Recommended values are: samples = 960, channels = 1, sample_rate = 48000
*/
int toxav_group_send_audio(Tox *tox, uint32_t groupnumber, const int16_t *pcm, unsigned int samples, uint8_t channels, int toxav_group_send_audio(Tox *tox, uint32_t groupnumber, const int16_t *pcm, unsigned int samples, uint8_t channels,
uint32_t sample_rate) uint32_t sample_rate)
{ {
return group_send_audio(tox->m->conferences_object, groupnumber, pcm, samples, channels, sample_rate); return group_send_audio(tox->m->conferences_object, groupnumber, pcm, samples, channels, sample_rate);
} }
/** @brief Enable A/V in a groupchat.
*
* A/V must be enabled on a groupchat for audio to be sent to it and for
* received audio to be handled.
*
* An A/V group created with `toxav_add_av_groupchat` or `toxav_join_av_groupchat`
* will start with A/V enabled.
*
* An A/V group loaded from a savefile will start with A/V disabled.
*
* @retval 0 on success.
* @retval -1 on failure.
*
* Note that total size of pcm in bytes is equal to `samples * channels * sizeof(int16_t)`.
*/
int toxav_groupchat_enable_av(Tox *tox, uint32_t groupnumber, audio_data_cb *audio_callback, void *userdata) int toxav_groupchat_enable_av(Tox *tox, uint32_t groupnumber, audio_data_cb *audio_callback, void *userdata)
{ {
return groupchat_enable_av(tox->m->log, tox, tox->m->conferences_object, groupnumber, audio_callback, userdata); return groupchat_enable_av(tox->m->log, tox, tox->m->conferences_object, groupnumber, audio_callback, userdata);
} }
/** @brief Disable A/V in a groupchat.
*
* @retval 0 on success.
* @retval -1 on failure.
*/
int toxav_groupchat_disable_av(Tox *tox, uint32_t groupnumber) int toxav_groupchat_disable_av(Tox *tox, uint32_t groupnumber)
{ {
return groupchat_disable_av(tox->m->conferences_object, groupnumber); return groupchat_disable_av(tox->m->conferences_object, groupnumber);

View File

@ -23,6 +23,28 @@ cc_library(
deps = [":attributes"], deps = [":attributes"],
) )
cc_library(
name = "mem",
srcs = ["mem.c"],
hdrs = ["mem.h"],
visibility = ["//c-toxcore:__subpackages__"],
deps = [
":attributes",
":ccompat",
],
)
cc_test(
name = "mem_test",
size = "small",
srcs = ["mem_test.cc"],
deps = [
":mem",
"@com_google_googletest//:gtest",
"@com_google_googletest//:gtest_main",
],
)
cc_library( cc_library(
name = "util", name = "util",
srcs = ["util.c"], srcs = ["util.c"],
@ -37,6 +59,7 @@ cc_library(
deps = [ deps = [
":attributes", ":attributes",
":ccompat", ":ccompat",
":mem",
"@pthread", "@pthread",
], ],
) )
@ -59,6 +82,7 @@ cc_library(
hdrs = ["bin_pack.h"], hdrs = ["bin_pack.h"],
visibility = ["//c-toxcore:__subpackages__"], visibility = ["//c-toxcore:__subpackages__"],
deps = [ deps = [
":attributes",
":ccompat", ":ccompat",
"//c-toxcore/third_party:cmp", "//c-toxcore/third_party:cmp",
], ],
@ -70,6 +94,7 @@ cc_library(
hdrs = ["bin_unpack.h"], hdrs = ["bin_unpack.h"],
visibility = ["//c-toxcore:__subpackages__"], visibility = ["//c-toxcore:__subpackages__"],
deps = [ deps = [
":attributes",
":ccompat", ":ccompat",
"//c-toxcore/third_party:cmp", "//c-toxcore/third_party:cmp",
], ],
@ -93,6 +118,7 @@ cc_library(
hdrs = ["crypto_core.h"], hdrs = ["crypto_core.h"],
visibility = ["//c-toxcore:__subpackages__"], visibility = ["//c-toxcore:__subpackages__"],
deps = [ deps = [
":attributes",
":ccompat", ":ccompat",
"@libsodium", "@libsodium",
], ],
@ -115,7 +141,10 @@ cc_library(
name = "list", name = "list",
srcs = ["list.c"], srcs = ["list.c"],
hdrs = ["list.h"], hdrs = ["list.h"],
deps = [":ccompat"], deps = [
":attributes",
":ccompat",
],
) )
cc_test( cc_test(
@ -139,7 +168,10 @@ cc_library(
"//c-toxcore/other/bootstrap_daemon:__pkg__", "//c-toxcore/other/bootstrap_daemon:__pkg__",
"//c-toxcore/toxav:__pkg__", "//c-toxcore/toxav:__pkg__",
], ],
deps = [":ccompat"], deps = [
":attributes",
":ccompat",
],
) )
cc_library( cc_library(
@ -164,7 +196,9 @@ cc_library(
"//c-toxcore/toxav:__pkg__", "//c-toxcore/toxav:__pkg__",
], ],
deps = [ deps = [
":attributes",
":ccompat", ":ccompat",
":mem",
"@pthread", "@pthread",
], ],
) )
@ -194,6 +228,7 @@ cc_library(
deps = [ deps = [
":ccompat", ":ccompat",
":crypto_core", ":crypto_core",
":mem",
":mono_time", ":mono_time",
], ],
) )
@ -213,6 +248,7 @@ cc_library(
":ccompat", ":ccompat",
":crypto_core", ":crypto_core",
":logger", ":logger",
":mem",
":mono_time", ":mono_time",
":util", ":util",
"@libsodium", "@libsodium",
@ -250,6 +286,7 @@ cc_library(
deps = [ deps = [
":ccompat", ":ccompat",
":crypto_core", ":crypto_core",
":mem",
":mono_time", ":mono_time",
":util", ":util",
], ],
@ -301,9 +338,11 @@ cc_library(
], ],
deps = [ deps = [
":LAN_discovery", ":LAN_discovery",
":attributes",
":ccompat", ":ccompat",
":crypto_core", ":crypto_core",
":logger", ":logger",
":mem",
":mono_time", ":mono_time",
":network", ":network",
":ping_array", ":ping_array",
@ -344,6 +383,7 @@ cc_library(
":DHT", ":DHT",
":ccompat", ":ccompat",
":crypto_core", ":crypto_core",
":logger",
":mono_time", ":mono_time",
":shared_key_cache", ":shared_key_cache",
":util", ":util",
@ -398,7 +438,10 @@ cc_library(
hdrs = ["TCP_common.h"], hdrs = ["TCP_common.h"],
visibility = ["//c-toxcore/auto_tests:__pkg__"], visibility = ["//c-toxcore/auto_tests:__pkg__"],
deps = [ deps = [
":attributes",
":ccompat", ":ccompat",
":crypto_core",
":mem",
":network", ":network",
], ],
) )
@ -436,8 +479,10 @@ cc_library(
deps = [ deps = [
":TCP_common", ":TCP_common",
":ccompat", ":ccompat",
":crypto_core",
":forwarding", ":forwarding",
":mono_time", ":mono_time",
":network",
":util", ":util",
], ],
) )
@ -478,9 +523,11 @@ cc_library(
visibility = ["//c-toxcore/auto_tests:__pkg__"], visibility = ["//c-toxcore/auto_tests:__pkg__"],
deps = [ deps = [
":DHT", ":DHT",
":LAN_discovery",
":TCP_connection", ":TCP_connection",
":ccompat", ":ccompat",
":list", ":list",
":logger",
":mono_time", ":mono_time",
":util", ":util",
], ],
@ -499,6 +546,7 @@ cc_library(
":DHT", ":DHT",
":LAN_discovery", ":LAN_discovery",
":ccompat", ":ccompat",
":logger",
":mono_time", ":mono_time",
":onion", ":onion",
":shared_key_cache", ":shared_key_cache",
@ -577,6 +625,7 @@ cc_library(
":net_crypto", ":net_crypto",
":network", ":network",
":onion_announce", ":onion_announce",
":ping_array",
":util", ":util",
], ],
) )
@ -588,6 +637,7 @@ cc_library(
visibility = ["//c-toxcore/auto_tests:__pkg__"], visibility = ["//c-toxcore/auto_tests:__pkg__"],
deps = [ deps = [
":DHT", ":DHT",
":LAN_discovery",
":ccompat", ":ccompat",
":mono_time", ":mono_time",
":net_crypto", ":net_crypto",
@ -698,6 +748,7 @@ cc_library(
":forwarding", ":forwarding",
":friend_connection", ":friend_connection",
":friend_requests", ":friend_requests",
":group_announce",
":group_moderation", ":group_moderation",
":group_onion_announce", ":group_onion_announce",
":logger", ":logger",
@ -744,6 +795,7 @@ cc_library(
":group", ":group",
":group_moderation", ":group_moderation",
":logger", ":logger",
":mem",
":mono_time", ":mono_time",
":network", ":network",
"//c-toxcore/toxencryptsave:defines", "//c-toxcore/toxencryptsave:defines",
@ -768,6 +820,7 @@ cc_library(
hdrs = ["tox_unpack.h"], hdrs = ["tox_unpack.h"],
visibility = ["//c-toxcore:__subpackages__"], visibility = ["//c-toxcore:__subpackages__"],
deps = [ deps = [
":attributes",
":bin_unpack", ":bin_unpack",
":ccompat", ":ccompat",
":tox", ":tox",
@ -783,9 +836,11 @@ cc_library(
hdrs = ["tox_events.h"], hdrs = ["tox_events.h"],
visibility = ["//c-toxcore:__subpackages__"], visibility = ["//c-toxcore:__subpackages__"],
deps = [ deps = [
":attributes",
":bin_pack", ":bin_pack",
":bin_unpack", ":bin_unpack",
":ccompat", ":ccompat",
":mem",
":tox", ":tox",
":tox_unpack", ":tox_unpack",
"//c-toxcore/third_party:cmp", "//c-toxcore/third_party:cmp",
@ -798,6 +853,7 @@ cc_test(
srcs = ["tox_events_test.cc"], srcs = ["tox_events_test.cc"],
deps = [ deps = [
":crypto_core", ":crypto_core",
":tox",
":tox_events", ":tox_events",
"@com_google_googletest//:gtest", "@com_google_googletest//:gtest",
"@com_google_googletest//:gtest_main", "@com_google_googletest//:gtest_main",
@ -808,7 +864,10 @@ cc_fuzz_test(
name = "tox_events_fuzz_test", name = "tox_events_fuzz_test",
srcs = ["tox_events_fuzz_test.cc"], srcs = ["tox_events_fuzz_test.cc"],
corpus = ["//tools/toktok-fuzzer/corpus:tox_events_fuzz_test"], corpus = ["//tools/toktok-fuzzer/corpus:tox_events_fuzz_test"],
deps = [":tox_events"], deps = [
":tox_events",
"//c-toxcore/testing/fuzzing:fuzz_support",
],
) )
cc_library( cc_library(

View File

@ -91,6 +91,7 @@ struct DHT {
const Logger *log; const Logger *log;
const Network *ns; const Network *ns;
Mono_Time *mono_time; Mono_Time *mono_time;
const Memory *mem;
const Random *rng; const Random *rng;
Networking_Core *net; Networking_Core *net;
@ -211,12 +212,6 @@ static IP_Port ip_port_normalize(const IP_Port *ip_port)
return res; return res;
} }
/** @brief Compares pk1 and pk2 with pk.
*
* @retval 0 if both are same distance.
* @retval 1 if pk1 is closer.
* @retval 2 if pk2 is closer.
*/
int id_closest(const uint8_t *pk, const uint8_t *pk1, const uint8_t *pk2) int id_closest(const uint8_t *pk, const uint8_t *pk1, const uint8_t *pk2)
{ {
for (size_t i = 0; i < CRYPTO_PUBLIC_KEY_SIZE; ++i) { for (size_t i = 0; i < CRYPTO_PUBLIC_KEY_SIZE; ++i) {
@ -280,27 +275,6 @@ 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) #define CRYPTO_SIZE (1 + CRYPTO_PUBLIC_KEY_SIZE * 2 + CRYPTO_NONCE_SIZE)
/**
* @brief Create a request to peer.
*
* Packs the data and sender public key and encrypts the packet.
*
* @param[in] send_public_key public key of the sender.
* @param[in] send_secret_key secret key of the sender.
* @param[out] packet an array of @ref MAX_CRYPTO_REQUEST_SIZE big.
* @param[in] recv_public_key public key of the receiver.
* @param[in] data represents the data we send with the request.
* @param[in] data_length the length of the data.
* @param[in] request_id the id of the request (32 = friend request, 254 = ping request).
*
* @attention Constraints:
* @code
* sizeof(packet) >= MAX_CRYPTO_REQUEST_SIZE
* @endcode
*
* @retval -1 on failure.
* @return the length of the created packet on success.
*/
int create_request(const Random *rng, const uint8_t *send_public_key, const uint8_t *send_secret_key, int create_request(const Random *rng, const uint8_t *send_public_key, const uint8_t *send_secret_key,
uint8_t *packet, const uint8_t *recv_public_key, uint8_t *packet, const uint8_t *recv_public_key,
const uint8_t *data, uint32_t data_length, uint8_t request_id) const uint8_t *data, uint32_t data_length, uint8_t request_id)
@ -334,28 +308,6 @@ int create_request(const Random *rng, const uint8_t *send_public_key, const uint
return len + CRYPTO_SIZE; return len + CRYPTO_SIZE;
} }
/**
* @brief Decrypts and unpacks a DHT request packet.
*
* Puts the senders public key in the request in @p public_key, the data from
* the request in @p data.
*
* @param[in] self_public_key public key of the receiver (us).
* @param[in] self_secret_key secret key of the receiver (us).
* @param[out] public_key public key of the sender, copied from the input packet.
* @param[out] data decrypted request data, copied from the input packet, must
* have room for @ref MAX_CRYPTO_REQUEST_SIZE bytes.
* @param[in] packet is the request packet.
* @param[in] packet_length length of the packet.
*
* @attention Constraints:
* @code
* sizeof(data) >= MAX_CRYPTO_REQUEST_SIZE
* @endcode
*
* @retval -1 if not valid request.
* @return the length of the unpacked data.
*/
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 uint8_t *self_public_key, const uint8_t *self_secret_key, uint8_t *public_key, uint8_t *data,
uint8_t *request_id, const uint8_t *packet, uint16_t packet_length) uint8_t *request_id, const uint8_t *packet, uint16_t packet_length)
{ {
@ -394,9 +346,6 @@ int handle_request(const uint8_t *self_public_key, const uint8_t *self_secret_ke
return len1; return len1;
} }
/** @return packet size of packed node with ip_family on success.
* @retval -1 on failure.
*/
int packed_node_size(Family ip_family) int packed_node_size(Family ip_family)
{ {
if (net_family_is_ipv4(ip_family) || net_family_is_tcp_ipv4(ip_family)) { if (net_family_is_ipv4(ip_family) || net_family_is_tcp_ipv4(ip_family)) {
@ -411,13 +360,6 @@ int packed_node_size(Family ip_family)
} }
/** @brief Pack an IP_Port structure into data of max size length.
*
* Packed_length is the offset of data currently packed.
*
* @return size of packed IP_Port data on success.
* @retval -1 on failure.
*/
int pack_ip_port(const Logger *logger, uint8_t *data, uint16_t length, const IP_Port *ip_port) int pack_ip_port(const Logger *logger, uint8_t *data, uint16_t length, const IP_Port *ip_port)
{ {
if (data == nullptr) { if (data == nullptr) {
@ -473,17 +415,13 @@ int pack_ip_port(const Logger *logger, uint8_t *data, uint16_t length, const IP_
} }
} }
/** @brief Encrypt plain and write resulting DHT packet into packet with max size length. int dht_create_packet(const Memory *mem, const Random *rng,
* const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
* @return size of packet on success.
* @retval -1 on failure.
*/
int dht_create_packet(const Random *rng, const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
const uint8_t *shared_key, const uint8_t type, const uint8_t *shared_key, const uint8_t type,
const uint8_t *plain, size_t plain_length, const uint8_t *plain, size_t plain_length,
uint8_t *packet, size_t length) uint8_t *packet, size_t length)
{ {
uint8_t *encrypted = (uint8_t *)malloc(plain_length + CRYPTO_MAC_SIZE); uint8_t *encrypted = (uint8_t *)mem_balloc(mem, plain_length + CRYPTO_MAC_SIZE);
uint8_t nonce[CRYPTO_NONCE_SIZE]; uint8_t nonce[CRYPTO_NONCE_SIZE];
if (encrypted == nullptr) { if (encrypted == nullptr) {
@ -495,12 +433,12 @@ int dht_create_packet(const Random *rng, const uint8_t public_key[CRYPTO_PUBLIC_
const int encrypted_length = encrypt_data_symmetric(shared_key, nonce, plain, plain_length, encrypted); const int encrypted_length = encrypt_data_symmetric(shared_key, nonce, plain, plain_length, encrypted);
if (encrypted_length == -1) { if (encrypted_length == -1) {
free(encrypted); mem_delete(mem, encrypted);
return -1; return -1;
} }
if (length < 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + encrypted_length) { if (length < 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + encrypted_length) {
free(encrypted); mem_delete(mem, encrypted);
return -1; return -1;
} }
@ -509,17 +447,10 @@ int dht_create_packet(const Random *rng, const uint8_t public_key[CRYPTO_PUBLIC_
memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, nonce, CRYPTO_NONCE_SIZE); memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, nonce, CRYPTO_NONCE_SIZE);
memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, encrypted, encrypted_length); memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, encrypted, encrypted_length);
free(encrypted); mem_delete(mem, encrypted);
return 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + encrypted_length; return 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + encrypted_length;
} }
/** @brief Unpack IP_Port structure from data of max size length into ip_port.
*
* len_processed is the offset of data currently unpacked.
*
* @return size of unpacked ip_port on success.
* @retval -1 on failure.
*/
int unpack_ip_port(IP_Port *ip_port, const uint8_t *data, uint16_t length, bool tcp_enabled) int unpack_ip_port(IP_Port *ip_port, const uint8_t *data, uint16_t length, bool tcp_enabled)
{ {
if (data == nullptr) { if (data == nullptr) {
@ -580,11 +511,6 @@ int unpack_ip_port(IP_Port *ip_port, const uint8_t *data, uint16_t length, bool
} }
} }
/** @brief Pack number of nodes into data of maxlength length.
*
* @return length of packed nodes on success.
* @retval -1 on failure.
*/
int pack_nodes(const Logger *logger, uint8_t *data, uint16_t length, const Node_format *nodes, uint16_t number) int pack_nodes(const Logger *logger, uint8_t *data, uint16_t length, const Node_format *nodes, uint16_t number)
{ {
uint32_t packed_length = 0; uint32_t packed_length = 0;
@ -614,13 +540,6 @@ int pack_nodes(const Logger *logger, uint8_t *data, uint16_t length, const Node_
return packed_length; return packed_length;
} }
/** @brief Unpack data of length into nodes of size max_num_nodes.
* Put the length of the data processed in processed_data_len.
* tcp_enabled sets if TCP nodes are expected (true) or not (false).
*
* @return number of unpacked nodes on success.
* @retval -1 on failure.
*/
int unpack_nodes(Node_format *nodes, uint16_t max_num_nodes, uint16_t *processed_data_len, const uint8_t *data, int unpack_nodes(Node_format *nodes, uint16_t max_num_nodes, uint16_t *processed_data_len, const uint8_t *data,
uint16_t length, bool tcp_enabled) uint16_t length, bool tcp_enabled)
{ {
@ -840,7 +759,7 @@ bool add_to_list(Node_format *nodes_list, uint32_t length, const uint8_t *pk, co
non_null() non_null()
static void get_close_nodes_inner(uint64_t cur_time, const uint8_t *public_key, Node_format *nodes_list, static void get_close_nodes_inner(uint64_t cur_time, const uint8_t *public_key, Node_format *nodes_list,
Family sa_family, const Client_data *client_list, uint32_t client_list_length, Family sa_family, const Client_data *client_list, uint32_t client_list_length,
uint32_t *num_nodes_ptr, bool is_LAN, uint32_t *num_nodes_ptr, bool is_lan,
bool want_announce) bool want_announce)
{ {
if (!net_family_is_ipv4(sa_family) && !net_family_is_ipv6(sa_family) && !net_family_is_unspec(sa_family)) { if (!net_family_is_ipv4(sa_family) && !net_family_is_ipv6(sa_family) && !net_family_is_unspec(sa_family)) {
@ -875,7 +794,7 @@ static void get_close_nodes_inner(uint64_t cur_time, const uint8_t *public_key,
} }
/* don't send LAN ips to non LAN peers */ /* don't send LAN ips to non LAN peers */
if (ip_is_lan(&ipptp->ip_port.ip) && !is_LAN) { if (ip_is_lan(&ipptp->ip_port.ip) && !is_lan) {
continue; continue;
} }
@ -909,27 +828,27 @@ static void get_close_nodes_inner(uint64_t cur_time, const uint8_t *public_key,
*/ */
non_null() non_null()
static int get_somewhat_close_nodes(const DHT *dht, const uint8_t *public_key, Node_format *nodes_list, static int get_somewhat_close_nodes(const DHT *dht, const uint8_t *public_key, Node_format *nodes_list,
Family sa_family, bool is_LAN, bool want_announce) Family sa_family, bool is_lan, bool want_announce)
{ {
uint32_t num_nodes = 0; uint32_t num_nodes = 0;
get_close_nodes_inner(dht->cur_time, public_key, nodes_list, sa_family, get_close_nodes_inner(dht->cur_time, public_key, nodes_list, sa_family,
dht->close_clientlist, LCLIENT_LIST, &num_nodes, is_LAN, want_announce); dht->close_clientlist, LCLIENT_LIST, &num_nodes, is_lan, want_announce);
for (uint32_t i = 0; i < dht->num_friends; ++i) { for (uint32_t i = 0; i < dht->num_friends; ++i) {
get_close_nodes_inner(dht->cur_time, public_key, nodes_list, sa_family, get_close_nodes_inner(dht->cur_time, public_key, nodes_list, sa_family,
dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS, dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS,
&num_nodes, is_LAN, want_announce); &num_nodes, is_lan, want_announce);
} }
return num_nodes; return num_nodes;
} }
int get_close_nodes(const DHT *dht, const uint8_t *public_key, Node_format *nodes_list, Family sa_family, int get_close_nodes(const DHT *dht, const uint8_t *public_key, Node_format *nodes_list, Family sa_family,
bool is_LAN, bool want_announce) bool is_lan, bool want_announce)
{ {
memset(nodes_list, 0, MAX_SENT_NODES * sizeof(Node_format)); memset(nodes_list, 0, MAX_SENT_NODES * sizeof(Node_format));
return get_somewhat_close_nodes(dht, public_key, nodes_list, sa_family, return get_somewhat_close_nodes(dht, public_key, nodes_list, sa_family,
is_LAN, want_announce); is_lan, want_announce);
} }
typedef struct DHT_Cmp_Data { typedef struct DHT_Cmp_Data {
@ -1020,7 +939,8 @@ static bool send_announce_ping(DHT *dht, const uint8_t *public_key, const IP_Por
uint8_t request[1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + sizeof(plain) + CRYPTO_MAC_SIZE]; uint8_t request[1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + sizeof(plain) + CRYPTO_MAC_SIZE];
if (dht_create_packet(dht->rng, dht->self_public_key, shared_key, NET_PACKET_DATA_SEARCH_REQUEST, if (dht_create_packet(dht->mem, dht->rng,
dht->self_public_key, shared_key, NET_PACKET_DATA_SEARCH_REQUEST,
plain, sizeof(plain), request, sizeof(request)) != sizeof(request)) { plain, sizeof(plain), request, sizeof(request)) != sizeof(request)) {
return false; return false;
} }
@ -1091,12 +1011,12 @@ static bool store_node_ok(const Client_data *client, uint64_t cur_time, const ui
} }
non_null() non_null()
static void sort_client_list(Client_data *list, uint64_t cur_time, unsigned int length, static void sort_client_list(const Memory *mem, Client_data *list, uint64_t cur_time, unsigned int length,
const uint8_t *comp_public_key) const uint8_t *comp_public_key)
{ {
// Pass comp_public_key to qsort with each Client_data entry, so the // Pass comp_public_key to qsort with each Client_data entry, so the
// comparison function can use it as the base of comparison. // comparison function can use it as the base of comparison.
DHT_Cmp_Data *cmp_list = (DHT_Cmp_Data *)calloc(length, sizeof(DHT_Cmp_Data)); DHT_Cmp_Data *cmp_list = (DHT_Cmp_Data *)mem_valloc(mem, length, sizeof(DHT_Cmp_Data));
if (cmp_list == nullptr) { if (cmp_list == nullptr) {
return; return;
@ -1114,7 +1034,7 @@ static void sort_client_list(Client_data *list, uint64_t cur_time, unsigned int
list[i] = cmp_list[i].entry; list[i] = cmp_list[i].entry;
} }
free(cmp_list); mem_delete(mem, cmp_list);
} }
non_null() non_null()
@ -1175,7 +1095,7 @@ static bool replace_all(const DHT *dht,
return false; return false;
} }
sort_client_list(list, dht->cur_time, length, comp_public_key); sort_client_list(dht->mem, list, dht->cur_time, length, comp_public_key);
Client_data *const client = &list[0]; Client_data *const client = &list[0];
pk_copy(client->public_key, public_key); pk_copy(client->public_key, public_key);
@ -1475,7 +1395,7 @@ bool dht_getnodes(DHT *dht, const IP_Port *ip_port, const uint8_t *public_key, c
const uint8_t *shared_key = dht_get_shared_key_sent(dht, public_key); const uint8_t *shared_key = dht_get_shared_key_sent(dht, public_key);
const int len = dht_create_packet(dht->rng, const int len = dht_create_packet(dht->mem, dht->rng,
dht->self_public_key, shared_key, NET_PACKET_GET_NODES, dht->self_public_key, shared_key, NET_PACKET_GET_NODES,
plain, sizeof(plain), data, sizeof(data)); plain, sizeof(plain), data, sizeof(data));
@ -1525,7 +1445,7 @@ static int sendnodes_ipv6(const DHT *dht, const IP_Port *ip_port, const uint8_t
const uint32_t crypto_size = 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_MAC_SIZE; const uint32_t crypto_size = 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_MAC_SIZE;
VLA(uint8_t, data, 1 + nodes_length + length + crypto_size); VLA(uint8_t, data, 1 + nodes_length + length + crypto_size);
const int len = dht_create_packet(dht->rng, const int len = dht_create_packet(dht->mem, dht->rng,
dht->self_public_key, shared_encryption_key, NET_PACKET_SEND_NODES_IPV6, dht->self_public_key, shared_encryption_key, NET_PACKET_SEND_NODES_IPV6,
plain, 1 + nodes_length + length, data, SIZEOF_VLA(data)); plain, 1 + nodes_length + length, data, SIZEOF_VLA(data));
@ -1764,7 +1684,7 @@ int dht_addfriend(DHT *dht, const uint8_t *public_key, dht_ip_cb *ip_callback,
return 0; return 0;
} }
DHT_Friend *const temp = (DHT_Friend *)realloc(dht->friends_list, sizeof(DHT_Friend) * (dht->num_friends + 1)); DHT_Friend *const temp = (DHT_Friend *)mem_vrealloc(dht->mem, dht->friends_list, dht->num_friends + 1, sizeof(DHT_Friend));
if (temp == nullptr) { if (temp == nullptr) {
return -1; return -1;
@ -1809,12 +1729,12 @@ int dht_delfriend(DHT *dht, const uint8_t *public_key, uint32_t lock_token)
} }
if (dht->num_friends == 0) { if (dht->num_friends == 0) {
free(dht->friends_list); mem_delete(dht->mem, dht->friends_list);
dht->friends_list = nullptr; dht->friends_list = nullptr;
return 0; return 0;
} }
DHT_Friend *const temp = (DHT_Friend *)realloc(dht->friends_list, sizeof(DHT_Friend) * dht->num_friends); DHT_Friend *const temp = (DHT_Friend *)mem_vrealloc(dht->mem, dht->friends_list, dht->num_friends, sizeof(DHT_Friend));
if (temp == nullptr) { if (temp == nullptr) {
return -1; return -1;
@ -1867,14 +1787,14 @@ static uint8_t do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, co
const uint64_t temp_time = mono_time_get(dht->mono_time); const uint64_t temp_time = mono_time_get(dht->mono_time);
uint32_t num_nodes = 0; uint32_t num_nodes = 0;
Client_data **client_list = (Client_data **)calloc(list_count * 2, sizeof(Client_data *)); Client_data **client_list = (Client_data **)mem_valloc(dht->mem, list_count * 2, sizeof(Client_data *));
IPPTsPng **assoc_list = (IPPTsPng **)calloc(list_count * 2, sizeof(IPPTsPng *)); IPPTsPng **assoc_list = (IPPTsPng **)mem_valloc(dht->mem, list_count * 2, sizeof(IPPTsPng *));
unsigned int sort = 0; unsigned int sort = 0;
bool sort_ok = false; bool sort_ok = false;
if (client_list == nullptr || assoc_list == nullptr) { if (client_list == nullptr || assoc_list == nullptr) {
free(assoc_list); mem_delete(dht->mem, assoc_list);
free(client_list); mem_delete(dht->mem, client_list);
return 0; return 0;
} }
@ -1914,7 +1834,7 @@ static uint8_t do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, co
} }
if (sortable && sort_ok) { if (sortable && sort_ok) {
sort_client_list(list, dht->cur_time, list_count, public_key); sort_client_list(dht->mem, list, dht->cur_time, list_count, public_key);
} }
if (num_nodes > 0 && (mono_time_is_timeout(dht->mono_time, *lastgetnode, GET_NODE_INTERVAL) if (num_nodes > 0 && (mono_time_is_timeout(dht->mono_time, *lastgetnode, GET_NODE_INTERVAL)
@ -1931,8 +1851,8 @@ static uint8_t do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, co
++*bootstrap_times; ++*bootstrap_times;
} }
free(assoc_list); mem_delete(dht->mem, assoc_list);
free(client_list); mem_delete(dht->mem, client_list);
return not_kill; return not_kill;
} }
@ -1964,7 +1884,7 @@ static void do_dht_friends(DHT *dht)
* Send a get nodes request every GET_NODE_INTERVAL seconds to a random good node in the list. * Send a get nodes request every GET_NODE_INTERVAL seconds to a random good node in the list.
*/ */
non_null() non_null()
static void do_Close(DHT *dht) static void do_close(DHT *dht)
{ {
for (size_t i = 0; i < dht->num_to_bootstrap; ++i) { for (size_t i = 0; i < dht->num_to_bootstrap; ++i) {
dht_getnodes(dht, &dht->to_bootstrap[i].ip_port, dht->to_bootstrap[i].public_key, dht->self_public_key); dht_getnodes(dht, &dht->to_bootstrap[i].ip_port, dht->to_bootstrap[i].public_key, dht->self_public_key);
@ -2043,11 +1963,6 @@ int dht_bootstrap_from_address(DHT *dht, const char *address, bool ipv6enabled,
return 0; return 0;
} }
/** @brief Send the given packet to node with public_key.
*
* @return number of bytes sent.
* @retval -1 if failure.
*/
int route_packet(const DHT *dht, const uint8_t *public_key, const uint8_t *packet, uint16_t length) int route_packet(const DHT *dht, const uint8_t *public_key, const uint8_t *packet, uint16_t length)
{ {
for (uint32_t i = 0; i < LCLIENT_LIST; ++i) { for (uint32_t i = 0; i < LCLIENT_LIST; ++i) {
@ -2294,7 +2209,7 @@ static uint32_t routeone_to_friend(const DHT *dht, const uint8_t *friend_id, con
/*---------------------BEGINNING OF NAT PUNCHING FUNCTIONS--------------------------*/ /*---------------------BEGINNING OF NAT PUNCHING FUNCTIONS--------------------------*/
non_null() non_null()
static int send_NATping(const DHT *dht, const uint8_t *public_key, uint64_t ping_id, uint8_t type) static int send_nat_ping(const DHT *dht, const uint8_t *public_key, uint64_t ping_id, uint8_t type)
{ {
uint8_t data[sizeof(uint64_t) + 1]; uint8_t data[sizeof(uint64_t) + 1];
uint8_t packet_data[MAX_CRYPTO_REQUEST_SIZE]; uint8_t packet_data[MAX_CRYPTO_REQUEST_SIZE];
@ -2329,7 +2244,7 @@ static int send_NATping(const DHT *dht, const uint8_t *public_key, uint64_t ping
/** Handle a received ping request for. */ /** Handle a received ping request for. */
non_null() non_null()
static int handle_NATping(void *object, const IP_Port *source, const uint8_t *source_pubkey, const uint8_t *packet, static int handle_nat_ping(void *object, const IP_Port *source, const uint8_t *source_pubkey, const uint8_t *packet,
uint16_t length, void *userdata) uint16_t length, void *userdata)
{ {
if (length != sizeof(uint64_t) + 1) { if (length != sizeof(uint64_t) + 1) {
@ -2350,7 +2265,7 @@ static int handle_NATping(void *object, const IP_Port *source, const uint8_t *so
if (packet[0] == NAT_PING_REQUEST) { if (packet[0] == NAT_PING_REQUEST) {
/* 1 is reply */ /* 1 is reply */
send_NATping(dht, source_pubkey, ping_id, NAT_PING_RESPONSE); send_nat_ping(dht, source_pubkey, ping_id, NAT_PING_RESPONSE);
dht_friend->nat.recv_nat_ping_timestamp = mono_time_get(dht->mono_time); dht_friend->nat.recv_nat_ping_timestamp = mono_time_get(dht->mono_time);
return 0; return 0;
} }
@ -2482,7 +2397,7 @@ static void punch_holes(DHT *dht, const IP *ip, const uint16_t *port_list, uint1
} }
non_null() non_null()
static void do_NAT(DHT *dht) static void do_nat(DHT *dht)
{ {
const uint64_t temp_time = mono_time_get(dht->mono_time); const uint64_t temp_time = mono_time_get(dht->mono_time);
@ -2496,7 +2411,7 @@ static void do_NAT(DHT *dht)
} }
if (dht->friends_list[i].nat.nat_ping_timestamp + PUNCH_INTERVAL < temp_time) { if (dht->friends_list[i].nat.nat_ping_timestamp + PUNCH_INTERVAL < temp_time) {
send_NATping(dht, dht->friends_list[i].public_key, dht->friends_list[i].nat.nat_ping_id, NAT_PING_REQUEST); send_nat_ping(dht, dht->friends_list[i].public_key, dht->friends_list[i].nat.nat_ping_id, NAT_PING_REQUEST);
dht->friends_list[i].nat.nat_ping_timestamp = temp_time; dht->friends_list[i].nat.nat_ping_timestamp = temp_time;
} }
@ -2551,9 +2466,7 @@ static uint16_t list_nodes(const Random *rng, const Client_data *list, size_t le
} }
if (!assoc_timeout(cur_time, &list[i - 1].assoc6)) { if (!assoc_timeout(cur_time, &list[i - 1].assoc6)) {
if (assoc == nullptr) { if (assoc == nullptr || (random_u08(rng) % 2) != 0) {
assoc = &list[i - 1].assoc6;
} else if ((random_u08(rng) % 2) != 0) {
assoc = &list[i - 1].assoc6; assoc = &list[i - 1].assoc6;
} }
} }
@ -2671,7 +2584,7 @@ void dht_callback_get_nodes_response(DHT *dht, dht_get_nodes_response_cb *functi
} }
non_null(1, 2, 3) nullable(5) non_null(1, 2, 3) nullable(5)
static int handle_LANdiscovery(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length, static int handle_lan_discovery(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length,
void *userdata) void *userdata)
{ {
DHT *dht = (DHT *)object; DHT *dht = (DHT *)object;
@ -2694,14 +2607,15 @@ static int handle_LANdiscovery(void *object, const IP_Port *source, const uint8_
/*----------------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------------*/
DHT *new_dht(const Logger *log, const Random *rng, const Network *ns, Mono_Time *mono_time, Networking_Core *net, DHT *new_dht(const Logger *log, const Memory *mem, const Random *rng, const Network *ns,
Mono_Time *mono_time, Networking_Core *net,
bool hole_punching_enabled, bool lan_discovery_enabled) bool hole_punching_enabled, bool lan_discovery_enabled)
{ {
if (net == nullptr) { if (net == nullptr) {
return nullptr; return nullptr;
} }
DHT *const dht = (DHT *)calloc(1, sizeof(DHT)); DHT *const dht = (DHT *)mem_alloc(mem, sizeof(DHT));
if (dht == nullptr) { if (dht == nullptr) {
return nullptr; return nullptr;
@ -2713,11 +2627,12 @@ DHT *new_dht(const Logger *log, const Random *rng, const Network *ns, Mono_Time
dht->log = log; dht->log = log;
dht->net = net; dht->net = net;
dht->rng = rng; dht->rng = rng;
dht->mem = mem;
dht->hole_punching_enabled = hole_punching_enabled; dht->hole_punching_enabled = hole_punching_enabled;
dht->lan_discovery_enabled = lan_discovery_enabled; dht->lan_discovery_enabled = lan_discovery_enabled;
dht->ping = ping_new(mono_time, rng, dht); dht->ping = ping_new(mem, mono_time, rng, dht);
if (dht->ping == nullptr) { if (dht->ping == nullptr) {
kill_dht(dht); kill_dht(dht);
@ -2727,8 +2642,8 @@ DHT *new_dht(const Logger *log, const Random *rng, const Network *ns, Mono_Time
networking_registerhandler(dht->net, NET_PACKET_GET_NODES, &handle_getnodes, dht); networking_registerhandler(dht->net, NET_PACKET_GET_NODES, &handle_getnodes, dht);
networking_registerhandler(dht->net, NET_PACKET_SEND_NODES_IPV6, &handle_sendnodes_ipv6, dht); networking_registerhandler(dht->net, NET_PACKET_SEND_NODES_IPV6, &handle_sendnodes_ipv6, dht);
networking_registerhandler(dht->net, NET_PACKET_CRYPTO, &cryptopacket_handle, dht); networking_registerhandler(dht->net, NET_PACKET_CRYPTO, &cryptopacket_handle, dht);
networking_registerhandler(dht->net, NET_PACKET_LAN_DISCOVERY, &handle_LANdiscovery, dht); networking_registerhandler(dht->net, NET_PACKET_LAN_DISCOVERY, &handle_lan_discovery, dht);
cryptopacket_registerhandler(dht, CRYPTO_PACKET_NAT_PING, &handle_NATping, dht); cryptopacket_registerhandler(dht, CRYPTO_PACKET_NAT_PING, &handle_nat_ping, dht);
#ifdef CHECK_ANNOUNCE_NODE #ifdef CHECK_ANNOUNCE_NODE
networking_registerhandler(dht->net, NET_PACKET_DATA_SEARCH_RESPONSE, &handle_data_search_response, dht); networking_registerhandler(dht->net, NET_PACKET_DATA_SEARCH_RESPONSE, &handle_data_search_response, dht);
@ -2736,8 +2651,8 @@ DHT *new_dht(const Logger *log, const Random *rng, const Network *ns, Mono_Time
crypto_new_keypair(rng, dht->self_public_key, dht->self_secret_key); crypto_new_keypair(rng, dht->self_public_key, dht->self_secret_key);
dht->shared_keys_recv = shared_key_cache_new(mono_time, dht->self_secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT); dht->shared_keys_recv = shared_key_cache_new(mono_time, mem, dht->self_secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT);
dht->shared_keys_sent = shared_key_cache_new(mono_time, dht->self_secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT); dht->shared_keys_sent = shared_key_cache_new(mono_time, mem, dht->self_secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT);
if (dht->shared_keys_recv == nullptr || dht->shared_keys_sent == nullptr) { if (dht->shared_keys_recv == nullptr || dht->shared_keys_sent == nullptr) {
kill_dht(dht); kill_dht(dht);
@ -2745,7 +2660,7 @@ DHT *new_dht(const Logger *log, const Random *rng, const Network *ns, Mono_Time
} }
dht->dht_ping_array = ping_array_new(DHT_PING_ARRAY_SIZE, PING_TIMEOUT); dht->dht_ping_array = ping_array_new(mem, DHT_PING_ARRAY_SIZE, PING_TIMEOUT);
if (dht->dht_ping_array == nullptr) { if (dht->dht_ping_array == nullptr) {
kill_dht(dht); kill_dht(dht);
@ -2789,9 +2704,9 @@ void do_dht(DHT *dht)
dht_connect_after_load(dht); dht_connect_after_load(dht);
} }
do_Close(dht); do_close(dht);
do_dht_friends(dht); do_dht_friends(dht);
do_NAT(dht); do_nat(dht);
ping_iterate(dht->ping); ping_iterate(dht->ping);
} }
@ -2810,11 +2725,11 @@ void kill_dht(DHT *dht)
shared_key_cache_free(dht->shared_keys_recv); shared_key_cache_free(dht->shared_keys_recv);
shared_key_cache_free(dht->shared_keys_sent); shared_key_cache_free(dht->shared_keys_sent);
ping_array_kill(dht->dht_ping_array); ping_array_kill(dht->dht_ping_array);
ping_kill(dht->ping); ping_kill(dht->mem, dht->ping);
free(dht->friends_list); mem_delete(dht->mem, dht->friends_list);
free(dht->loaded_nodes_list); mem_delete(dht->mem, dht->loaded_nodes_list);
crypto_memzero(dht->self_secret_key, sizeof(dht->self_secret_key)); crypto_memzero(dht->self_secret_key, sizeof(dht->self_secret_key));
free(dht); mem_delete(dht->mem, dht);
} }
/* new DHT format for load/save, more robust and forward compatible */ /* new DHT format for load/save, more robust and forward compatible */
@ -2868,7 +2783,7 @@ void dht_save(const DHT *dht, uint8_t *data)
/* get right offset. we write the actual header later. */ /* get right offset. we write the actual header later. */
data = state_write_section_header(data, DHT_STATE_COOKIE_TYPE, 0, 0); data = state_write_section_header(data, DHT_STATE_COOKIE_TYPE, 0, 0);
Node_format *clients = (Node_format *)calloc(MAX_SAVED_DHT_NODES, sizeof(Node_format)); Node_format *clients = (Node_format *)mem_valloc(dht->mem, MAX_SAVED_DHT_NODES, sizeof(Node_format));
if (clients == nullptr) { if (clients == nullptr) {
LOGGER_ERROR(dht->log, "could not allocate %u nodes", MAX_SAVED_DHT_NODES); LOGGER_ERROR(dht->log, "could not allocate %u nodes", MAX_SAVED_DHT_NODES);
@ -2917,17 +2832,12 @@ void dht_save(const DHT *dht, uint8_t *data)
state_write_section_header(old_data, DHT_STATE_COOKIE_TYPE, pack_nodes(dht->log, data, sizeof(Node_format) * num, state_write_section_header(old_data, DHT_STATE_COOKIE_TYPE, pack_nodes(dht->log, data, sizeof(Node_format) * num,
clients, num), DHT_STATE_TYPE_NODES); clients, num), DHT_STATE_TYPE_NODES);
free(clients); mem_delete(dht->mem, clients);
} }
/** Bootstrap from this number of nodes every time `dht_connect_after_load()` is called */ /** Bootstrap from this number of nodes every time `dht_connect_after_load()` is called */
#define SAVE_BOOTSTAP_FREQUENCY 8 #define SAVE_BOOTSTAP_FREQUENCY 8
/** @brief Start sending packets after DHT loaded_friends_list and loaded_clients_list are set.
*
* @retval 0 if successful
* @retval -1 otherwise
*/
int dht_connect_after_load(DHT *dht) int dht_connect_after_load(DHT *dht)
{ {
if (dht == nullptr) { if (dht == nullptr) {
@ -2940,7 +2850,7 @@ int dht_connect_after_load(DHT *dht)
/* DHT is connected, stop. */ /* DHT is connected, stop. */
if (dht_non_lan_connected(dht)) { if (dht_non_lan_connected(dht)) {
free(dht->loaded_nodes_list); mem_delete(dht->mem, dht->loaded_nodes_list);
dht->loaded_nodes_list = nullptr; dht->loaded_nodes_list = nullptr;
dht->loaded_num_nodes = 0; dht->loaded_num_nodes = 0;
return 0; return 0;
@ -2966,9 +2876,9 @@ static State_Load_Status dht_load_state_callback(void *outer, const uint8_t *dat
break; break;
} }
free(dht->loaded_nodes_list); mem_delete(dht->mem, dht->loaded_nodes_list);
// Copy to loaded_clients_list // Copy to loaded_clients_list
dht->loaded_nodes_list = (Node_format *)calloc(MAX_SAVED_DHT_NODES, sizeof(Node_format)); dht->loaded_nodes_list = (Node_format *)mem_valloc(dht->mem, MAX_SAVED_DHT_NODES, sizeof(Node_format));
if (dht->loaded_nodes_list == nullptr) { if (dht->loaded_nodes_list == nullptr) {
LOGGER_ERROR(dht->log, "could not allocate %u nodes", MAX_SAVED_DHT_NODES); LOGGER_ERROR(dht->log, "could not allocate %u nodes", MAX_SAVED_DHT_NODES);
@ -2997,11 +2907,6 @@ static State_Load_Status dht_load_state_callback(void *outer, const uint8_t *dat
return STATE_LOAD_STATUS_CONTINUE; return STATE_LOAD_STATUS_CONTINUE;
} }
/** @brief Load the DHT from data of size size.
*
* @retval -1 if failure.
* @retval 0 if success.
*/
int dht_load(DHT *dht, const uint8_t *data, uint32_t length) int dht_load(DHT *dht, const uint8_t *data, uint32_t length)
{ {
const uint32_t cookie_len = sizeof(uint32_t); const uint32_t cookie_len = sizeof(uint32_t);
@ -3060,16 +2965,6 @@ bool dht_non_lan_connected(const DHT *dht)
return false; return false;
} }
/** @brief Copies our own ip_port structure to `dest`.
*
* WAN addresses take priority over LAN addresses.
*
* This function will zero the `dest` buffer before use.
*
* @retval 0 if our ip port can't be found (this usually means we're not connected to the DHT).
* @retval 1 if IP is a WAN address.
* @retval 2 if IP is a LAN address.
*/
unsigned int ipport_self_copy(const DHT *dht, IP_Port *dest) unsigned int ipport_self_copy(const DHT *dht, IP_Port *dest)
{ {
ipport_reset(dest); ipport_reset(dest);

View File

@ -14,6 +14,7 @@
#include "attributes.h" #include "attributes.h"
#include "crypto_core.h" #include "crypto_core.h"
#include "logger.h" #include "logger.h"
#include "mem.h"
#include "mono_time.h" #include "mono_time.h"
#include "network.h" #include "network.h"
#include "ping_array.h" #include "ping_array.h"
@ -219,7 +220,7 @@ int pack_ip_port(const Logger *logger, uint8_t *data, uint16_t length, const IP_
* @retval -1 on failure. * @retval -1 on failure.
*/ */
non_null() non_null()
int dht_create_packet(const Random *rng, int dht_create_packet(const Memory *mem, const Random *rng,
const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE],
const uint8_t *shared_key, const uint8_t type, const uint8_t *shared_key, const uint8_t type,
const uint8_t *plain, size_t plain_length, const uint8_t *plain, size_t plain_length,
@ -393,7 +394,7 @@ void set_announce_node(DHT *dht, const uint8_t *public_key);
*/ */
non_null() non_null()
int get_close_nodes(const DHT *dht, const uint8_t *public_key, Node_format *nodes_list, Family sa_family, int get_close_nodes(const DHT *dht, const uint8_t *public_key, Node_format *nodes_list, Family sa_family,
bool is_LAN, bool want_announce); bool is_lan, bool want_announce);
/** @brief Put up to max_num nodes in nodes from the random friends. /** @brief Put up to max_num nodes in nodes from the random friends.
@ -494,8 +495,8 @@ int dht_load(DHT *dht, const uint8_t *data, uint32_t length);
/** Initialize DHT. */ /** Initialize DHT. */
non_null() non_null()
DHT *new_dht(const Logger *log, const Random *rng, const Network *ns, Mono_Time *mono_time, Networking_Core *net, DHT *new_dht(const Logger *log, const Memory *mem, const Random *rng, const Network *ns,
bool hole_punching_enabled, bool lan_discovery_enabled); Mono_Time *mono_time, Networking_Core *net, bool hole_punching_enabled, bool lan_discovery_enabled);
nullable(1) nullable(1)
void kill_dht(DHT *dht); void kill_dht(DHT *dht);

View File

@ -187,12 +187,14 @@ TEST(Request, CreateAndParse)
TEST(AnnounceNodes, SetAndTest) TEST(AnnounceNodes, SetAndTest)
{ {
Logger *log = logger_new();
Mono_Time *mono_time = mono_time_new(nullptr, nullptr);
const Random *rng = system_random(); const Random *rng = system_random();
const Network *ns = system_network(); const Network *ns = system_network();
Networking_Core *net = new_networking_no_udp(log, ns); const Memory *mem = system_memory();
DHT *dht = new_dht(log, rng, ns, mono_time, net, true, true);
Logger *log = logger_new();
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
Networking_Core *net = new_networking_no_udp(log, mem, ns);
DHT *dht = new_dht(log, mem, rng, ns, mono_time, net, true, true);
ASSERT_NE(dht, nullptr); ASSERT_NE(dht, nullptr);
uint8_t pk_data[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t pk_data[CRYPTO_PUBLIC_KEY_SIZE];
@ -224,7 +226,7 @@ TEST(AnnounceNodes, SetAndTest)
kill_dht(dht); kill_dht(dht);
kill_networking(net); kill_networking(net);
mono_time_free(mono_time); mono_time_free(mem, mono_time);
logger_kill(log); logger_kill(log);
} }

View File

@ -57,6 +57,8 @@ libtoxcore_la_SOURCES = ../third_party/cmp/cmp.c \
../toxcore/events/group_voice_state.c \ ../toxcore/events/group_voice_state.c \
../toxcore/DHT.h \ ../toxcore/DHT.h \
../toxcore/DHT.c \ ../toxcore/DHT.c \
../toxcore/mem.h \
../toxcore/mem.c \
../toxcore/mono_time.h \ ../toxcore/mono_time.h \
../toxcore/mono_time.c \ ../toxcore/mono_time.c \
../toxcore/network.h \ ../toxcore/network.h \

View File

@ -41,18 +41,18 @@ bool friend_is_valid(const Messenger *m, int32_t friendnumber)
/** @brief Set the size of the friend list to numfriends. /** @brief Set the size of the friend list to numfriends.
* *
* @retval -1 if realloc fails. * @retval -1 if mem_vrealloc fails.
*/ */
non_null() non_null()
static int realloc_friendlist(Messenger *m, uint32_t num) static int realloc_friendlist(Messenger *m, uint32_t num)
{ {
if (num == 0) { if (num == 0) {
free(m->friendlist); mem_delete(m->mem, m->friendlist);
m->friendlist = nullptr; m->friendlist = nullptr;
return 0; return 0;
} }
Friend *newfriendlist = (Friend *)realloc(m->friendlist, num * sizeof(Friend)); Friend *newfriendlist = (Friend *)mem_vrealloc(m->mem, m->friendlist, num, sizeof(Friend));
if (newfriendlist == nullptr) { if (newfriendlist == nullptr) {
return -1; return -1;
@ -313,7 +313,7 @@ static int clear_receipts(Messenger *m, int32_t friendnumber)
while (receipts != nullptr) { while (receipts != nullptr) {
struct Receipts *temp_r = receipts->next; struct Receipts *temp_r = receipts->next;
free(receipts); mem_delete(m->mem, receipts);
receipts = temp_r; receipts = temp_r;
} }
@ -329,7 +329,7 @@ static int add_receipt(Messenger *m, int32_t friendnumber, uint32_t packet_num,
return -1; return -1;
} }
struct Receipts *new_receipts = (struct Receipts *)calloc(1, sizeof(struct Receipts)); struct Receipts *new_receipts = (struct Receipts *)mem_alloc(m->mem, sizeof(struct Receipts));
if (new_receipts == nullptr) { if (new_receipts == nullptr) {
return -1; return -1;
@ -430,7 +430,7 @@ static int do_receipts(Messenger *m, int32_t friendnumber, void *userdata)
struct Receipts *r_next = receipts->next; struct Receipts *r_next = receipts->next;
free(receipts); mem_delete(m->mem, receipts);
m->friendlist[friendnumber].receipts_start = r_next; m->friendlist[friendnumber].receipts_start = r_next;
@ -2640,7 +2640,7 @@ void do_messenger(Messenger *m, void *userdata)
} }
if (m->tcp_server != nullptr) { if (m->tcp_server != nullptr) {
do_TCP_server(m->tcp_server, m->mono_time); do_tcp_server(m->tcp_server, m->mono_time);
} }
do_net_crypto(m->net_crypto, userdata); do_net_crypto(m->net_crypto, userdata);
@ -2915,15 +2915,16 @@ bool m_register_state_plugin(Messenger *m, State_Type type, m_state_size_cb *siz
m_state_load_cb *load_callback, m_state_load_cb *load_callback,
m_state_save_cb *save_callback) m_state_save_cb *save_callback)
{ {
Messenger_State_Plugin *temp = (Messenger_State_Plugin *)realloc(m->options.state_plugins, const uint32_t new_length = m->options.state_plugins_length + 1;
sizeof(Messenger_State_Plugin) * (m->options.state_plugins_length + 1)); Messenger_State_Plugin *temp = (Messenger_State_Plugin *)mem_vrealloc(
m->mem, m->options.state_plugins, new_length, sizeof(Messenger_State_Plugin));
if (temp == nullptr) { if (temp == nullptr) {
return false; return false;
} }
m->options.state_plugins = temp; m->options.state_plugins = temp;
++m->options.state_plugins_length; m->options.state_plugins_length = new_length;
const uint8_t index = m->options.state_plugins_length - 1; const uint8_t index = m->options.state_plugins_length - 1;
m->options.state_plugins[index].type = type; m->options.state_plugins[index].type = type;
@ -3502,7 +3503,8 @@ static void m_handle_friend_request(
* *
* if error is not NULL it will be set to one of the values in the enum above. * if error is not NULL it will be set to one of the values in the enum above.
*/ */
Messenger *new_messenger(Mono_Time *mono_time, const Random *rng, const Network *ns, Messenger_Options *options, Messenger_Error *error) Messenger *new_messenger(Mono_Time *mono_time, const Memory *mem, const Random *rng, const Network *ns,
Messenger_Options *options, Messenger_Error *error)
{ {
if (options == nullptr) { if (options == nullptr) {
return nullptr; return nullptr;
@ -3512,20 +3514,21 @@ Messenger *new_messenger(Mono_Time *mono_time, const Random *rng, const Network
*error = MESSENGER_ERROR_OTHER; *error = MESSENGER_ERROR_OTHER;
} }
Messenger *m = (Messenger *)calloc(1, sizeof(Messenger)); Messenger *m = (Messenger *)mem_alloc(mem, sizeof(Messenger));
if (m == nullptr) { if (m == nullptr) {
return nullptr; return nullptr;
} }
m->mono_time = mono_time; m->mono_time = mono_time;
m->mem = mem;
m->rng = rng; m->rng = rng;
m->ns = ns; m->ns = ns;
m->fr = friendreq_new(); m->fr = friendreq_new();
if (m->fr == nullptr) { if (m->fr == nullptr) {
free(m); mem_delete(mem, m);
return nullptr; return nullptr;
} }
@ -3533,7 +3536,7 @@ Messenger *new_messenger(Mono_Time *mono_time, const Random *rng, const Network
if (m->log == nullptr) { if (m->log == nullptr) {
friendreq_kill(m->fr); friendreq_kill(m->fr);
free(m); mem_delete(mem, m);
return nullptr; return nullptr;
} }
@ -3548,17 +3551,17 @@ Messenger *new_messenger(Mono_Time *mono_time, const Random *rng, const Network
} }
if (options->udp_disabled) { if (options->udp_disabled) {
m->net = new_networking_no_udp(m->log, m->ns); m->net = new_networking_no_udp(m->log, m->mem, m->ns);
} else { } else {
IP ip; IP ip;
ip_init(&ip, options->ipv6enabled); ip_init(&ip, options->ipv6enabled);
m->net = new_networking_ex(m->log, m->ns, &ip, options->port_range[0], options->port_range[1], &net_err); m->net = new_networking_ex(m->log, m->mem, m->ns, &ip, options->port_range[0], options->port_range[1], &net_err);
} }
if (m->net == nullptr) { if (m->net == nullptr) {
friendreq_kill(m->fr); friendreq_kill(m->fr);
logger_kill(m->log); logger_kill(m->log);
free(m); mem_delete(mem, m);
if (error != nullptr && net_err == 1) { if (error != nullptr && net_err == 1) {
*error = MESSENGER_ERROR_PORT; *error = MESSENGER_ERROR_PORT;
@ -3567,24 +3570,24 @@ Messenger *new_messenger(Mono_Time *mono_time, const Random *rng, const Network
return nullptr; return nullptr;
} }
m->dht = new_dht(m->log, m->rng, m->ns, m->mono_time, m->net, options->hole_punching_enabled, options->local_discovery_enabled); m->dht = new_dht(m->log, m->mem, m->rng, m->ns, m->mono_time, m->net, options->hole_punching_enabled, options->local_discovery_enabled);
if (m->dht == nullptr) { if (m->dht == nullptr) {
kill_networking(m->net); kill_networking(m->net);
friendreq_kill(m->fr); friendreq_kill(m->fr);
logger_kill(m->log); logger_kill(m->log);
free(m); mem_delete(mem, m);
return nullptr; return nullptr;
} }
m->net_crypto = new_net_crypto(m->log, m->rng, m->ns, m->mono_time, m->dht, &options->proxy_info); m->net_crypto = new_net_crypto(m->log, m->mem, m->rng, m->ns, m->mono_time, m->dht, &options->proxy_info);
if (m->net_crypto == nullptr) { if (m->net_crypto == nullptr) {
kill_dht(m->dht); kill_dht(m->dht);
kill_networking(m->net); kill_networking(m->net);
friendreq_kill(m->fr); friendreq_kill(m->fr);
logger_kill(m->log); logger_kill(m->log);
free(m); mem_delete(mem, m);
return nullptr; return nullptr;
} }
@ -3597,7 +3600,7 @@ Messenger *new_messenger(Mono_Time *mono_time, const Random *rng, const Network
kill_networking(m->net); kill_networking(m->net);
friendreq_kill(m->fr); friendreq_kill(m->fr);
logger_kill(m->log); logger_kill(m->log);
free(m); mem_delete(mem, m);
return nullptr; return nullptr;
} }
@ -3605,15 +3608,15 @@ Messenger *new_messenger(Mono_Time *mono_time, const Random *rng, const Network
if (options->dht_announcements_enabled) { if (options->dht_announcements_enabled) {
m->forwarding = new_forwarding(m->log, m->rng, m->mono_time, m->dht); m->forwarding = new_forwarding(m->log, m->rng, m->mono_time, m->dht);
m->announce = new_announcements(m->log, m->rng, m->mono_time, m->forwarding); m->announce = new_announcements(m->log, m->mem, m->rng, m->mono_time, m->forwarding);
} else { } else {
m->forwarding = nullptr; m->forwarding = nullptr;
m->announce = nullptr; m->announce = nullptr;
} }
m->onion = new_onion(m->log, m->mono_time, m->rng, m->dht); m->onion = new_onion(m->log, m->mem, m->mono_time, m->rng, m->dht);
m->onion_a = new_onion_announce(m->log, m->rng, m->mono_time, m->dht); m->onion_a = new_onion_announce(m->log, m->mem, m->rng, m->mono_time, m->dht);
m->onion_c = new_onion_client(m->log, m->rng, m->mono_time, m->net_crypto); m->onion_c = new_onion_client(m->log, m->mem, m->rng, m->mono_time, m->net_crypto);
m->fr_c = new_friend_connections(m->log, m->mono_time, m->ns, m->onion_c, options->local_discovery_enabled); m->fr_c = new_friend_connections(m->log, m->mono_time, m->ns, m->onion_c, options->local_discovery_enabled);
if ((options->dht_announcements_enabled && (m->forwarding == nullptr || m->announce == nullptr)) || if ((options->dht_announcements_enabled && (m->forwarding == nullptr || m->announce == nullptr)) ||
@ -3632,7 +3635,7 @@ Messenger *new_messenger(Mono_Time *mono_time, const Random *rng, const Network
kill_networking(m->net); kill_networking(m->net);
friendreq_kill(m->fr); friendreq_kill(m->fr);
logger_kill(m->log); logger_kill(m->log);
free(m); mem_delete(mem, m);
return nullptr; return nullptr;
} }
@ -3654,15 +3657,16 @@ Messenger *new_messenger(Mono_Time *mono_time, const Random *rng, const Network
kill_networking(m->net); kill_networking(m->net);
friendreq_kill(m->fr); friendreq_kill(m->fr);
logger_kill(m->log); logger_kill(m->log);
free(m); mem_delete(mem, m);
return nullptr; return nullptr;
} }
#endif /* VANILLA_NACL */ #endif /* VANILLA_NACL */
if (options->tcp_server_port != 0) { if (options->tcp_server_port != 0) {
m->tcp_server = new_TCP_server(m->log, m->rng, m->ns, options->ipv6enabled, 1, &options->tcp_server_port, m->tcp_server = new_tcp_server(m->log, m->mem, m->rng, m->ns, options->ipv6enabled, 1,
dht_get_self_secret_key(m->dht), m->onion, m->forwarding); &options->tcp_server_port, dht_get_self_secret_key(m->dht),
m->onion, m->forwarding);
if (m->tcp_server == nullptr) { if (m->tcp_server == nullptr) {
kill_onion(m->onion); kill_onion(m->onion);
@ -3682,7 +3686,7 @@ Messenger *new_messenger(Mono_Time *mono_time, const Random *rng, const Network
kill_networking(m->net); kill_networking(m->net);
friendreq_kill(m->fr); friendreq_kill(m->fr);
logger_kill(m->log); logger_kill(m->log);
free(m); mem_delete(mem, m);
if (error != nullptr) { if (error != nullptr) {
*error = MESSENGER_ERROR_TCP_SERVER; *error = MESSENGER_ERROR_TCP_SERVER;
@ -3721,7 +3725,7 @@ void kill_messenger(Messenger *m)
} }
if (m->tcp_server != nullptr) { if (m->tcp_server != nullptr) {
kill_TCP_server(m->tcp_server); kill_tcp_server(m->tcp_server);
} }
kill_onion(m->onion); kill_onion(m->onion);
@ -3745,11 +3749,11 @@ void kill_messenger(Messenger *m)
} }
logger_kill(m->log); logger_kill(m->log);
free(m->friendlist); mem_delete(m->mem, m->friendlist);
friendreq_kill(m->fr); friendreq_kill(m->fr);
free(m->options.state_plugins); mem_delete(m->mem, m->options.state_plugins);
free(m); mem_delete(m->mem, m);
} }
bool m_is_receiving_file(Messenger *m) bool m_is_receiving_file(Messenger *m)

View File

@ -245,6 +245,7 @@ typedef struct Friend {
struct Messenger { struct Messenger {
Logger *log; Logger *log;
Mono_Time *mono_time; Mono_Time *mono_time;
const Memory *mem;
const Random *rng; const Random *rng;
const Network *ns; const Network *ns;
@ -813,7 +814,8 @@ typedef enum Messenger_Error {
* if error is not NULL it will be set to one of the values in the enum above. * if error is not NULL it will be set to one of the values in the enum above.
*/ */
non_null() non_null()
Messenger *new_messenger(Mono_Time *mono_time, const Random *rng, const Network *ns, Messenger_Options *options, Messenger_Error *error); Messenger *new_messenger(Mono_Time *mono_time, const Memory *mem, const Random *rng, const Network *ns,
Messenger_Options *options, Messenger_Error *error);
/** @brief Run this before closing shop. /** @brief Run this before closing shop.
* *

View File

@ -8,6 +8,7 @@
*/ */
#include "TCP_client.h" #include "TCP_client.h"
#include <assert.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -101,12 +102,12 @@ void tcp_con_set_custom_uint(TCP_Client_Connection *con, uint32_t value)
* @retval false on failure * @retval false on failure
*/ */
non_null() non_null()
static bool connect_sock_to(const Logger *logger, Socket sock, const IP_Port *ip_port, const TCP_Proxy_Info *proxy_info) static bool connect_sock_to(const Logger *logger, const Memory *mem, Socket sock, const IP_Port *ip_port, const TCP_Proxy_Info *proxy_info)
{ {
if (proxy_info->proxy_type != TCP_PROXY_NONE) { if (proxy_info->proxy_type != TCP_PROXY_NONE) {
return net_connect(logger, sock, &proxy_info->ip_port); return net_connect(mem, logger, sock, &proxy_info->ip_port);
} else { } else {
return net_connect(logger, sock, ip_port); return net_connect(mem, logger, sock, ip_port);
} }
} }
@ -151,8 +152,8 @@ static int proxy_http_read_connection_response(const Logger *logger, const TCP_C
char success[] = "200"; char success[] = "200";
uint8_t data[16]; // draining works the best if the length is a power of 2 uint8_t data[16]; // draining works the best if the length is a power of 2
const int ret = read_TCP_packet(logger, tcp_conn->con.ns, tcp_conn->con.sock, data, sizeof(data) - 1, const TCP_Connection *con0 = &tcp_conn->con;
&tcp_conn->con.ip_port); const int ret = read_tcp_packet(logger, con0->mem, con0->ns, con0->sock, data, sizeof(data) - 1, &con0->ip_port);
if (ret == -1) { if (ret == -1) {
return 0; return 0;
@ -167,9 +168,10 @@ static int proxy_http_read_connection_response(const Logger *logger, const TCP_C
while (data_left > 0) { while (data_left > 0) {
uint8_t temp_data[16]; uint8_t temp_data[16];
const uint16_t temp_data_size = min_u16(data_left, sizeof(temp_data)); const uint16_t temp_data_size = min_u16(data_left, sizeof(temp_data));
const TCP_Connection *con = &tcp_conn->con;
if (read_TCP_packet(logger, tcp_conn->con.ns, tcp_conn->con.sock, temp_data, temp_data_size, if (read_tcp_packet(logger, con->mem, con->ns, con->sock, temp_data, temp_data_size,
&tcp_conn->con.ip_port) == -1) { &con->ip_port) == -1) {
LOGGER_ERROR(logger, "failed to drain TCP data (but ignoring failure)"); LOGGER_ERROR(logger, "failed to drain TCP data (but ignoring failure)");
return 1; return 1;
} }
@ -212,7 +214,8 @@ non_null()
static int socks5_read_handshake_response(const Logger *logger, const TCP_Client_Connection *tcp_conn) static int socks5_read_handshake_response(const Logger *logger, const TCP_Client_Connection *tcp_conn)
{ {
uint8_t data[2]; uint8_t data[2];
const int ret = read_TCP_packet(logger, tcp_conn->con.ns, tcp_conn->con.sock, data, sizeof(data), &tcp_conn->con.ip_port); const TCP_Connection *con = &tcp_conn->con;
const int ret = read_tcp_packet(logger, con->mem, con->ns, con->sock, data, sizeof(data), &con->ip_port);
if (ret == -1) { if (ret == -1) {
return 0; return 0;
@ -262,7 +265,8 @@ static int proxy_socks5_read_connection_response(const Logger *logger, const TCP
{ {
if (net_family_is_ipv4(tcp_conn->ip_port.ip.family)) { if (net_family_is_ipv4(tcp_conn->ip_port.ip.family)) {
uint8_t data[4 + sizeof(IP4) + sizeof(uint16_t)]; uint8_t data[4 + sizeof(IP4) + sizeof(uint16_t)];
const int ret = read_TCP_packet(logger, tcp_conn->con.ns, tcp_conn->con.sock, data, sizeof(data), &tcp_conn->con.ip_port); const TCP_Connection *con = &tcp_conn->con;
const int ret = read_tcp_packet(logger, con->mem, con->ns, con->sock, data, sizeof(data), &con->ip_port);
if (ret == -1) { if (ret == -1) {
return 0; return 0;
@ -273,7 +277,8 @@ static int proxy_socks5_read_connection_response(const Logger *logger, const TCP
} }
} else { } else {
uint8_t data[4 + sizeof(IP6) + sizeof(uint16_t)]; uint8_t data[4 + sizeof(IP6) + sizeof(uint16_t)];
int ret = read_TCP_packet(logger, tcp_conn->con.ns, tcp_conn->con.sock, data, sizeof(data), &tcp_conn->con.ip_port); const TCP_Connection *con = &tcp_conn->con;
int ret = read_tcp_packet(logger, con->mem, con->ns, con->sock, data, sizeof(data), &con->ip_port);
if (ret == -1) { if (ret == -1) {
return 0; return 0;
@ -345,7 +350,7 @@ int send_routing_request(const Logger *logger, TCP_Client_Connection *con, const
uint8_t packet[1 + CRYPTO_PUBLIC_KEY_SIZE]; uint8_t packet[1 + CRYPTO_PUBLIC_KEY_SIZE];
packet[0] = TCP_PACKET_ROUTING_REQUEST; packet[0] = TCP_PACKET_ROUTING_REQUEST;
memcpy(packet + 1, public_key, CRYPTO_PUBLIC_KEY_SIZE); memcpy(packet + 1, public_key, CRYPTO_PUBLIC_KEY_SIZE);
return write_packet_TCP_secure_connection(logger, &con->con, packet, sizeof(packet), true); return write_packet_tcp_secure_connection(logger, &con->con, packet, sizeof(packet), true);
} }
void routing_response_handler(TCP_Client_Connection *con, tcp_routing_response_cb *response_callback, void *object) void routing_response_handler(TCP_Client_Connection *con, tcp_routing_response_cb *response_callback, void *object)
@ -385,7 +390,7 @@ int send_data(const Logger *logger, TCP_Client_Connection *con, uint8_t con_id,
VLA(uint8_t, packet, 1 + length); VLA(uint8_t, packet, 1 + length);
packet[0] = con_id + NUM_RESERVED_PORTS; packet[0] = con_id + NUM_RESERVED_PORTS;
memcpy(packet + 1, data, length); memcpy(packet + 1, data, length);
return write_packet_TCP_secure_connection(logger, &con->con, packet, SIZEOF_VLA(packet), false); return write_packet_tcp_secure_connection(logger, &con->con, packet, SIZEOF_VLA(packet), false);
} }
/** /**
@ -404,7 +409,7 @@ int send_oob_packet(const Logger *logger, TCP_Client_Connection *con, const uint
packet[0] = TCP_PACKET_OOB_SEND; packet[0] = TCP_PACKET_OOB_SEND;
memcpy(packet + 1, public_key, CRYPTO_PUBLIC_KEY_SIZE); memcpy(packet + 1, public_key, CRYPTO_PUBLIC_KEY_SIZE);
memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, data, length); memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, data, length);
return write_packet_TCP_secure_connection(logger, &con->con, packet, SIZEOF_VLA(packet), false); return write_packet_tcp_secure_connection(logger, &con->con, packet, SIZEOF_VLA(packet), false);
} }
@ -452,7 +457,7 @@ static int client_send_disconnect_notification(const Logger *logger, TCP_Client_
uint8_t packet[1 + 1]; uint8_t packet[1 + 1];
packet[0] = TCP_PACKET_DISCONNECT_NOTIFICATION; packet[0] = TCP_PACKET_DISCONNECT_NOTIFICATION;
packet[1] = id; packet[1] = id;
return write_packet_TCP_secure_connection(logger, &con->con, packet, sizeof(packet), true); return write_packet_tcp_secure_connection(logger, &con->con, packet, sizeof(packet), true);
} }
/** /**
@ -469,7 +474,7 @@ static int tcp_send_ping_request(const Logger *logger, TCP_Client_Connection *co
uint8_t packet[1 + sizeof(uint64_t)]; uint8_t packet[1 + sizeof(uint64_t)];
packet[0] = TCP_PACKET_PING; packet[0] = TCP_PACKET_PING;
memcpy(packet + 1, &con->ping_request_id, sizeof(uint64_t)); memcpy(packet + 1, &con->ping_request_id, sizeof(uint64_t));
const int ret = write_packet_TCP_secure_connection(logger, &con->con, packet, sizeof(packet), true); const int ret = write_packet_tcp_secure_connection(logger, &con->con, packet, sizeof(packet), true);
if (ret == 1) { if (ret == 1) {
con->ping_request_id = 0; con->ping_request_id = 0;
@ -492,7 +497,7 @@ static int tcp_send_ping_response(const Logger *logger, TCP_Client_Connection *c
uint8_t packet[1 + sizeof(uint64_t)]; uint8_t packet[1 + sizeof(uint64_t)];
packet[0] = TCP_PACKET_PONG; packet[0] = TCP_PACKET_PONG;
memcpy(packet + 1, &con->ping_response_id, sizeof(uint64_t)); memcpy(packet + 1, &con->ping_response_id, sizeof(uint64_t));
const int ret = write_packet_TCP_secure_connection(logger, &con->con, packet, sizeof(packet), true); const int ret = write_packet_tcp_secure_connection(logger, &con->con, packet, sizeof(packet), true);
if (ret == 1) { if (ret == 1) {
con->ping_response_id = 0; con->ping_response_id = 0;
@ -527,7 +532,7 @@ int send_onion_request(const Logger *logger, TCP_Client_Connection *con, const u
VLA(uint8_t, packet, 1 + length); VLA(uint8_t, packet, 1 + length);
packet[0] = TCP_PACKET_ONION_REQUEST; packet[0] = TCP_PACKET_ONION_REQUEST;
memcpy(packet + 1, data, length); memcpy(packet + 1, data, length);
return write_packet_TCP_secure_connection(logger, &con->con, packet, SIZEOF_VLA(packet), false); return write_packet_tcp_secure_connection(logger, &con->con, packet, SIZEOF_VLA(packet), false);
} }
void onion_response_handler(TCP_Client_Connection *con, tcp_onion_response_cb *onion_callback, void *object) void onion_response_handler(TCP_Client_Connection *con, tcp_onion_response_cb *onion_callback, void *object)
@ -555,7 +560,7 @@ int send_forward_request_tcp(const Logger *logger, TCP_Client_Connection *con, c
} }
memcpy(packet + 1 + ipport_length, data, length); memcpy(packet + 1 + ipport_length, data, length);
return write_packet_TCP_secure_connection(logger, &con->con, packet, 1 + ipport_length + length, false); return write_packet_tcp_secure_connection(logger, &con->con, packet, 1 + ipport_length + length, false);
} }
void forwarding_handler(TCP_Client_Connection *con, forwarded_response_cb *forwarded_response_callback, void *object) void forwarding_handler(TCP_Client_Connection *con, forwarded_response_cb *forwarded_response_callback, void *object)
@ -565,11 +570,17 @@ void forwarding_handler(TCP_Client_Connection *con, forwarded_response_cb *forwa
} }
/** Create new TCP connection to ip_port/public_key */ /** Create new TCP connection to ip_port/public_key */
TCP_Client_Connection *new_TCP_connection( TCP_Client_Connection *new_tcp_connection(
const Logger *logger, const Mono_Time *mono_time, const Random *rng, const Network *ns, const IP_Port *ip_port, const Logger *logger, const Memory *mem, const Mono_Time *mono_time, const Random *rng, const Network *ns,
const uint8_t *public_key, const uint8_t *self_public_key, const uint8_t *self_secret_key, 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) const TCP_Proxy_Info *proxy_info)
{ {
assert(logger != nullptr);
assert(mem != nullptr);
assert(mono_time != nullptr);
assert(rng != nullptr);
assert(ns != nullptr);
if (!net_family_is_ipv4(ip_port->ip.family) && !net_family_is_ipv6(ip_port->ip.family)) { if (!net_family_is_ipv4(ip_port->ip.family) && !net_family_is_ipv6(ip_port->ip.family)) {
return nullptr; return nullptr;
} }
@ -597,12 +608,12 @@ TCP_Client_Connection *new_TCP_connection(
return nullptr; return nullptr;
} }
if (!(set_socket_nonblock(ns, sock) && connect_sock_to(logger, sock, ip_port, proxy_info))) { if (!(set_socket_nonblock(ns, sock) && connect_sock_to(logger, mem, sock, ip_port, proxy_info))) {
kill_sock(ns, sock); kill_sock(ns, sock);
return nullptr; return nullptr;
} }
TCP_Client_Connection *temp = (TCP_Client_Connection *)calloc(1, sizeof(TCP_Client_Connection)); TCP_Client_Connection *temp = (TCP_Client_Connection *)mem_alloc(mem, sizeof(TCP_Client_Connection));
if (temp == nullptr) { if (temp == nullptr) {
kill_sock(ns, sock); kill_sock(ns, sock);
@ -610,6 +621,7 @@ TCP_Client_Connection *new_TCP_connection(
} }
temp->con.ns = ns; temp->con.ns = ns;
temp->con.mem = mem;
temp->con.rng = rng; temp->con.rng = rng;
temp->con.sock = sock; temp->con.sock = sock;
temp->con.ip_port = *ip_port; temp->con.ip_port = *ip_port;
@ -637,7 +649,7 @@ TCP_Client_Connection *new_TCP_connection(
if (generate_handshake(temp) == -1) { if (generate_handshake(temp) == -1) {
kill_sock(ns, sock); kill_sock(ns, sock);
free(temp); mem_delete(mem, temp);
return nullptr; return nullptr;
} }
@ -651,7 +663,7 @@ TCP_Client_Connection *new_TCP_connection(
} }
non_null() non_null()
static int handle_TCP_client_routing_response(TCP_Client_Connection *conn, const uint8_t *data, uint16_t length) static int handle_tcp_client_routing_response(TCP_Client_Connection *conn, const uint8_t *data, uint16_t length)
{ {
if (length != 1 + 1 + CRYPTO_PUBLIC_KEY_SIZE) { if (length != 1 + 1 + CRYPTO_PUBLIC_KEY_SIZE) {
return -1; return -1;
@ -679,7 +691,7 @@ static int handle_TCP_client_routing_response(TCP_Client_Connection *conn, const
} }
non_null() non_null()
static int handle_TCP_client_connection_notification(TCP_Client_Connection *conn, const uint8_t *data, uint16_t length) static int handle_tcp_client_connection_notification(TCP_Client_Connection *conn, const uint8_t *data, uint16_t length)
{ {
if (length != 1 + 1) { if (length != 1 + 1) {
return -1; return -1;
@ -706,7 +718,7 @@ static int handle_TCP_client_connection_notification(TCP_Client_Connection *conn
} }
non_null() non_null()
static int handle_TCP_client_disconnect_notification(TCP_Client_Connection *conn, const uint8_t *data, uint16_t length) static int handle_tcp_client_disconnect_notification(TCP_Client_Connection *conn, const uint8_t *data, uint16_t length)
{ {
if (length != 1 + 1) { if (length != 1 + 1) {
return -1; return -1;
@ -737,7 +749,7 @@ static int handle_TCP_client_disconnect_notification(TCP_Client_Connection *conn
} }
non_null() non_null()
static int handle_TCP_client_ping(const Logger *logger, TCP_Client_Connection *conn, const uint8_t *data, uint16_t length) static int handle_tcp_client_ping(const Logger *logger, TCP_Client_Connection *conn, const uint8_t *data, uint16_t length)
{ {
if (length != 1 + sizeof(uint64_t)) { if (length != 1 + sizeof(uint64_t)) {
return -1; return -1;
@ -751,7 +763,7 @@ static int handle_TCP_client_ping(const Logger *logger, TCP_Client_Connection *c
} }
non_null() non_null()
static int handle_TCP_client_pong(TCP_Client_Connection *conn, const uint8_t *data, uint16_t length) static int handle_tcp_client_pong(TCP_Client_Connection *conn, const uint8_t *data, uint16_t length)
{ {
if (length != 1 + sizeof(uint64_t)) { if (length != 1 + sizeof(uint64_t)) {
return -1; return -1;
@ -772,7 +784,7 @@ static int handle_TCP_client_pong(TCP_Client_Connection *conn, const uint8_t *da
} }
non_null(1, 2) nullable(4) non_null(1, 2) nullable(4)
static int handle_TCP_client_oob_recv(TCP_Client_Connection *conn, const uint8_t *data, uint16_t length, void *userdata) static int handle_tcp_client_oob_recv(TCP_Client_Connection *conn, const uint8_t *data, uint16_t length, void *userdata)
{ {
if (length <= 1 + CRYPTO_PUBLIC_KEY_SIZE) { if (length <= 1 + CRYPTO_PUBLIC_KEY_SIZE) {
return -1; return -1;
@ -791,7 +803,7 @@ static int handle_TCP_client_oob_recv(TCP_Client_Connection *conn, const uint8_t
* @retval -1 on failure * @retval -1 on failure
*/ */
non_null(1, 2, 3) nullable(5) non_null(1, 2, 3) nullable(5)
static int handle_TCP_client_packet(const Logger *logger, TCP_Client_Connection *conn, const uint8_t *data, static int handle_tcp_client_packet(const Logger *logger, TCP_Client_Connection *conn, const uint8_t *data,
uint16_t length, void *userdata) uint16_t length, void *userdata)
{ {
if (length <= 1) { if (length <= 1) {
@ -800,22 +812,22 @@ static int handle_TCP_client_packet(const Logger *logger, TCP_Client_Connection
switch (data[0]) { switch (data[0]) {
case TCP_PACKET_ROUTING_RESPONSE: case TCP_PACKET_ROUTING_RESPONSE:
return handle_TCP_client_routing_response(conn, data, length); return handle_tcp_client_routing_response(conn, data, length);
case TCP_PACKET_CONNECTION_NOTIFICATION: case TCP_PACKET_CONNECTION_NOTIFICATION:
return handle_TCP_client_connection_notification(conn, data, length); return handle_tcp_client_connection_notification(conn, data, length);
case TCP_PACKET_DISCONNECT_NOTIFICATION: case TCP_PACKET_DISCONNECT_NOTIFICATION:
return handle_TCP_client_disconnect_notification(conn, data, length); return handle_tcp_client_disconnect_notification(conn, data, length);
case TCP_PACKET_PING: case TCP_PACKET_PING:
return handle_TCP_client_ping(logger, conn, data, length); return handle_tcp_client_ping(logger, conn, data, length);
case TCP_PACKET_PONG: case TCP_PACKET_PONG:
return handle_TCP_client_pong(conn, data, length); return handle_tcp_client_pong(conn, data, length);
case TCP_PACKET_OOB_RECV: case TCP_PACKET_OOB_RECV:
return handle_TCP_client_oob_recv(conn, data, length, userdata); return handle_tcp_client_oob_recv(conn, data, length, userdata);
case TCP_PACKET_ONION_RESPONSE: { case TCP_PACKET_ONION_RESPONSE: {
if (conn->onion_callback != nullptr) { if (conn->onion_callback != nullptr) {
@ -852,7 +864,7 @@ non_null(1, 2) nullable(3)
static bool tcp_process_packet(const Logger *logger, TCP_Client_Connection *conn, void *userdata) static bool tcp_process_packet(const Logger *logger, TCP_Client_Connection *conn, void *userdata)
{ {
uint8_t packet[MAX_PACKET_SIZE]; uint8_t packet[MAX_PACKET_SIZE];
const int len = read_packet_TCP_secure_connection(logger, conn->con.ns, conn->con.sock, &conn->next_packet_length, conn->con.shared_key, conn->recv_nonce, packet, sizeof(packet), &conn->ip_port); const int len = read_packet_tcp_secure_connection(logger, conn->con.mem, conn->con.ns, conn->con.sock, &conn->next_packet_length, conn->con.shared_key, conn->recv_nonce, packet, sizeof(packet), &conn->ip_port);
if (len == 0) { if (len == 0) {
return false; return false;
@ -863,7 +875,7 @@ static bool tcp_process_packet(const Logger *logger, TCP_Client_Connection *conn
return false; return false;
} }
if (handle_TCP_client_packet(logger, conn, packet, len, userdata) == -1) { if (handle_tcp_client_packet(logger, conn, packet, len, userdata) == -1) {
conn->status = TCP_CLIENT_DISCONNECTED; conn->status = TCP_CLIENT_DISCONNECTED;
return false; return false;
} }
@ -872,7 +884,7 @@ static bool tcp_process_packet(const Logger *logger, TCP_Client_Connection *conn
} }
non_null(1, 2, 3) nullable(4) non_null(1, 2, 3) nullable(4)
static int do_confirmed_TCP(const Logger *logger, TCP_Client_Connection *conn, const Mono_Time *mono_time, static int do_confirmed_tcp(const Logger *logger, TCP_Client_Connection *conn, const Mono_Time *mono_time,
void *userdata) void *userdata)
{ {
send_pending_data(logger, &conn->con); send_pending_data(logger, &conn->con);
@ -906,7 +918,7 @@ static int do_confirmed_TCP(const Logger *logger, TCP_Client_Connection *conn, c
} }
/** Run the TCP connection */ /** Run the TCP connection */
void do_TCP_connection(const Logger *logger, const Mono_Time *mono_time, void do_tcp_connection(const Logger *logger, const Mono_Time *mono_time,
TCP_Client_Connection *tcp_connection, void *userdata) TCP_Client_Connection *tcp_connection, void *userdata)
{ {
if (tcp_connection->status == TCP_CLIENT_DISCONNECTED) { if (tcp_connection->status == TCP_CLIENT_DISCONNECTED) {
@ -969,7 +981,8 @@ void do_TCP_connection(const Logger *logger, const Mono_Time *mono_time,
if (tcp_connection->status == TCP_CLIENT_UNCONFIRMED) { if (tcp_connection->status == TCP_CLIENT_UNCONFIRMED) {
uint8_t data[TCP_SERVER_HANDSHAKE_SIZE]; uint8_t data[TCP_SERVER_HANDSHAKE_SIZE];
const int len = read_TCP_packet(logger, tcp_connection->con.ns, tcp_connection->con.sock, data, sizeof(data), &tcp_connection->con.ip_port); const TCP_Connection *con = &tcp_connection->con;
const int len = read_tcp_packet(logger, con->mem, con->ns, con->sock, data, sizeof(data), &con->ip_port);
if (sizeof(data) == len) { if (sizeof(data) == len) {
if (handle_handshake(tcp_connection, data) == 0) { if (handle_handshake(tcp_connection, data) == 0) {
@ -983,7 +996,7 @@ void do_TCP_connection(const Logger *logger, const Mono_Time *mono_time,
} }
if (tcp_connection->status == TCP_CLIENT_CONFIRMED) { if (tcp_connection->status == TCP_CLIENT_CONFIRMED) {
do_confirmed_TCP(logger, tcp_connection, mono_time, userdata); do_confirmed_tcp(logger, tcp_connection, mono_time, userdata);
} }
if (tcp_connection->kill_at <= mono_time_get(mono_time)) { if (tcp_connection->kill_at <= mono_time_get(mono_time)) {
@ -992,14 +1005,16 @@ void do_TCP_connection(const Logger *logger, const Mono_Time *mono_time,
} }
/** Kill the TCP connection */ /** Kill the TCP connection */
void kill_TCP_connection(TCP_Client_Connection *tcp_connection) void kill_tcp_connection(TCP_Client_Connection *tcp_connection)
{ {
if (tcp_connection == nullptr) { if (tcp_connection == nullptr) {
return; return;
} }
wipe_priority_list(tcp_connection->con.priority_queue_start); const Memory *mem = tcp_connection->con.mem;
wipe_priority_list(tcp_connection->con.mem, tcp_connection->con.priority_queue_start);
kill_sock(tcp_connection->con.ns, tcp_connection->con.sock); kill_sock(tcp_connection->con.ns, tcp_connection->con.sock);
crypto_memzero(tcp_connection, sizeof(TCP_Client_Connection)); crypto_memzero(tcp_connection, sizeof(TCP_Client_Connection));
free(tcp_connection); mem_delete(mem, tcp_connection);
} }

View File

@ -57,20 +57,20 @@ non_null()
void tcp_con_set_custom_uint(TCP_Client_Connection *con, uint32_t value); void tcp_con_set_custom_uint(TCP_Client_Connection *con, uint32_t value);
/** Create new TCP connection to ip_port/public_key */ /** Create new TCP connection to ip_port/public_key */
non_null(1, 2, 3, 4, 5, 6, 7, 8) nullable(9) non_null(1, 2, 3, 4, 5, 6, 7, 8, 9) nullable(10)
TCP_Client_Connection *new_TCP_connection( TCP_Client_Connection *new_tcp_connection(
const Logger *logger, const Mono_Time *mono_time, const Random *rng, const Network *ns, const IP_Port *ip_port, const Logger *logger, const Memory *mem, const Mono_Time *mono_time, const Random *rng, const Network *ns,
const uint8_t *public_key, const uint8_t *self_public_key, const uint8_t *self_secret_key, 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); const TCP_Proxy_Info *proxy_info);
/** Run the TCP connection */ /** Run the TCP connection */
non_null(1, 2, 3) nullable(4) non_null(1, 2, 3) nullable(4)
void do_TCP_connection(const Logger *logger, const Mono_Time *mono_time, void do_tcp_connection(const Logger *logger, const Mono_Time *mono_time,
TCP_Client_Connection *tcp_connection, void *userdata); TCP_Client_Connection *tcp_connection, void *userdata);
/** Kill the TCP connection */ /** Kill the TCP connection */
nullable(1) nullable(1)
void kill_TCP_connection(TCP_Client_Connection *tcp_connection); void kill_tcp_connection(TCP_Client_Connection *tcp_connection);
typedef int tcp_onion_response_cb(void *object, const uint8_t *data, uint16_t length, void *userdata); typedef int tcp_onion_response_cb(void *object, const uint8_t *data, uint16_t length, void *userdata);

View File

@ -10,13 +10,13 @@
#include "ccompat.h" #include "ccompat.h"
void wipe_priority_list(TCP_Priority_List *p) void wipe_priority_list(const Memory *mem, TCP_Priority_List *p)
{ {
while (p != nullptr) { while (p != nullptr) {
TCP_Priority_List *pp = p; TCP_Priority_List *pp = p;
p = p->next; p = p->next;
free(pp->data); mem_delete(mem, pp->data);
free(pp); mem_delete(mem, pp);
} }
} }
@ -74,8 +74,8 @@ int send_pending_data(const Logger *logger, TCP_Connection *con)
TCP_Priority_List *pp = p; TCP_Priority_List *pp = p;
p = p->next; p = p->next;
free(pp->data); mem_delete(con->mem, pp->data);
free(pp); mem_delete(con->mem, pp);
} }
con->priority_queue_start = p; con->priority_queue_start = p;
@ -89,14 +89,14 @@ int send_pending_data(const Logger *logger, TCP_Connection *con)
} }
/** /**
* @retval false on failure (only if calloc fails) * @retval false on failure (only if mem_alloc fails)
* @retval true on success * @retval true on success
*/ */
non_null() non_null()
static bool add_priority(TCP_Connection *con, const uint8_t *packet, uint16_t size, uint16_t sent) static bool add_priority(TCP_Connection *con, const uint8_t *packet, uint16_t size, uint16_t sent)
{ {
TCP_Priority_List *p = con->priority_queue_end; TCP_Priority_List *p = con->priority_queue_end;
TCP_Priority_List *new_list = (TCP_Priority_List *)calloc(1, sizeof(TCP_Priority_List)); TCP_Priority_List *new_list = (TCP_Priority_List *)mem_alloc(con->mem, sizeof(TCP_Priority_List));
if (new_list == nullptr) { if (new_list == nullptr) {
return false; return false;
@ -105,10 +105,10 @@ static bool add_priority(TCP_Connection *con, const uint8_t *packet, uint16_t si
new_list->next = nullptr; new_list->next = nullptr;
new_list->size = size; new_list->size = size;
new_list->sent = sent; new_list->sent = sent;
new_list->data = (uint8_t *)malloc(size); new_list->data = (uint8_t *)mem_balloc(con->mem, size);
if (new_list->data == nullptr) { if (new_list->data == nullptr) {
free(new_list); mem_delete(con->mem, new_list);
return false; return false;
} }
@ -129,7 +129,7 @@ static bool add_priority(TCP_Connection *con, const uint8_t *packet, uint16_t si
* @retval 0 if could not send packet. * @retval 0 if could not send packet.
* @retval -1 on failure (connection must be killed). * @retval -1 on failure (connection must be killed).
*/ */
int write_packet_TCP_secure_connection(const Logger *logger, TCP_Connection *con, const uint8_t *data, uint16_t length, int write_packet_tcp_secure_connection(const Logger *logger, TCP_Connection *con, const uint8_t *data, uint16_t length,
bool priority) bool priority)
{ {
if (length + CRYPTO_MAC_SIZE > MAX_PACKET_SIZE) { if (length + CRYPTO_MAC_SIZE > MAX_PACKET_SIZE) {
@ -195,7 +195,8 @@ int write_packet_TCP_secure_connection(const Logger *logger, TCP_Connection *con
* return length on success * return length on success
* return -1 on failure/no data in buffer. * return -1 on failure/no data in buffer.
*/ */
int read_TCP_packet(const Logger *logger, const Network *ns, Socket sock, uint8_t *data, uint16_t length, const IP_Port *ip_port) int read_tcp_packet(
const Logger *logger, const Memory *mem, const Network *ns, Socket sock, uint8_t *data, uint16_t length, const IP_Port *ip_port)
{ {
const uint16_t count = net_socket_data_recv_buffer(ns, sock); const uint16_t count = net_socket_data_recv_buffer(ns, sock);
@ -222,7 +223,7 @@ int read_TCP_packet(const Logger *logger, const Network *ns, Socket sock, uint8_
* return -1 on failure. * return -1 on failure.
*/ */
non_null() non_null()
static uint16_t read_TCP_length(const Logger *logger, const Network *ns, Socket sock, const IP_Port *ip_port) static uint16_t read_tcp_length(const Logger *logger, const Memory *mem, const Network *ns, Socket sock, const IP_Port *ip_port)
{ {
const uint16_t count = net_socket_data_recv_buffer(ns, sock); const uint16_t count = net_socket_data_recv_buffer(ns, sock);
@ -254,13 +255,14 @@ static uint16_t read_TCP_length(const Logger *logger, const Network *ns, Socket
* @retval 0 if could not read any packet. * @retval 0 if could not read any packet.
* @retval -1 on failure (connection must be killed). * @retval -1 on failure (connection must be killed).
*/ */
int read_packet_TCP_secure_connection( int read_packet_tcp_secure_connection(
const Logger *logger, const Network *ns, Socket sock, uint16_t *next_packet_length, const Logger *logger, const Memory *mem, const Network *ns,
Socket sock, uint16_t *next_packet_length,
const uint8_t *shared_key, uint8_t *recv_nonce, uint8_t *data, const uint8_t *shared_key, uint8_t *recv_nonce, uint8_t *data,
uint16_t max_len, const IP_Port *ip_port) uint16_t max_len, const IP_Port *ip_port)
{ {
if (*next_packet_length == 0) { if (*next_packet_length == 0) {
const uint16_t len = read_TCP_length(logger, ns, sock, ip_port); const uint16_t len = read_tcp_length(logger, mem, ns, sock, ip_port);
if (len == (uint16_t) -1) { if (len == (uint16_t) -1) {
return -1; return -1;
@ -279,7 +281,7 @@ int read_packet_TCP_secure_connection(
} }
VLA(uint8_t, data_encrypted, (int) *next_packet_length); VLA(uint8_t, data_encrypted, (int) *next_packet_length);
const int len_packet = read_TCP_packet(logger, ns, sock, data_encrypted, *next_packet_length, ip_port); const int len_packet = read_tcp_packet(logger, mem, ns, sock, data_encrypted, *next_packet_length, ip_port);
if (len_packet == -1) { if (len_packet == -1) {
return 0; return 0;

View File

@ -7,6 +7,7 @@
#define C_TOXCORE_TOXCORE_TCP_COMMON_H #define C_TOXCORE_TOXCORE_TCP_COMMON_H
#include "crypto_core.h" #include "crypto_core.h"
#include "mem.h"
#include "network.h" #include "network.h"
typedef struct TCP_Priority_List TCP_Priority_List; typedef struct TCP_Priority_List TCP_Priority_List;
@ -17,8 +18,8 @@ struct TCP_Priority_List {
uint8_t *data; uint8_t *data;
}; };
nullable(1) non_null(1) nullable(2)
void wipe_priority_list(TCP_Priority_List *p); void wipe_priority_list(const Memory *mem, TCP_Priority_List *p);
#define NUM_RESERVED_PORTS 16 #define NUM_RESERVED_PORTS 16
#define NUM_CLIENT_CONNECTIONS (256 - NUM_RESERVED_PORTS) #define NUM_CLIENT_CONNECTIONS (256 - NUM_RESERVED_PORTS)
@ -63,6 +64,7 @@ void wipe_priority_list(TCP_Priority_List *p);
#define MAX_PACKET_SIZE 2048 #define MAX_PACKET_SIZE 2048
typedef struct TCP_Connection { typedef struct TCP_Connection {
const Memory *mem;
const Random *rng; const Random *rng;
const Network *ns; const Network *ns;
Socket sock; Socket sock;
@ -97,7 +99,7 @@ int send_pending_data(const Logger *logger, TCP_Connection *con);
* @retval -1 on failure (connection must be killed). * @retval -1 on failure (connection must be killed).
*/ */
non_null() non_null()
int write_packet_TCP_secure_connection( int write_packet_tcp_secure_connection(
const Logger *logger, TCP_Connection *con, const uint8_t *data, uint16_t length, const Logger *logger, TCP_Connection *con, const uint8_t *data, uint16_t length,
bool priority); bool priority);
@ -107,8 +109,8 @@ int write_packet_TCP_secure_connection(
* return -1 on failure/no data in buffer. * return -1 on failure/no data in buffer.
*/ */
non_null() non_null()
int read_TCP_packet( int read_tcp_packet(
const Logger *logger, const Network *ns, Socket sock, uint8_t *data, uint16_t length, const IP_Port *ip_port); const Logger *logger, const Memory *mem, const Network *ns, Socket sock, uint8_t *data, uint16_t length, const IP_Port *ip_port);
/** /**
* @return length of received packet on success. * @return length of received packet on success.
@ -116,8 +118,9 @@ int read_TCP_packet(
* @retval -1 on failure (connection must be killed). * @retval -1 on failure (connection must be killed).
*/ */
non_null() non_null()
int read_packet_TCP_secure_connection( int read_packet_tcp_secure_connection(
const Logger *logger, const Network *ns, Socket sock, uint16_t *next_packet_length, const Logger *logger, const Memory *mem, const Network *ns,
Socket sock, uint16_t *next_packet_length,
const uint8_t *shared_key, uint8_t *recv_nonce, uint8_t *data, const uint8_t *shared_key, uint8_t *recv_nonce, uint8_t *data,
uint16_t max_len, const IP_Port *ip_port); uint16_t max_len, const IP_Port *ip_port);

View File

@ -19,6 +19,7 @@
struct TCP_Connections { struct TCP_Connections {
const Logger *logger; const Logger *logger;
const Memory *mem;
const Random *rng; const Random *rng;
Mono_Time *mono_time; Mono_Time *mono_time;
const Network *ns; const Network *ns;
@ -69,20 +70,20 @@ uint32_t tcp_connections_count(const TCP_Connections *tcp_c)
/** @brief Set the size of the array to num. /** @brief Set the size of the array to num.
* *
* @retval -1 if realloc fails. * @retval -1 if mem_vrealloc fails.
* @retval 0 if it succeeds. * @retval 0 if it succeeds.
*/ */
non_null() non_null()
static int realloc_TCP_Connection_to(TCP_Connection_to **array, size_t num) static int realloc_tcp_connection_to(const Memory *mem, TCP_Connection_to **array, size_t num)
{ {
if (num == 0) { if (num == 0) {
free(*array); mem_delete(mem, *array);
*array = nullptr; *array = nullptr;
return 0; return 0;
} }
TCP_Connection_to *temp_pointer = TCP_Connection_to *temp_pointer =
(TCP_Connection_to *)realloc(*array, num * sizeof(TCP_Connection_to)); (TCP_Connection_to *)mem_vrealloc(mem, *array, num, sizeof(TCP_Connection_to));
if (temp_pointer == nullptr) { if (temp_pointer == nullptr) {
return -1; return -1;
@ -94,15 +95,15 @@ static int realloc_TCP_Connection_to(TCP_Connection_to **array, size_t num)
} }
non_null() non_null()
static int realloc_TCP_con(TCP_con **array, size_t num) static int realloc_tcp_con(const Memory *mem, TCP_con **array, size_t num)
{ {
if (num == 0) { if (num == 0) {
free(*array); mem_delete(mem, *array);
*array = nullptr; *array = nullptr;
return 0; return 0;
} }
TCP_con *temp_pointer = (TCP_con *)realloc(*array, num * sizeof(TCP_con)); TCP_con *temp_pointer = (TCP_con *)mem_vrealloc(mem, *array, num, sizeof(TCP_con));
if (temp_pointer == nullptr) { if (temp_pointer == nullptr) {
return -1; return -1;
@ -164,7 +165,7 @@ static int create_connection(TCP_Connections *tcp_c)
int id = -1; int id = -1;
if (realloc_TCP_Connection_to(&tcp_c->connections, tcp_c->connections_length + 1) == 0) { if (realloc_tcp_connection_to(tcp_c->mem, &tcp_c->connections, tcp_c->connections_length + 1) == 0) {
id = tcp_c->connections_length; id = tcp_c->connections_length;
++tcp_c->connections_length; ++tcp_c->connections_length;
tcp_c->connections[id] = empty_tcp_connection_to; tcp_c->connections[id] = empty_tcp_connection_to;
@ -189,7 +190,7 @@ static int create_tcp_connection(TCP_Connections *tcp_c)
int id = -1; int id = -1;
if (realloc_TCP_con(&tcp_c->tcp_connections, tcp_c->tcp_connections_length + 1) == 0) { if (realloc_tcp_con(tcp_c->mem, &tcp_c->tcp_connections, tcp_c->tcp_connections_length + 1) == 0) {
id = tcp_c->tcp_connections_length; id = tcp_c->tcp_connections_length;
++tcp_c->tcp_connections_length; ++tcp_c->tcp_connections_length;
tcp_c->tcp_connections[id] = empty_tcp_con; tcp_c->tcp_connections[id] = empty_tcp_con;
@ -221,7 +222,9 @@ static int wipe_connection(TCP_Connections *tcp_c, int connections_number)
if (tcp_c->connections_length != i) { if (tcp_c->connections_length != i) {
tcp_c->connections_length = i; tcp_c->connections_length = i;
realloc_TCP_Connection_to(&tcp_c->connections, tcp_c->connections_length); if (realloc_tcp_connection_to(tcp_c->mem, &tcp_c->connections, tcp_c->connections_length) != 0) {
return -1;
}
} }
return 0; return 0;
@ -251,7 +254,9 @@ static int wipe_tcp_connection(TCP_Connections *tcp_c, int tcp_connections_numbe
if (tcp_c->tcp_connections_length != i) { if (tcp_c->tcp_connections_length != i) {
tcp_c->tcp_connections_length = i; tcp_c->tcp_connections_length = i;
realloc_TCP_con(&tcp_c->tcp_connections, tcp_c->tcp_connections_length); if (realloc_tcp_con(tcp_c->mem, &tcp_c->tcp_connections, tcp_c->tcp_connections_length) != 0) {
return -1;
}
} }
return 0; return 0;
@ -898,7 +903,7 @@ int kill_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connections_number
--tcp_c->onion_num_conns; --tcp_c->onion_num_conns;
} }
kill_TCP_connection(tcp_con->connection); kill_tcp_connection(tcp_con->connection);
return wipe_tcp_connection(tcp_c, tcp_connections_number); return wipe_tcp_connection(tcp_c, tcp_connections_number);
} }
@ -919,8 +924,8 @@ static int reconnect_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connec
IP_Port ip_port = tcp_con_ip_port(tcp_con->connection); IP_Port ip_port = tcp_con_ip_port(tcp_con->connection);
uint8_t relay_pk[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t relay_pk[CRYPTO_PUBLIC_KEY_SIZE];
memcpy(relay_pk, tcp_con_public_key(tcp_con->connection), CRYPTO_PUBLIC_KEY_SIZE); memcpy(relay_pk, tcp_con_public_key(tcp_con->connection), CRYPTO_PUBLIC_KEY_SIZE);
kill_TCP_connection(tcp_con->connection); kill_tcp_connection(tcp_con->connection);
tcp_con->connection = new_TCP_connection(tcp_c->logger, 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_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) { if (tcp_con->connection == nullptr) {
kill_tcp_relay_connection(tcp_c, tcp_connections_number); kill_tcp_relay_connection(tcp_c, tcp_connections_number);
@ -969,7 +974,7 @@ static int sleep_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connection
tcp_con->ip_port = tcp_con_ip_port(tcp_con->connection); tcp_con->ip_port = tcp_con_ip_port(tcp_con->connection);
memcpy(tcp_con->relay_pk, tcp_con_public_key(tcp_con->connection), CRYPTO_PUBLIC_KEY_SIZE); memcpy(tcp_con->relay_pk, tcp_con_public_key(tcp_con->connection), CRYPTO_PUBLIC_KEY_SIZE);
kill_TCP_connection(tcp_con->connection); kill_tcp_connection(tcp_con->connection);
tcp_con->connection = nullptr; tcp_con->connection = nullptr;
for (uint32_t i = 0; i < tcp_c->connections_length; ++i) { for (uint32_t i = 0; i < tcp_c->connections_length; ++i) {
@ -1007,8 +1012,8 @@ static int unsleep_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connecti
return -1; return -1;
} }
tcp_con->connection = new_TCP_connection( tcp_con->connection = new_tcp_connection(
tcp_c->logger, tcp_c->mono_time, tcp_c->rng, tcp_c->ns, &tcp_con->ip_port, 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_con->relay_pk, tcp_c->self_public_key, tcp_c->self_secret_key, &tcp_c->proxy_info);
if (tcp_con->connection == nullptr) { if (tcp_con->connection == nullptr) {
@ -1303,8 +1308,8 @@ static int add_tcp_relay_instance(TCP_Connections *tcp_c, const IP_Port *ip_port
TCP_con *tcp_con = &tcp_c->tcp_connections[tcp_connections_number]; TCP_con *tcp_con = &tcp_c->tcp_connections[tcp_connections_number];
tcp_con->connection = new_TCP_connection( tcp_con->connection = new_tcp_connection(
tcp_c->logger, tcp_c->mono_time, tcp_c->rng, tcp_c->ns, &ipp_copy, 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); relay_pk, tcp_c->self_public_key, tcp_c->self_secret_key, &tcp_c->proxy_info);
if (tcp_con->connection == nullptr) { if (tcp_con->connection == nullptr) {
@ -1580,21 +1585,27 @@ int set_tcp_onion_status(TCP_Connections *tcp_c, bool status)
* *
* Returns NULL on failure. * Returns NULL on failure.
*/ */
TCP_Connections *new_tcp_connections( TCP_Connections *new_tcp_connections(const Logger *logger, const Memory *mem, const Random *rng, const Network *ns,
const Logger *logger, const Random *rng, const Network *ns, Mono_Time *mono_time, const uint8_t *secret_key, Mono_Time *mono_time, const uint8_t *secret_key, const TCP_Proxy_Info *proxy_info)
const TCP_Proxy_Info *proxy_info)
{ {
assert(logger != nullptr);
assert(mem != nullptr);
assert(rng != nullptr);
assert(ns != nullptr);
assert(mono_time != nullptr);
if (secret_key == nullptr) { if (secret_key == nullptr) {
return nullptr; return nullptr;
} }
TCP_Connections *temp = (TCP_Connections *)calloc(1, sizeof(TCP_Connections)); TCP_Connections *temp = (TCP_Connections *)mem_alloc(mem, sizeof(TCP_Connections));
if (temp == nullptr) { if (temp == nullptr) {
return nullptr; return nullptr;
} }
temp->logger = logger; temp->logger = logger;
temp->mem = mem;
temp->rng = rng; temp->rng = rng;
temp->mono_time = mono_time; temp->mono_time = mono_time;
temp->ns = ns; temp->ns = ns;
@ -1617,7 +1628,7 @@ static void do_tcp_conns(const Logger *logger, TCP_Connections *tcp_c, void *use
} }
if (tcp_con->status != TCP_CONN_SLEEPING) { if (tcp_con->status != TCP_CONN_SLEEPING) {
do_TCP_connection(logger, tcp_c->mono_time, tcp_con->connection, userdata); do_tcp_connection(logger, tcp_c->mono_time, tcp_con->connection, userdata);
/* callbacks can change TCP connection address. */ /* callbacks can change TCP connection address. */
tcp_con = get_tcp_connection(tcp_c, i); tcp_con = get_tcp_connection(tcp_c, i);
@ -1702,12 +1713,12 @@ void kill_tcp_connections(TCP_Connections *tcp_c)
} }
for (uint32_t i = 0; i < tcp_c->tcp_connections_length; ++i) { for (uint32_t i = 0; i < tcp_c->tcp_connections_length; ++i) {
kill_TCP_connection(tcp_c->tcp_connections[i].connection); kill_tcp_connection(tcp_c->tcp_connections[i].connection);
} }
crypto_memzero(tcp_c->self_secret_key, sizeof(tcp_c->self_secret_key)); crypto_memzero(tcp_c->self_secret_key, sizeof(tcp_c->self_secret_key));
free(tcp_c->tcp_connections); mem_delete(tcp_c->mem, tcp_c->tcp_connections);
free(tcp_c->connections); mem_delete(tcp_c->mem, tcp_c->connections);
free(tcp_c); mem_delete(tcp_c->mem, tcp_c);
} }

View File

@ -298,9 +298,8 @@ uint32_t tcp_copy_connected_relays_index(const TCP_Connections *tcp_c, Node_form
* Returns NULL on failure. * Returns NULL on failure.
*/ */
non_null() non_null()
TCP_Connections *new_tcp_connections( TCP_Connections *new_tcp_connections(const Logger *logger, const Memory *mem, const Random *rng, const Network *ns,
const Logger *logger, const Random *rng, const Network *ns, Mono_Time *mono_time, Mono_Time *mono_time, const uint8_t *secret_key, const TCP_Proxy_Info *proxy_info);
const uint8_t *secret_key, const TCP_Proxy_Info *proxy_info);
non_null() non_null()
int kill_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connections_number); int kill_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connections_number);

View File

@ -58,6 +58,7 @@ typedef struct TCP_Secure_Connection {
struct TCP_Server { struct TCP_Server {
const Logger *logger; const Logger *logger;
const Memory *mem;
const Random *rng; const Random *rng;
const Network *ns; const Network *ns;
Onion *onion; Onion *onion;
@ -117,9 +118,9 @@ static int alloc_new_connections(TCP_Server *tcp_server, uint32_t num)
return -1; return -1;
} }
TCP_Secure_Connection *new_connections = (TCP_Secure_Connection *)realloc( TCP_Secure_Connection *new_connections = (TCP_Secure_Connection *)mem_vrealloc(
tcp_server->accepted_connection_array, tcp_server->mem, tcp_server->accepted_connection_array,
new_size * sizeof(TCP_Secure_Connection)); new_size, sizeof(TCP_Secure_Connection));
if (new_connections == nullptr) { if (new_connections == nullptr) {
return -1; return -1;
@ -138,7 +139,7 @@ non_null()
static void wipe_secure_connection(TCP_Secure_Connection *con) static void wipe_secure_connection(TCP_Secure_Connection *con)
{ {
if (con->status != 0) { if (con->status != 0) {
wipe_priority_list(con->con.priority_queue_start); wipe_priority_list(con->con.mem, con->con.priority_queue_start);
crypto_memzero(con, sizeof(TCP_Secure_Connection)); crypto_memzero(con, sizeof(TCP_Secure_Connection));
} }
} }
@ -161,7 +162,7 @@ static void free_accepted_connection_array(TCP_Server *tcp_server)
wipe_secure_connection(&tcp_server->accepted_connection_array[i]); wipe_secure_connection(&tcp_server->accepted_connection_array[i]);
} }
free(tcp_server->accepted_connection_array); mem_delete(tcp_server->mem, tcp_server->accepted_connection_array);
tcp_server->accepted_connection_array = nullptr; tcp_server->accepted_connection_array = nullptr;
tcp_server->size_accepted_connections = 0; tcp_server->size_accepted_connections = 0;
} }
@ -171,7 +172,7 @@ static void free_accepted_connection_array(TCP_Server *tcp_server)
* @retval -1 on failure. * @retval -1 on failure.
*/ */
non_null() non_null()
static int get_TCP_connection_index(const TCP_Server *tcp_server, const uint8_t *public_key) static int get_tcp_connection_index(const TCP_Server *tcp_server, const uint8_t *public_key)
{ {
return bs_list_find(&tcp_server->accepted_key_list, public_key); return bs_list_find(&tcp_server->accepted_key_list, public_key);
} }
@ -188,7 +189,7 @@ static int kill_accepted(TCP_Server *tcp_server, int index);
non_null() non_null()
static int add_accepted(TCP_Server *tcp_server, const Mono_Time *mono_time, TCP_Secure_Connection *con) static int add_accepted(TCP_Server *tcp_server, const Mono_Time *mono_time, TCP_Secure_Connection *con)
{ {
int index = get_TCP_connection_index(tcp_server, con->public_key); int index = get_tcp_connection_index(tcp_server, con->public_key);
if (index != -1) { /* If an old connection to the same public key exists, kill it. */ if (index != -1) { /* If an old connection to the same public key exists, kill it. */
kill_accepted(tcp_server, index); kill_accepted(tcp_server, index);
@ -262,7 +263,7 @@ static int del_accepted(TCP_Server *tcp_server, int index)
/** Kill a TCP_Secure_Connection */ /** Kill a TCP_Secure_Connection */
non_null() non_null()
static void kill_TCP_secure_connection(TCP_Secure_Connection *con) static void kill_tcp_secure_connection(TCP_Secure_Connection *con)
{ {
kill_sock(con->con.ns, con->con.sock); kill_sock(con->con.ns, con->con.sock);
wipe_secure_connection(con); wipe_secure_connection(con);
@ -301,7 +302,7 @@ static int kill_accepted(TCP_Server *tcp_server, int index)
* @retval -1 if the connection must be killed. * @retval -1 if the connection must be killed.
*/ */
non_null() non_null()
static int handle_TCP_handshake(const Logger *logger, TCP_Secure_Connection *con, const uint8_t *data, uint16_t length, static int handle_tcp_handshake(const Logger *logger, TCP_Secure_Connection *con, const uint8_t *data, uint16_t length,
const uint8_t *self_secret_key) const uint8_t *self_secret_key)
{ {
if (length != TCP_CLIENT_HANDSHAKE_SIZE) { if (length != TCP_CLIENT_HANDSHAKE_SIZE) {
@ -369,14 +370,14 @@ non_null()
static int read_connection_handshake(const Logger *logger, TCP_Secure_Connection *con, const uint8_t *self_secret_key) static int read_connection_handshake(const Logger *logger, TCP_Secure_Connection *con, const uint8_t *self_secret_key)
{ {
uint8_t data[TCP_CLIENT_HANDSHAKE_SIZE]; uint8_t data[TCP_CLIENT_HANDSHAKE_SIZE];
const int len = read_TCP_packet(logger, con->con.ns, con->con.sock, data, TCP_CLIENT_HANDSHAKE_SIZE, &con->con.ip_port); const int len = read_tcp_packet(logger, con->con.mem, con->con.ns, con->con.sock, data, TCP_CLIENT_HANDSHAKE_SIZE, &con->con.ip_port);
if (len == -1) { if (len == -1) {
LOGGER_TRACE(logger, "connection handshake is not ready yet"); LOGGER_TRACE(logger, "connection handshake is not ready yet");
return 0; return 0;
} }
return handle_TCP_handshake(logger, con, data, len, self_secret_key); return handle_tcp_handshake(logger, con, data, len, self_secret_key);
} }
/** /**
@ -393,7 +394,7 @@ static int send_routing_response(const Logger *logger, TCP_Secure_Connection *co
data[1] = rpid; data[1] = rpid;
memcpy(data + 2, public_key, CRYPTO_PUBLIC_KEY_SIZE); memcpy(data + 2, public_key, CRYPTO_PUBLIC_KEY_SIZE);
return write_packet_TCP_secure_connection(logger, &con->con, data, sizeof(data), true); return write_packet_tcp_secure_connection(logger, &con->con, data, sizeof(data), true);
} }
/** /**
@ -405,7 +406,7 @@ non_null()
static int send_connect_notification(const Logger *logger, TCP_Secure_Connection *con, uint8_t id) static int send_connect_notification(const Logger *logger, TCP_Secure_Connection *con, uint8_t id)
{ {
uint8_t data[2] = {TCP_PACKET_CONNECTION_NOTIFICATION, (uint8_t)(id + NUM_RESERVED_PORTS)}; uint8_t data[2] = {TCP_PACKET_CONNECTION_NOTIFICATION, (uint8_t)(id + NUM_RESERVED_PORTS)};
return write_packet_TCP_secure_connection(logger, &con->con, data, sizeof(data), true); return write_packet_tcp_secure_connection(logger, &con->con, data, sizeof(data), true);
} }
/** /**
@ -417,7 +418,7 @@ non_null()
static int send_disconnect_notification(const Logger *logger, TCP_Secure_Connection *con, uint8_t id) static int send_disconnect_notification(const Logger *logger, TCP_Secure_Connection *con, uint8_t id)
{ {
uint8_t data[2] = {TCP_PACKET_DISCONNECT_NOTIFICATION, (uint8_t)(id + NUM_RESERVED_PORTS)}; uint8_t data[2] = {TCP_PACKET_DISCONNECT_NOTIFICATION, (uint8_t)(id + NUM_RESERVED_PORTS)};
return write_packet_TCP_secure_connection(logger, &con->con, data, sizeof(data), true); return write_packet_tcp_secure_connection(logger, &con->con, data, sizeof(data), true);
} }
/** /**
@ -425,7 +426,7 @@ static int send_disconnect_notification(const Logger *logger, TCP_Secure_Connect
* @retval -1 on failure (connection must be killed). * @retval -1 on failure (connection must be killed).
*/ */
non_null() non_null()
static int handle_TCP_routing_req(TCP_Server *tcp_server, uint32_t con_id, const uint8_t *public_key) static int handle_tcp_routing_req(TCP_Server *tcp_server, uint32_t con_id, const uint8_t *public_key)
{ {
uint32_t index = -1; uint32_t index = -1;
TCP_Secure_Connection *con = &tcp_server->accepted_connection_array[con_id]; TCP_Secure_Connection *con = &tcp_server->accepted_connection_array[con_id];
@ -473,7 +474,7 @@ static int handle_TCP_routing_req(TCP_Server *tcp_server, uint32_t con_id, const
con->connections[index].status = 1; con->connections[index].status = 1;
memcpy(con->connections[index].public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE); memcpy(con->connections[index].public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE);
const int other_index = get_TCP_connection_index(tcp_server, public_key); const int other_index = get_tcp_connection_index(tcp_server, public_key);
if (other_index != -1) { if (other_index != -1) {
uint32_t other_id = -1; uint32_t other_id = -1;
@ -508,7 +509,7 @@ static int handle_TCP_routing_req(TCP_Server *tcp_server, uint32_t con_id, const
* @retval -1 on failure (connection must be killed). * @retval -1 on failure (connection must be killed).
*/ */
non_null() non_null()
static int handle_TCP_oob_send(TCP_Server *tcp_server, uint32_t con_id, const uint8_t *public_key, const uint8_t *data, static int handle_tcp_oob_send(TCP_Server *tcp_server, uint32_t con_id, const uint8_t *public_key, const uint8_t *data,
uint16_t length) uint16_t length)
{ {
if (length == 0 || length > TCP_MAX_OOB_DATA_LENGTH) { if (length == 0 || length > TCP_MAX_OOB_DATA_LENGTH) {
@ -517,14 +518,14 @@ static int handle_TCP_oob_send(TCP_Server *tcp_server, uint32_t con_id, const ui
const TCP_Secure_Connection *con = &tcp_server->accepted_connection_array[con_id]; const TCP_Secure_Connection *con = &tcp_server->accepted_connection_array[con_id];
const int other_index = get_TCP_connection_index(tcp_server, public_key); const int other_index = get_tcp_connection_index(tcp_server, public_key);
if (other_index != -1) { if (other_index != -1) {
VLA(uint8_t, resp_packet, 1 + CRYPTO_PUBLIC_KEY_SIZE + length); VLA(uint8_t, resp_packet, 1 + CRYPTO_PUBLIC_KEY_SIZE + length);
resp_packet[0] = TCP_PACKET_OOB_RECV; resp_packet[0] = TCP_PACKET_OOB_RECV;
memcpy(resp_packet + 1, con->public_key, CRYPTO_PUBLIC_KEY_SIZE); memcpy(resp_packet + 1, con->public_key, CRYPTO_PUBLIC_KEY_SIZE);
memcpy(resp_packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, data, length); memcpy(resp_packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, data, length);
write_packet_TCP_secure_connection(tcp_server->logger, &tcp_server->accepted_connection_array[other_index].con, write_packet_tcp_secure_connection(tcp_server->logger, &tcp_server->accepted_connection_array[other_index].con,
resp_packet, SIZEOF_VLA(resp_packet), false); resp_packet, SIZEOF_VLA(resp_packet), false);
} }
@ -612,7 +613,7 @@ static int handle_onion_recv_1(void *object, const IP_Port *dest, const uint8_t
memcpy(packet + 1, data, length); memcpy(packet + 1, data, length);
packet[0] = TCP_PACKET_ONION_RESPONSE; packet[0] = TCP_PACKET_ONION_RESPONSE;
if (write_packet_TCP_secure_connection(tcp_server->logger, &con->con, packet, SIZEOF_VLA(packet), false) != 1) { if (write_packet_tcp_secure_connection(tcp_server->logger, &con->con, packet, SIZEOF_VLA(packet), false) != 1) {
return 1; return 1;
} }
@ -652,7 +653,7 @@ static bool handle_forward_reply_tcp(void *object, const uint8_t *sendback_data,
memcpy(packet + 1, data, length); memcpy(packet + 1, data, length);
packet[0] = TCP_PACKET_FORWARDING; packet[0] = TCP_PACKET_FORWARDING;
return write_packet_TCP_secure_connection(tcp_server->logger, &con->con, packet, SIZEOF_VLA(packet), false) == 1; return write_packet_tcp_secure_connection(tcp_server->logger, &con->con, packet, SIZEOF_VLA(packet), false) == 1;
} }
/** /**
@ -660,7 +661,7 @@ static bool handle_forward_reply_tcp(void *object, const uint8_t *sendback_data,
* @retval -1 on failure * @retval -1 on failure
*/ */
non_null() non_null()
static int handle_TCP_packet(TCP_Server *tcp_server, uint32_t con_id, const uint8_t *data, uint16_t length) static int handle_tcp_packet(TCP_Server *tcp_server, uint32_t con_id, const uint8_t *data, uint16_t length)
{ {
if (length == 0) { if (length == 0) {
return -1; return -1;
@ -675,7 +676,7 @@ static int handle_TCP_packet(TCP_Server *tcp_server, uint32_t con_id, const uint
} }
LOGGER_TRACE(tcp_server->logger, "handling routing request for %d", con_id); LOGGER_TRACE(tcp_server->logger, "handling routing request for %d", con_id);
return handle_TCP_routing_req(tcp_server, con_id, data + 1); return handle_tcp_routing_req(tcp_server, con_id, data + 1);
} }
case TCP_PACKET_CONNECTION_NOTIFICATION: { case TCP_PACKET_CONNECTION_NOTIFICATION: {
@ -706,7 +707,7 @@ static int handle_TCP_packet(TCP_Server *tcp_server, uint32_t con_id, const uint
uint8_t response[1 + sizeof(uint64_t)]; uint8_t response[1 + sizeof(uint64_t)];
response[0] = TCP_PACKET_PONG; response[0] = TCP_PACKET_PONG;
memcpy(response + 1, data + 1, sizeof(uint64_t)); memcpy(response + 1, data + 1, sizeof(uint64_t));
write_packet_TCP_secure_connection(tcp_server->logger, &con->con, response, sizeof(response), true); write_packet_tcp_secure_connection(tcp_server->logger, &con->con, response, sizeof(response), true);
return 0; return 0;
} }
@ -738,7 +739,7 @@ static int handle_TCP_packet(TCP_Server *tcp_server, uint32_t con_id, const uint
LOGGER_TRACE(tcp_server->logger, "handling oob send for %d", con_id); LOGGER_TRACE(tcp_server->logger, "handling oob send for %d", con_id);
return handle_TCP_oob_send(tcp_server, con_id, data + 1, data + 1 + CRYPTO_PUBLIC_KEY_SIZE, return handle_tcp_oob_send(tcp_server, con_id, data + 1, data + 1 + CRYPTO_PUBLIC_KEY_SIZE,
length - (1 + CRYPTO_PUBLIC_KEY_SIZE)); length - (1 + CRYPTO_PUBLIC_KEY_SIZE));
} }
@ -821,7 +822,7 @@ static int handle_TCP_packet(TCP_Server *tcp_server, uint32_t con_id, const uint
VLA(uint8_t, new_data, length); VLA(uint8_t, new_data, length);
memcpy(new_data, data, length); memcpy(new_data, data, length);
new_data[0] = other_c_id; new_data[0] = other_c_id;
const int ret = write_packet_TCP_secure_connection(tcp_server->logger, const int ret = write_packet_tcp_secure_connection(tcp_server->logger,
&tcp_server->accepted_connection_array[index].con, new_data, length, false); &tcp_server->accepted_connection_array[index].con, new_data, length, false);
if (ret == -1) { if (ret == -1) {
@ -837,20 +838,20 @@ static int handle_TCP_packet(TCP_Server *tcp_server, uint32_t con_id, const uint
non_null() non_null()
static int confirm_TCP_connection(TCP_Server *tcp_server, const Mono_Time *mono_time, TCP_Secure_Connection *con, static int confirm_tcp_connection(TCP_Server *tcp_server, const Mono_Time *mono_time, TCP_Secure_Connection *con,
const uint8_t *data, uint16_t length) const uint8_t *data, uint16_t length)
{ {
const int index = add_accepted(tcp_server, mono_time, con); const int index = add_accepted(tcp_server, mono_time, con);
if (index == -1) { if (index == -1) {
LOGGER_DEBUG(tcp_server->logger, "dropping connection %u: not accepted", (unsigned int)con->identifier); LOGGER_DEBUG(tcp_server->logger, "dropping connection %u: not accepted", (unsigned int)con->identifier);
kill_TCP_secure_connection(con); kill_tcp_secure_connection(con);
return -1; return -1;
} }
wipe_secure_connection(con); wipe_secure_connection(con);
if (handle_TCP_packet(tcp_server, index, data, length) == -1) { if (handle_tcp_packet(tcp_server, index, data, length) == -1) {
LOGGER_DEBUG(tcp_server->logger, "dropping connection %u: data packet (len=%d) not handled", LOGGER_DEBUG(tcp_server->logger, "dropping connection %u: data packet (len=%d) not handled",
(unsigned int)con->identifier, length); (unsigned int)con->identifier, length);
kill_accepted(tcp_server, index); kill_accepted(tcp_server, index);
@ -887,11 +888,12 @@ static int accept_connection(TCP_Server *tcp_server, Socket sock)
if (conn->status != TCP_STATUS_NO_STATUS) { if (conn->status != TCP_STATUS_NO_STATUS) {
LOGGER_DEBUG(tcp_server->logger, "connection %d dropped before accepting", index); LOGGER_DEBUG(tcp_server->logger, "connection %d dropped before accepting", index);
kill_TCP_secure_connection(conn); kill_tcp_secure_connection(conn);
} }
conn->status = TCP_STATUS_CONNECTED; conn->status = TCP_STATUS_CONNECTED;
conn->con.ns = tcp_server->ns; conn->con.ns = tcp_server->ns;
conn->con.mem = tcp_server->mem;
conn->con.rng = tcp_server->rng; conn->con.rng = tcp_server->rng;
conn->con.sock = sock; conn->con.sock = sock;
conn->next_packet_length = 0; conn->next_packet_length = 0;
@ -901,7 +903,7 @@ static int accept_connection(TCP_Server *tcp_server, Socket sock)
} }
non_null() non_null()
static Socket new_listening_TCP_socket(const Logger *logger, const Network *ns, Family family, uint16_t port) static Socket new_listening_tcp_socket(const Logger *logger, const Network *ns, Family family, uint16_t port)
{ {
const Socket sock = net_socket(ns, family, TOX_SOCK_STREAM, TOX_PROTO_TCP); const Socket sock = net_socket(ns, family, TOX_SOCK_STREAM, TOX_PROTO_TCP);
@ -935,7 +937,7 @@ static Socket new_listening_TCP_socket(const Logger *logger, const Network *ns,
return sock; return sock;
} }
TCP_Server *new_TCP_server(const Logger *logger, const Random *rng, const Network *ns, TCP_Server *new_tcp_server(const Logger *logger, const Memory *mem, const Random *rng, const Network *ns,
bool ipv6_enabled, uint16_t num_sockets, bool ipv6_enabled, uint16_t num_sockets,
const uint16_t *ports, const uint8_t *secret_key, Onion *onion, Forwarding *forwarding) const uint16_t *ports, const uint8_t *secret_key, Onion *onion, Forwarding *forwarding)
{ {
@ -949,7 +951,7 @@ TCP_Server *new_TCP_server(const Logger *logger, const Random *rng, const Networ
return nullptr; return nullptr;
} }
TCP_Server *temp = (TCP_Server *)calloc(1, sizeof(TCP_Server)); TCP_Server *temp = (TCP_Server *)mem_alloc(mem, sizeof(TCP_Server));
if (temp == nullptr) { if (temp == nullptr) {
LOGGER_ERROR(logger, "TCP server allocation failed"); LOGGER_ERROR(logger, "TCP server allocation failed");
@ -957,14 +959,15 @@ TCP_Server *new_TCP_server(const Logger *logger, const Random *rng, const Networ
} }
temp->logger = logger; temp->logger = logger;
temp->mem = mem;
temp->ns = ns; temp->ns = ns;
temp->rng = rng; temp->rng = rng;
temp->socks_listening = (Socket *)calloc(num_sockets, sizeof(Socket)); temp->socks_listening = (Socket *)mem_valloc(mem, num_sockets, sizeof(Socket));
if (temp->socks_listening == nullptr) { if (temp->socks_listening == nullptr) {
LOGGER_ERROR(logger, "socket allocation failed"); LOGGER_ERROR(logger, "socket allocation failed");
free(temp); mem_delete(mem, temp);
return nullptr; return nullptr;
} }
@ -973,8 +976,8 @@ TCP_Server *new_TCP_server(const Logger *logger, const Random *rng, const Networ
if (temp->efd == -1) { if (temp->efd == -1) {
LOGGER_ERROR(logger, "epoll initialisation failed"); LOGGER_ERROR(logger, "epoll initialisation failed");
free(temp->socks_listening); mem_delete(mem, temp->socks_listening);
free(temp); mem_delete(mem, temp);
return nullptr; return nullptr;
} }
@ -983,7 +986,7 @@ TCP_Server *new_TCP_server(const Logger *logger, const Random *rng, const Networ
const Family family = ipv6_enabled ? net_family_ipv6() : net_family_ipv4(); const Family family = ipv6_enabled ? net_family_ipv6() : net_family_ipv4();
for (uint32_t i = 0; i < num_sockets; ++i) { for (uint32_t i = 0; i < num_sockets; ++i) {
const Socket sock = new_listening_TCP_socket(logger, ns, family, ports[i]); const Socket sock = new_listening_tcp_socket(logger, ns, family, ports[i]);
if (!sock_valid(sock)) { if (!sock_valid(sock)) {
continue; continue;
@ -1006,8 +1009,8 @@ TCP_Server *new_TCP_server(const Logger *logger, const Random *rng, const Networ
} }
if (temp->num_listening_socks == 0) { if (temp->num_listening_socks == 0) {
free(temp->socks_listening); mem_delete(mem, temp->socks_listening);
free(temp); mem_delete(mem, temp);
return nullptr; return nullptr;
} }
@ -1031,7 +1034,7 @@ TCP_Server *new_TCP_server(const Logger *logger, const Random *rng, const Networ
#ifndef TCP_SERVER_USE_EPOLL #ifndef TCP_SERVER_USE_EPOLL
non_null() non_null()
static void do_TCP_accept_new(TCP_Server *tcp_server) static void do_tcp_accept_new(TCP_Server *tcp_server)
{ {
for (uint32_t sock_idx = 0; sock_idx < tcp_server->num_listening_socks; ++sock_idx) { for (uint32_t sock_idx = 0; sock_idx < tcp_server->num_listening_socks; ++sock_idx) {
@ -1061,7 +1064,7 @@ static int do_incoming(TCP_Server *tcp_server, uint32_t i)
if (ret == -1) { if (ret == -1) {
LOGGER_TRACE(tcp_server->logger, "incoming connection %d dropped due to failed handshake", i); LOGGER_TRACE(tcp_server->logger, "incoming connection %d dropped due to failed handshake", i);
kill_TCP_secure_connection(conn); kill_tcp_secure_connection(conn);
return -1; return -1;
} }
@ -1075,7 +1078,7 @@ static int do_incoming(TCP_Server *tcp_server, uint32_t i)
if (conn_new->status != TCP_STATUS_NO_STATUS) { if (conn_new->status != TCP_STATUS_NO_STATUS) {
LOGGER_ERROR(tcp_server->logger, "incoming connection %d would overwrite existing", i); LOGGER_ERROR(tcp_server->logger, "incoming connection %d would overwrite existing", i);
kill_TCP_secure_connection(conn_new); kill_tcp_secure_connection(conn_new);
} }
move_secure_connection(conn_new, conn_old); move_secure_connection(conn_new, conn_old);
@ -1096,18 +1099,18 @@ static int do_unconfirmed(TCP_Server *tcp_server, const Mono_Time *mono_time, ui
LOGGER_TRACE(tcp_server->logger, "handling unconfirmed TCP connection %d", i); LOGGER_TRACE(tcp_server->logger, "handling unconfirmed TCP connection %d", i);
uint8_t packet[MAX_PACKET_SIZE]; uint8_t packet[MAX_PACKET_SIZE];
const int len = read_packet_TCP_secure_connection(tcp_server->logger, conn->con.ns, conn->con.sock, &conn->next_packet_length, conn->con.shared_key, conn->recv_nonce, packet, sizeof(packet), &conn->con.ip_port); const int len = read_packet_tcp_secure_connection(tcp_server->logger, conn->con.mem, conn->con.ns, conn->con.sock, &conn->next_packet_length, conn->con.shared_key, conn->recv_nonce, packet, sizeof(packet), &conn->con.ip_port);
if (len == 0) { if (len == 0) {
return -1; return -1;
} }
if (len == -1) { if (len == -1) {
kill_TCP_secure_connection(conn); kill_tcp_secure_connection(conn);
return -1; return -1;
} }
return confirm_TCP_connection(tcp_server, mono_time, conn, packet, len); return confirm_tcp_connection(tcp_server, mono_time, conn, packet, len);
} }
non_null() non_null()
@ -1116,7 +1119,7 @@ static bool tcp_process_secure_packet(TCP_Server *tcp_server, uint32_t i)
TCP_Secure_Connection *const conn = &tcp_server->accepted_connection_array[i]; TCP_Secure_Connection *const conn = &tcp_server->accepted_connection_array[i];
uint8_t packet[MAX_PACKET_SIZE]; uint8_t packet[MAX_PACKET_SIZE];
const int len = read_packet_TCP_secure_connection(tcp_server->logger, conn->con.ns, conn->con.sock, &conn->next_packet_length, conn->con.shared_key, conn->recv_nonce, packet, sizeof(packet), &conn->con.ip_port); const int len = read_packet_tcp_secure_connection(tcp_server->logger, conn->con.mem, conn->con.ns, conn->con.sock, &conn->next_packet_length, conn->con.shared_key, conn->recv_nonce, packet, sizeof(packet), &conn->con.ip_port);
LOGGER_TRACE(tcp_server->logger, "processing packet for %d: %d", i, len); LOGGER_TRACE(tcp_server->logger, "processing packet for %d: %d", i, len);
if (len == 0) { if (len == 0) {
@ -1128,7 +1131,7 @@ static bool tcp_process_secure_packet(TCP_Server *tcp_server, uint32_t i)
return false; return false;
} }
if (handle_TCP_packet(tcp_server, i, packet, len) == -1) { if (handle_tcp_packet(tcp_server, i, packet, len) == -1) {
LOGGER_TRACE(tcp_server->logger, "dropping connection %d: data packet (len=%d) not handled", i, len); LOGGER_TRACE(tcp_server->logger, "dropping connection %d: data packet (len=%d) not handled", i, len);
kill_accepted(tcp_server, i); kill_accepted(tcp_server, i);
return false; return false;
@ -1148,7 +1151,7 @@ static void do_confirmed_recv(TCP_Server *tcp_server, uint32_t i)
#ifndef TCP_SERVER_USE_EPOLL #ifndef TCP_SERVER_USE_EPOLL
non_null() non_null()
static void do_TCP_incoming(TCP_Server *tcp_server) static void do_tcp_incoming(TCP_Server *tcp_server)
{ {
for (uint32_t i = 0; i < MAX_INCOMING_CONNECTIONS; ++i) { for (uint32_t i = 0; i < MAX_INCOMING_CONNECTIONS; ++i) {
do_incoming(tcp_server, i); do_incoming(tcp_server, i);
@ -1156,7 +1159,7 @@ static void do_TCP_incoming(TCP_Server *tcp_server)
} }
non_null() non_null()
static void do_TCP_unconfirmed(TCP_Server *tcp_server, const Mono_Time *mono_time) static void do_tcp_unconfirmed(TCP_Server *tcp_server, const Mono_Time *mono_time)
{ {
for (uint32_t i = 0; i < MAX_INCOMING_CONNECTIONS; ++i) { for (uint32_t i = 0; i < MAX_INCOMING_CONNECTIONS; ++i) {
do_unconfirmed(tcp_server, mono_time, i); do_unconfirmed(tcp_server, mono_time, i);
@ -1165,7 +1168,7 @@ static void do_TCP_unconfirmed(TCP_Server *tcp_server, const Mono_Time *mono_tim
#endif #endif
non_null() non_null()
static void do_TCP_confirmed(TCP_Server *tcp_server, const Mono_Time *mono_time) static void do_tcp_confirmed(TCP_Server *tcp_server, const Mono_Time *mono_time)
{ {
#ifdef TCP_SERVER_USE_EPOLL #ifdef TCP_SERVER_USE_EPOLL
@ -1193,7 +1196,7 @@ static void do_TCP_confirmed(TCP_Server *tcp_server, const Mono_Time *mono_time)
} }
memcpy(ping + 1, &ping_id, sizeof(uint64_t)); memcpy(ping + 1, &ping_id, sizeof(uint64_t));
const int ret = write_packet_TCP_secure_connection(tcp_server->logger, &conn->con, ping, sizeof(ping), true); const int ret = write_packet_tcp_secure_connection(tcp_server->logger, &conn->con, ping, sizeof(ping), true);
if (ret == 1) { if (ret == 1) {
conn->last_pinged = mono_time_get(mono_time); conn->last_pinged = mono_time_get(mono_time);
@ -1245,13 +1248,13 @@ static bool tcp_epoll_process(TCP_Server *tcp_server, const Mono_Time *mono_time
case TCP_SOCKET_INCOMING: { case TCP_SOCKET_INCOMING: {
LOGGER_TRACE(tcp_server->logger, "incoming connection %d dropped", index); LOGGER_TRACE(tcp_server->logger, "incoming connection %d dropped", index);
kill_TCP_secure_connection(&tcp_server->incoming_connection_queue[index]); kill_tcp_secure_connection(&tcp_server->incoming_connection_queue[index]);
break; break;
} }
case TCP_SOCKET_UNCONFIRMED: { case TCP_SOCKET_UNCONFIRMED: {
LOGGER_TRACE(tcp_server->logger, "unconfirmed connection %d dropped", index); LOGGER_TRACE(tcp_server->logger, "unconfirmed connection %d dropped", index);
kill_TCP_secure_connection(&tcp_server->unconfirmed_connection_queue[index]); kill_tcp_secure_connection(&tcp_server->unconfirmed_connection_queue[index]);
break; break;
} }
@ -1294,7 +1297,7 @@ static bool tcp_epoll_process(TCP_Server *tcp_server, const Mono_Time *mono_time
if (epoll_ctl(tcp_server->efd, EPOLL_CTL_ADD, sock_new.sock, &ev) == -1) { if (epoll_ctl(tcp_server->efd, EPOLL_CTL_ADD, sock_new.sock, &ev) == -1) {
LOGGER_DEBUG(tcp_server->logger, "new connection %d was dropped due to epoll error %d", index, net_error()); LOGGER_DEBUG(tcp_server->logger, "new connection %d was dropped due to epoll error %d", index, net_error());
kill_TCP_secure_connection(&tcp_server->incoming_connection_queue[index_new]); kill_tcp_secure_connection(&tcp_server->incoming_connection_queue[index_new]);
continue; continue;
} }
} }
@ -1312,7 +1315,7 @@ static bool tcp_epoll_process(TCP_Server *tcp_server, const Mono_Time *mono_time
if (epoll_ctl(tcp_server->efd, EPOLL_CTL_MOD, sock.sock, &events[n]) == -1) { if (epoll_ctl(tcp_server->efd, EPOLL_CTL_MOD, sock.sock, &events[n]) == -1) {
LOGGER_DEBUG(tcp_server->logger, "incoming connection %d was dropped due to epoll error %d", index, net_error()); LOGGER_DEBUG(tcp_server->logger, "incoming connection %d was dropped due to epoll error %d", index, net_error());
kill_TCP_secure_connection(&tcp_server->unconfirmed_connection_queue[index_new]); kill_tcp_secure_connection(&tcp_server->unconfirmed_connection_queue[index_new]);
break; break;
} }
} }
@ -1350,7 +1353,7 @@ static bool tcp_epoll_process(TCP_Server *tcp_server, const Mono_Time *mono_time
} }
non_null() non_null()
static void do_TCP_epoll(TCP_Server *tcp_server, const Mono_Time *mono_time) static void do_tcp_epoll(TCP_Server *tcp_server, const Mono_Time *mono_time)
{ {
while (tcp_epoll_process(tcp_server, mono_time)) { while (tcp_epoll_process(tcp_server, mono_time)) {
// Keep processing packets until there are no more FDs ready for reading. // Keep processing packets until there are no more FDs ready for reading.
@ -1359,21 +1362,21 @@ static void do_TCP_epoll(TCP_Server *tcp_server, const Mono_Time *mono_time)
} }
#endif #endif
void do_TCP_server(TCP_Server *tcp_server, const Mono_Time *mono_time) void do_tcp_server(TCP_Server *tcp_server, const Mono_Time *mono_time)
{ {
#ifdef TCP_SERVER_USE_EPOLL #ifdef TCP_SERVER_USE_EPOLL
do_TCP_epoll(tcp_server, mono_time); do_tcp_epoll(tcp_server, mono_time);
#else #else
do_TCP_accept_new(tcp_server); do_tcp_accept_new(tcp_server);
do_TCP_incoming(tcp_server); do_tcp_incoming(tcp_server);
do_TCP_unconfirmed(tcp_server, mono_time); do_tcp_unconfirmed(tcp_server, mono_time);
#endif #endif
do_TCP_confirmed(tcp_server, mono_time); do_tcp_confirmed(tcp_server, mono_time);
} }
void kill_TCP_server(TCP_Server *tcp_server) void kill_tcp_server(TCP_Server *tcp_server)
{ {
if (tcp_server == nullptr) { if (tcp_server == nullptr) {
return; return;
@ -1406,6 +1409,6 @@ void kill_TCP_server(TCP_Server *tcp_server)
crypto_memzero(tcp_server->secret_key, sizeof(tcp_server->secret_key)); crypto_memzero(tcp_server->secret_key, sizeof(tcp_server->secret_key));
free(tcp_server->socks_listening); mem_delete(tcp_server->mem, tcp_server->socks_listening);
free(tcp_server); mem_delete(tcp_server->mem, tcp_server);
} }

View File

@ -34,18 +34,18 @@ non_null()
size_t tcp_server_listen_count(const TCP_Server *tcp_server); size_t tcp_server_listen_count(const TCP_Server *tcp_server);
/** Create new TCP server instance. */ /** Create new TCP server instance. */
non_null(1, 2, 3, 6, 7) nullable(8, 9) non_null(1, 2, 3, 4, 7, 8) nullable(9, 10)
TCP_Server *new_TCP_server(const Logger *logger, const Random *rng, const Network *ns, TCP_Server *new_tcp_server(const Logger *logger, const Memory *mem, const Random *rng, const Network *ns,
bool ipv6_enabled, uint16_t num_sockets, const uint16_t *ports, bool ipv6_enabled, uint16_t num_sockets, const uint16_t *ports,
const uint8_t *secret_key, Onion *onion, Forwarding *forwarding); const uint8_t *secret_key, Onion *onion, Forwarding *forwarding);
/** Run the TCP_server */ /** Run the TCP_server */
non_null() non_null()
void do_TCP_server(TCP_Server *tcp_server, const Mono_Time *mono_time); void do_tcp_server(TCP_Server *tcp_server, const Mono_Time *mono_time);
/** Kill the TCP server */ /** Kill the TCP server */
nullable(1) nullable(1)
void kill_TCP_server(TCP_Server *tcp_server); void kill_tcp_server(TCP_Server *tcp_server);
#endif #endif

View File

@ -50,6 +50,7 @@ typedef struct Announce_Entry {
struct Announcements { struct Announcements {
const Logger *log; const Logger *log;
const Memory *mem;
const Random *rng; const Random *rng;
Forwarding *forwarding; Forwarding *forwarding;
const Mono_Time *mono_time; const Mono_Time *mono_time;
@ -593,8 +594,8 @@ static int create_reply(Announcements *announce, const IP_Port *source,
const uint8_t response_type = announce_response_of_request_type(data[0]); const uint8_t response_type = announce_response_of_request_type(data[0]);
return dht_create_packet(announce->rng, announce->public_key, shared_key, response_type, return dht_create_packet(announce->mem, announce->rng, announce->public_key, shared_key,
plain_reply, plain_reply_len, reply, reply_max_length); response_type, plain_reply, plain_reply_len, reply, reply_max_length);
} }
non_null(1, 2, 3, 5) nullable(7) non_null(1, 2, 3, 5) nullable(7)
@ -636,7 +637,7 @@ static int handle_dht_announce_request(void *object, const IP_Port *source,
return sendpacket(announce->net, source, reply, len) == len ? 0 : -1; return sendpacket(announce->net, source, reply, len) == len ? 0 : -1;
} }
Announcements *new_announcements(const Logger *log, const Random *rng, const Mono_Time *mono_time, Announcements *new_announcements(const Logger *log, const Memory *mem, const Random *rng, const Mono_Time *mono_time,
Forwarding *forwarding) Forwarding *forwarding)
{ {
if (log == nullptr || mono_time == nullptr || forwarding == nullptr) { if (log == nullptr || mono_time == nullptr || forwarding == nullptr) {
@ -650,6 +651,7 @@ Announcements *new_announcements(const Logger *log, const Random *rng, const Mon
} }
announce->log = log; announce->log = log;
announce->mem = mem;
announce->rng = rng; announce->rng = rng;
announce->forwarding = forwarding; announce->forwarding = forwarding;
announce->mono_time = mono_time; announce->mono_time = mono_time;
@ -658,7 +660,7 @@ Announcements *new_announcements(const Logger *log, const Random *rng, const Mon
announce->public_key = dht_get_self_public_key(announce->dht); announce->public_key = dht_get_self_public_key(announce->dht);
announce->secret_key = dht_get_self_secret_key(announce->dht); announce->secret_key = dht_get_self_secret_key(announce->dht);
new_hmac_key(announce->rng, announce->hmac_key); new_hmac_key(announce->rng, announce->hmac_key);
announce->shared_keys = shared_key_cache_new(mono_time, announce->secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT); announce->shared_keys = shared_key_cache_new(mono_time, mem, announce->secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT);
if (announce->shared_keys == nullptr) { if (announce->shared_keys == nullptr) {
free(announce); free(announce);
return nullptr; return nullptr;

View File

@ -16,7 +16,8 @@ uint8_t announce_response_of_request_type(uint8_t request_type);
typedef struct Announcements Announcements; typedef struct Announcements Announcements;
non_null() non_null()
Announcements *new_announcements(const Logger *log, const Random *rng, const Mono_Time *mono_time, Forwarding *forwarding); Announcements *new_announcements(const Logger *log, const Memory *mem, const Random *rng, const Mono_Time *mono_time,
Forwarding *forwarding);
/** /**
* @brief If data is stored, run `on_retrieve_callback` on it. * @brief If data is stored, run `on_retrieve_callback` on it.

View File

@ -358,7 +358,7 @@ int32_t decrypt_data(const uint8_t *public_key, const uint8_t *secret_key, const
/** /**
* @brief Fast encrypt/decrypt operations. * @brief Fast encrypt/decrypt operations.
* *
* Use if this is not a one-time communication. @ref encrypt_precompute does the * Use if this is not a one-time communication. `encrypt_precompute` does the
* shared-key generation once so it does not have to be performed on every * shared-key generation once so it does not have to be performed on every
* encrypt/decrypt. * encrypt/decrypt.
*/ */

View File

@ -12,8 +12,10 @@ void TestSendForwardRequest(Fuzz_Data &input)
{ {
const Network *ns = system_network(); // TODO(iphydf): fuzz_network const Network *ns = system_network(); // TODO(iphydf): fuzz_network
assert(ns != nullptr); assert(ns != nullptr);
const Memory *mem = system_memory(); // TODO(iphydf): fuzz_memory
assert(mem != nullptr);
with<Logger>{} >> with<Networking_Core>{input, ns} >> [&input](Ptr<Networking_Core> net) { with<Logger>{} >> with<Networking_Core>{input, ns, mem} >> [&input](Ptr<Networking_Core> net) {
with<IP_Port>{input} >> [net = std::move(net), &input](const IP_Port &forwarder) { with<IP_Port>{input} >> [net = std::move(net), &input](const IP_Port &forwarder) {
CONSUME1_OR_RETURN(const uint16_t chain_length, input); CONSUME1_OR_RETURN(const uint16_t chain_length, input);
const uint16_t chain_keys_size = chain_length * CRYPTO_PUBLIC_KEY_SIZE; const uint16_t chain_keys_size = chain_length * CRYPTO_PUBLIC_KEY_SIZE;
@ -29,8 +31,10 @@ void TestForwardReply(Fuzz_Data &input)
{ {
const Network *ns = system_network(); // TODO(iphydf): fuzz_network const Network *ns = system_network(); // TODO(iphydf): fuzz_network
assert(ns != nullptr); assert(ns != nullptr);
const Memory *mem = system_memory(); // TODO(iphydf): fuzz_memory
assert(mem != nullptr);
with<Logger>{} >> with<Networking_Core>{input, ns} >> [&input](Ptr<Networking_Core> net) { with<Logger>{} >> with<Networking_Core>{input, ns, mem} >> [&input](Ptr<Networking_Core> net) {
with<IP_Port>{input} >> [net = std::move(net), &input](const IP_Port &forwarder) { with<IP_Port>{input} >> [net = std::move(net), &input](const IP_Port &forwarder) {
CONSUME1_OR_RETURN(const uint16_t sendback_length, input); CONSUME1_OR_RETURN(const uint16_t sendback_length, input);
CONSUME_OR_RETURN(const uint8_t *sendback, input, sendback_length); CONSUME_OR_RETURN(const uint8_t *sendback, input, sendback_length);

View File

@ -461,7 +461,7 @@ static void dht_pk_callback(void *object, int32_t number, const uint8_t *dht_pub
} }
friend_new_connection(fr_c, number); friend_new_connection(fr_c, number);
onion_set_friend_DHT_pubkey(fr_c->onion_c, friend_con->onion_friendnum, dht_public_key); onion_set_friend_dht_pubkey(fr_c->onion_c, friend_con->onion_friendnum, dht_public_key);
} }
non_null() non_null()

View File

@ -1,6 +1,7 @@
#include "group_announce.h" #include "group_announce.h"
#include <cassert> #include <cassert>
#include <functional>
#include <memory> #include <memory>
#include <vector> #include <vector>
@ -44,9 +45,10 @@ void TestUnpackPublicAnnounce(Fuzz_Data &input)
void TestDoGca(Fuzz_Data &input) void TestDoGca(Fuzz_Data &input)
{ {
const Memory *mem = system_memory();
std::unique_ptr<Logger, void (*)(Logger *)> logger(logger_new(), logger_kill); std::unique_ptr<Logger, void (*)(Logger *)> logger(logger_new(), logger_kill);
std::unique_ptr<Mono_Time, void (*)(Mono_Time *)> mono_time( std::unique_ptr<Mono_Time, std::function<void(Mono_Time *)>> mono_time(
mono_time_new(nullptr, nullptr), mono_time_free); mono_time_new(mem, nullptr, nullptr), [mem](Mono_Time *ptr) { mono_time_free(mem, ptr); });
assert(mono_time != nullptr); assert(mono_time != nullptr);
uint64_t clock = 1; uint64_t clock = 1;
mono_time_set_current_time_callback( mono_time_set_current_time_callback(

View File

@ -8,6 +8,7 @@ namespace {
struct Announces : ::testing::Test { struct Announces : ::testing::Test {
protected: protected:
const Memory *mem_ = system_memory();
uint64_t clock_ = 0; uint64_t clock_ = 0;
Mono_Time *mono_time_ = nullptr; Mono_Time *mono_time_ = nullptr;
GC_Announces_List *gca_ = nullptr; GC_Announces_List *gca_ = nullptr;
@ -16,7 +17,7 @@ protected:
void SetUp() override void SetUp() override
{ {
mono_time_ = mono_time_new(nullptr, nullptr); mono_time_ = mono_time_new(mem_, nullptr, nullptr);
ASSERT_NE(mono_time_, nullptr); ASSERT_NE(mono_time_, nullptr);
mono_time_set_current_time_callback( mono_time_set_current_time_callback(
mono_time_, [](void *user_data) { return *static_cast<uint64_t *>(user_data); }, mono_time_, [](void *user_data) { return *static_cast<uint64_t *>(user_data); },
@ -28,7 +29,7 @@ protected:
~Announces() override ~Announces() override
{ {
kill_gca(gca_); kill_gca(gca_);
mono_time_free(mono_time_); mono_time_free(mem_, mono_time_);
} }
void advance_clock(uint64_t increment) void advance_clock(uint64_t increment)

View File

@ -5691,13 +5691,13 @@ static int handle_gc_handshake_request(GC_Chat *chat, const IP_Port *ipp, const
return -1; return -1;
} }
if (chat->connection_O_metre >= GC_NEW_PEER_CONNECTION_LIMIT) { if (chat->connection_o_metre >= GC_NEW_PEER_CONNECTION_LIMIT) {
chat->block_handshakes = true; chat->block_handshakes = true;
LOGGER_DEBUG(chat->log, "Handshake overflow. Blocking handshakes."); LOGGER_DEBUG(chat->log, "Handshake overflow. Blocking handshakes.");
return -1; return -1;
} }
++chat->connection_O_metre; ++chat->connection_o_metre;
const uint8_t *public_sig_key = data + ENC_PUBLIC_KEY_SIZE; const uint8_t *public_sig_key = data + ENC_PUBLIC_KEY_SIZE;
@ -7015,7 +7015,7 @@ static void do_gc_ping_and_key_rotation(GC_Chat *chat)
non_null() non_null()
static void do_new_connection_cooldown(GC_Chat *chat) static void do_new_connection_cooldown(GC_Chat *chat)
{ {
if (chat->connection_O_metre == 0) { if (chat->connection_o_metre == 0) {
return; return;
} }
@ -7023,9 +7023,9 @@ static void do_new_connection_cooldown(GC_Chat *chat)
if (chat->connection_cooldown_timer < tm) { if (chat->connection_cooldown_timer < tm) {
chat->connection_cooldown_timer = tm; chat->connection_cooldown_timer = tm;
--chat->connection_O_metre; --chat->connection_o_metre;
if (chat->connection_O_metre == 0 && chat->block_handshakes) { if (chat->connection_o_metre == 0 && chat->block_handshakes) {
chat->block_handshakes = false; chat->block_handshakes = false;
LOGGER_DEBUG(chat->log, "Unblocking handshakes"); LOGGER_DEBUG(chat->log, "Unblocking handshakes");
} }
@ -7250,7 +7250,7 @@ static bool init_gc_tcp_connection(const GC_Session *c, GC_Chat *chat)
{ {
const Messenger *m = c->messenger; const Messenger *m = c->messenger;
chat->tcp_conn = new_tcp_connections(chat->log, chat->rng, m->ns, chat->mono_time, chat->self_secret_key, chat->tcp_conn = new_tcp_connections(chat->log, chat->mem, chat->rng, m->ns, chat->mono_time, chat->self_secret_key,
&m->options.proxy_info); &m->options.proxy_info);
if (chat->tcp_conn == nullptr) { if (chat->tcp_conn == nullptr) {
@ -7305,6 +7305,7 @@ static void init_gc_moderation(GC_Chat *chat)
memcpy(chat->moderation.self_secret_sig_key, get_sig_pk(chat->self_secret_key), SIG_SECRET_KEY_SIZE); memcpy(chat->moderation.self_secret_sig_key, get_sig_pk(chat->self_secret_key), SIG_SECRET_KEY_SIZE);
chat->moderation.shared_state_version = chat->shared_state.version; chat->moderation.shared_state_version = chat->shared_state.version;
chat->moderation.log = chat->log; chat->moderation.log = chat->log;
chat->moderation.mem = chat->mem;
} }
non_null() non_null()
@ -7332,6 +7333,7 @@ static int create_new_group(GC_Session *c, const uint8_t *nick, size_t nick_leng
GC_Chat *chat = &c->chats[group_number]; GC_Chat *chat = &c->chats[group_number];
chat->log = m->log; chat->log = m->log;
chat->mem = m->mem;
chat->rng = m->rng; chat->rng = m->rng;
const uint64_t tm = mono_time_get(m->mono_time); const uint64_t tm = mono_time_get(m->mono_time);
@ -7476,10 +7478,15 @@ int gc_group_load(GC_Session *c, Bin_Unpack *bu)
chat->net = m->net; chat->net = m->net;
chat->mono_time = m->mono_time; chat->mono_time = m->mono_time;
chat->log = m->log; chat->log = m->log;
chat->mem = m->mem;
chat->rng = m->rng; chat->rng = m->rng;
chat->last_ping_interval = tm; chat->last_ping_interval = tm;
chat->friend_connection_id = -1; chat->friend_connection_id = -1;
// Initialise these first, because we may need to log/dealloc things on cleanup.
chat->moderation.log = m->log;
chat->moderation.mem = m->mem;
if (!gc_load_unpack_group(chat, bu)) { if (!gc_load_unpack_group(chat, bu)) {
LOGGER_ERROR(chat->log, "Failed to unpack group"); LOGGER_ERROR(chat->log, "Failed to unpack group");
return -1; return -1;

View File

@ -247,6 +247,7 @@ typedef struct GC_TopicInfo {
typedef struct GC_Chat { typedef struct GC_Chat {
Mono_Time *mono_time; Mono_Time *mono_time;
const Logger *log; const Logger *log;
const Memory *mem;
const Random *rng; const Random *rng;
uint32_t connected_tcp_relays; uint32_t connected_tcp_relays;
@ -291,7 +292,7 @@ typedef struct GC_Chat {
uint64_t last_time_peers_loaded; uint64_t last_time_peers_loaded;
/* keeps track of frequency of new inbound connections */ /* keeps track of frequency of new inbound connections */
uint8_t connection_O_metre; uint8_t connection_o_metre;
uint64_t connection_cooldown_timer; uint64_t connection_cooldown_timer;
bool block_handshakes; bool block_handshakes;

View File

@ -61,7 +61,7 @@ int mod_list_unpack(Moderation *moderation, const uint8_t *data, uint16_t length
tmp_list[i] = (uint8_t *)malloc(sizeof(uint8_t) * MOD_LIST_ENTRY_SIZE); tmp_list[i] = (uint8_t *)malloc(sizeof(uint8_t) * MOD_LIST_ENTRY_SIZE);
if (tmp_list[i] == nullptr) { if (tmp_list[i] == nullptr) {
free_uint8_t_pointer_array(tmp_list, i); free_uint8_t_pointer_array(moderation->mem, tmp_list, i);
return -1; return -1;
} }
@ -221,7 +221,7 @@ bool mod_list_add_entry(Moderation *moderation, const uint8_t *mod_data)
void mod_list_cleanup(Moderation *moderation) void mod_list_cleanup(Moderation *moderation)
{ {
free_uint8_t_pointer_array(moderation->mod_list, moderation->num_mods); free_uint8_t_pointer_array(moderation->mem, moderation->mod_list, moderation->num_mods);
moderation->num_mods = 0; moderation->num_mods = 0;
moderation->mod_list = nullptr; moderation->mod_list = nullptr;
} }

View File

@ -78,6 +78,7 @@ typedef struct Mod_Sanction {
} Mod_Sanction; } Mod_Sanction;
typedef struct Moderation { typedef struct Moderation {
const Memory *mem;
const Logger *log; const Logger *log;
Mod_Sanction *sanctions; Mod_Sanction *sanctions;

View File

@ -7,7 +7,7 @@ namespace {
void TestModListUnpack(Fuzz_Data &input) void TestModListUnpack(Fuzz_Data &input)
{ {
CONSUME1_OR_RETURN(const uint16_t num_mods, input); CONSUME1_OR_RETURN(const uint16_t num_mods, input);
Moderation mods{}; Moderation mods{system_memory()};
mod_list_unpack(&mods, input.data, input.size, num_mods); mod_list_unpack(&mods, input.data, input.size, num_mods);
mod_list_cleanup(&mods); mod_list_cleanup(&mods);
} }

View File

@ -18,7 +18,7 @@ using ModerationHash = std::array<uint8_t, MOD_MODERATION_HASH_SIZE>;
TEST(ModList, PackedSizeOfEmptyModListIsZero) TEST(ModList, PackedSizeOfEmptyModListIsZero)
{ {
Moderation mods{}; Moderation mods{system_memory()};
EXPECT_EQ(mod_list_packed_size(&mods), 0); EXPECT_EQ(mod_list_packed_size(&mods), 0);
uint8_t byte = 1; uint8_t byte = 1;
@ -28,14 +28,14 @@ TEST(ModList, PackedSizeOfEmptyModListIsZero)
TEST(ModList, UnpackingZeroSizeArrayIsNoop) TEST(ModList, UnpackingZeroSizeArrayIsNoop)
{ {
Moderation mods{}; Moderation mods{system_memory()};
const uint8_t byte = 1; const uint8_t byte = 1;
EXPECT_EQ(mod_list_unpack(&mods, &byte, 0, 0), 0); EXPECT_EQ(mod_list_unpack(&mods, &byte, 0, 0), 0);
} }
TEST(ModList, AddRemoveMultipleMods) TEST(ModList, AddRemoveMultipleMods)
{ {
Moderation mods{}; Moderation mods{system_memory()};
uint8_t sig_pk1[32] = {1}; uint8_t sig_pk1[32] = {1};
uint8_t sig_pk2[32] = {2}; uint8_t sig_pk2[32] = {2};
EXPECT_TRUE(mod_list_add_entry(&mods, sig_pk1)); EXPECT_TRUE(mod_list_add_entry(&mods, sig_pk1));
@ -47,7 +47,7 @@ TEST(ModList, AddRemoveMultipleMods)
TEST(ModList, PackingAndUnpackingList) TEST(ModList, PackingAndUnpackingList)
{ {
using ModListEntry = std::array<uint8_t, MOD_LIST_ENTRY_SIZE>; using ModListEntry = std::array<uint8_t, MOD_LIST_ENTRY_SIZE>;
Moderation mods{}; Moderation mods{system_memory()};
EXPECT_TRUE(mod_list_add_entry(&mods, ModListEntry{}.data())); EXPECT_TRUE(mod_list_add_entry(&mods, ModListEntry{}.data()));
std::vector<uint8_t> packed(mod_list_packed_size(&mods)); std::vector<uint8_t> packed(mod_list_packed_size(&mods));
@ -55,7 +55,7 @@ TEST(ModList, PackingAndUnpackingList)
EXPECT_TRUE(mod_list_remove_entry(&mods, ModListEntry{}.data())); EXPECT_TRUE(mod_list_remove_entry(&mods, ModListEntry{}.data()));
Moderation mods2{}; Moderation mods2{system_memory()};
EXPECT_EQ(mod_list_unpack(&mods2, packed.data(), packed.size(), 1), packed.size()); EXPECT_EQ(mod_list_unpack(&mods2, packed.data(), packed.size(), 1), packed.size());
EXPECT_TRUE(mod_list_remove_entry(&mods2, ModListEntry{}.data())); EXPECT_TRUE(mod_list_remove_entry(&mods2, ModListEntry{}.data()));
} }
@ -63,13 +63,13 @@ TEST(ModList, PackingAndUnpackingList)
TEST(ModList, UnpackingTooManyModsFails) TEST(ModList, UnpackingTooManyModsFails)
{ {
using ModListEntry = std::array<uint8_t, MOD_LIST_ENTRY_SIZE>; using ModListEntry = std::array<uint8_t, MOD_LIST_ENTRY_SIZE>;
Moderation mods{}; Moderation mods{system_memory()};
EXPECT_TRUE(mod_list_add_entry(&mods, ModListEntry{}.data())); EXPECT_TRUE(mod_list_add_entry(&mods, ModListEntry{}.data()));
std::vector<uint8_t> packed(mod_list_packed_size(&mods)); std::vector<uint8_t> packed(mod_list_packed_size(&mods));
mod_list_pack(&mods, packed.data()); mod_list_pack(&mods, packed.data());
Moderation mods2{}; Moderation mods2{system_memory()};
EXPECT_EQ(mod_list_unpack(&mods2, packed.data(), packed.size(), 2), -1); EXPECT_EQ(mod_list_unpack(&mods2, packed.data(), packed.size(), 2), -1);
EXPECT_TRUE(mod_list_remove_entry(&mods, ModListEntry{}.data())); EXPECT_TRUE(mod_list_remove_entry(&mods, ModListEntry{}.data()));
} }
@ -78,7 +78,7 @@ TEST(ModList, UnpackingFromEmptyBufferFails)
{ {
std::vector<uint8_t> packed(1); std::vector<uint8_t> packed(1);
Moderation mods{}; Moderation mods{system_memory()};
EXPECT_EQ(mod_list_unpack(&mods, packed.end().base(), 0, 1), -1); EXPECT_EQ(mod_list_unpack(&mods, packed.end().base(), 0, 1), -1);
} }
@ -87,7 +87,7 @@ TEST(ModList, HashOfEmptyModListZeroesOutBuffer)
const Random *rng = system_random(); const Random *rng = system_random();
ASSERT_NE(rng, nullptr); ASSERT_NE(rng, nullptr);
Moderation mods{}; Moderation mods{system_memory()};
// Fill with random data, check that it's zeroed. // Fill with random data, check that it's zeroed.
ModerationHash hash; ModerationHash hash;
@ -98,21 +98,21 @@ TEST(ModList, HashOfEmptyModListZeroesOutBuffer)
TEST(ModList, RemoveIndexFromEmptyModListFails) TEST(ModList, RemoveIndexFromEmptyModListFails)
{ {
Moderation mods{}; Moderation mods{system_memory()};
EXPECT_FALSE(mod_list_remove_index(&mods, 0)); EXPECT_FALSE(mod_list_remove_index(&mods, 0));
EXPECT_FALSE(mod_list_remove_index(&mods, UINT16_MAX)); EXPECT_FALSE(mod_list_remove_index(&mods, UINT16_MAX));
} }
TEST(ModList, RemoveEntryFromEmptyModListFails) TEST(ModList, RemoveEntryFromEmptyModListFails)
{ {
Moderation mods{}; Moderation mods{system_memory()};
uint8_t sig_pk[32] = {0}; uint8_t sig_pk[32] = {0};
EXPECT_FALSE(mod_list_remove_entry(&mods, sig_pk)); EXPECT_FALSE(mod_list_remove_entry(&mods, sig_pk));
} }
TEST(ModList, ModListRemoveIndex) TEST(ModList, ModListRemoveIndex)
{ {
Moderation mods{}; Moderation mods{system_memory()};
uint8_t sig_pk[32] = {1}; uint8_t sig_pk[32] = {1};
EXPECT_TRUE(mod_list_add_entry(&mods, sig_pk)); EXPECT_TRUE(mod_list_add_entry(&mods, sig_pk));
EXPECT_TRUE(mod_list_remove_index(&mods, 0)); EXPECT_TRUE(mod_list_remove_index(&mods, 0));
@ -120,20 +120,20 @@ TEST(ModList, ModListRemoveIndex)
TEST(ModList, CleanupOnEmptyModsIsNoop) TEST(ModList, CleanupOnEmptyModsIsNoop)
{ {
Moderation mods{}; Moderation mods{system_memory()};
mod_list_cleanup(&mods); mod_list_cleanup(&mods);
} }
TEST(ModList, EmptyModListCannotVerifyAnySigPk) TEST(ModList, EmptyModListCannotVerifyAnySigPk)
{ {
Moderation mods{}; Moderation mods{system_memory()};
uint8_t sig_pk[32] = {1}; uint8_t sig_pk[32] = {1};
EXPECT_FALSE(mod_list_verify_sig_pk(&mods, sig_pk)); EXPECT_FALSE(mod_list_verify_sig_pk(&mods, sig_pk));
} }
TEST(ModList, ModListAddVerifyRemoveSigPK) TEST(ModList, ModListAddVerifyRemoveSigPK)
{ {
Moderation mods{}; Moderation mods{system_memory()};
uint8_t sig_pk[32] = {1}; uint8_t sig_pk[32] = {1};
EXPECT_TRUE(mod_list_add_entry(&mods, sig_pk)); EXPECT_TRUE(mod_list_add_entry(&mods, sig_pk));
EXPECT_TRUE(mod_list_verify_sig_pk(&mods, sig_pk)); EXPECT_TRUE(mod_list_verify_sig_pk(&mods, sig_pk));
@ -143,7 +143,7 @@ TEST(ModList, ModListAddVerifyRemoveSigPK)
TEST(ModList, ModListHashCheck) TEST(ModList, ModListHashCheck)
{ {
Moderation mods1{}; Moderation mods1{system_memory()};
uint8_t sig_pk1[32] = {1}; uint8_t sig_pk1[32] = {1};
std::array<uint8_t, MOD_MODERATION_HASH_SIZE> hash1; std::array<uint8_t, MOD_MODERATION_HASH_SIZE> hash1;
@ -165,7 +165,7 @@ TEST(SanctionsList, PackingIntoUndersizedBufferFails)
TEST(SanctionsList, PackUnpackSanctionsCreds) TEST(SanctionsList, PackUnpackSanctionsCreds)
{ {
Moderation mod{}; Moderation mod{system_memory()};
std::array<uint8_t, MOD_SANCTIONS_CREDS_SIZE> packed; std::array<uint8_t, MOD_SANCTIONS_CREDS_SIZE> packed;
EXPECT_EQ(sanctions_creds_pack(&mod.sanctions_creds, packed.data()), MOD_SANCTIONS_CREDS_SIZE); EXPECT_EQ(sanctions_creds_pack(&mod.sanctions_creds, packed.data()), MOD_SANCTIONS_CREDS_SIZE);
EXPECT_EQ( EXPECT_EQ(
@ -177,7 +177,7 @@ protected:
ExtPublicKey pk; ExtPublicKey pk;
ExtSecretKey sk; ExtSecretKey sk;
Logger *log = logger_new(); Logger *log = logger_new();
Moderation mod{}; Moderation mod{system_memory()};
Mod_Sanction sanctions[2] = {}; Mod_Sanction sanctions[2] = {};
const uint8_t sanctioned_pk1[32] = {1}; const uint8_t sanctioned_pk1[32] = {1};

88
toxcore/mem.c Normal file
View File

@ -0,0 +1,88 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright © 2016-2018 The TokTok team.
* Copyright © 2013 Tox project.
*/
#include "mem.h"
#include <stdlib.h>
#include "ccompat.h"
nullable(1)
static void *sys_malloc(void *obj, uint32_t size)
{
return malloc(size);
}
nullable(1)
static void *sys_calloc(void *obj, uint32_t nmemb, uint32_t size)
{
return calloc(nmemb, size);
}
nullable(1, 2)
static void *sys_realloc(void *obj, void *ptr, uint32_t size)
{
return realloc(ptr, size);
}
nullable(1, 2)
static void sys_free(void *obj, void *ptr)
{
free(ptr);
}
static const Memory_Funcs system_memory_funcs = {
sys_malloc,
sys_calloc,
sys_realloc,
sys_free,
};
static const Memory system_memory_obj = {&system_memory_funcs};
const Memory *system_memory(void)
{
return &system_memory_obj;
}
void *mem_balloc(const Memory *mem, uint32_t size)
{
void *const ptr = mem->funcs->malloc(mem->obj, size);
return ptr;
}
void *mem_alloc(const Memory *mem, uint32_t size)
{
void *const ptr = mem->funcs->calloc(mem->obj, 1, size);
return ptr;
}
void *mem_valloc(const Memory *mem, uint32_t nmemb, uint32_t size)
{
const uint32_t bytes = nmemb * size;
if (size != 0 && bytes / size != nmemb) {
return nullptr;
}
void *const ptr = mem->funcs->calloc(mem->obj, nmemb, size);
return ptr;
}
void *mem_vrealloc(const Memory *mem, void *ptr, uint32_t nmemb, uint32_t size)
{
const uint32_t bytes = nmemb * size;
if (size != 0 && bytes / size != nmemb) {
return nullptr;
}
void *const new_ptr = mem->funcs->realloc(mem->obj, ptr, bytes);
return new_ptr;
}
void mem_delete(const Memory *mem, void *ptr)
{
mem->funcs->free(mem->obj, ptr);
}

86
toxcore/mem.h Normal file
View File

@ -0,0 +1,86 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright © 2016-2018 The TokTok team.
* Copyright © 2013 Tox project.
*/
/**
* Memory allocation and deallocation functions.
*/
#ifndef C_TOXCORE_TOXCORE_MEM_H
#define C_TOXCORE_TOXCORE_MEM_H
#include <stdint.h> // uint*_t
#include "attributes.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef void *mem_malloc_cb(void *obj, uint32_t size);
typedef void *mem_calloc_cb(void *obj, uint32_t nmemb, uint32_t size);
typedef void *mem_realloc_cb(void *obj, void *ptr, uint32_t size);
typedef void mem_free_cb(void *obj, void *ptr);
/** @brief Functions wrapping standard C memory allocation functions. */
typedef struct Memory_Funcs {
mem_malloc_cb *malloc;
mem_calloc_cb *calloc;
mem_realloc_cb *realloc;
mem_free_cb *free;
} Memory_Funcs;
typedef struct Memory {
const Memory_Funcs *funcs;
void *obj;
} Memory;
const Memory *system_memory(void);
/**
* @brief Allocate an array of a given size for built-in types.
*
* The array will not be initialised. Supported built-in types are
* `uint8_t`, `int8_t`, and `int16_t`.
*/
non_null() void *mem_balloc(const Memory *mem, uint32_t size);
/**
* @brief Allocate a single object.
*
* Always use as `(T *)mem_alloc(mem, sizeof(T))`.
*/
non_null() void *mem_alloc(const Memory *mem, uint32_t size);
/**
* @brief Allocate a vector (array) of objects.
*
* Always use as `(T *)mem_valloc(mem, N, sizeof(T))`.
*/
non_null() void *mem_valloc(const Memory *mem, uint32_t nmemb, uint32_t size);
/**
* @brief Resize an object vector.
*
* Changes the size of (and possibly moves) the memory block pointed to by
* @p ptr to be large enough for an array of @p nmemb elements, each of which
* is @p size bytes. It is similar to the call
*
* @code
* realloc(ptr, nmemb * size);
* @endcode
*
* However, unlike that `realloc()` call, `mem_vrealloc()` fails safely in the
* case where the multiplication would overflow. If such an overflow occurs,
* `mem_vrealloc()` returns `nullptr`.
*/
non_null(1) nullable(2) void *mem_vrealloc(const Memory *mem, void *ptr, uint32_t nmemb, uint32_t size);
/** @brief Free an array, object, or object vector. */
non_null(1) nullable(2) void mem_delete(const Memory *mem, void *ptr);
#ifdef __cplusplus
} // extern "C"
#endif
#endif

40
toxcore/mem_test.cc Normal file
View File

@ -0,0 +1,40 @@
#include "mem.h"
#include <gtest/gtest.h>
namespace {
TEST(Mem, AllocLarge)
{
// Mebi prefix: https://en.wikipedia.org/wiki/Binary_prefix.
constexpr uint32_t MI = 1024 * 1024;
const Memory *mem = system_memory();
void *ptr = mem_valloc(mem, 4, MI);
EXPECT_NE(ptr, nullptr);
mem_delete(mem, ptr);
}
TEST(Mem, AllocOverflow)
{
// Gibi prefix.
constexpr uint32_t GI = 1024 * 1024 * 1024;
const Memory *mem = system_memory();
// 1 gibi-elements of 100 bytes each.
void *ptr = mem_valloc(mem, GI, 100);
EXPECT_EQ(ptr, nullptr);
// 100 elements of 1 gibibyte each.
ptr = mem_valloc(mem, 100, GI);
EXPECT_EQ(ptr, nullptr);
// 128 (a multiple of 2) elements of 1 gibibyte each.
ptr = mem_valloc(mem, 128, GI);
EXPECT_EQ(ptr, nullptr);
}
} // namespace

View File

@ -122,25 +122,25 @@ static uint64_t current_time_monotonic_default(void *user_data)
#endif // !OS_WIN32 #endif // !OS_WIN32
Mono_Time *mono_time_new(mono_time_current_time_cb *current_time_callback, void *user_data) Mono_Time *mono_time_new(const Memory *mem, mono_time_current_time_cb *current_time_callback, void *user_data)
{ {
Mono_Time *mono_time = (Mono_Time *)calloc(1, sizeof(Mono_Time)); Mono_Time *mono_time = (Mono_Time *)mem_alloc(mem, sizeof(Mono_Time));
if (mono_time == nullptr) { if (mono_time == nullptr) {
return nullptr; return nullptr;
} }
#ifndef ESP_PLATFORM #ifndef ESP_PLATFORM
mono_time->time_update_lock = (pthread_rwlock_t *)calloc(1, sizeof(pthread_rwlock_t)); mono_time->time_update_lock = (pthread_rwlock_t *)mem_alloc(mem, sizeof(pthread_rwlock_t));
if (mono_time->time_update_lock == nullptr) { if (mono_time->time_update_lock == nullptr) {
free(mono_time); mem_delete(mem, mono_time);
return nullptr; return nullptr;
} }
if (pthread_rwlock_init(mono_time->time_update_lock, nullptr) < 0) { if (pthread_rwlock_init(mono_time->time_update_lock, nullptr) != 0) {
free(mono_time->time_update_lock); mem_delete(mem, mono_time->time_update_lock);
free(mono_time); mem_delete(mem, mono_time);
return nullptr; return nullptr;
} }
#endif #endif
@ -153,8 +153,8 @@ Mono_Time *mono_time_new(mono_time_current_time_cb *current_time_callback, void
mono_time->last_clock_update = false; mono_time->last_clock_update = false;
if (pthread_mutex_init(&mono_time->last_clock_lock, nullptr) < 0) { if (pthread_mutex_init(&mono_time->last_clock_lock, nullptr) < 0) {
free(mono_time->time_update_lock); mem_delete(mem, mono_time->time_update_lock);
free(mono_time); mem_delete(mem, mono_time);
return nullptr; return nullptr;
} }
@ -173,7 +173,7 @@ Mono_Time *mono_time_new(mono_time_current_time_cb *current_time_callback, void
return mono_time; return mono_time;
} }
void mono_time_free(Mono_Time *mono_time) void mono_time_free(const Memory *mem, Mono_Time *mono_time)
{ {
if (mono_time == nullptr) { if (mono_time == nullptr) {
return; return;
@ -183,9 +183,9 @@ void mono_time_free(Mono_Time *mono_time)
#endif #endif
#ifndef ESP_PLATFORM #ifndef ESP_PLATFORM
pthread_rwlock_destroy(mono_time->time_update_lock); pthread_rwlock_destroy(mono_time->time_update_lock);
free(mono_time->time_update_lock); mem_delete(mem, mono_time->time_update_lock);
#endif #endif
free(mono_time); mem_delete(mem, mono_time);
} }
void mono_time_update(Mono_Time *mono_time) void mono_time_update(Mono_Time *mono_time)

View File

@ -9,6 +9,7 @@
#include <stdint.h> #include <stdint.h>
#include "attributes.h" #include "attributes.h"
#include "mem.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -47,11 +48,11 @@ typedef struct Mono_Time Mono_Time;
typedef uint64_t mono_time_current_time_cb(void *user_data); typedef uint64_t mono_time_current_time_cb(void *user_data);
nullable(1, 2) non_null(1) nullable(2, 3)
Mono_Time *mono_time_new(mono_time_current_time_cb *current_time_callback, void *user_data); Mono_Time *mono_time_new(const Memory *mem, mono_time_current_time_cb *current_time_callback, void *user_data);
nullable(1) non_null(1) nullable(2)
void mono_time_free(Mono_Time *mono_time); void mono_time_free(const Memory *mem, Mono_Time *mono_time);
/** /**
* Update mono_time; subsequent calls to mono_time_get or mono_time_is_timeout * Update mono_time; subsequent calls to mono_time_get or mono_time_is_timeout

View File

@ -6,7 +6,8 @@ namespace {
TEST(MonoTime, UnixTimeIncreasesOverTime) TEST(MonoTime, UnixTimeIncreasesOverTime)
{ {
Mono_Time *mono_time = mono_time_new(nullptr, nullptr); const Memory *mem = system_memory();
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
ASSERT_NE(mono_time, nullptr); ASSERT_NE(mono_time, nullptr);
mono_time_update(mono_time); mono_time_update(mono_time);
@ -19,12 +20,13 @@ TEST(MonoTime, UnixTimeIncreasesOverTime)
uint64_t const end = mono_time_get(mono_time); uint64_t const end = mono_time_get(mono_time);
EXPECT_GT(end, start); EXPECT_GT(end, start);
mono_time_free(mono_time); mono_time_free(mem, mono_time);
} }
TEST(MonoTime, IsTimeout) TEST(MonoTime, IsTimeout)
{ {
Mono_Time *mono_time = mono_time_new(nullptr, nullptr); const Memory *mem = system_memory();
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
ASSERT_NE(mono_time, nullptr); ASSERT_NE(mono_time, nullptr);
uint64_t const start = mono_time_get(mono_time); uint64_t const start = mono_time_get(mono_time);
@ -36,12 +38,13 @@ TEST(MonoTime, IsTimeout)
EXPECT_TRUE(mono_time_is_timeout(mono_time, start, 1)); EXPECT_TRUE(mono_time_is_timeout(mono_time, start, 1));
mono_time_free(mono_time); mono_time_free(mem, mono_time);
} }
TEST(MonoTime, CustomTime) TEST(MonoTime, CustomTime)
{ {
Mono_Time *mono_time = mono_time_new(nullptr, nullptr); const Memory *mem = system_memory();
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
ASSERT_NE(mono_time, nullptr); ASSERT_NE(mono_time, nullptr);
uint64_t test_time = current_time_monotonic(mono_time) + 42137; uint64_t test_time = current_time_monotonic(mono_time) + 42137;
@ -61,7 +64,7 @@ TEST(MonoTime, CustomTime)
EXPECT_EQ(current_time_monotonic(mono_time), test_time); EXPECT_EQ(current_time_monotonic(mono_time), test_time);
mono_time_free(mono_time); mono_time_free(mem, mono_time);
} }
} // namespace } // namespace

View File

@ -127,6 +127,7 @@ static const Crypto_Connection empty_crypto_connection = {{0}};
struct Net_Crypto { struct Net_Crypto {
const Logger *log; const Logger *log;
const Memory *mem;
const Random *rng; const Random *rng;
Mono_Time *mono_time; Mono_Time *mono_time;
const Network *ns; const Network *ns;
@ -758,7 +759,7 @@ static uint32_t num_packets_array(const Packets_Array *array)
* @retval 0 on success. * @retval 0 on success.
*/ */
non_null() non_null()
static int add_data_to_buffer(Packets_Array *array, uint32_t number, const Packet_Data *data) static int add_data_to_buffer(const Memory *mem, Packets_Array *array, uint32_t number, const Packet_Data *data)
{ {
if (number - array->buffer_start >= CRYPTO_PACKET_BUFFER_SIZE) { if (number - array->buffer_start >= CRYPTO_PACKET_BUFFER_SIZE) {
return -1; return -1;
@ -770,7 +771,7 @@ static int add_data_to_buffer(Packets_Array *array, uint32_t number, const Packe
return -1; return -1;
} }
Packet_Data *new_d = (Packet_Data *)calloc(1, sizeof(Packet_Data)); Packet_Data *new_d = (Packet_Data *)mem_alloc(mem, sizeof(Packet_Data));
if (new_d == nullptr) { if (new_d == nullptr) {
return -1; return -1;
@ -817,7 +818,7 @@ static int get_data_pointer(const Packets_Array *array, Packet_Data **data, uint
* @return packet number on success. * @return packet number on success.
*/ */
non_null() non_null()
static int64_t add_data_end_of_buffer(const Logger *logger, Packets_Array *array, const Packet_Data *data) static int64_t add_data_end_of_buffer(const Logger *logger, const Memory *mem, Packets_Array *array, const Packet_Data *data)
{ {
const uint32_t num_spots = num_packets_array(array); const uint32_t num_spots = num_packets_array(array);
@ -826,7 +827,7 @@ static int64_t add_data_end_of_buffer(const Logger *logger, Packets_Array *array
return -1; return -1;
} }
Packet_Data *new_d = (Packet_Data *)calloc(1, sizeof(Packet_Data)); Packet_Data *new_d = (Packet_Data *)mem_alloc(mem, sizeof(Packet_Data));
if (new_d == nullptr) { if (new_d == nullptr) {
LOGGER_ERROR(logger, "packet data allocation failed"); LOGGER_ERROR(logger, "packet data allocation failed");
@ -846,7 +847,7 @@ static int64_t add_data_end_of_buffer(const Logger *logger, Packets_Array *array
* @return packet number on success. * @return packet number on success.
*/ */
non_null() non_null()
static int64_t read_data_beg_buffer(Packets_Array *array, Packet_Data *data) static int64_t read_data_beg_buffer(const Memory *mem, Packets_Array *array, Packet_Data *data)
{ {
if (array->buffer_end == array->buffer_start) { if (array->buffer_end == array->buffer_start) {
return -1; return -1;
@ -861,7 +862,7 @@ static int64_t read_data_beg_buffer(Packets_Array *array, Packet_Data *data)
*data = *array->buffer[num]; *data = *array->buffer[num];
const uint32_t id = array->buffer_start; const uint32_t id = array->buffer_start;
++array->buffer_start; ++array->buffer_start;
free(array->buffer[num]); mem_delete(mem, array->buffer[num]);
array->buffer[num] = nullptr; array->buffer[num] = nullptr;
return id; return id;
} }
@ -872,7 +873,7 @@ static int64_t read_data_beg_buffer(Packets_Array *array, Packet_Data *data)
* @retval 0 on success * @retval 0 on success
*/ */
non_null() non_null()
static int clear_buffer_until(Packets_Array *array, uint32_t number) static int clear_buffer_until(const Memory *mem, Packets_Array *array, uint32_t number)
{ {
const uint32_t num_spots = num_packets_array(array); const uint32_t num_spots = num_packets_array(array);
@ -886,7 +887,7 @@ static int clear_buffer_until(Packets_Array *array, uint32_t number)
const uint32_t num = i % CRYPTO_PACKET_BUFFER_SIZE; const uint32_t num = i % CRYPTO_PACKET_BUFFER_SIZE;
if (array->buffer[num] != nullptr) { if (array->buffer[num] != nullptr) {
free(array->buffer[num]); mem_delete(mem, array->buffer[num]);
array->buffer[num] = nullptr; array->buffer[num] = nullptr;
} }
} }
@ -896,7 +897,7 @@ static int clear_buffer_until(Packets_Array *array, uint32_t number)
} }
non_null() non_null()
static int clear_buffer(Packets_Array *array) static int clear_buffer(const Memory *mem, Packets_Array *array)
{ {
uint32_t i; uint32_t i;
@ -904,7 +905,7 @@ static int clear_buffer(Packets_Array *array)
const uint32_t num = i % CRYPTO_PACKET_BUFFER_SIZE; const uint32_t num = i % CRYPTO_PACKET_BUFFER_SIZE;
if (array->buffer[num] != nullptr) { if (array->buffer[num] != nullptr) {
free(array->buffer[num]); mem_delete(mem, array->buffer[num]);
array->buffer[num] = nullptr; array->buffer[num] = nullptr;
} }
} }
@ -995,7 +996,7 @@ static int generate_request_packet(uint8_t *data, uint16_t length, const Packets
* @return number of requested packets on success. * @return number of requested packets on success.
*/ */
non_null() non_null()
static int handle_request_packet(Mono_Time *mono_time, Packets_Array *send_array, static int handle_request_packet(const Memory *mem, Mono_Time *mono_time, Packets_Array *send_array,
const uint8_t *data, uint16_t length, const uint8_t *data, uint16_t length,
uint64_t *latest_send_time, uint64_t rtt_time) uint64_t *latest_send_time, uint64_t rtt_time)
{ {
@ -1044,7 +1045,7 @@ static int handle_request_packet(Mono_Time *mono_time, Packets_Array *send_array
if (send_array->buffer[num] != nullptr) { if (send_array->buffer[num] != nullptr) {
l_sent_time = max_u64(l_sent_time, send_array->buffer[num]->sent_time); l_sent_time = max_u64(l_sent_time, send_array->buffer[num]->sent_time);
free(send_array->buffer[num]); mem_delete(mem, send_array->buffer[num]);
send_array->buffer[num] = nullptr; send_array->buffer[num] = nullptr;
} }
} }
@ -1204,7 +1205,7 @@ static int64_t send_lossless_packet(Net_Crypto *c, int crypt_connection_id, cons
dt.length = length; dt.length = length;
memcpy(dt.data, data, length); memcpy(dt.data, data, length);
pthread_mutex_lock(conn->mutex); pthread_mutex_lock(conn->mutex);
const int64_t packet_num = add_data_end_of_buffer(c->log, &conn->send_array, &dt); const int64_t packet_num = add_data_end_of_buffer(c->log, c->mem, &conn->send_array, &dt);
pthread_mutex_unlock(conn->mutex); pthread_mutex_unlock(conn->mutex);
if (packet_num == -1) { if (packet_num == -1) {
@ -1384,14 +1385,14 @@ static int new_temp_packet(const Net_Crypto *c, int crypt_connection_id, const u
return -1; return -1;
} }
uint8_t *temp_packet = (uint8_t *)malloc(length); uint8_t *temp_packet = (uint8_t *)mem_balloc(c->mem, length);
if (temp_packet == nullptr) { if (temp_packet == nullptr) {
return -1; return -1;
} }
if (conn->temp_packet != nullptr) { if (conn->temp_packet != nullptr) {
free(conn->temp_packet); mem_delete(c->mem, conn->temp_packet);
} }
memcpy(temp_packet, packet, length); memcpy(temp_packet, packet, length);
@ -1417,7 +1418,7 @@ static int clear_temp_packet(const Net_Crypto *c, int crypt_connection_id)
} }
if (conn->temp_packet != nullptr) { if (conn->temp_packet != nullptr) {
free(conn->temp_packet); mem_delete(c->mem, conn->temp_packet);
} }
conn->temp_packet = nullptr; conn->temp_packet = nullptr;
@ -1575,7 +1576,7 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const
rtt_calc_time = packet_time->sent_time; rtt_calc_time = packet_time->sent_time;
} }
if (clear_buffer_until(&conn->send_array, buffer_start) != 0) { if (clear_buffer_until(c->mem, &conn->send_array, buffer_start) != 0) {
return -1; return -1;
} }
} }
@ -1616,9 +1617,7 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const
rtt_time = DEFAULT_TCP_PING_CONNECTION; rtt_time = DEFAULT_TCP_PING_CONNECTION;
} }
const int requested = handle_request_packet(c->mono_time, &conn->send_array, const int requested = handle_request_packet(c->mem, c->mono_time, &conn->send_array, real_data, real_length, &rtt_calc_time, rtt_time);
real_data, real_length,
&rtt_calc_time, rtt_time);
if (requested == -1) { if (requested == -1) {
return -1; return -1;
@ -1630,13 +1629,13 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const
dt.length = real_length; dt.length = real_length;
memcpy(dt.data, real_data, real_length); memcpy(dt.data, real_data, real_length);
if (add_data_to_buffer(&conn->recv_array, num, &dt) != 0) { if (add_data_to_buffer(c->mem, &conn->recv_array, num, &dt) != 0) {
return -1; return -1;
} }
while (true) { while (true) {
pthread_mutex_lock(conn->mutex); pthread_mutex_lock(conn->mutex);
const int ret = read_data_beg_buffer(&conn->recv_array, &dt); const int ret = read_data_beg_buffer(c->mem, &conn->recv_array, &dt);
pthread_mutex_unlock(conn->mutex); pthread_mutex_unlock(conn->mutex);
if (ret == -1) { if (ret == -1) {
@ -1804,20 +1803,20 @@ static int handle_packet_connection(Net_Crypto *c, int crypt_connection_id, cons
/** @brief Set the size of the friend list to numfriends. /** @brief Set the size of the friend list to numfriends.
* *
* @retval -1 if realloc fails. * @retval -1 if mem_vrealloc fails.
* @retval 0 if it succeeds. * @retval 0 if it succeeds.
*/ */
non_null() non_null()
static int realloc_cryptoconnection(Net_Crypto *c, uint32_t num) static int realloc_cryptoconnection(Net_Crypto *c, uint32_t num)
{ {
if (num == 0) { if (num == 0) {
free(c->crypto_connections); mem_delete(c->mem, c->crypto_connections);
c->crypto_connections = nullptr; c->crypto_connections = nullptr;
return 0; return 0;
} }
Crypto_Connection *newcrypto_connections = (Crypto_Connection *)realloc(c->crypto_connections, Crypto_Connection *newcrypto_connections = (Crypto_Connection *)mem_vrealloc(
num * sizeof(Crypto_Connection)); c->mem, c->crypto_connections, num, sizeof(Crypto_Connection));
if (newcrypto_connections == nullptr) { if (newcrypto_connections == nullptr) {
return -1; return -1;
@ -1870,7 +1869,7 @@ static int create_crypto_connection(Net_Crypto *c)
c->crypto_connections[id].last_packets_left_rem = 0; c->crypto_connections[id].last_packets_left_rem = 0;
c->crypto_connections[id].packet_send_rate_requested = 0; c->crypto_connections[id].packet_send_rate_requested = 0;
c->crypto_connections[id].last_packets_left_requested_rem = 0; c->crypto_connections[id].last_packets_left_requested_rem = 0;
c->crypto_connections[id].mutex = (pthread_mutex_t *)calloc(1, sizeof(pthread_mutex_t)); c->crypto_connections[id].mutex = (pthread_mutex_t *)mem_alloc(c->mem, sizeof(pthread_mutex_t));
if (c->crypto_connections[id].mutex == nullptr) { if (c->crypto_connections[id].mutex == nullptr) {
pthread_mutex_unlock(&c->connections_mutex); pthread_mutex_unlock(&c->connections_mutex);
@ -1878,7 +1877,7 @@ static int create_crypto_connection(Net_Crypto *c)
} }
if (pthread_mutex_init(c->crypto_connections[id].mutex, nullptr) != 0) { if (pthread_mutex_init(c->crypto_connections[id].mutex, nullptr) != 0) {
free(c->crypto_connections[id].mutex); mem_delete(c->mem, c->crypto_connections[id].mutex);
pthread_mutex_unlock(&c->connections_mutex); pthread_mutex_unlock(&c->connections_mutex);
return -1; return -1;
} }
@ -1915,7 +1914,7 @@ static int wipe_crypto_connection(Net_Crypto *c, int crypt_connection_id)
uint32_t i; uint32_t i;
pthread_mutex_destroy(c->crypto_connections[crypt_connection_id].mutex); pthread_mutex_destroy(c->crypto_connections[crypt_connection_id].mutex);
free(c->crypto_connections[crypt_connection_id].mutex); mem_delete(c->mem, c->crypto_connections[crypt_connection_id].mutex);
crypto_memzero(&c->crypto_connections[crypt_connection_id], sizeof(Crypto_Connection)); crypto_memzero(&c->crypto_connections[crypt_connection_id], sizeof(Crypto_Connection));
/* check if we can resize the connections array */ /* check if we can resize the connections array */
@ -2019,7 +2018,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source,
void *userdata) void *userdata)
{ {
New_Connection n_c; New_Connection n_c;
n_c.cookie = (uint8_t *)malloc(COOKIE_LENGTH); n_c.cookie = (uint8_t *)mem_balloc(c->mem, COOKIE_LENGTH);
if (n_c.cookie == nullptr) { if (n_c.cookie == nullptr) {
return -1; return -1;
@ -2030,7 +2029,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source,
if (!handle_crypto_handshake(c, n_c.recv_nonce, n_c.peersessionpublic_key, n_c.public_key, n_c.dht_public_key, if (!handle_crypto_handshake(c, n_c.recv_nonce, n_c.peersessionpublic_key, n_c.public_key, n_c.dht_public_key,
n_c.cookie, data, length, nullptr)) { n_c.cookie, data, length, nullptr)) {
free(n_c.cookie); mem_delete(c->mem, n_c.cookie);
return -1; return -1;
} }
@ -2047,7 +2046,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source,
connection_kill(c, crypt_connection_id, userdata); connection_kill(c, crypt_connection_id, userdata);
} else { } else {
if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING && conn->status != CRYPTO_CONN_HANDSHAKE_SENT) { if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING && conn->status != CRYPTO_CONN_HANDSHAKE_SENT) {
free(n_c.cookie); mem_delete(c->mem, n_c.cookie);
return -1; return -1;
} }
@ -2058,18 +2057,18 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source,
crypto_connection_add_source(c, crypt_connection_id, source); crypto_connection_add_source(c, crypt_connection_id, source);
if (create_send_handshake(c, crypt_connection_id, n_c.cookie, n_c.dht_public_key) != 0) { if (create_send_handshake(c, crypt_connection_id, n_c.cookie, n_c.dht_public_key) != 0) {
free(n_c.cookie); mem_delete(c->mem, n_c.cookie);
return -1; return -1;
} }
conn->status = CRYPTO_CONN_NOT_CONFIRMED; conn->status = CRYPTO_CONN_NOT_CONFIRMED;
free(n_c.cookie); mem_delete(c->mem, n_c.cookie);
return 0; return 0;
} }
} }
const int ret = c->new_connection_callback(c->new_connection_callback_object, &n_c); const int ret = c->new_connection_callback(c->new_connection_callback_object, &n_c);
free(n_c.cookie); mem_delete(c->mem, n_c.cookie);
return ret; return ret;
} }
@ -3045,8 +3044,8 @@ int crypto_kill(Net_Crypto *c, int crypt_connection_id)
bs_list_remove(&c->ip_port_list, (uint8_t *)&conn->ip_portv4, crypt_connection_id); bs_list_remove(&c->ip_port_list, (uint8_t *)&conn->ip_portv4, crypt_connection_id);
bs_list_remove(&c->ip_port_list, (uint8_t *)&conn->ip_portv6, crypt_connection_id); bs_list_remove(&c->ip_port_list, (uint8_t *)&conn->ip_portv6, crypt_connection_id);
clear_temp_packet(c, crypt_connection_id); clear_temp_packet(c, crypt_connection_id);
clear_buffer(&conn->send_array); clear_buffer(c->mem, &conn->send_array);
clear_buffer(&conn->recv_array); clear_buffer(c->mem, &conn->recv_array);
ret = wipe_crypto_connection(c, crypt_connection_id); ret = wipe_crypto_connection(c, crypt_connection_id);
} }
@ -3067,9 +3066,8 @@ bool crypto_connection_status(const Net_Crypto *c, int crypt_connection_id, bool
const uint64_t current_time = mono_time_get(c->mono_time); const uint64_t current_time = mono_time_get(c->mono_time);
if ((UDP_DIRECT_TIMEOUT + conn->direct_lastrecv_timev4) > current_time) { if ((UDP_DIRECT_TIMEOUT + conn->direct_lastrecv_timev4) > current_time ||
*direct_connected = true; (UDP_DIRECT_TIMEOUT + conn->direct_lastrecv_timev6) > current_time) {
} else if ((UDP_DIRECT_TIMEOUT + conn->direct_lastrecv_timev6) > current_time) {
*direct_connected = true; *direct_connected = true;
} }
} }
@ -3109,27 +3107,29 @@ void load_secret_key(Net_Crypto *c, const uint8_t *sk)
/** @brief Create new instance of Net_Crypto. /** @brief Create new instance of Net_Crypto.
* Sets all the global connection variables to their default values. * Sets all the global connection variables to their default values.
*/ */
Net_Crypto *new_net_crypto(const Logger *log, const Random *rng, const Network *ns, Mono_Time *mono_time, DHT *dht, const TCP_Proxy_Info *proxy_info) Net_Crypto *new_net_crypto(const Logger *log, const Memory *mem, const Random *rng, const Network *ns,
Mono_Time *mono_time, DHT *dht, const TCP_Proxy_Info *proxy_info)
{ {
if (dht == nullptr) { if (dht == nullptr) {
return nullptr; return nullptr;
} }
Net_Crypto *temp = (Net_Crypto *)calloc(1, sizeof(Net_Crypto)); Net_Crypto *temp = (Net_Crypto *)mem_alloc(mem, sizeof(Net_Crypto));
if (temp == nullptr) { if (temp == nullptr) {
return nullptr; return nullptr;
} }
temp->log = log; temp->log = log;
temp->mem = mem;
temp->rng = rng; temp->rng = rng;
temp->mono_time = mono_time; temp->mono_time = mono_time;
temp->ns = ns; temp->ns = ns;
temp->tcp_c = new_tcp_connections(log, rng, ns, mono_time, dht_get_self_secret_key(dht), proxy_info); temp->tcp_c = new_tcp_connections(log, mem, rng, ns, mono_time, dht_get_self_secret_key(dht), proxy_info);
if (temp->tcp_c == nullptr) { if (temp->tcp_c == nullptr) {
free(temp); mem_delete(mem, temp);
return nullptr; return nullptr;
} }
@ -3139,7 +3139,7 @@ Net_Crypto *new_net_crypto(const Logger *log, const Random *rng, const Network *
if (create_recursive_mutex(&temp->tcp_mutex) != 0 || if (create_recursive_mutex(&temp->tcp_mutex) != 0 ||
pthread_mutex_init(&temp->connections_mutex, nullptr) != 0) { pthread_mutex_init(&temp->connections_mutex, nullptr) != 0) {
kill_tcp_connections(temp->tcp_c); kill_tcp_connections(temp->tcp_c);
free(temp); mem_delete(mem, temp);
return nullptr; return nullptr;
} }
@ -3210,6 +3210,8 @@ void kill_net_crypto(Net_Crypto *c)
return; return;
} }
const Memory *mem = c->mem;
for (uint32_t i = 0; i < c->crypto_connections_length; ++i) { for (uint32_t i = 0; i < c->crypto_connections_length; ++i) {
crypto_kill(c, i); crypto_kill(c, i);
} }
@ -3224,5 +3226,5 @@ void kill_net_crypto(Net_Crypto *c)
networking_registerhandler(dht_get_net(c->dht), NET_PACKET_CRYPTO_HS, nullptr, nullptr); networking_registerhandler(dht_get_net(c->dht), NET_PACKET_CRYPTO_HS, nullptr, nullptr);
networking_registerhandler(dht_get_net(c->dht), NET_PACKET_CRYPTO_DATA, nullptr, nullptr); networking_registerhandler(dht_get_net(c->dht), NET_PACKET_CRYPTO_DATA, nullptr, nullptr);
crypto_memzero(c, sizeof(Net_Crypto)); crypto_memzero(c, sizeof(Net_Crypto));
free(c); mem_delete(mem, c);
} }

View File

@ -398,7 +398,8 @@ void load_secret_key(Net_Crypto *c, const uint8_t *sk);
* Sets all the global connection variables to their default values. * Sets all the global connection variables to their default values.
*/ */
non_null() non_null()
Net_Crypto *new_net_crypto(const Logger *log, const Random *rng, const Network *ns, Mono_Time *mono_time, DHT *dht, const TCP_Proxy_Info *proxy_info); Net_Crypto *new_net_crypto(const Logger *log, const Memory *mem, const Random *rng, const Network *ns,
Mono_Time *mono_time, DHT *dht, const TCP_Proxy_Info *proxy_info);
/** return the optimal interval in ms for running do_net_crypto. */ /** return the optimal interval in ms for running do_net_crypto. */
non_null() non_null()

View File

@ -139,15 +139,15 @@ static const char *inet_ntop6(const struct in6_addr *addr, char *buf, size_t buf
} }
non_null() non_null()
static int inet_pton4(const char *addrString, struct in_addr *addrbuf) static int inet_pton4(const char *addr_string, struct in_addr *addrbuf)
{ {
return inet_pton(AF_INET, addrString, addrbuf); return inet_pton(AF_INET, addr_string, addrbuf);
} }
non_null() non_null()
static int inet_pton6(const char *addrString, struct in6_addr *addrbuf) static int inet_pton6(const char *addr_string, struct in6_addr *addrbuf)
{ {
return inet_pton(AF_INET6, addrString, addrbuf); return inet_pton(AF_INET6, addr_string, addrbuf);
} }
#else #else
@ -377,47 +377,47 @@ IP6 get_ip6_loopback(void)
const Socket net_invalid_socket = { (int)INVALID_SOCKET }; const Socket net_invalid_socket = { (int)INVALID_SOCKET };
Family net_family_unspec() Family net_family_unspec(void)
{ {
return family_unspec; return family_unspec;
} }
Family net_family_ipv4() Family net_family_ipv4(void)
{ {
return family_ipv4; return family_ipv4;
} }
Family net_family_ipv6() Family net_family_ipv6(void)
{ {
return family_ipv6; return family_ipv6;
} }
Family net_family_tcp_server() Family net_family_tcp_server(void)
{ {
return family_tcp_server; return family_tcp_server;
} }
Family net_family_tcp_client() Family net_family_tcp_client(void)
{ {
return family_tcp_client; return family_tcp_client;
} }
Family net_family_tcp_ipv4() Family net_family_tcp_ipv4(void)
{ {
return family_tcp_ipv4; return family_tcp_ipv4;
} }
Family net_family_tcp_ipv6() Family net_family_tcp_ipv6(void)
{ {
return family_tcp_ipv6; return family_tcp_ipv6;
} }
Family net_family_tox_tcp_ipv4() Family net_family_tox_tcp_ipv4(void)
{ {
return family_tox_tcp_ipv4; return family_tox_tcp_ipv4;
} }
Family net_family_tox_tcp_ipv6() Family net_family_tox_tcp_ipv6(void)
{ {
return family_tox_tcp_ipv6; return family_tox_tcp_ipv6;
} }
@ -898,6 +898,7 @@ typedef struct Packet_Handler {
struct Networking_Core { struct Networking_Core {
const Logger *log; const Logger *log;
const Memory *mem;
Packet_Handler packethandlers[256]; Packet_Handler packethandlers[256];
const Network *ns; const Network *ns;
@ -1009,7 +1010,7 @@ int sendpacket(const Networking_Core *net, const IP_Port *ip_port, const uint8_t
* Packet length is put into length. * Packet length is put into length.
*/ */
non_null() non_null()
static int receivepacket(const Network *ns, const Logger *log, Socket sock, IP_Port *ip_port, uint8_t *data, uint32_t *length) static int receivepacket(const Network *ns, const Memory *mem, const Logger *log, Socket sock, IP_Port *ip_port, uint8_t *data, uint32_t *length)
{ {
memset(ip_port, 0, sizeof(IP_Port)); memset(ip_port, 0, sizeof(IP_Port));
Network_Addr addr = {{0}}; Network_Addr addr = {{0}};
@ -1088,7 +1089,7 @@ void networking_poll(const Networking_Core *net, void *userdata)
uint8_t data[MAX_UDP_PACKET_SIZE]; uint8_t data[MAX_UDP_PACKET_SIZE];
uint32_t length; uint32_t length;
while (receivepacket(net->ns, net->log, net->sock, &ip_port, data, &length) != -1) { while (receivepacket(net->ns, net->mem, net->log, net->sock, &ip_port, data, &length) != -1) {
if (length < 1) { if (length < 1) {
continue; continue;
} }
@ -1117,7 +1118,7 @@ void networking_poll(const Networking_Core *net, void *userdata)
* If error is non NULL it is set to 0 if no issues, 1 if socket related error, 2 if other. * If error is non NULL it is set to 0 if no issues, 1 if socket related error, 2 if other.
*/ */
Networking_Core *new_networking_ex( Networking_Core *new_networking_ex(
const Logger *log, const Network *ns, const IP *ip, const Logger *log, const Memory *mem, const Network *ns, const IP *ip,
uint16_t port_from, uint16_t port_to, unsigned int *error) uint16_t port_from, uint16_t port_to, unsigned int *error)
{ {
/* If both from and to are 0, use default port range /* If both from and to are 0, use default port range
@ -1147,7 +1148,7 @@ Networking_Core *new_networking_ex(
return nullptr; return nullptr;
} }
Networking_Core *temp = (Networking_Core *)calloc(1, sizeof(Networking_Core)); Networking_Core *temp = (Networking_Core *)mem_alloc(mem, sizeof(Networking_Core));
if (temp == nullptr) { if (temp == nullptr) {
return nullptr; return nullptr;
@ -1155,6 +1156,7 @@ Networking_Core *new_networking_ex(
temp->ns = ns; temp->ns = ns;
temp->log = log; temp->log = log;
temp->mem = mem;
temp->family = ip->family; temp->family = ip->family;
temp->port = 0; temp->port = 0;
@ -1168,7 +1170,7 @@ Networking_Core *new_networking_ex(
char *strerror = net_new_strerror(neterror); char *strerror = net_new_strerror(neterror);
LOGGER_ERROR(log, "failed to get a socket?! %d, %s", neterror, strerror); LOGGER_ERROR(log, "failed to get a socket?! %d, %s", neterror, strerror);
net_kill_strerror(strerror); net_kill_strerror(strerror);
free(temp); mem_delete(mem, temp);
if (error != nullptr) { if (error != nullptr) {
*error = 1; *error = 1;
@ -1246,7 +1248,7 @@ Networking_Core *new_networking_ex(
portptr = &addr6->sin6_port; portptr = &addr6->sin6_port;
} else { } else {
free(temp); mem_delete(mem, temp);
return nullptr; return nullptr;
} }
@ -1350,10 +1352,10 @@ Networking_Core *new_networking_ex(
return nullptr; return nullptr;
} }
Networking_Core *new_networking_no_udp(const Logger *log, const Network *ns) Networking_Core *new_networking_no_udp(const Logger *log, const Memory *mem, const Network *ns)
{ {
/* this is the easiest way to completely disable UDP without changing too much code. */ /* this is the easiest way to completely disable UDP without changing too much code. */
Networking_Core *net = (Networking_Core *)calloc(1, sizeof(Networking_Core)); Networking_Core *net = (Networking_Core *)mem_alloc(mem, sizeof(Networking_Core));
if (net == nullptr) { if (net == nullptr) {
return nullptr; return nullptr;
@ -1361,6 +1363,7 @@ Networking_Core *new_networking_no_udp(const Logger *log, const Network *ns)
net->ns = ns; net->ns = ns;
net->log = log; net->log = log;
net->mem = mem;
return net; return net;
} }
@ -1377,7 +1380,7 @@ void kill_networking(Networking_Core *net)
kill_sock(net->ns, net->sock); kill_sock(net->ns, net->sock);
} }
free(net); mem_delete(net->mem, net);
} }
@ -1712,7 +1715,7 @@ bool addr_resolve_or_parse_ip(const Network *ns, const char *address, IP *to, IP
return true; return true;
} }
bool net_connect(const Logger *log, Socket sock, const IP_Port *ip_port) bool net_connect(const Memory *mem, const Logger *log, Socket sock, const IP_Port *ip_port)
{ {
struct sockaddr_storage addr = {0}; struct sockaddr_storage addr = {0};
size_t addrsize; size_t addrsize;
@ -1765,13 +1768,16 @@ bool net_connect(const Logger *log, Socket sock, const IP_Port *ip_port)
return true; return true;
} }
int32_t net_getipport(const char *node, IP_Port **res, int tox_type) int32_t net_getipport(const Memory *mem, const char *node, IP_Port **res, int tox_type)
{ {
// Try parsing as IP address first. // Try parsing as IP address first.
IP_Port parsed = {{{0}}}; IP_Port parsed = {{{0}}};
// Initialise to nullptr. In error paths, at least we initialise the out
// parameter.
*res = nullptr;
if (addr_parse_ip(node, &parsed.ip)) { if (addr_parse_ip(node, &parsed.ip)) {
IP_Port *tmp = (IP_Port *)calloc(1, sizeof(IP_Port)); IP_Port *tmp = (IP_Port *)mem_alloc(mem, sizeof(IP_Port));
if (tmp == nullptr) { if (tmp == nullptr) {
return -1; return -1;
@ -1784,7 +1790,7 @@ int32_t net_getipport(const char *node, IP_Port **res, int tox_type)
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
if ((true)) { if ((true)) {
*res = (IP_Port *)calloc(1, sizeof(IP_Port)); *res = (IP_Port *)mem_alloc(mem, sizeof(IP_Port));
assert(*res != nullptr); assert(*res != nullptr);
IP_Port *ip_port = *res; IP_Port *ip_port = *res;
ip_port->ip.ip.v4.uint32 = net_htonl(0x7F000003); // 127.0.0.3 ip_port->ip.ip.v4.uint32 = net_htonl(0x7F000003); // 127.0.0.3
@ -1797,7 +1803,6 @@ int32_t net_getipport(const char *node, IP_Port **res, int tox_type)
// It's not an IP address, so now we try doing a DNS lookup. // It's not an IP address, so now we try doing a DNS lookup.
struct addrinfo *infos; struct addrinfo *infos;
const int ret = getaddrinfo(node, nullptr, nullptr, &infos); const int ret = getaddrinfo(node, nullptr, nullptr, &infos);
*res = nullptr;
if (ret != 0) { if (ret != 0) {
return -1; return -1;
@ -1827,7 +1832,7 @@ int32_t net_getipport(const char *node, IP_Port **res, int tox_type)
return 0; return 0;
} }
*res = (IP_Port *)calloc(count, sizeof(IP_Port)); *res = (IP_Port *)mem_valloc(mem, count, sizeof(IP_Port));
if (*res == nullptr) { if (*res == nullptr) {
freeaddrinfo(infos); freeaddrinfo(infos);
@ -1869,9 +1874,9 @@ int32_t net_getipport(const char *node, IP_Port **res, int tox_type)
return count; return count;
} }
void net_freeipport(IP_Port *ip_ports) void net_freeipport(const Memory *mem, IP_Port *ip_ports)
{ {
free(ip_ports); mem_delete(mem, ip_ports);
} }
bool bind_to_port(const Network *ns, Socket sock, Family family, uint16_t port) bool bind_to_port(const Network *ns, Socket sock, Family family, uint16_t port)

View File

@ -14,6 +14,7 @@
#include <stdint.h> // uint*_t #include <stdint.h> // uint*_t
#include "logger.h" #include "logger.h"
#include "mem.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -533,7 +534,7 @@ void networking_poll(const Networking_Core *net, void *userdata);
* Return false on failure. * Return false on failure.
*/ */
non_null() non_null()
bool net_connect(const Logger *log, Socket sock, const IP_Port *ip_port); bool net_connect(const Memory *mem, const Logger *log, Socket sock, const IP_Port *ip_port);
/** @brief High-level getaddrinfo implementation. /** @brief High-level getaddrinfo implementation.
* *
@ -549,11 +550,11 @@ bool net_connect(const Logger *log, Socket sock, const IP_Port *ip_port);
* @retval -1 on error. * @retval -1 on error.
*/ */
non_null() non_null()
int32_t net_getipport(const char *node, IP_Port **res, int tox_type); int32_t net_getipport(const Memory *mem, const char *node, IP_Port **res, int tox_type);
/** Deallocates memory allocated by net_getipport */ /** Deallocates memory allocated by net_getipport */
nullable(1) non_null(1) nullable(2)
void net_freeipport(IP_Port *ip_ports); void net_freeipport(const Memory *mem, IP_Port *ip_ports);
/** /**
* @return true on success, false on failure. * @return true on success, false on failure.
@ -600,13 +601,13 @@ void net_kill_strerror(char *strerror);
* *
* If error is non NULL it is set to 0 if no issues, 1 if socket related error, 2 if other. * If error is non NULL it is set to 0 if no issues, 1 if socket related error, 2 if other.
*/ */
non_null(1, 2, 3) nullable(6) non_null(1, 2, 3, 4) nullable(7)
Networking_Core *new_networking_ex( Networking_Core *new_networking_ex(
const Logger *log, const Network *ns, const IP *ip, const Logger *log, const Memory *mem, const Network *ns, const IP *ip,
uint16_t port_from, uint16_t port_to, unsigned int *error); uint16_t port_from, uint16_t port_to, unsigned int *error);
non_null() non_null()
Networking_Core *new_networking_no_udp(const Logger *log, const Network *ns); Networking_Core *new_networking_no_udp(const Logger *log, const Memory *mem, const Network *ns);
/** Function to cleanup networking stuff (doesn't do much right now). */ /** Function to cleanup networking stuff (doesn't do much right now). */
nullable(1) nullable(1)

View File

@ -668,13 +668,13 @@ void set_callback_handle_recv_1(Onion *onion, onion_recv_1_cb *function, void *o
onion->callback_object = object; onion->callback_object = object;
} }
Onion *new_onion(const Logger *log, const Mono_Time *mono_time, const Random *rng, DHT *dht) Onion *new_onion(const Logger *log, const Memory *mem, const Mono_Time *mono_time, const Random *rng, DHT *dht)
{ {
if (dht == nullptr) { if (dht == nullptr) {
return nullptr; return nullptr;
} }
Onion *onion = (Onion *)calloc(1, sizeof(Onion)); Onion *onion = (Onion *)mem_alloc(mem, sizeof(Onion));
if (onion == nullptr) { if (onion == nullptr) {
return nullptr; return nullptr;
@ -685,13 +685,14 @@ Onion *new_onion(const Logger *log, const Mono_Time *mono_time, const Random *rn
onion->net = dht_get_net(dht); onion->net = dht_get_net(dht);
onion->mono_time = mono_time; onion->mono_time = mono_time;
onion->rng = rng; onion->rng = rng;
onion->mem = mem;
new_symmetric_key(rng, onion->secret_symmetric_key); new_symmetric_key(rng, onion->secret_symmetric_key);
onion->timestamp = mono_time_get(onion->mono_time); onion->timestamp = mono_time_get(onion->mono_time);
const uint8_t *secret_key = dht_get_self_secret_key(dht); const uint8_t *secret_key = dht_get_self_secret_key(dht);
onion->shared_keys_1 = shared_key_cache_new(mono_time, secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT); onion->shared_keys_1 = shared_key_cache_new(mono_time, mem, secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT);
onion->shared_keys_2 = shared_key_cache_new(mono_time, secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT); onion->shared_keys_2 = shared_key_cache_new(mono_time, mem, secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT);
onion->shared_keys_3 = shared_key_cache_new(mono_time, secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT); onion->shared_keys_3 = shared_key_cache_new(mono_time, mem, secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT);
if (onion->shared_keys_1 == nullptr || if (onion->shared_keys_1 == nullptr ||
onion->shared_keys_2 == nullptr || onion->shared_keys_2 == nullptr ||
@ -732,5 +733,5 @@ void kill_onion(Onion *onion)
shared_key_cache_free(onion->shared_keys_2); shared_key_cache_free(onion->shared_keys_2);
shared_key_cache_free(onion->shared_keys_3); shared_key_cache_free(onion->shared_keys_3);
free(onion); mem_delete(onion->mem, onion);
} }

View File

@ -20,6 +20,7 @@ typedef struct Onion {
const Logger *log; const Logger *log;
const Mono_Time *mono_time; const Mono_Time *mono_time;
const Random *rng; const Random *rng;
const Memory *mem;
DHT *dht; DHT *dht;
Networking_Core *net; Networking_Core *net;
uint8_t secret_symmetric_key[CRYPTO_SYMMETRIC_KEY_SIZE]; uint8_t secret_symmetric_key[CRYPTO_SYMMETRIC_KEY_SIZE];
@ -147,7 +148,7 @@ non_null(1) nullable(2, 3)
void set_callback_handle_recv_1(Onion *onion, onion_recv_1_cb *function, void *object); void set_callback_handle_recv_1(Onion *onion, onion_recv_1_cb *function, void *object);
non_null() non_null()
Onion *new_onion(const Logger *log, const Mono_Time *mono_time, const Random *rng, DHT *dht); Onion *new_onion(const Logger *log, const Memory *mem, const Mono_Time *mono_time, const Random *rng, DHT *dht);
nullable(1) nullable(1)
void kill_onion(Onion *onion); void kill_onion(Onion *onion);

View File

@ -51,6 +51,7 @@ struct Onion_Announce {
const Logger *log; const Logger *log;
const Mono_Time *mono_time; const Mono_Time *mono_time;
const Random *rng; const Random *rng;
const Memory *mem;
DHT *dht; DHT *dht;
Networking_Core *net; Networking_Core *net;
Onion_Announce_Entry entries[ONION_ANNOUNCE_MAX_ENTRIES]; Onion_Announce_Entry entries[ONION_ANNOUNCE_MAX_ENTRIES];
@ -316,12 +317,13 @@ static int cmp_entry(const void *a, const void *b)
} }
non_null() non_null()
static void sort_onion_announce_list(Onion_Announce_Entry *list, unsigned int length, const Mono_Time *mono_time, 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) const uint8_t *comp_public_key)
{ {
// Pass comp_public_key to qsort with each Client_data entry, so the // Pass comp_public_key to qsort with each Client_data entry, so the
// comparison function can use it as the base of comparison. // comparison function can use it as the base of comparison.
Cmp_Data *cmp_list = (Cmp_Data *)calloc(length, sizeof(Cmp_Data)); Cmp_Data *cmp_list = (Cmp_Data *)mem_valloc(mem, length, sizeof(Cmp_Data));
if (cmp_list == nullptr) { if (cmp_list == nullptr) {
return; return;
@ -339,7 +341,7 @@ static void sort_onion_announce_list(Onion_Announce_Entry *list, unsigned int le
list[i] = cmp_list[i].entry; list[i] = cmp_list[i].entry;
} }
free(cmp_list); mem_delete(mem, cmp_list);
} }
/** @brief add entry to entries list /** @brief add entry to entries list
@ -377,7 +379,8 @@ static int add_to_entries(Onion_Announce *onion_a, const IP_Port *ret_ip_port, c
memcpy(onion_a->entries[pos].data_public_key, data_public_key, CRYPTO_PUBLIC_KEY_SIZE); memcpy(onion_a->entries[pos].data_public_key, data_public_key, CRYPTO_PUBLIC_KEY_SIZE);
onion_a->entries[pos].announce_time = mono_time_get(onion_a->mono_time); onion_a->entries[pos].announce_time = mono_time_get(onion_a->mono_time);
sort_onion_announce_list(onion_a->entries, ONION_ANNOUNCE_MAX_ENTRIES, onion_a->mono_time, sort_onion_announce_list(onion_a->mem, onion_a->mono_time,
onion_a->entries, ONION_ANNOUNCE_MAX_ENTRIES,
dht_get_self_public_key(onion_a->dht)); dht_get_self_public_key(onion_a->dht));
return in_entries(onion_a, public_key); return in_entries(onion_a, public_key);
} }
@ -438,7 +441,7 @@ static int handle_announce_request_common(
return 1; return 1;
} }
uint8_t *plain = (uint8_t *)malloc(plain_size); uint8_t *plain = (uint8_t *)mem_balloc(onion_a->mem, plain_size);
if (plain == nullptr) { if (plain == nullptr) {
return 1; return 1;
@ -448,7 +451,7 @@ static int handle_announce_request_common(
packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE, plain_size + CRYPTO_MAC_SIZE, plain); packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE, plain_size + CRYPTO_MAC_SIZE, plain);
if ((uint32_t)decrypted_len != plain_size) { if ((uint32_t)decrypted_len != plain_size) {
free(plain); mem_delete(onion_a->mem, plain);
return 1; return 1;
} }
@ -483,10 +486,10 @@ static int handle_announce_request_common(
const uint16_t response_size = nodes_offset const uint16_t response_size = nodes_offset
+ MAX_SENT_NODES * PACKED_NODE_SIZE_IP6 + MAX_SENT_NODES * PACKED_NODE_SIZE_IP6
+ max_extra_size; + max_extra_size;
uint8_t *response = (uint8_t *)malloc(response_size); uint8_t *response = (uint8_t *)mem_balloc(onion_a->mem, response_size);
if (response == nullptr) { if (response == nullptr) {
free(plain); mem_delete(onion_a->mem, plain);
return 1; return 1;
} }
@ -504,8 +507,8 @@ static int handle_announce_request_common(
if (nodes_length <= 0) { if (nodes_length <= 0) {
LOGGER_WARNING(onion_a->log, "Failed to pack nodes"); LOGGER_WARNING(onion_a->log, "Failed to pack nodes");
free(response); mem_delete(onion_a->mem, response);
free(plain); mem_delete(onion_a->mem, plain);
return 1; return 1;
} }
} }
@ -523,8 +526,8 @@ static int handle_announce_request_common(
response, response_size, offset); response, response_size, offset);
if (extra_size == -1) { if (extra_size == -1) {
free(response); mem_delete(onion_a->mem, response);
free(plain); mem_delete(onion_a->mem, plain);
return 1; return 1;
} }
@ -536,8 +539,8 @@ static int handle_announce_request_common(
if (len != offset + CRYPTO_MAC_SIZE) { if (len != offset + CRYPTO_MAC_SIZE) {
LOGGER_ERROR(onion_a->log, "Failed to encrypt announce response"); LOGGER_ERROR(onion_a->log, "Failed to encrypt announce response");
free(response); mem_delete(onion_a->mem, response);
free(plain); mem_delete(onion_a->mem, plain);
return 1; return 1;
} }
@ -549,13 +552,13 @@ static int handle_announce_request_common(
if (send_onion_response(onion_a->net, source, data, if (send_onion_response(onion_a->net, source, data,
1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE + len, 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE + len,
packet + (length - ONION_RETURN_3)) == -1) { packet + (length - ONION_RETURN_3)) == -1) {
free(response); mem_delete(onion_a->mem, response);
free(plain); mem_delete(onion_a->mem, plain);
return 1; return 1;
} }
free(response); mem_delete(onion_a->mem, response);
free(plain); mem_delete(onion_a->mem, plain);
return 0; return 0;
} }
@ -639,13 +642,13 @@ static int handle_data_request(void *object, const IP_Port *source, const uint8_
return 0; return 0;
} }
Onion_Announce *new_onion_announce(const Logger *log, const Random *rng, const Mono_Time *mono_time, DHT *dht) Onion_Announce *new_onion_announce(const Logger *log, const Memory *mem, const Random *rng, const Mono_Time *mono_time, DHT *dht)
{ {
if (dht == nullptr) { if (dht == nullptr) {
return nullptr; return nullptr;
} }
Onion_Announce *onion_a = (Onion_Announce *)calloc(1, sizeof(Onion_Announce)); Onion_Announce *onion_a = (Onion_Announce *)mem_alloc(mem, sizeof(Onion_Announce));
if (onion_a == nullptr) { if (onion_a == nullptr) {
return nullptr; return nullptr;
@ -653,6 +656,7 @@ Onion_Announce *new_onion_announce(const Logger *log, const Random *rng, const M
onion_a->log = log; onion_a->log = log;
onion_a->rng = rng; onion_a->rng = rng;
onion_a->mem = mem;
onion_a->mono_time = mono_time; onion_a->mono_time = mono_time;
onion_a->dht = dht; onion_a->dht = dht;
onion_a->net = dht_get_net(dht); onion_a->net = dht_get_net(dht);
@ -661,7 +665,7 @@ Onion_Announce *new_onion_announce(const Logger *log, const Random *rng, const M
onion_a->extra_data_object = nullptr; onion_a->extra_data_object = nullptr;
new_hmac_key(rng, onion_a->hmac_key); new_hmac_key(rng, onion_a->hmac_key);
onion_a->shared_keys_recv = shared_key_cache_new(mono_time, dht_get_self_secret_key(dht), KEYS_TIMEOUT, MAX_KEYS_PER_SLOT); onion_a->shared_keys_recv = shared_key_cache_new(mono_time, mem, dht_get_self_secret_key(dht), KEYS_TIMEOUT, MAX_KEYS_PER_SLOT);
if (onion_a->shared_keys_recv == nullptr) { if (onion_a->shared_keys_recv == nullptr) {
kill_onion_announce(onion_a); kill_onion_announce(onion_a);
return nullptr; return nullptr;
@ -687,5 +691,5 @@ void kill_onion_announce(Onion_Announce *onion_a)
crypto_memzero(onion_a->hmac_key, CRYPTO_HMAC_KEY_SIZE); crypto_memzero(onion_a->hmac_key, CRYPTO_HMAC_KEY_SIZE);
shared_key_cache_free(onion_a->shared_keys_recv); shared_key_cache_free(onion_a->shared_keys_recv);
free(onion_a); mem_delete(onion_a->mem, onion_a);
} }

View File

@ -131,7 +131,7 @@ void onion_announce_extra_data_callback(Onion_Announce *onion_a, uint16_t extra_
pack_extra_data_cb *extra_data_callback, void *extra_data_object); pack_extra_data_cb *extra_data_callback, void *extra_data_object);
non_null() non_null()
Onion_Announce *new_onion_announce(const Logger *log, const Random *rng, const Mono_Time *mono_time, DHT *dht); Onion_Announce *new_onion_announce(const Logger *log, const Memory *mem, const Random *rng, const Mono_Time *mono_time, DHT *dht);
nullable(1) nullable(1)
void kill_onion_announce(Onion_Announce *onion_a); void kill_onion_announce(Onion_Announce *onion_a);

View File

@ -106,6 +106,7 @@ struct Onion_Client {
const Mono_Time *mono_time; const Mono_Time *mono_time;
const Logger *logger; const Logger *logger;
const Random *rng; const Random *rng;
const Memory *mem;
DHT *dht; DHT *dht;
Net_Crypto *c; Net_Crypto *c;
@ -731,12 +732,12 @@ static int onion_client_cmp_entry(const void *a, const void *b)
} }
non_null() non_null()
static void sort_onion_node_list(Onion_Node *list, unsigned int length, const Mono_Time *mono_time, static void sort_onion_node_list(const Memory *mem, const Mono_Time *mono_time,
const uint8_t *comp_public_key) 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 qsort with each Client_data entry, so the
// comparison function can use it as the base of comparison. // comparison function can use it as the base of comparison.
Onion_Client_Cmp_Data *cmp_list = (Onion_Client_Cmp_Data *)calloc(length, sizeof(Onion_Client_Cmp_Data)); Onion_Client_Cmp_Data *cmp_list = (Onion_Client_Cmp_Data *)mem_valloc(mem, length, sizeof(Onion_Client_Cmp_Data));
if (cmp_list == nullptr) { if (cmp_list == nullptr) {
return; return;
@ -754,7 +755,7 @@ static void sort_onion_node_list(Onion_Node *list, unsigned int length, const Mo
list[i] = cmp_list[i].entry; list[i] = cmp_list[i].entry;
} }
free(cmp_list); mem_delete(mem, cmp_list);
} }
non_null() non_null()
@ -787,7 +788,7 @@ static int client_add_to_list(Onion_Client *onion_c, uint32_t num, const uint8_t
list_length = MAX_ONION_CLIENTS; list_length = MAX_ONION_CLIENTS;
} }
sort_onion_node_list(node_list, list_length, onion_c->mono_time, reference_id); sort_onion_node_list(onion_c->mem, onion_c->mono_time, node_list, list_length, reference_id);
int index = -1; int index = -1;
bool stored = false; bool stored = false;
@ -1161,7 +1162,7 @@ static int handle_dhtpk_announce(void *object, const uint8_t *source_pubkey, con
onion_c->friends_list[friend_num].dht_pk_callback_number, data + 1 + sizeof(uint64_t), userdata); onion_c->friends_list[friend_num].dht_pk_callback_number, data + 1 + sizeof(uint64_t), userdata);
} }
onion_set_friend_DHT_pubkey(onion_c, friend_num, data + 1 + sizeof(uint64_t)); onion_set_friend_dht_pubkey(onion_c, friend_num, data + 1 + sizeof(uint64_t));
const uint16_t len_nodes = length - DHTPK_DATA_MIN_LENGTH; const uint16_t len_nodes = length - DHTPK_DATA_MIN_LENGTH;
@ -1457,19 +1458,19 @@ int onion_friend_num(const Onion_Client *onion_c, const uint8_t *public_key)
/** @brief Set the size of the friend list to num. /** @brief Set the size of the friend list to num.
* *
* @retval -1 if realloc fails. * @retval -1 if mem_vrealloc fails.
* @retval 0 if it succeeds. * @retval 0 if it succeeds.
*/ */
non_null() non_null()
static int realloc_onion_friends(Onion_Client *onion_c, uint32_t num) static int realloc_onion_friends(Onion_Client *onion_c, uint32_t num)
{ {
if (num == 0) { if (num == 0) {
free(onion_c->friends_list); mem_delete(onion_c->mem, onion_c->friends_list);
onion_c->friends_list = nullptr; onion_c->friends_list = nullptr;
return 0; return 0;
} }
Onion_Friend *newonion_friends = (Onion_Friend *)realloc(onion_c->friends_list, num * sizeof(Onion_Friend)); Onion_Friend *newonion_friends = (Onion_Friend *)mem_vrealloc(onion_c->mem, onion_c->friends_list, num, sizeof(Onion_Friend));
if (newonion_friends == nullptr) { if (newonion_friends == nullptr) {
return -1; return -1;
@ -1601,7 +1602,7 @@ int onion_dht_pk_callback(Onion_Client *onion_c, int friend_num,
* return -1 on failure. * return -1 on failure.
* return 0 on success. * return 0 on success.
*/ */
int onion_set_friend_DHT_pubkey(Onion_Client *onion_c, int friend_num, const uint8_t *dht_key) int onion_set_friend_dht_pubkey(Onion_Client *onion_c, int friend_num, const uint8_t *dht_key)
{ {
if ((uint32_t)friend_num >= onion_c->num_friends) { if ((uint32_t)friend_num >= onion_c->num_friends) {
return -1; return -1;
@ -1628,7 +1629,7 @@ int onion_set_friend_DHT_pubkey(Onion_Client *onion_c, int friend_num, const uin
* return 0 on failure (no key copied). * return 0 on failure (no key copied).
* return 1 on success (key copied). * return 1 on success (key copied).
*/ */
unsigned int onion_getfriend_DHT_pubkey(const Onion_Client *onion_c, int friend_num, uint8_t *dht_key) unsigned int onion_getfriend_dht_pubkey(const Onion_Client *onion_c, int friend_num, uint8_t *dht_key)
{ {
if ((uint32_t)friend_num >= onion_c->num_friends) { if ((uint32_t)friend_num >= onion_c->num_friends) {
return 0; return 0;
@ -1656,7 +1657,7 @@ int onion_getfriendip(const Onion_Client *onion_c, int friend_num, IP_Port *ip_p
{ {
uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE];
if (onion_getfriend_DHT_pubkey(onion_c, friend_num, dht_public_key) == 0) { if (onion_getfriend_dht_pubkey(onion_c, friend_num, dht_public_key) == 0) {
return -1; return -1;
} }
@ -2074,28 +2075,29 @@ void do_onion_client(Onion_Client *onion_c)
onion_c->last_run = mono_time_get(onion_c->mono_time); onion_c->last_run = mono_time_get(onion_c->mono_time);
} }
Onion_Client *new_onion_client(const Logger *logger, const Random *rng, const Mono_Time *mono_time, Net_Crypto *c) Onion_Client *new_onion_client(const Logger *logger, const Memory *mem, const Random *rng, const Mono_Time *mono_time, Net_Crypto *c)
{ {
if (c == nullptr) { if (c == nullptr) {
return nullptr; return nullptr;
} }
Onion_Client *onion_c = (Onion_Client *)calloc(1, sizeof(Onion_Client)); Onion_Client *onion_c = (Onion_Client *)mem_alloc(mem, sizeof(Onion_Client));
if (onion_c == nullptr) { if (onion_c == nullptr) {
return nullptr; return nullptr;
} }
onion_c->announce_ping_array = ping_array_new(ANNOUNCE_ARRAY_SIZE, ANNOUNCE_TIMEOUT); onion_c->announce_ping_array = ping_array_new(mem, ANNOUNCE_ARRAY_SIZE, ANNOUNCE_TIMEOUT);
if (onion_c->announce_ping_array == nullptr) { if (onion_c->announce_ping_array == nullptr) {
free(onion_c); mem_delete(mem, onion_c);
return nullptr; return nullptr;
} }
onion_c->mono_time = mono_time; onion_c->mono_time = mono_time;
onion_c->logger = logger; onion_c->logger = logger;
onion_c->rng = rng; onion_c->rng = rng;
onion_c->mem = mem;
onion_c->dht = nc_get_dht(c); onion_c->dht = nc_get_dht(c);
onion_c->net = dht_get_net(onion_c->dht); onion_c->net = dht_get_net(onion_c->dht);
onion_c->c = c; onion_c->c = c;
@ -2117,6 +2119,8 @@ void kill_onion_client(Onion_Client *onion_c)
return; return;
} }
const Memory *mem = onion_c->mem;
ping_array_kill(onion_c->announce_ping_array); ping_array_kill(onion_c->announce_ping_array);
realloc_onion_friends(onion_c, 0); realloc_onion_friends(onion_c, 0);
networking_registerhandler(onion_c->net, NET_PACKET_ANNOUNCE_RESPONSE, nullptr, nullptr); networking_registerhandler(onion_c->net, NET_PACKET_ANNOUNCE_RESPONSE, nullptr, nullptr);
@ -2126,5 +2130,5 @@ void kill_onion_client(Onion_Client *onion_c)
cryptopacket_registerhandler(onion_c->dht, CRYPTO_PACKET_DHTPK, nullptr, nullptr); cryptopacket_registerhandler(onion_c->dht, CRYPTO_PACKET_DHTPK, nullptr, nullptr);
set_onion_packet_tcp_connection_callback(nc_get_tcp_c(onion_c->c), nullptr, nullptr); set_onion_packet_tcp_connection_callback(nc_get_tcp_c(onion_c->c), nullptr, nullptr);
crypto_memzero(onion_c, sizeof(Onion_Client)); crypto_memzero(onion_c, sizeof(Onion_Client));
free(onion_c); mem_delete(mem, onion_c);
} }

View File

@ -165,7 +165,7 @@ int onion_dht_pk_callback(Onion_Client *onion_c, int friend_num, onion_dht_pk_cb
* return 0 on success. * return 0 on success.
*/ */
non_null() non_null()
int onion_set_friend_DHT_pubkey(Onion_Client *onion_c, int friend_num, const uint8_t *dht_key); int onion_set_friend_dht_pubkey(Onion_Client *onion_c, int friend_num, const uint8_t *dht_key);
/** @brief Copy friends DHT public key into dht_key. /** @brief Copy friends DHT public key into dht_key.
* *
@ -173,7 +173,7 @@ int onion_set_friend_DHT_pubkey(Onion_Client *onion_c, int friend_num, const uin
* return 1 on success (key copied). * return 1 on success (key copied).
*/ */
non_null() non_null()
unsigned int onion_getfriend_DHT_pubkey(const Onion_Client *onion_c, int friend_num, uint8_t *dht_key); unsigned int onion_getfriend_dht_pubkey(const Onion_Client *onion_c, int friend_num, uint8_t *dht_key);
#define ONION_DATA_IN_RESPONSE_MIN_SIZE (CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE) #define ONION_DATA_IN_RESPONSE_MIN_SIZE (CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_MAC_SIZE)
#define ONION_CLIENT_MAX_DATA_SIZE (MAX_DATA_REQUEST_SIZE - ONION_DATA_IN_RESPONSE_MIN_SIZE) #define ONION_CLIENT_MAX_DATA_SIZE (MAX_DATA_REQUEST_SIZE - ONION_DATA_IN_RESPONSE_MIN_SIZE)
@ -208,7 +208,7 @@ non_null()
void do_onion_client(Onion_Client *onion_c); void do_onion_client(Onion_Client *onion_c);
non_null() non_null()
Onion_Client *new_onion_client(const Logger *logger, const Random *rng, const Mono_Time *mono_time, Net_Crypto *c); Onion_Client *new_onion_client(const Logger *logger, const Memory *mem, const Random *rng, const Mono_Time *mono_time, Net_Crypto *c);
nullable(1) nullable(1)
void kill_onion_client(Onion_Client *onion_c); void kill_onion_client(Onion_Client *onion_c);

View File

@ -336,18 +336,18 @@ void ping_iterate(Ping *ping)
} }
Ping *ping_new(const Mono_Time *mono_time, const Random *rng, DHT *dht) Ping *ping_new(const Memory *mem, const Mono_Time *mono_time, const Random *rng, DHT *dht)
{ {
Ping *ping = (Ping *)calloc(1, sizeof(Ping)); Ping *ping = (Ping *)mem_alloc(mem, sizeof(Ping));
if (ping == nullptr) { if (ping == nullptr) {
return nullptr; return nullptr;
} }
ping->ping_array = ping_array_new(PING_NUM_MAX, PING_TIMEOUT); ping->ping_array = ping_array_new(mem, PING_NUM_MAX, PING_TIMEOUT);
if (ping->ping_array == nullptr) { if (ping->ping_array == nullptr) {
free(ping); mem_delete(mem, ping);
return nullptr; return nullptr;
} }
@ -360,7 +360,7 @@ Ping *ping_new(const Mono_Time *mono_time, const Random *rng, DHT *dht)
return ping; return ping;
} }
void ping_kill(Ping *ping) void ping_kill(const Memory *mem, Ping *ping)
{ {
if (ping == nullptr) { if (ping == nullptr) {
return; return;
@ -370,5 +370,5 @@ void ping_kill(Ping *ping)
networking_registerhandler(dht_get_net(ping->dht), NET_PACKET_PING_RESPONSE, nullptr, nullptr); networking_registerhandler(dht_get_net(ping->dht), NET_PACKET_PING_RESPONSE, nullptr, nullptr);
ping_array_kill(ping->ping_array); ping_array_kill(ping->ping_array);
free(ping); mem_delete(mem, ping);
} }

View File

@ -18,10 +18,10 @@
typedef struct Ping Ping; typedef struct Ping Ping;
non_null() non_null()
Ping *ping_new(const Mono_Time *mono_time, const Random *rng, DHT *dht); Ping *ping_new(const Memory *mem, const Mono_Time *mono_time, const Random *rng, DHT *dht);
nullable(1) non_null(1) nullable(2)
void ping_kill(Ping *ping); void ping_kill(const Memory *mem, Ping *ping);
/** @brief Add nodes to the to_ping list. /** @brief Add nodes to the to_ping list.
* All nodes in this list are pinged every TIME_TO_PING seconds * All nodes in this list are pinged every TIME_TO_PING seconds

View File

@ -24,6 +24,7 @@ typedef struct Ping_Array_Entry {
} Ping_Array_Entry; } Ping_Array_Entry;
struct Ping_Array { struct Ping_Array {
const Memory *mem;
Ping_Array_Entry *entries; Ping_Array_Entry *entries;
uint32_t last_deleted; /* number representing the next entry to be deleted. */ uint32_t last_deleted; /* number representing the next entry to be deleted. */
@ -32,7 +33,7 @@ struct Ping_Array {
uint32_t timeout; /* The timeout after which entries are cleared. */ uint32_t timeout; /* The timeout after which entries are cleared. */
}; };
Ping_Array *ping_array_new(uint32_t size, uint32_t timeout) Ping_Array *ping_array_new(const Memory *mem, uint32_t size, uint32_t timeout)
{ {
if (size == 0 || timeout == 0) { if (size == 0 || timeout == 0) {
return nullptr; return nullptr;
@ -43,16 +44,17 @@ Ping_Array *ping_array_new(uint32_t size, uint32_t timeout)
return nullptr; return nullptr;
} }
Ping_Array *const empty_array = (Ping_Array *)calloc(1, sizeof(Ping_Array)); Ping_Array *const empty_array = (Ping_Array *)mem_alloc(mem, sizeof(Ping_Array));
if (empty_array == nullptr) { if (empty_array == nullptr) {
return nullptr; return nullptr;
} }
empty_array->entries = (Ping_Array_Entry *)calloc(size, sizeof(Ping_Array_Entry)); empty_array->mem = mem;
empty_array->entries = (Ping_Array_Entry *)mem_valloc(mem, size, sizeof(Ping_Array_Entry));
if (empty_array->entries == nullptr) { if (empty_array->entries == nullptr) {
free(empty_array); mem_delete(mem, empty_array);
return nullptr; return nullptr;
} }
@ -67,7 +69,7 @@ non_null()
static void clear_entry(Ping_Array *array, uint32_t index) static void clear_entry(Ping_Array *array, uint32_t index)
{ {
const Ping_Array_Entry empty = {nullptr}; const Ping_Array_Entry empty = {nullptr};
free(array->entries[index].data); mem_delete(array->mem, array->entries[index].data);
array->entries[index] = empty; array->entries[index] = empty;
} }
@ -83,8 +85,8 @@ void ping_array_kill(Ping_Array *array)
++array->last_deleted; ++array->last_deleted;
} }
free(array->entries); mem_delete(array->mem, array->entries);
free(array); mem_delete(array->mem, array);
} }
/** Clear timed out entries. */ /** Clear timed out entries. */
@ -114,7 +116,7 @@ uint64_t ping_array_add(Ping_Array *array, const Mono_Time *mono_time, const Ran
clear_entry(array, index); clear_entry(array, index);
} }
array->entries[index].data = (uint8_t *)malloc(length); array->entries[index].data = (uint8_t *)mem_balloc(array->mem, length);
if (array->entries[index].data == nullptr) { if (array->entries[index].data == nullptr) {
return 0; return 0;

View File

@ -13,6 +13,7 @@
#include <stdint.h> #include <stdint.h>
#include "crypto_core.h" #include "crypto_core.h"
#include "mem.h"
#include "mono_time.h" #include "mono_time.h"
#ifdef __cplusplus #ifdef __cplusplus
@ -29,7 +30,8 @@ typedef struct Ping_Array Ping_Array;
* *
* @return pointer to allocated Ping_Array on success, nullptr on failure. * @return pointer to allocated Ping_Array on success, nullptr on failure.
*/ */
struct Ping_Array *ping_array_new(uint32_t size, uint32_t timeout); non_null()
struct Ping_Array *ping_array_new(const Memory *mem, uint32_t size, uint32_t timeout);
/** /**
* @brief Free all the allocated memory in a @ref Ping_Array. * @brief Free all the allocated memory in a @ref Ping_Array.

View File

@ -15,41 +15,54 @@ struct Ping_Array_Deleter {
using Ping_Array_Ptr = std::unique_ptr<Ping_Array, Ping_Array_Deleter>; using Ping_Array_Ptr = std::unique_ptr<Ping_Array, Ping_Array_Deleter>;
struct Mono_Time_Deleter { struct Mono_Time_Deleter {
void operator()(Mono_Time *arr) { mono_time_free(arr); } Mono_Time_Deleter(const Memory *mem)
: mem_(mem)
{
}
void operator()(Mono_Time *arr) { mono_time_free(mem_, arr); }
private:
const Memory *mem_;
}; };
using Mono_Time_Ptr = std::unique_ptr<Mono_Time, Mono_Time_Deleter>; using Mono_Time_Ptr = std::unique_ptr<Mono_Time, Mono_Time_Deleter>;
TEST(PingArray, MinimumTimeoutIsOne) TEST(PingArray, MinimumTimeoutIsOne)
{ {
EXPECT_EQ(ping_array_new(1, 0), nullptr); const Memory *mem = system_memory();
EXPECT_NE(Ping_Array_Ptr(ping_array_new(1, 1)), nullptr); EXPECT_EQ(ping_array_new(mem, 1, 0), nullptr);
EXPECT_NE(Ping_Array_Ptr(ping_array_new(mem, 1, 1)), nullptr);
} }
TEST(PingArray, MinimumArraySizeIsOne) TEST(PingArray, MinimumArraySizeIsOne)
{ {
EXPECT_EQ(ping_array_new(0, 1), nullptr); const Memory *mem = system_memory();
EXPECT_NE(Ping_Array_Ptr(ping_array_new(1, 1)), nullptr); EXPECT_EQ(ping_array_new(mem, 0, 1), nullptr);
EXPECT_NE(Ping_Array_Ptr(ping_array_new(mem, 1, 1)), nullptr);
} }
TEST(PingArray, ArraySizeMustBePowerOfTwo) TEST(PingArray, ArraySizeMustBePowerOfTwo)
{ {
const Memory *mem = system_memory();
Ping_Array_Ptr arr; Ping_Array_Ptr arr;
arr.reset(ping_array_new(2, 1)); arr.reset(ping_array_new(mem, 2, 1));
EXPECT_NE(arr, nullptr); EXPECT_NE(arr, nullptr);
arr.reset(ping_array_new(4, 1)); arr.reset(ping_array_new(mem, 4, 1));
EXPECT_NE(arr, nullptr); EXPECT_NE(arr, nullptr);
arr.reset(ping_array_new(1024, 1)); arr.reset(ping_array_new(mem, 1024, 1));
EXPECT_NE(arr, nullptr); EXPECT_NE(arr, nullptr);
EXPECT_EQ(ping_array_new(1023, 1), nullptr); EXPECT_EQ(ping_array_new(mem, 1023, 1), nullptr);
EXPECT_EQ(ping_array_new(1234, 1), nullptr); EXPECT_EQ(ping_array_new(mem, 1234, 1), nullptr);
} }
TEST(PingArray, StoredDataCanBeRetrieved) TEST(PingArray, StoredDataCanBeRetrieved)
{ {
Ping_Array_Ptr const arr(ping_array_new(2, 1)); const Memory *mem = system_memory();
Mono_Time_Ptr const mono_time(mono_time_new(nullptr, nullptr));
Ping_Array_Ptr const arr(ping_array_new(mem, 2, 1));
Mono_Time_Ptr const mono_time(mono_time_new(mem, nullptr, nullptr), mem);
ASSERT_NE(mono_time, nullptr); ASSERT_NE(mono_time, nullptr);
const Random *rng = system_random(); const Random *rng = system_random();
ASSERT_NE(rng, nullptr); ASSERT_NE(rng, nullptr);
@ -65,8 +78,10 @@ TEST(PingArray, StoredDataCanBeRetrieved)
TEST(PingArray, RetrievingDataWithTooSmallOutputBufferHasNoEffect) TEST(PingArray, RetrievingDataWithTooSmallOutputBufferHasNoEffect)
{ {
Ping_Array_Ptr const arr(ping_array_new(2, 1)); const Memory *mem = system_memory();
Mono_Time_Ptr const mono_time(mono_time_new(nullptr, nullptr));
Ping_Array_Ptr const arr(ping_array_new(mem, 2, 1));
Mono_Time_Ptr const mono_time(mono_time_new(mem, nullptr, nullptr), mem);
ASSERT_NE(mono_time, nullptr); ASSERT_NE(mono_time, nullptr);
const Random *rng = system_random(); const Random *rng = system_random();
ASSERT_NE(rng, nullptr); ASSERT_NE(rng, nullptr);
@ -86,8 +101,10 @@ TEST(PingArray, RetrievingDataWithTooSmallOutputBufferHasNoEffect)
TEST(PingArray, ZeroLengthDataCanBeAdded) TEST(PingArray, ZeroLengthDataCanBeAdded)
{ {
Ping_Array_Ptr const arr(ping_array_new(2, 1)); const Memory *mem = system_memory();
Mono_Time_Ptr const mono_time(mono_time_new(nullptr, nullptr));
Ping_Array_Ptr const arr(ping_array_new(mem, 2, 1));
Mono_Time_Ptr const mono_time(mono_time_new(mem, nullptr, nullptr), mem);
ASSERT_NE(mono_time, nullptr); ASSERT_NE(mono_time, nullptr);
const Random *rng = system_random(); const Random *rng = system_random();
ASSERT_NE(rng, nullptr); ASSERT_NE(rng, nullptr);
@ -101,8 +118,10 @@ TEST(PingArray, ZeroLengthDataCanBeAdded)
TEST(PingArray, PingId0IsInvalid) TEST(PingArray, PingId0IsInvalid)
{ {
Ping_Array_Ptr const arr(ping_array_new(2, 1)); const Memory *mem = system_memory();
Mono_Time_Ptr const mono_time(mono_time_new(nullptr, nullptr));
Ping_Array_Ptr const arr(ping_array_new(mem, 2, 1));
Mono_Time_Ptr const mono_time(mono_time_new(mem, nullptr, nullptr), mem);
ASSERT_NE(mono_time, nullptr); ASSERT_NE(mono_time, nullptr);
uint8_t c = 0; uint8_t c = 0;
@ -112,8 +131,10 @@ TEST(PingArray, PingId0IsInvalid)
// Protection against replay attacks. // Protection against replay attacks.
TEST(PingArray, DataCanOnlyBeRetrievedOnce) TEST(PingArray, DataCanOnlyBeRetrievedOnce)
{ {
Ping_Array_Ptr const arr(ping_array_new(2, 1)); const Memory *mem = system_memory();
Mono_Time_Ptr const mono_time(mono_time_new(nullptr, nullptr));
Ping_Array_Ptr const arr(ping_array_new(mem, 2, 1));
Mono_Time_Ptr const mono_time(mono_time_new(mem, nullptr, nullptr), mem);
ASSERT_NE(mono_time, nullptr); ASSERT_NE(mono_time, nullptr);
const Random *rng = system_random(); const Random *rng = system_random();
ASSERT_NE(rng, nullptr); ASSERT_NE(rng, nullptr);
@ -128,8 +149,10 @@ TEST(PingArray, DataCanOnlyBeRetrievedOnce)
TEST(PingArray, PingIdMustMatchOnCheck) TEST(PingArray, PingIdMustMatchOnCheck)
{ {
Ping_Array_Ptr const arr(ping_array_new(1, 1)); const Memory *mem = system_memory();
Mono_Time_Ptr const mono_time(mono_time_new(nullptr, nullptr));
Ping_Array_Ptr const arr(ping_array_new(mem, 1, 1));
Mono_Time_Ptr const mono_time(mono_time_new(mem, nullptr, nullptr), mem);
ASSERT_NE(mono_time, nullptr); ASSERT_NE(mono_time, nullptr);
const Random *rng = system_random(); const Random *rng = system_random();
ASSERT_NE(rng, nullptr); ASSERT_NE(rng, nullptr);

View File

@ -6,7 +6,6 @@
#include <assert.h> #include <assert.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> // calloc(...)
#include <string.h> // memcpy(...) #include <string.h> // memcpy(...)
#include "ccompat.h" #include "ccompat.h"
@ -23,7 +22,8 @@ struct Shared_Key_Cache {
Shared_Key *keys; Shared_Key *keys;
const uint8_t* self_secret_key; const uint8_t* self_secret_key;
uint64_t timeout; /** After this time (in seconds), a key is erased on the next housekeeping cycle */ uint64_t timeout; /** After this time (in seconds), a key is erased on the next housekeeping cycle */
const Mono_Time *time; const Mono_Time *mono_time;
const Memory *mem;
uint8_t keys_per_slot; uint8_t keys_per_slot;
}; };
@ -43,37 +43,38 @@ static void shared_key_set_empty(Shared_Key *k) {
assert(shared_key_is_empty(k)); assert(shared_key_is_empty(k));
} }
Shared_Key_Cache *shared_key_cache_new(const Mono_Time *time, const uint8_t *self_secret_key, uint64_t timeout, uint8_t keys_per_slot) Shared_Key_Cache *shared_key_cache_new(const Mono_Time *mono_time, const Memory *mem, const uint8_t *self_secret_key, uint64_t timeout, uint8_t keys_per_slot)
{ {
if (time == nullptr || self_secret_key == nullptr || timeout == 0 || keys_per_slot == 0) { if (mono_time == nullptr || self_secret_key == nullptr || timeout == 0 || keys_per_slot == 0) {
return nullptr; return nullptr;
} }
// Time must not be zero, since we use that as special value for empty slots // Time must not be zero, since we use that as special value for empty slots
if (mono_time_get(time) == 0) { if (mono_time_get(mono_time) == 0) {
// Fail loudly in debug environments // Fail loudly in debug environments
assert(false); assert(false);
return nullptr; return nullptr;
} }
Shared_Key_Cache *res = (Shared_Key_Cache *)calloc(1, sizeof (Shared_Key_Cache)); Shared_Key_Cache *res = (Shared_Key_Cache *)mem_alloc(mem, sizeof(Shared_Key_Cache));
if (res == nullptr) { if (res == nullptr) {
return nullptr; return nullptr;
} }
res->self_secret_key = self_secret_key; res->self_secret_key = self_secret_key;
res->time = time; res->mono_time = mono_time;
res->mem = mem;
res->keys_per_slot = keys_per_slot; res->keys_per_slot = keys_per_slot;
// We take one byte from the public key for each bucket and store keys_per_slot elements there // We take one byte from the public key for each bucket and store keys_per_slot elements there
const size_t cache_size = 256 * keys_per_slot; const size_t cache_size = 256 * keys_per_slot;
res->keys = (Shared_Key *)calloc(cache_size, sizeof (Shared_Key)); res->keys = (Shared_Key *)mem_valloc(mem, cache_size, sizeof(Shared_Key));
if (res->keys == nullptr) { if (res->keys == nullptr) {
free(res); mem_delete(mem, res);
return nullptr; return nullptr;
} }
crypto_memlock(res->keys, cache_size * sizeof (Shared_Key)); crypto_memlock(res->keys, cache_size * sizeof(Shared_Key));
return res; return res;
} }
@ -88,15 +89,15 @@ void shared_key_cache_free(Shared_Key_Cache *cache)
// Don't leave key material in memory // Don't leave key material in memory
crypto_memzero(cache->keys, cache_size * sizeof (Shared_Key)); crypto_memzero(cache->keys, cache_size * sizeof (Shared_Key));
crypto_memunlock(cache->keys, cache_size * sizeof (Shared_Key)); crypto_memunlock(cache->keys, cache_size * sizeof (Shared_Key));
free(cache->keys); mem_delete(cache->mem, cache->keys);
free(cache); mem_delete(cache->mem, cache);
} }
/* NOTE: On each lookup housekeeping is performed to evict keys that did timeout. */ /* NOTE: On each lookup housekeeping is performed to evict keys that did timeout. */
const uint8_t *shared_key_cache_lookup(Shared_Key_Cache *cache, const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]) const uint8_t *shared_key_cache_lookup(Shared_Key_Cache *cache, const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE])
{ {
// caching the time is not necessary, but calls to mono_time_get(...) are not free // caching the time is not necessary, but calls to mono_time_get(...) are not free
const uint64_t cur_time = mono_time_get(cache->time); const uint64_t cur_time = mono_time_get(cache->mono_time);
// We can't use the first and last bytes because they are masked in curve25519. Selected 8 for good alignment. // We can't use the first and last bytes because they are masked in curve25519. Selected 8 for good alignment.
const uint8_t bucket_idx = public_key[8]; const uint8_t bucket_idx = public_key[8];
Shared_Key* bucket_start = &cache->keys[bucket_idx*cache->keys_per_slot]; Shared_Key* bucket_start = &cache->keys[bucket_idx*cache->keys_per_slot];

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